web-dev-qa-db-fra.com

comment activer la synchronisation verticale en opengl?

Comment activez-vous la synchronisation verticale?

Est-ce quelque chose de simple comme glEnable(GL_VSYNC)? (bien qu'il n'y ait rien de tel que GL_VSYNC ou quelque chose comme ça dans les options acceptées par glEnable).

ou n'y a-t-il pas de moyen standard de le faire en opengl?

36
hasen

Sous Windows, il existe la méthode d'extension OpenGL wglSwapIntervalEXT. Extrait de l'article par b2b3 http://www.gamedev.net/community/forums/topic.asp?topic_id=360862 :

Si vous travaillez sous Windows, vous devez utiliser des extensions pour utiliser la fonction wglSwapIntervalExt. Il est défini dans wglext.h. Vous voudrez également télécharger le fichier glext.h. Dans le fichier wglext, tous les points d'entrée pour les extensions spécifiques à Windows sont déclarés. Toutes ces fonctions commencent par le préfixe wgl. Pour obtenir plus d'informations sur toutes les extensions publiées, vous pouvez consulter le Registre des extensions OpenGL.

wglSwapIntervalEXT provient de l'extension WGL_EXT_swap_control. Il vous permet de spécifier le nombre minimum d'images avant chaque échange de tampon. Il est généralement utilisé pour la synchronisation verticale (si vous définissez l'intervalle de permutation sur 1). Vous trouverez plus d'informations sur l'extension complète ici. Avant d'utiliser cette fonction, vous devez vous demander si votre carte prend en charge WGL_EXT_swap_control, Puis obtenir un pointeur vers la fonction à l'aide de la fonction wglGetProcAddress.

Pour tester la prise en charge d'une extension donnée, vous pouvez utiliser une fonction comme celle-ci:

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

Pour initialiser vos pointeurs de fonction, vous devez:

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

Vous pouvez ensuite utiliser ces pointeurs comme tout autre pointeur pour fonctionner. Pour activer le vync, vous pouvez appeler wglSwapIntervalEXT(1), pour le désactiver, vous appelez wglSwapIntervalEXT(0).

Pour obtenir l'intervalle de swap actuel, vous devez appeler wglGetSwapIntervalEXT().

43
eugensk00

Le cas [~ # ~] wgl [~ # ~] est décrit dans le réponse de eugensk .

Pour [~ # ~] cgl [~ # ~] (MacOSX) voir cette réponse vers un autre SO question.

Pour [~ # ~] egl [~ # ~] il y a eglSwapInterval () fonction, mais apparemment (voir this and this ) il ne garantit pas un résultat sans déchirure - n'attend qu'une période donnée (peut-être est-ce juste à cause de pilotes cassés).

Pour [~ # ~] glx [~ # ~] (Linux avec X11 etc.), il existe au moins 3 extensions similaires pour cela, avec des degrés divers de fonctionnalité. Le wiki OpenGL n'en répertorie actuellement qu'un seul, qui n'est pas pris en charge par Mesa <= 10.5.9 (et peut-être plus). Voici une liste de la plupart des extensions complètes (répertoriées dans le wiki OpenGL) au moins:

  1. GLX_EXT_swap_control

    • Définir l'intervalle de permutation par tirage par affichage: glXSwapIntervalEXT(dpy, drawable, interval)

    • Obtenir l'intervalle de swap actuel: glXQueryDrawable(dpy, drawable, GLX_SWAP_INTERVAL_EXT, &interval)

    • Obtenir l'intervalle de swap maximum: glXQueryDrawable(dpy, drawable, GLX_MAX_SWAP_INTERVAL_EXT, &maxInterval)

    • Désactivez Vsync: définissez interval sur 0

  2. GLX_MESA_swap_control

    • Définir l'intervalle de swap par contexte: glXSwapIntervalMESA(interval)

    • Obtenir l'intervalle de swap actuel: glXGetSwapIntervalMESA()

    • Obtenez l'intervalle de swap maximum: non pris en charge

    • Désactivez Vsync: définissez interval sur 0

  3. GLX_SGI_swap_control

    • Définissez l'intervalle de swap: glXSwapIntervalSGI(interval).

    • Obtenir l'intervalle de swap actuel: non pris en charge

    • Obtenez l'intervalle de swap maximum: non pris en charge

    • Désactiver Vsync: non pris en charge (interval==0 est une erreur)

Pour Vsync adaptatif, voir wiki OpenGL .

4
Ruslan
((BOOL(WINAPI*)(int))wglGetProcAddress("wglSwapIntervalEXT"))(1);

google: wglSwapIntervalEXT
https://www.khronos.org/opengl/wiki/Swap_Interval

"wglSwapIntervalEXT (1) est utilisé pour activer vsync; wglSwapIntervalEXT (0) pour désactiver vsync."

"Un intervalle de swap de 1 indique au GPU d'attendre un vide en V avant de permuter les tampons avant et arrière. Un intervalle de swap de 0 spécifie que le GPU ne doit jamais attendre les v-blancs"

0
Puddle