gluUnProject 光线拾取(opengl/c++/glut)

发布于 2024-12-26 06:12:05 字数 2175 浏览 5 评论 0原文

我想看看是否可以在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文