11

问题

我刚刚开始使用 GLUT 使用 OpenGL。下面的代码编译并显示了两个线框立方体和一个球体。问题是当我尝试拖动或调整窗口大小时,它会在跟随我的鼠标之前引起明显的延迟。

这个问题在我同事的电脑上没有出现,同样的代码。

我正在 Windows 7 计算机上使用 Visual Studio 2012 c++ express。我不是一个经验丰富的程序员。

编码

    // OpenGLHandin1.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <GL/glut.h>

void initView(int argc, char * argv[]){
    //init here
    glutInit(&argc, argv);
    //Simple buffer
    glutInitDisplayMode( GLUT_SINGLE | GLUT_RGBA );
    glutInitWindowPosition(100,100);
    glutInitWindowSize(800,400);
    glutCreateWindow("Handin 2");
}
void draw(){

    glClearColor(0,0,0,1);
    glClear(GL_COLOR_BUFFER_BIT);
    //Background color

    glPushMatrix();
    glLoadIdentity();
    glTranslatef(0.6, 0, 0);

    glColor3f(0.8,0,0);
    glutWireCube(1.1); //Draw the cube
    glPopMatrix();

    glPushMatrix();
    glLoadIdentity();
    glTranslatef(-0.5, 0, -0.2);

    glColor3f(0,0.8,0);
    glutWireCube(1.1); //Draw the cube
    glPopMatrix();

    glPushMatrix();
    glLoadIdentity();
    glTranslatef(0, 1.2, 0);
    glRotatef(90, 1, 0, 0);

    glColor3f(1,1,1);
    glutWireSphere(0.6, 20, 20); //Draw the sphere
    glPopMatrix();

    //draw here
    //glutSwapBuffers();
    glutPostRedisplay();
    glFlush();

}
void reshape (int w, int h){
    glViewport(0,0,w ,h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45, (float)w/(float)h, 1.5, 10);
    gluLookAt(1.5, 2.5, 4, 
              0, 0.6, 0, 
              0, 1, 0); //Orient the camera
    glRotatef(5, 0, 0, 1);
    glMatrixMode(GL_MODELVIEW);
}
int main(int argc, char * argv[])
{
    initView(argc,argv);
    glutDisplayFunc(draw);
    glutReshapeFunc(reshape);
    glutMainLoop();
}
4

1 回答 1

12

解决方案:

似乎Sleep(1)在渲染函数中使用的简单解决方案有效。您还问过为什么 - 我不确定我能否正确解决这个问题,但这是我最好的猜测:

为什么它甚至可以工作?

您的同学可以在他们的驱动程序中默认打开 VSync。这导致他们的代码只能以屏幕刷新的速度运行,很可能是 60 fps。它为您提供大约 16 毫秒的帧渲染时间,如果代码高效(例如,渲染时间为 2 毫秒),它会为 CPU 留出大量时间来执行其他与操作系统相关的事情,例如移动窗口。

现在,如果您禁用垂直同步,程序将尝试渲染尽可能多的帧,从而有效地阻塞所有其他进程。我建议您使用睡眠,因为它揭示了这一特定问题。它是 1 毫秒还是 3 毫秒并不重要,它真正做的是说“嘿,CPU,我现在没有特别做任何事情,所以你可以做其他事情”。

但这不会减慢我的程序吗?

使用睡眠是一种常见的技术。如果您担心每帧丢失 1 毫秒,您也可以尝试 put Sleep(0),因为它的行为应该完全相同 - 将空闲时间留给 CPU。您也可以尝试启用垂直同步并验证我的猜测是否正确。

附带说明一下,您还可以查看有和没有睡眠的 CPU 使用率图表。它应该是 100%(或在双核 CPU 上为 50%)没有(尽可能快地运行),并且要低得多,具体取决于您的程序要求和 CPU 的速度。

关于 Sleep(0) 的补充说明

休眠间隔过后,线程就可以运行了。如果您指定 0 毫秒,线程将放弃其时间片的剩余部分但保持就绪状态。请注意,不保证就绪线程会立即运行。因此,线程可能要等到休眠间隔过去一段时间后才会运行。- 来自这里

另请注意,在 Linux 系统上的行为可能略有不同;但我不是 linux 专家;也许路人可以澄清一下。

于 2012-09-27T11:35:54.947 回答