删除glLoadIdentity时屏幕变为空白

时间:2015-05-03 18:36:10

标签: opengl freeglut

我有一个摄像头类和一个Vector3类(显然他们的意思),Vector3类构造函数需要三个浮点参数,每个参数的默认值为零,因此调用Vector3()相当于Vector3(0,0,0)

相机类构造函数还有三个参数,每个参数是一个Vector3,即定位,视点和向上矢量。

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

#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;
} 

我有一个相机类,可以很好地使用上面的代码,但是当从显示功能中删除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 *。

在键事件中调用更改摄像机变量的唯一调用,我看到窗口出现后的空白屏幕(没有按下按键),我按下一些键没有用。

2 个答案:

答案 0 :(得分:2)

当您在相机类中调用glTranslate*()glRotate*()等函数(或调用使用它们的函数,如gluLookAt())时,函数不会将您的视图矩阵设置为一个特定的状态,但只是改变它们。

这意味着当你的显示函数反复调用这些函数而不在每个帧之间调用glLoadIdentity()时,将矩阵设置为标识状态,旋转或转换将总结为可能导致的黑屏因为经过一些迭代后你的相机处于不知名的地方。

并且由于性能原因,不要害怕调用这些函数。 你必须想象像游戏这样的应用程序每帧调用数千个矩阵操作函数。 所以一个电话不会杀死任何表演。

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

只需谷歌浏览" opengl 4 tutorial"或者"现代opengl"联系使用OpenGL的最新方法。

修改

就像你已经说过的那样,你的相机类中没有矩阵操作函数的调用。但是gluLookAt()函数调用了这样的函数。

你必须记住,没有像摄像机那样的东西。在OpenGL中。移动虚拟摄像机的唯一方法是更改​​视图矩阵,这也可以通过gluLookAt()等功能完成。

答案 1 :(得分:0)

我不知道你的camera.lookAt()是如何完全实现的,但我正在做出有根据的猜测,即它使用的是gluLookAt()。现在,gluLookAt()(与除glLoad*()之外的所有GL矩阵函数一样)通过其内部创建的LookAt矩阵将当前所选矩阵模式的当前矩阵相乘。在大多数情况下,您希望当前矩阵为Identity,否则摄像机转换将不是您所期望的。

我还猜测,您的//draw some things代码实际上修改了GL_MODELVIEW矩阵,因此它不会留在camera.LookAt()返回后的内容 - 这完全没问题,因为{ {1}}矩阵是模型矩阵的组成(可以根据对象而变化)和视图矩阵(在整个帧中通常是不变的。)

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