我需要检测鼠标移动并在鼠标位置画一个球。我需要球在世界坐标。所以我正在尝试使用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
或同类事情的正确方法是什么?
答案 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 ++中是相同的。