gluPickMatrix - 出了点问题,一个对象总是在现场

时间:2012-07-19 15:51:43

标签: c++ qt opengl graphics 3d

我有以下代码来绘制一个openGL场景

void QGLDiagramWidget::paintGL()
{

    glClearColor(0.2f, 0.0f, 0.5f, 0.0f);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LESS);
    glEnable(GL_MULTISAMPLE);

    ... load shaders...

    ... load buffers...

    ... load textures...

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // Set viewport area
    glViewport(0, 0, this->size().width(), this->size().height());

    GLint view[4];
    glGetIntegerv(GL_VIEWPORT, view);
    glLoadIdentity();

    gluPickMatrix(1, 1, 1, 1, view); // THIS IS THE RELEVANT CODE

    // I don't use a fixed pipeline, so let's store this pickmatrix in a variable
    Matrix pickingPerspMatrix;
    glGetFloatv(GL_PROJECTION_MATRIX, pickingPerspMatrix); // This is successful in my code

    // Create the projection matrix
    gl_projection.setToIdentity();
    gl_projection *= pickingPerspMatrix; // APPLY THE PICKING MATRIX
    gl_projection.perspective(45.,((GLfloat)this->size().width())/((GLfloat)this->size().height()),0.1f,100.0f);



    ... now draw the entire scene with shaders, there's a camera matrix (view) and a model matrix (model) ...
}

只要我知道,这应该从宽度为1和高度为1的左下角像素1,1(场景的第一个)的矩形中选取一个拾取矩阵,并将其乘以单位矩阵,然后应用透视矩阵。

目标是:将我的像素区域居中放在视口上并渲染那里真正可见的内容。

事实证明,无论我放入gluPickMatrix的任何值,我的视口中的对象始终可见,只是缩小或扭曲或变形,但总是在视口区域中。这是错误的,因为要求从点(0; 0)加上宽度1和高度1的拾取矩阵应该返回一个空区域。

这是我为帮助您理解问题而获得的图像

enter image description here

为什么会这样?什么是选择矩阵应该做什么?将对象翻译出场景?由于我在着色器中使用可编程管道(它们基本上是简单的着色器,用于在对象上加载纹理并使用phong照明),是什么原因可能导致对象变形并在场景中不断出现?

1 个答案:

答案 0 :(得分:1)

pickmatrix用于限制渲染到视口的一小部分。在这里阅读gluPickMatrix:http://www.opengl.org/sdk/docs/man/xhtml/gluPickMatrix.xml

拣货不适用于您的可编程管道。拣选的工作原理是将每个drawcall与一个“name”(一个代表可选择对象的数字)相关联,当用拾取渲染场景时,它会返回任何像素/碎片。

详细说明如下: http://content.gpwiki.org/index.php/OpenGL:Tutorials:Picking 和这里 web.engr.oregonstate.edu /.../Picking/picking.pdf

最好避免使用已弃用的功能并使用颜色选择,使用唯一的纯色渲染每个对象,然后使用glReadPixels找出鼠标下的内容。

这里很好地解释了Colorpicking:http://content.gpwiki.org/index.php/OpenGL_Selection_Using_Unique_Color_IDs

另一种可能性是使用光线原始测试进行选择。