用鼠标单击OpenGL拖动3d对象

时间:2018-11-15 03:26:02

标签: c++ opengl glut

我试图左键单击并拖动任何3d对象,如果我放开它,它应该保持在新位置,我将如何实现呢? 3d对象是从我在头文件中拥有的绘图功能加载的。

有人说我应该使用glutMouseFunc或glutMotionFunc。

void MouseClickCallbackFunction(int button, int state, int x, int y)
{

    if (state == GLUT_DOWN) {

    if (button == GLUT_LEFT)
    {
        std::cout << "Left " << x << " " << y <<std::endl;
        leftClick.x = x;
        leftClick.y = y;
    }
    else if (button == GLUT_RIGHT_BUTTON) {

        std::cout << "Right " << x << " " << y << std::endl;
        rightClick.x = x;
        rightClick.y = y;

    }
}
    theGame->mouseClicked(button, state, x, y);
    glutPostRedisplay();

}

/* function MouseMotionCallbackFunction()
 * Description:
 *   - this is called when the mouse is clicked and moves
 */
void MouseMotionCallbackFunction(int x, int y)
{
    theGame->mouseMoved(x, y);
    glutPostRedisplay();
}

int main(int argc, char **argv)
{
    /* initialize the window and OpenGL properly */
    glutInit(&argc, argv);
    glutInitContextVersion(4, 2);
    glutInitWindowSize(WINDOW_WIDTH, WINDOW_HEIGHT);
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
    glutCreateWindow("OpenGL Framework");

    glewExperimental = true;
    if (glewInit() != GLEW_OK)
    {
        std::cout << "GLEW could not be initialized. \n";
        system("pause");
        return 0;
    }

    //glewInit();

    std::cout << "OpenGL version: " << glGetString(GL_VERSION) << std::endl;

    /* set up our function callbacks */
    glutDisplayFunc(DisplayCallbackFunction);
    glutKeyboardFunc(KeyboardCallbackFunction);
    glutKeyboardUpFunc(KeyboardUpCallbackFunction);
    glutMouseFunc(MouseClickCallbackFunction);
    glutMotionFunc(MouseMotionCallbackFunction);
    glutTimerFunc(1, TimerCallbackFunction, 0);

    /* init the game */
    theGame = new Game();
    theGame->initializeGame();

    /* start the game */
    glutMainLoop();
    return 0;
         }

这是带有对象的绘图功能

void Game::draw()
{
    glClearColor(0, 0, 0, 0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    PassThrough.Bind();
    PassThrough.SendUniformMat4("uModel", MonkeyTransform.data, false);
    PassThrough.SendUniformMat4("uView", CameraTransform.GetInverse().data, false);
    PassThrough.SendUniformMat4("uProj", CameraProjection.data, false);

    PassThrough.SendUniform("uTex", 0);
    PassThrough.SendUniform("LightPosition", CameraTransform.GetInverse() * vec4(4.0f,0.0f,0.0f,1.0f));
    PassThrough.SendUniform("LightAmbient", vec3(0.15f, 0.15f, 0.15f));
    PassThrough.SendUniform("LightDiffuse", vec3(0.7f,0.1f,0.2f));
    PassThrough.SendUniform("LightSpecular", vec3(0.8f,0.1f,0.1f));
    PassThrough.SendUniform("LightSpecularExponent", 50.0f);
    PassThrough.SendUniform("Attenuation_Constant", 1.0f);
    PassThrough.SendUniform("Attenuation_Linear", 0.1f);
    PassThrough.SendUniform("Attenuation_Quadratic", 0.01f);

    glBindVertexArray(Monkey.VAO);
    glDrawArrays(GL_TRIANGLES, 0, Monkey.GetNumVerticies());
    glBindVertexArray(0); 

    PassThrough.unBind();
    glutSwapBuffers();
}

1 个答案:

答案 0 :(得分:0)

该概念称为鼠标拾取。实现此目的的一种方法是射线投射。本质上,您要做的就是将鼠标坐标映射到场景中的某个区域。在您的情况下,您要检查位置是否在猴子内。然后,就像处理鼠标的上,下和移动事件一样简单。

鼠标向下:检查是否正在拾取对象。如果是这样,那就太好了-也许要突出显示它或其他东西。将引用存储到拾取的对象;在拾取(pos)开始时存储鼠标的位置

鼠标移动:鼠标按下了吗?是拾取的对象参考?根据鼠标移动事件中pos和坐标之间的增量更新对象位置

鼠标向上移动:清除选择的obj参考,位置

此链接可能是您感兴趣的http://antongerdelan.net/opengl/raycasting.html