如何在opengl中启用垂直同步?

时间:2009-02-26 04:07:14

标签: opengl vsync vertical-sync

如何启用垂直同步?

glEnable(GL_VSYNC)那样简单吗? (虽然在glEnable接受的选项中没有GL_VSYNC或类似的东西)。

或者在opengl中没有标准的方法吗?

3 个答案:

答案 0 :(得分:43)

在Windows上有OpenGL扩展方法wglSwapIntervalEXT。 来自b2b3的帖子http://www.gamedev.net/community/forums/topic.asp?topic_id=360862

  

如果您使用的是Windows,则必须使用扩展程序才能使用   wglSwapIntervalExt功能。它是   在wgle​​xt.h中定义。你也想要   下载glext.h文件。   在wgle​​xt文件中,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()功能,但显然(见thisthis)它并不保证无撕裂结果 - 只等待给定的时间段(也许是因为司机损坏)。

对于 GLX (Linux与X11等),至少有3个类似的扩展,具有不同程度的功能。 OpenGL wiki目前只列出一个,Mesa&lt; = 10.5.9(可能更高)不支持。这是从大多数功能完整扩展(在OpenGL维基中列出)到最少的列表:

  1. GLX_EXT_swap_control

    • 设置每次展示的每次展示交换间隔:glXSwapIntervalEXT(dpy, drawable, interval)

    • 获取当前的互换时间间隔:glXQueryDrawable(dpy, drawable, GLX_SWAP_INTERVAL_EXT, &interval)

    • 获取最长互换间隔:glXQueryDrawable(dpy, drawable, GLX_MAX_SWAP_INTERVAL_EXT, &maxInterval)

    • 禁用Vsync:将interval设置为0

  2. GLX_MESA_swap_control

    • 设置每个上下文的交换间隔:glXSwapIntervalMESA(interval)

    • 获取当前的互换时间间隔:glXGetSwapIntervalMESA()

    • 获取最大交换间隔:不支持

    • 禁用Vsync:将interval设置为0

  3. GLX_SGI_swap_control

    • 设置交换间隔:glXSwapIntervalSGI(interval)

    • 获取当前的交换间隔:不支持

    • 获取最大交换间隔:不支持

    • 禁用Vsync:不支持interval==0是错误的)

  4. 对于自适应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””