Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Opengl选择使用不同投影矩阵绘制的三维模型_Opengl_User Interface_Selection_Projection - Fatal编程技术网

Opengl选择使用不同投影矩阵绘制的三维模型

Opengl选择使用不同投影矩阵绘制的三维模型,opengl,user-interface,selection,projection,Opengl,User Interface,Selection,Projection,我需要画一个立方体并用默认的投影矩阵投影它。另外,我想画一个控制球体方向的hud。hud通过另一个投影矩阵进行投影 render() { DrawGUI(); // project GUI with another projection matrix glPushMatrix(); glutSolidCube(); // project the cube with the default projection matrix glPopMatrix();

我需要画一个立方体并用默认的投影矩阵投影它。另外,我想画一个控制球体方向的hud。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);
}
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
}
渲染部分工作得很好。GUI和多维数据集的绘制都没有问题。但是,该选择无法按预期工作


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

如果使用“选择缓冲区”(selection buffer)方法,则可以像进行常规渲染一样使用混合投影进行渲染。唯一的区别是,您也应用了拾取矩阵。也不要试图在矩阵推送/弹出方面太聪明。在投影矩阵堆栈中使用它几乎没有意义(因此它只需要2个推送级别,而不是modelview的32个推送级别)。也不要使用重塑函数来定义投影矩阵

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);
}
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版本中删除。强烈建议使用索引缓冲区选择(即使用专用索引“颜色”渲染每个对象)或对场景数据执行手动光线相交拾取。

谢谢。我通过在render()中定义投影矩阵来实现它。选择正确地分别处理GUI和多维数据集。但是我仍然对我以前遇到的问题感到困惑——“每次我点击窗口时,选择缓冲区总是包含GUI,即使我没有点击GUI。”@user2127480:是否您的GUI是一个单一的、充满屏幕的四块体?OpenGL选择模式相当于转储:它只是检查渲染的几何体的任何部分是否显示在选择视口的限制范围内。如果只渲染单个视口填充四边形,则该四边形将始终显示在选择缓冲区中。OpenGL选择模式真的不值得很多。最好自己实现一个真正的拾取机制,它可以感知纹理四边形上的GUI元素。关于你的建议,“也不要使用重塑函数来定义投影矩阵。”你能解释一下吗?@user2127480:OpenGL是一个状态驱动的绘图系统。与每个状态机一样,您应该在需要时将其置于所需状态。在渲染帧的过程中,必须多次更改使用的投影。你的申请就是其中之一。只有在下一层的操作建立在已经存在的基础上时,在堆栈上推送/弹出矩阵才有意义,因为它的用途在于构建一种可以退一步的转换继承方法。如果从标识开始,则推送/弹出没有任何意义。@user2127480:通常,您应该从显示处理程序中进行与图形相关的OpenGL调用。设置转换矩阵与图形相关。