PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = NULL;
PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT = NULL;
if (WGLExtensionSupported("WGL_EXT_swap_control"))
{
// Extension is supported, init pointers.
wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT");
// this is another function from WGL_EXT_swap_control extension
wglGetSwapIntervalEXT = (PFNWGLGETSWAPINTERVALEXTPROC)wglGetProcAddress("wglGetSwapIntervalEXT");
}
//calculate time taken to render last frame (and assume the next will be similar)
thisTime = getElapsedTimeOfChoice(); //the higher resolution this is the better
deltaTime = thisTime - lastTime;
lastTime = thisTime;
//limit framerate by sleeping. a sleep call is never really that accurate
if (minFrameTime > 0)
{
sleepTime += minFrameTime - deltaTime; //add difference to desired deltaTime
sleepTime = max(sleepTime, 0); //negative sleeping won't make it go faster :(
sleepFunctionOfChoice(sleepTime);
}
7条答案
按热度按时间luaexgnf1#
你可以在opengl中使用wglSwapIntervalEXT同步到vblank。这不是很好的代码,但它确实有效。
http://www.gamedev.net/topic/360862-wglswapintervalext/#entry3371062
和
kxkpmulp2#
由于OpenGL只是一个低级的图形API,你不会发现任何类似的东西直接内置在OpenGL中。
但是,我认为你的逻辑有点缺陷。而不是以下内容:
1.并条机
1.等待1000/fps毫秒
1.重复
你应该这样做:
1.启动计时器
1.并条机
1.停止计时器
1.等待(1000/fps -(停止-开始))毫秒
1.重复
这样,如果你只是等待你应该的量,你应该结束非常接近60(或任何你的目标)帧每秒。
1wnzp6jl3#
不要使用sleeps。如果使用了,那么应用程序的其余部分必须等待它们完成。
相反,跟踪已经过去了多少时间,并仅在达到1000/fps时进行渲染。如果计时器没有达到,则跳过它并做其他事情。
在一个单线程的环境中,很难确保你的绘制速度是1000/fps,除非你只做这一件事。一个更通用和更健壮的方法是在一个单独的线程中完成所有的渲染,并在一个计时器上启动/运行该线程。这是一个更复杂的问题,但会让你最接近你的要求。
此外,跟踪发布渲染所需的时间将有助于动态调整渲染时间。
0tdrvxhp4#
OpenGL本身没有任何允许限制帧率的功能。
然而,在现代GPU上有很多功能,包括帧率,帧预测等。有约翰卡马克的问题,他推动使一些功能可用。还有英伟达的自适应同步。
这一切对你意味着什么?让GPU来决定吧。假设绘图是完全不可预测的(当你只使用OpenGL时,你应该这样做),自己计时事件,并将逻辑更新(如物理)与绘图分开。这样用户就可以从所有这些先进技术中受益,你就不必再担心了。
oyxsuwqo5#
一个简单的方法是使用GLUT。这段代码可以大致完成这项工作。
erhoui1w6#
将其放在绘制和调用交换缓冲区之后:
如果你想要60 fps,
minFrameTime = 1.0/60.0
(假设时间以秒为单位)。这不会给予你vsync,但将意味着你的应用程序不会失控,这可能会影响物理计算(如果他们不是固定的步骤),动画等。只要记住处理输入 * 后 * 睡眠!我已经尝试尝试平均帧时间,但这是最好的工作到目前为止。
对于
getElapsedTimeOfChoice()
,我使用前面提到的here,即clock_gettime(CLOCK_MONOTONIC, &ts);
QueryPerformanceCounter
cvxl0en27#
另一个想法是使用WaitableTimers(如果可能的话,例如在Windows上)
基本理念:
更多信息:How to limit fps information