如何用OpenGL制作一个可拖动的对象?

时间:2013-02-01 17:38:54

标签: opengl graphics glfw

我有一个代码,我在OpenGL中生成一个pawn。但是,我想让它的部件可拖动。我的问题更多的是一般问题,但这里是我的典当的代码,以便你了解我在做什么:

int main()
{
    /* open gl initialization */

    while(running())
    {
        glClear(GL_COLOR_BUFFER_BIT + GL_DEPTH_BUFFER_BIT);
        glLoadIdentity();

        glColor3ub(0, 0, 0);

        /* the basis of the pawn */
        glPushMatrix();
        glScalef(1.6, 1.6, 0.8);
        glTranslatef(0.0, 0.0, -2.7 - offset);
        drawSmoothUnityEllipsoidPatch(0, 2*M_PI, 0, M_PI /2 );
        glPopMatrix();

        /* upped ellipsoid */
        glPushMatrix();
        glScalef(0.8, 0.8, 0.15);
        glTranslatef(0.0 - offset, 0.0, 6.0);
        drawSmoothUnitySphere();
        glPopMatrix();

        /* lower ellipsoid */
        glPushMatrix();
        glScalef(1.2, 1.2, 0.15);
        glTranslatef(0.0 - offset, 0.0, -10.0);
        drawSmoothUnitySphere();
        glPopMatrix();

        /* the cone */
        glPushMatrix();
        glScalef(1.0, 1.0, 3.5);
        glTranslatef(0.0 + offset, 0.0, -0.5);
        drawSmoothUnityCone();
        glPopMatrix();

        /* the sphere on top of the pawn */
        glPushMatrix();
        glScalef(0.7, 0.7, 0.7);
        glTranslatef(0.0, 0.0, 2.3 + offset);
        drawSmoothUnitySphere();
        glPopMatrix();

    glfwTerminate();
    return 0;
}

其中offset与此无关。函数drawSmoothUnity(shape)只是在坐标系的中心绘制一个统一的形状。我希望能够在可见区域中拖放任何这些形状(800x600,我的窗口大小)。

1 个答案:

答案 0 :(得分:1)

您可以使用gluUnproject将光标位置从屏幕空间映射到世界空间。通过首次点击鼠标按钮到当前位置(拖动后)跟踪3D世界坐标的增量,可以获得用于翻译对象的x,y和z值。

此外,它应该是'glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);'

这有点脱离我的头脑并且是伪装的。这不考虑任何选择或任何选择。因此,单击并移动鼠标将移动对象,即使单击时对象不在鼠标光标下也是如此。你显然需要添加鼠标处理程序。

glm::dvec3 original_position;//position of object when we start moving
glm::dvec3 world_anchor;//world space coordinates of where we left clicked
glm::ivec2 screen_anchor;//screen space coordinates of where we left clicked
Object object;
OnLButtonDown(int x, int y)//x,y = where we clicked
{
   original_position = object.GetPosition();
   screen_anchor = ivec2(x,y);//screen coords where we clicked
   gluUnproject(x,y,0,modelview_matrix,projection_matrix,viewport,&world_anchor.x,
   &world_anchor.y,&world_anchor.z);
}
OnMouseMove(int x, int y) //x,y = current mouse cursor position
{
   if(left_button_down)
      MoveObject(screen_anchor.x-x,screen_anchor.y-y);
}


}
MoveObject(int dx, int dy)//dx,dy = distance from current mouse position to screen_anchor
{
    glm::dvec3 world_position;//current mouse position in world coordinates
    gluUnProject(dx,dy,0,modelview_matrix,projection_matrix,viewport,&world_position.x,
    &world_position.y,&world_position.z);

    glm::dev3 world_delta = world_anchor-world_position;
    object.SetPosition(original_position+world_delta);

}