gluUnProject 光线拾取(opengl/c++/glut)
我想看看是否可以在 3D 世界中使用鼠标单击 3D 绘制的对象。我知道我必须使用 gluUnProject 所以我通过以下方式进行了尝试:
首先,我有一个从鼠标获取 x,y 坐标(窗口坐标)的函数,并尝试将它们转换为现实世界坐标:
void project(int x_cursor, int y_cursor){
GLint viewport[4];
GLdouble modelview[16];
GLdouble projection[16];
GLfloat winX,winY;
glGetIntegerv(GL_VIEWPORT, viewport);
glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
glGetDoublev(GL_PROJECTION_MATRIX, projection);
// obtain the Z position (not world coordinates but in range 0 - 1)
GLfloat z_cursor;
winX = (float)x_cursor;
winY = (float)viewport[3]-(float)y_cursor;
glReadPixels(winX, winY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &z_cursor);
// obtain the world coordinates
gluUnProject(winX, winY, z_cursor, modelview, projection, viewport, &x, &y, &z);
}
然后我有鼠标回调函数:
void mouse(int button, int state, int x_cursor, int y_cursor){
if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
mouse_x=x_cursor;
mouse_y=y_cursor;
project(mouse_x,mouse_y);
cout<<x<<" "<<"Printed out variable x"<<endl;
cout<<y<<" "<<"Printed out variable y"<<endl;
cout<<z<<" "<<"Printed out variable z"<<endl;
/**for (int i = 0; i < 150; i++) {
if ((enemies[i]!=NULL)&&(enemies[i]->getTranslation().x > x - 1 && enemies[i]->getTranslation().x < x + 1)
&& (enemies[i]->getTranslation().z > z - 1 && enemies[i]->getTranslation().z < z + 1)
&& (enemies[i]->getTranslation().y > y - 1 && enemies[i]->getTranslation().y < y + 1)) {
running=false;
}
}**/
}
}
目前我只是打印出坐标 x,y,z,但在注释代码中您可以看到我打算对它们做什么:验证绘制的对象是否在直接位置我点击的地方 老鼠。
最后我添加了 glutMouseFunc(mouse); main() 函数中的行,它编译正常,但从打印的结果来看,它没有指示正确的值。
我想补充一点,我有一个移动相机;我的意思是我可以使用键盘输入更改 glulookat 参数。您能看一下我的代码,也许可以告诉我哪里做错了。多谢。
[编辑] 它似乎只在我设置相机时才起作用: gluLookAt(-35, 0, 0, 0, 100, 0, 0, 0, 1);
[EDIT2] 另外,如果我移动相机的位置,然后将其返回到初始位置(它工作的位置),它就不再工作了。
解决了。上面的代码没问题。问题是我添加了 glPushMatrix();和 glPopMatrix();绘制场景中的对象之前和之后。问题可以结束了。
I am trying to see if I can click on a 3D drawn object, using the mouse, in a 3D world. I understood that I have to use gluUnProject so I tried it out in the following way:
Firstly I have a function that gets the x,y coordinates from the mouse(the window coordinates), and tries to transform them into real world coordinates:
void project(int x_cursor, int y_cursor){
GLint viewport[4];
GLdouble modelview[16];
GLdouble projection[16];
GLfloat winX,winY;
glGetIntegerv(GL_VIEWPORT, viewport);
glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
glGetDoublev(GL_PROJECTION_MATRIX, projection);
// obtain the Z position (not world coordinates but in range 0 - 1)
GLfloat z_cursor;
winX = (float)x_cursor;
winY = (float)viewport[3]-(float)y_cursor;
glReadPixels(winX, winY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &z_cursor);
// obtain the world coordinates
gluUnProject(winX, winY, z_cursor, modelview, projection, viewport, &x, &y, &z);
}
Then I have the mouse callback function:
void mouse(int button, int state, int x_cursor, int y_cursor){
if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
mouse_x=x_cursor;
mouse_y=y_cursor;
project(mouse_x,mouse_y);
cout<<x<<" "<<"Printed out variable x"<<endl;
cout<<y<<" "<<"Printed out variable y"<<endl;
cout<<z<<" "<<"Printed out variable z"<<endl;
/**for (int i = 0; i < 150; i++) {
if ((enemies[i]!=NULL)&&(enemies[i]->getTranslation().x > x - 1 && enemies[i]->getTranslation().x < x + 1)
&& (enemies[i]->getTranslation().z > z - 1 && enemies[i]->getTranslation().z < z + 1)
&& (enemies[i]->getTranslation().y > y - 1 && enemies[i]->getTranslation().y < y + 1)) {
running=false;
}
}**/
}
}
For the moment I am just printing out the coordinates x,y,z, but in the commented code you can see what I intend to do with them: verify if a drawn object is in the immediate vecinity of the spot where I clicked the mouse.
Lastly I added the glutMouseFunc(mouse); line in the main() function, and it compiles ok, but judging by the result of the prints it doesn't indicate the correct values.
I would like to add the fact that I have a moving camera;by this I mean I can change the glulookat parameters, using keyboard input. Could you please look at my code and maybe show me where I'm doing wrong. Thanks a lot.
[EDIT] It only seems to work when I set the camera like: gluLookAt(-35, 0, 0, 0, 100, 0, 0, 0, 1);
[EDIT2] Also if I move the position of the camera, and then return it in the initial position(where it worked), it doesn't work anymore.
Solved. The above code is ok. The problem was I was adding glPushMatrix(); and glPopMatrix(); before and after drawing the objects in the scene. The question can be closed.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论