删除 glLoadIdentity 时屏幕变为空白

when removing glLoadIdentity screen goes blank

我有一个相机 class 和一个 Vector3 class(很明显它们的意思),Vector3 class 构造函数采用三个浮点参数,每个参数的默认值为零,所以调用 Vector3() 等同于 Vector3(0,0,0)

相机 class 构造函数也采用三个参数,每个参数是 Vector3、positing、viewpoint 和 up 向量。

这是我的代码,稍后会解释问题:

#include "camera.h"
Vector3 StartPoint(1000,1000,1000);

Camera camera(Vector3(1000,1000,1100),Vector3(StartPoint),Vector3(0,1));
void resize(int width, int height)
{
    const float ar = (float) width / (float) height;
    glViewport(0, 0, width, height);    
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glFrustum(-ar, ar, -1.0, 1.0, 2, 1000.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    camera.LookAt();
}   
void display()
{

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();
    camera.LookAt();   
    //draw some things
    glutSwapBuffers();
}   
void idle(void)
{    
    glutPostRedisplay();
}    

/* Program entry point */
int main(int argc, char *argv[])
{
    glutInit(&argc, argv);
    glutInitWindowSize(640,480);
    glutInitWindowPosition(300,200);
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
    glutCreateWindow("Tischfussball");
    glutReshapeFunc(resize);    
    glutDisplayFunc(display);   
    glutIdleFunc(idle);   
    glutMainLoop();
    return EXIT_SUCCESS;
} 

我有一个相机 class,它与上面的代码配合得很好,但是当从显示功能中删除 glLoadIdentity 行时,屏幕显示为空白!

我搜索并发现了一些关于空闲函数的信息,所以我将带有 camera.LookAt 的 glLoadIdentity 移动到空闲函数,但没有用。

我不想放入我不理解的代码,我想删除该行,因为我认为我的逻辑没有任何必要,我的意思是 glLoadIdentity 只是将矩阵恢复为单位矩阵(根据最后的 MatrixMode,它在这里恢复了 MODELVIEW 矩阵),根本没有必要在每个显示器上调用它(我认为这是对性能的浪费)。

我真的很困惑,这是如何工作的?!!

编辑

camera.LookAt() 等同于 gluLookAt(camera.position.x,camera.position.y,camera.position.z,camera.view.x,camera.view.y,camera.view.z,camera.up.x,camera.up.y,camera.up.z)

//draw some things 部分没有调用 glTranslate* 或 glRotate*。

唯一更改相机变量的调用是在按键事件上调用的,我在 window 出现后看到空白屏幕(还没有按下任何键),我按下了一些没有用的键。

我不知道你的 camera.lookAt() 是如何实现的,但我有根据地猜测它使用了类似 gluLookAt() 的东西。现在 gluLookAt()(像除 glLoad*() 之外的所有 GL 矩阵函数) 将当前所选矩阵模式的当前矩阵乘以它在内部创建的 LookAt 矩阵。在大多数情况下,您希望当前矩阵是 Identity,否则相机变换将不是您所期望的。

我还猜测您的 //draw some things 代码实际上修改了 GL_MODELVIEW 矩阵,因此它不会保留在 camera.LookAt() 返回后的原样 - 这非常好,因为GL_MODIELVIEW 矩阵是模型矩阵(每个对象可能不同)和视图矩阵(通常在整个帧中保持不变)的组合。

所以当你不重置它时,前一帧的变换将会累积,很可能将你的场景完全移出视野。

当您在相机 class 中调用 glTranslate*()glRotate*() 等函数时(或调用使用它们的函数,例如 gluLookAt()),这些函数将不要将您的视图矩阵设置为特定状态,而只是转换它们。

这意味着当您的显示函数一遍又一遍地调用此函数而不在每一帧之间调用 glLoadIdentity() 时,这会将矩阵设置为恒等状态,旋转或变换将总结可能导致的结果到黑屏,因为经过一些迭代后,您的相机处于无处可去的状态。

不要害怕出于性能原因调用此类函数。 您必须想象像游戏这样的应用程序每帧调用数千个矩阵操作函数。 所以一次调用不会破坏任何性能。

我知道这不是主题,但我强烈建议您使用更新的 OpenGL API。您这样做的方式已被弃用。

只需 google 即可获得 "opengl 4 tutorial" 或 "modern opengl" 之类的东西,以了解使用 OpenGL 的最新方法。

编辑:

正如您已经说过的,您的相机中没有调用矩阵操作函数class。但是gluLookAt()函数调用了这样的函数。

您必须记住,在 OpenGL 中没有什么比 'camera' 更好的了。移动虚拟相机的唯一方法是更改​​视图矩阵,这也是通过 gluLookAt().

等函数完成的