gpt4 book ai didi

linux - OpenGL - 渲染时间抖动使动画不稳定

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:10:56 26 4
gpt4 key购买 nike

一个小的测试程序(见下文)显示了不稳定的输出,我认为这是由 OpenGL glutSwapBuffer() 期间奇怪的时序抖动引起的。与平均水平相比,测试程序经常显示单帧的渲染时间非常长(~330 微秒对我机器上的~5.8 毫秒)程序的输出显示:

[...]
render time: 330us
render time: 372us
render time: 330us
render time: 331us
render time: 5820us
render time: 335us
render time: 332us
render time: 324us
render time: 346us
[...]

设置:快速 PC(Intel i7 CPU @3.2GHz)、Ubuntu 12.04、NVIDIA GTS450 主板、最新的 GL 驱动程序:OpenGL 渲染器字符串:GeForce GTS 450/PCIe/SSE2OpenGL 版本字符串:4.3.0 NVIDIA 310.19三星显示器(我假设是 23"@60Hz,因为所有这些都有 60Hz)

在上面的测试用例中,我通过以下方式明确否决了 vblank sync: __GL_SYNC_TO_VBLANK=0

启用 vblank 后我的时间也很不稳定:

__GL_SYNC_TO_VBLANK=1

[...]
render time: 9169us
render time: 14548us
render time: 14613us
render time: 16057us
render time: 18075us
[...]

我还尝试了其他参数,例如将 X 服务器置于高优先级(sudo schedtool -p 0 -n -20 -N pgrep X) 或将程序本身置于高优先级 (chrt -p -a --fifo 99 ...)

仍然存在不稳定的动画 - 这(这是我的假设)是由奇怪的时间引起的。

没有 `glutSwapBuffers();' 的计时在代码中显示非常稳定的输出:

[...]
render time: 2us
render time: 2us
render time: 2us
render time: 1us
render time: 2us
[...]

因此可以排除外部(其他过程)的影响。

谁能解释这种行为?

知道如何改进吗?

程序:

#include <stdio.h>
#include <GL/gl.h>
#include <GL/glut.h>
#include <time.h>

GLfloat gfPosX = 0.0;
GLfloat gfDeltaX = .01;

#define TS_TOUSEC(x) (x.tv_sec * 1000000L + (x.tv_nsec / 1000))
struct timespec t1, t2;

void Draw() {
int x = 0;

glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 1.0, 1.0);

clock_gettime(CLOCK_REALTIME, &t1);
glBegin(GL_LINES);
glVertex3f(gfPosX, 0.25, 0.0);
glVertex3f(gfPosX, 0.75,0.0);
glEnd();
clock_gettime(CLOCK_REALTIME, &t2);
glutSwapBuffers();
printf("render time: %5uus\n", TS_TOUSEC(t2) - TS_TOUSEC(t1));

gfPosX += gfDeltaX;
if (gfPosX >= 1.0 || gfPosX <= 0.0) {
gfDeltaX = -gfDeltaX;
}
}

void Timer(int iUnused)
{
glutPostRedisplay();
glutTimerFunc(5, Timer, 0);
}

void Initialize() {
glClearColor(0.0, 0.0, 0.0, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
}

int main(int iArgc, char** cppArgv) {
glutInit(&iArgc, cppArgv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(250, 250);
glutInitWindowPosition(200, 200);
glutCreateWindow("XoaX.net");
Initialize();
glutDisplayFunc(Draw);
Timer(0);
glutMainLoop();
return 0;
}

最佳答案

我不会用这个:

clock_gettime(CLOCK_REALTIME, &t1);

CLOCK_REALTIME 显示挂钟时间(即卡在墙上的时钟显示的时间),即它不能保证是单调的。它可能会向前或向后一点,因为时间守护进程会对其进行调整。

要测量帧渲染时间,您需要 CLOCK_MONOTONIC_RAW。

在没有 SwapBuffers 的情况下,您仅测量发出渲染调用所需的时间。不是渲染时间本身。您必须添加一个 glFinish 来获取它,以便实际执行命令队列。

出于所有实际目的,您不应该计算渲染帧所花费的时间,而是计算各个帧之间的时间,即调用显示函数之间的时间间隔。这提供了更准确的动画。

为了解决输入滞后问题,我会使用卡尔曼滤波器来预测渲染完成时的输入状态(因为您需要帧渲染时间,只需收集统计数据)并使用预测的输入状态进行帧推进。

关于linux - OpenGL - 渲染时间抖动使动画不稳定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14416033/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com