OpenGL Optimization or...?

OpenGL Optimization or...?

本文关键字:or Optimization OpenGL      更新时间:2023-10-16

我正在制作OpenGL游戏,但我在优化方面遇到了问题。当我启动它时,它没有响应。如果在Update()中,我只放了一个for循环和_time += 0.1f,我会得到一个空白屏幕。

void Update(){
    for(; ;){
        _time += 0.1f;
        Render();
    }
}
void Render() {
    glClearDepth(1.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    _colorProgram.use();
    GLuint timeLocation = _colorProgram.getUniformLocation("time");
    glUniform1f(timeLocation, _time);
    _sprite.Render();
    _colorProgram.unuse();
    glutSwapBuffers();
}
int main(int argc, char** argv) {
    std::printf("OpenGL version is %s",glGetString(GL_VERSION));
    // Window
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
    glutInitWindowPosition(520, 200);
    glutInitWindowSize(800, 600);
    glutInitDisplayMode(GLUT_DOUBLE);
    glutCreateWindow("OpenGL [ Shader #1 error pt 3 ]");
    // Setup GLEW
    if( GLEW_OK != glewInit()){
        return 1;
    } while( GL_NO_ERROR != glGetError() );
    // After creating window
    Init();
    glutDisplayFunc(Render);
    Update();
   glutMainLoop();
}

Update()中的无限循环从不允许GLUT泵送事件队列。

请改用glutTimerFunc()glutIdleFunc()来调用Update()。这样,执行流周期性地返回到GLUT,GLUT可以做它需要做的事情来让操作系统满意。

使用GLUT运行动画的正确方法是使用计时器功能。通过这种方式,GLUT可以返回到它的主循环,并调用您的显示函数。您不应该直接从自己的代码中调用display函数。

例如,在初始化期间注册一个计时器函数(第一个参数是以毫秒为单位的时间):

glutTimerFunc(10, timerFunc, 0);

然后在定时器功能中:

void timerFunc(int value) {
    _time += 0.1f;
    glutPostRedisplay();
    glutTimerFunc(10, timerFunc, 0);
}

在上面的代码片段中有两个关键部分:

  • 您不直接调用Render()函数。相反,您可以调用glutPostRedisplay()来告诉GLUT需要重新显示。然后它将调用您的Render()函数,因为您已将其注册为glutDisplayFunc()的显示函数。

  • 你必须重新注册计时器。glutTimerFunc()只触发定时器一次,而不是周期性地。所以每次它开火时你都必须重新注册。

您的代码中还有另一个问题。您的main():中有这些呼叫

glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
...
glutInitDisplayMode(GLUT_DOUBLE);

第二次调用中传递的标志将覆盖第一次调用中的标志。虽然GL_RGBA是默认值,但由于第二次调用中缺少GL_DEPTH,因此不会获得深度缓冲区。您可以简单地删除第二个调用,因为第一个调用很可能是您想要的。