opengl鼠标坐标到世界坐标

时间:2012-08-18 15:44:48

标签: opengl glut

我需要检测鼠标移动并在鼠标位置画一个球。我需要球在世界坐标。所以我正在尝试使用glUnProject来完成这项任务,看起来我到目前为止还没有成功。这是我的motionFunc

void motionFunc( int x, int y)
{


    GLint viewport[4];
    GLdouble modelview[16];
    GLdouble projection[16];
    GLfloat winX, winY, winZ;
    GLdouble posX, posY, posZ;

    glGetDoublev( GL_MODELVIEW_MATRIX, modelview );
    glGetDoublev( GL_PROJECTION_MATRIX, projection );
    glGetIntegerv( GL_VIEWPORT, viewport );

    winX = (float)x;
    winY = (float)viewport[3] - (float)y;
    glReadPixels( x, int(winY), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ );

    gluUnProject( winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ);      //printf("winz: %f posz: %f\n",winZ,posZ);
    Ball.x=posX;
    Ball.y=posY;
    Ball.z=posZ;
    //printf("%f %f %f\n",Ball.x,Ball.y,posZ);
    glutPostRedisplay();
}

现在,我在glutPostRedisplay上添加了一个断点。当我点击拖动鼠标时,Ball的坐标(Ball.x,Ball.y,Ball.z)就像是:

(Ball).x -727.175354
(Ball).y 407.310242
(Ball).z -865.000610

为什么z坐标到目前为止?我的相机在z = + 135。我的模型中的其他对象就像是在z = -3到+3。我需要球的z坐标在相同的范围内。

现在,究竟是什么winZ?在这里,我检查它总是1.00。我试图硬编码winZ,我发现winZ=0.85,球看起来总是在鼠标下面(我可以用鼠标拖球,球总是在指针下面)。但是Ball的坐标就像:

(Ball).x -4.67813921
(Ball).y 2.57806134
(Ball).z 128.370895

这是如此接近相机,但x和y坐标对我不利。他们总是出来靠近原点。这不是我想要的。我的其他物体的x和y坐标范围更广。

最后,我的问题是,glUnproject或同类事情的正确方法是什么?

1 个答案:

答案 0 :(得分:0)

2D鼠标坐标无法明确地取消映射到3D世界坐标。 2D坐标对应于3D空间中的线。 winz会影响此行的哪一点返回。当您使用0.0作为winz时,您将获得近剪裁平面上的点。当你使用1.0时,你将得到远剪裁平面上的点。

如果您使用深度缓冲区,则可以使用glReadPixels函数从深度缓冲区中检索值,并将其用作winz。这是我在Java中玩具项目的一段代码

    FloatBuffer depth = BufferUtils.createFloatBuffer(1);
    glReadPixels(mouse_x, mouse_y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, depth);

    depth.rewind();
    FloatBuffer farPos = BufferUtils.createFloatBuffer(3);
    GLU.gluUnProject(mouse_x, mouse_y, depth.get(), 
            mainContext.getModelviewMatrix(), 
            mainContext.getProjectionMatrix(), viewport, farPos);

除了奇怪的NIO缓冲区外,大多数在C / C ++中是相同的。