如何启用垂直同步?
像glEnable(GL_VSYNC)
那样简单吗? (虽然在glEnable接受的选项中没有GL_VSYNC或类似的东西)。
或者在opengl中没有标准的方法吗?
答案 0 :(得分:43)
在Windows上有OpenGL扩展方法wglSwapIntervalEXT
。
来自b2b3的帖子http://www.gamedev.net/community/forums/topic.asp?topic_id=360862:
如果您使用的是Windows,则必须使用扩展程序才能使用
wglSwapIntervalExt
功能。它是 在wglext.h中定义。你也想要 下载glext.h文件。 在wglext文件中,Windows特定扩展的所有入口点都是 声明。所有这些功能都开始了 带有前缀wgl。 要获得有关所有已发布扩展的更多信息,您可以查看 OpenGL扩展注册表。
wglSwapIntervalEXT
来自WGL_EXT_swap_control
分机。它 允许您指定最小数量 每个缓冲区交换前的帧。 通常它用于垂直 同步(如果设置交换 间隔为1)。关于整个的更多信息 扩展可以在这里找到。 在使用此功能之前,您需要查询您的卡是否有 支持WGL_EXT_swap_control
和 然后获取指向该函数的指针 使用wglGetProcAddress
函数。要测试对给定扩展名的支持,您可以使用以下函数:
#include <windows.h>
#include "wglext.h"
bool WGLExtensionSupported(const char *extension_name)
{
// this is pointer to function which returns pointer to string with list of all wgl extensions
PFNWGLGETEXTENSIONSSTRINGEXTPROC _wglGetExtensionsStringEXT = NULL;
// determine pointer to wglGetExtensionsStringEXT function
_wglGetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC) wglGetProcAddress("wglGetExtensionsStringEXT");
if (strstr(_wglGetExtensionsStringEXT(), extension_name) == NULL)
{
// string was not found
return false;
}
// extension is supported
return true;
}
要初始化函数指针,您需要:
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");
}
然后你可以使用这些指针作为任何其他指向函数的指针。要启用vync,您可以致电
wglSwapIntervalEXT(1)
,要将其停用,请致电wglSwapIntervalEXT(0)
。要获得当前的交换间隔,您需要致电
wglGetSwapIntervalEXT()
。
答案 1 :(得分:4)
WGL 案例在answer by eugensk00。
中有所描述对于 CGL (MacOSX),请参阅另一个问题this answer。
对于 EGL 有eglSwapInterval()功能,但显然(见this和this)它并不保证无撕裂结果 - 只等待给定的时间段(也许是因为司机损坏)。
对于 GLX (Linux与X11等),至少有3个类似的扩展,具有不同程度的功能。 OpenGL wiki目前只列出一个,Mesa&lt; = 10.5.9(可能更高)不支持。这是从大多数功能完整扩展(在OpenGL维基中列出)到最少的列表:
设置每次展示的每次展示交换间隔:glXSwapIntervalEXT(dpy, drawable, interval)
获取当前的互换时间间隔:glXQueryDrawable(dpy, drawable, GLX_SWAP_INTERVAL_EXT, &interval)
获取最长互换间隔:glXQueryDrawable(dpy, drawable, GLX_MAX_SWAP_INTERVAL_EXT, &maxInterval)
禁用Vsync:将interval
设置为0
设置每个上下文的交换间隔:glXSwapIntervalMESA(interval)
获取当前的互换时间间隔:glXGetSwapIntervalMESA()
获取最大交换间隔:不支持
禁用Vsync:将interval
设置为0
设置交换间隔:glXSwapIntervalSGI(interval)
。
获取当前的交换间隔:不支持
获取最大交换间隔:不支持
禁用Vsync:不支持(interval==0
是错误的)
对于自适应Vsync,请参阅OpenGL wiki。
答案 2 :(得分:0)
((BOOL(WINAPI*)(int))wglGetProcAddress("wglSwapIntervalEXT"))(1);
google:wglSwapIntervalEXT
https://www.khronos.org/opengl/wiki/Swap_Interval
“ wglSwapIntervalEXT(1)用于启用vsync; wglSwapIntervalEXT(0)用于禁用vsync。”
“交换间隔为1告诉GPU在交换前后缓冲区之前等待一个v-blank。交换间隔为0表示GPU永远不应该等待v-blank””