0

我需要检测鼠标运动并在鼠标的位置画一个球。我需要球处于世界坐标中。所以我正在尝试使用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.x,Ball.y,Ball.z)类似于:

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

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

now, what exactly is winZ? Here, I checked it always turns out to be 1.00. I tried to hardcode winZ and I found at winZ=0.85, the ball seems like to be always under the mouse(I can drag the ball with my mouse and the ball is always under the pointer). But then the Ball's coordinates are like:

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

which is so close to the camera but x and y coordinates are not good for me. they always come out to be near the origin. which is not what I want. My other objects' x and y coordinates have a wider range.

Finally, my question is, what is the correct way to do glUnproject or something of the same sort?

4

1 回答 1

1

A 2D mouse coordinate cannot unambiguously unmapped to a 3D world coordinate. The 2D coordinate corresponds with a line in 3D space. The winz influences which point on this line is returned. When you use 0.0 for winz you will get the point at the near clipping plane. When you use 1.0 you will get the point at the far clipping plane.

If you are using a depth buffer you could retrieve the value from the depth buffer using the glReadPixels function and use that as winz. Here a piece of code from a toy project of mine in 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);

Most is the same in C/C++ except for the weird NIO buffers.

于 2012-08-18T16:02:53.440 回答