0

我需要绘制一个立方体并使用默认投影矩阵对其进行投影。另外,我想画一个控制球体方向的平视显示器。使用另一个投影矩阵对 hud 进行投影。

render()
{
    DrawGUI(); // project GUI with another projection matrix

    glPushMatrix();
    glutSolidCube(); // project the cube with the default projection matrix
    glPopMatrix();

    glutSwapBuffers();
}

reshape()
{
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(...);

    ...
}

DrawGUI()
{
    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();
    gluOrtho2D(...); // project the GUI with this matrix

    glMatrixMode(GL_MODELVEIW);
    glPushMatrix();
    glLoadIdentity();


    glBegin();
    //... drawing GUI
    glEnd();

    glPopMatrix();
    glMatrixMode(GL_PROJECTION);
    glPopMatrix();
    glMatrixMode(GL_MODELVIEW);

}

#define BUFFER_LENGTH 64

void processSelection(int xPos, int yPos)
{

    static GLuint selectBuff[BUFFER_LENGTH];
    GLint hits, viewport[4];

    glSelectBuffer(BUFFER_LENGTH, selectBuff);
    glGetIntegerv(GL_VIEWPORT, viewport);

    // Switch to projection and save the matrix
    glMatrixMode(GL_PROJECTION);
    glPushMatrix();

    glRenderMode(GL_SELECT);
    glLoadIdentity();

    gluPickMatrix(xPos, viewport[3] - yPos, 2,2, viewport);

    glOrtho (-100, 100, -100, 100, -100, 100); // this line of code is the most

    glMatrixMode(GL_MODELVIEW);
    render();

    hits = glRenderMode(GL_RENDER);

    //...process hits

    // Restore the projection matrix
    glMatrixMode(GL_PROJECTION);
    glPopMatrix();
    glMatrixMode(GL_MODELVIEW);
}

渲染部分效果很好。GUI 和立方体都可以毫无问题地绘制。但是,选择不会按预期工作。

我的问题是:由于我用不同的投影矩阵投影 3D 模型,我应该如何处理选择?我尝试实现典型的选择缓冲区方法,但是每次在窗口中单击时,即使我没有单击 GUI,选择缓冲区也始终包含 GUI。此外,如果我单击多维数据集,选择缓冲区将同时包含多维数据集和 GUI。

4

1 回答 1

2

如果您使用选择缓冲区方法,您将使用混合投影进行渲染,就像在进行通常的渲染时一样。唯一的区别是,您也应用了该选择矩阵。也不要试图对矩阵推/弹出太聪明。在投影矩阵堆栈中使用它几乎没有意义(因此它只需要 2 个推送级别,而不是模型视图的 32 个)。也不要使用 reshape 函数来定义投影矩阵。

DrawCube()
{
    glMatrixMode(GL_MODELVEIW);
    glLoadIdentity();

    glutSolidCube();
}

DrawGUI()
{
    glMatrixMode(GL_MODELVEIW);
    glLoadIdentity();

    glBegin();
    //... drawing GUI
    glEnd();
}

void render()
{
    // base the projection on whats already in the projection
    // matrix stack. For normal render this is identity, for
    // selection it is a pick matrix.

    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    gluOrtho2D(...); // project the GUI with this matrix
    DrawGUI();
    glMatrixMode(GL_PROJECTION);
    glPopMatrix();

    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    gluPerspective(...);
    glMatrixMode(GL_PROJECTION);
    glPopMatrix();
}

void display()
{
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    render();

    glutSwapBuffers();
}

#define BUFFER_LENGTH 64

void select(int xPos, int yPos)
{
    static GLuint selectBuff[BUFFER_LENGTH];
    GLint hits, viewport[4];

    glSelectBuffer(BUFFER_LENGTH, selectBuff);
    glGetIntegerv(GL_VIEWPORT, viewport);

    // Switch to projection and augment it with a picking matrix
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPickMatrix(xPos, viewport[3] - yPos, 2,2, viewport);

    glRenderMode(GL_SELECT);
    render();

    hits = glRenderMode(GL_RENDER);

    //...process hits
}

请注意,OpenGL 选择模式通常不是 GPU 加速的,因此非常慢。此外,它已被弃用并从现代 OpenGL 版本中删除。强烈建议使用索引缓冲区选择(即使用专用索引“颜色”渲染每个对象)或在场景数据中执行手动光线交叉拾取。

于 2013-08-15T09:27:47.457 回答