无法实施openGL选择

时间:2011-08-11 15:26:52

标签: c++ opengl picking

我已经能够找到我点击的地方的世界坐标,并且它还会使用深度缓冲区进行检查。为此,使用以下代码:

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
GLdouble x, y, z;
gluUnProject(winX, winY, z_cursor, modelview, projection, viewport, &x, &y, &z);

x_cursor和y_cursor是我的光标坐标。

到目前为止一直很好,打印x,y,z时,它们似乎很好!

但现在...... 解析包含所有多边形/三角形的文件后。我把每一个都放在openGL DISPLAY列表中。所以我的程序基本上只调用列表,并翻译/旋转它们。每个对象都有一个唯一的名称。所以我保留的是列表,我没有保留每个对象的点/三角形

我的问题:

所以我有我点击的世界坐标,但我怎样才能确定哪个对象与该位置匹配!?

4 个答案:

答案 0 :(得分:4)

如果您只想要对象ID并且愿意容忍2倍过度抽取:

1)清除颜色和深度缓冲区

2)绘制具有不同纯色的所有对象(禁用光照和纹理),保持颜色 - >对象ID图。

3)在鼠标位置读取颜色缓冲区,记下颜色并在颜色图中查找。

4)清除颜色和深度缓冲区并正常重新渲染场景。

答案 1 :(得分:1)

我想您可能对以下内容感兴趣: http://www.gpwiki.org/index.php/OpenGL:Tutorials:Picking

答案 2 :(得分:0)

请参阅OpenGL Picking Tutorial。它包含一个完整的工作示例。但是,如果您只想选择最接近相机的对象(例如,顶部绘制的对象),似乎仍然可以改进代码。但是,您可以修改代码以获得此结果。

void list_hits(GLint hits, GLuint *names)
{
    int i; int bestmatch; GLuint bestdistance;
    if (hits < 1) {
      return;
    }
    bestmatch = 0;
    bestdistance = names[bestmatch*4+1]; // min distance to object.
    for (i = 1; i < hits; i++)
    {
        distance = names[i*4+1];
        if (distance < bestdistance) {
           bestmatch = i; bestdistance = distance;
        }
    }
    printf("Hit: %d.\n", bestmatch);
 }

警告:我以前做过这个,但是这个特殊的代码没有经过测试。

答案 3 :(得分:0)

从眼睛的角度将光线投射到场景中。

使用矢量算法计算鼠标单击在近平面上的世界空间xyz位置。

以下是您需要做的事情的图表:

enter image description here

这比非项目更有效,因为unproject涉及matrix inverse (which is quite costly)

这正是您用于将光线投射到光线跟踪器的场景中用于所点击的像素的过程。 (在光线跟踪器中,您正在检索颜色,此处您正在检索对象的ID)。