Pregunta cómo habilitar la sincronización vertical en OpenGL?


¿Cómo habilita la sincronización vertical?

¿Es algo simple como glEnable(GL_VSYNC)? (aunque no hay nada como GL_VSYNC ni nada parecido en las opciones que glEnable acepta).

o no hay una forma estándar de hacer esto en OpenGL?


32
2018-02-26 04:07


origen


Respuestas:


En Windows hay un método de extensión OpenGL wglSwapIntervalEXT. De la publicación de b2b3 http://www.gamedev.net/community/forums/topic.asp?topic_id=360862:

Si está trabajando en Windows, debe usar extensiones para usar    wglSwapIntervalExt función. Es   definido en wglext.h. También querrás   descarga el archivo glext.h   En el archivo wglext, todos los puntos de entrada para las extensiones específicas de Windows son   declarado. Todas esas funciones comienzan   con prefijo wgl.   Para obtener más información sobre todas las extensiones publicadas, puede consultar   OpenGL Extension Registry.

wglSwapIntervalEXT es desde WGL_EXT_swap_control extensión. Eso   te permite especificar el número mínimo de   fotogramas antes de cada intercambio de memoria intermedia.   Por lo general, se utiliza para vertical   sincronización (si configura swap)   intervalo a 1). Más información sobre todo   la extensión se puede encontrar aquí.   Antes de usar esta función, necesita consultar si su tarjeta tiene   apoyo para WGL_EXT_swap_control y   luego obtenga puntero a la función   utilizando wglGetProcAddress función.

Para probar el soporte de la extensión dada, puede usar una función como esta:

#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;
}

Para inicializar los punteros a su función, necesita:

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");
}

Luego puede usar estos punteros como cualquier otro puntero para funcionar. Para habilitar vync puedes llamar wglSwapIntervalEXT(1), para deshabilitarlo llamas wglSwapIntervalEXT(0).

Para obtener el intervalo de intercambio actual, debe llamar wglGetSwapIntervalEXT().


43
2018-02-26 05:33



WGL caso se describe en el respuesta por eugensk00.

por CGL (MacOSX) ver esta respuesta a otra pregunta SO.

por EGL hay eglSwapInterval () función, pero aparentemente (ver esta y esta) no garantiza un resultado sin rasgaduras, solo espera un período determinado (tal vez solo sea por rotura de los controladores).

por GLX (Linux con X11 etc.) hay al menos 3 extensiones similares para esto, con un grado variable de funcionalidad. La wiki de OpenGL actualmente solo muestra una, que no está soportada por Mesa <= 10.5.9 (y tal vez más). Aquí hay una lista de la mayoría de las funciones completas de la extensión (enumeradas en OpenGL wiki) al menos:

  1. GLX_EXT_swap_control

    • Establecer el intervalo de intercambio por dibujo por visualización: glXSwapIntervalEXT(dpy, drawable, interval)

    • Obtener el intervalo de intercambio actual: glXQueryDrawable(dpy, drawable, GLX_SWAP_INTERVAL_EXT, &interval)

    • Obtener el intervalo de intercambio máximo: glXQueryDrawable(dpy, drawable, GLX_MAX_SWAP_INTERVAL_EXT, &maxInterval)

    • Deshabilitar Vsync: establecer interval a 0

  2. GLX_MESA_swap_control

    • Establecer intervalo de intercambio por contexto: glXSwapIntervalMESA(interval)

    • Obtener el intervalo de intercambio actual: glXGetSwapIntervalMESA()

    • Obtener el intervalo de intercambio máximo: sin soporte

    • Deshabilitar Vsync: establecer interval a 0

  3. GLX_SGI_swap_control

    • Establecer intervalo de intercambio: glXSwapIntervalSGI(interval).

    • Obtener el intervalo de intercambio actual: sin soporte

    • Obtener el intervalo de intercambio máximo: sin soporte

    • Deshabilitar Vsync: sin soporte (interval==0 es un error)

Para Vsync adaptativo ver OpenGL wiki.


3
2017-08-12 09:43