Opengl GLX动画比预期的慢

Opengl GLX动画比预期的慢,opengl,xcb,glx,Opengl,Xcb,Glx,我有一个使用XCB和openGL的应用程序。首先,我选择具有以下属性的帧缓冲区配置: const int attributes[] = {GLX_BUFFER_SIZE, 32, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, True, GLX_RENDER_TYPE, GLX_RGBA_BIT, None}; fb_configs = glXChooseFBConfig(display, screen_index, attributes, &fb_conf

我有一个使用XCB和openGL的应用程序。首先,我选择具有以下属性的帧缓冲区配置:

const int attributes[] = {GLX_BUFFER_SIZE, 32, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, True, GLX_RENDER_TYPE, GLX_RGBA_BIT, None};
fb_configs = glXChooseFBConfig(display, screen_index, attributes, &fb_configs_count);
我运行了一个简单的动画,它应该持续一个固定的时间(1s),但是在屏幕上显示它需要更长的时间(大约5s)。在添加日志以显示进度值之后,我发现实际循环只持续1s

struct timeval start; // start time of the animation
gettimeofday(&start, 0);

while (1)
{
    double progress = timer_progress(&start);
    if (progress > 1.0)
        break; // end the animation

    draw(progress);
    glXSwapBuffers(display, drawable);

    xcb_generic_event_t *event = xcb_poll_for_event(connection);
    if (!event)
    {
        usleep(1000);
        continue;
    }

    switch (event->response_type & ~0x80)
    {
    case XCB_EXPOSE:
    default:
        free(event);
        continue;
    }
}
我不确定到底发生了什么。我假设在每次迭代中,
glXSwapBuffers()
都会将用于绘图的opengl命令排成队列,其中大多数命令在循环结束后仍有待执行

调整
usleep()
的参数除了使动画变得不太平滑或使动画变得更慢之外,没有其他效果。当我切换到单缓冲时,问题就消失了(但我得到了与单缓冲相关的问题)


似乎我没有做正确的事情,但我不知道该做什么。

glXSwapBuffers的确切计时行为对每个实现都是开放的。NVidia和fglrx选择阻止GLXSWAPBuffer,直到V-Sync(如果启用了V-Sync),Mesa和Intel选择立即返回,并在下一次调用时阻止不再适合命令队列的调用,在下一次调用时,将在V-Sync停止前修改后缓冲区的调用

但是,如果您希望的是动画的精确长度,则具有固定帧数和执行延迟的循环将不起作用。相反,您应该尽可能快地重新绘制(并且仅使用延迟来限制绘制速率)。动画应该按照实际绘制迭代之间经过的实际时间进行,而不是固定的时间步(这与游戏循环相反,游戏循环实际上应该使用固定的时间步,尽管速度比绘制快得多)


最后但并非最不重要的一点是,您不能使用
gettimeofday
来控制动画
gettimeofday
报告挂钟时间,挂钟时间可能会跳变、变慢或上升,甚至向后运行。请使用高精度计时器(
clock\u gettime(clock\u MONOTONIC,…)
)。

我使用延迟只是为了限制绘图速率
timer\u progress()
返回自
start
draw()
使用该值以来经过的时间。