2009-02-26 7 views

Antwort

41

Unter Windows gibt es die OpenGL-Erweiterungsmethode wglSwapIntervalEXT.
Aus dem Beitrag von b2b3 http://www.gamedev.net/community/forums/topic.asp?topic_id=360862:

---- Zitat beginnt -----

Wenn Sie unter Windows arbeiten, müssen Sie Erweiterungen verwenden Funktion wglSwapIntervalExt zu verwenden. Es ist definiert in wglext.h. Sie möchten auch glext.h Datei herunterladen. In der wglext-Datei sind alle Einstiegspunkte für Windows-spezifische Erweiterungen deklariert. Alle diese Funktionen starten mit Präfix wgl. Um mehr Informationen über alle veröffentlichten Erweiterungen zu erhalten, können Sie unter OpenGL Extension Registry nachsehen.

wglSwapIntervalEXT ist von WGL_EXT_swap_control Erweiterung. Mit können Sie die Mindestanzahl von Frames vor jedem Pufferaustausch festlegen. Normalerweise wird es für die vertikale Synchronisation verwendet (wenn Sie das Intervall auf 1 setzen). Weitere Informationen über die ganze Erweiterung finden Sie hier. Vor der Verwendung dieser Funktion benötigen Sie Abfrage, ob Ihre Karte Unterstützung für WGL_EXT_swap_control und dann Zeiger auf die Funktion mit wglGetProcAddress Funktion erhalten.

zur Unterstützung von bestimmten Erweiterung testen Sie Funktion wie folgt verwendet werden:

#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(_wglGetExtensionsString(), extension_name) == NULL) 
    { 
     // string was not found 
     return false; 
    } 

    // extension is supported 
    return true; 
} 

initialisieren Ihre Funktionszeiger müssen Sie:

PFNWGLSWAPINTERVALEXTPROC  wglSwapIntervalEXT = NULL; 
PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT = NULL; 

if (WGLExtensionSupported("WGL_EXT_swap_control")) 
{ 
    // Extension is supported, init pointers. 
    wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC) LogGetProcAddress("wglSwapIntervalEXT"); 

    // this is another function from WGL_EXT_swap_control extension 
    wglGetSwapIntervalEXT = (PFNWGLGETSWAPINTERVALEXTPROC) LogGetProcAddress("wglGetSwapIntervalEXT"); 
} 

Dann Sie können diese Zeiger als jeden anderen Zeiger verwenden, um zu funktionieren. Um vync zu aktivieren, können Sie wglSwapIntervalEXT (1) aufrufen, um es zu deaktivieren, rufen Sie wglSwapIntervalEXT (0) auf.

Um das aktuelle Auslagerungsintervall zu erhalten, müssen Sie wglGetSwapIntervalEXT() aufrufen.

---- Zitat endet -----

+2

In Ihrem ersten Codeausschnitt if (strstr (_wglGetExtensionsString(), Erweiterungsname) == NULL) sollte lesen if (strstr (_wglGetExtensionsStringEXT(), Erweiterungsname) == NULL) - Aber danke, das hat mir geholfen !!! – HoboBen

+3

Auch ich wglGetProcAddress statt LogGetProcAddress verwendet – HoboBen

+3

Das ist keine Erweiterung zu OpenGL, sondern eher zu WGL (der Microsoft Windows-Fenster-System-API für OpenGL). Pufferaustausch ist von Natur aus eine fenstersystemspezifische Operation. Was den GL anbelangt, zieht er sich einfach zu einem Vor/Zurück-Links/Rechts-Puffer oder einem beliebigen FBO. Das Fenstersystem ist das einzige, das genug Wissen über das zugrundeliegende Host-System hat, um die Präsentation von gezeichneten Puffern mit irgendeinem Ereignis (in diesem Fall dem vertikalen Rücklauf des Monitors) zu synchronisieren. –

10

Es ist auf der OpenGL Wiki zusammengefasst ist, hier: http://www.opengl.org/wiki/Swap_Interval

+1

Beachten Sie, dass diese Seite sehr unvollständig ist: Die einzige dort aufgeführte GLX Vsync-Erweiterung wird von Mesa nicht unterstützt. Dies ist die Standard-OpenGL-Implementierung für die meisten Linux-Distributionen für die gesamte Hardware. Eine vollständige Liste der GLX Vsync-Erweiterungen finden Sie unter [meine Antwort] (http://stackoverflow.com/a/38914829/673852). – Ruslan

0

WGL Fall ist in der answer by eugensk00 beschrieben.

Für CGL (MacOSX) siehe this answer zu einer anderen SO Frage.

Für EGL gibt es eglSwapInterval() Funktion, aber anscheinend (siehe this und this) ist es nicht Zerreißen freies Ergebnis garantiert - nur wartet Zeit gegeben (vielleicht ist es Fahrer nur aufgrund gebrochen).

Für GLX (Linux mit X11 etc.) gibt es mindestens 3 ähnliche Erweiterungen mit unterschiedlichem Funktionsumfang. OpenGL-Wiki listet derzeit nur eine auf, die von Mesa < = 10.5.9 (und vielleicht höher) nicht unterstützt wird. Hier ist eine Liste von den meist Feature-complete-Erweiterung (aufgelistet in OpenGL Wiki) auf die am wenigsten:

  1. GLX_EXT_swap_control

    • Set Swap-Intervall pro-ziehbar pro-Anzeige: glXSwapIntervalEXT(dpy, drawable, interval)

    • Aktuelles Swapintervall abrufen: glXQueryDrawable(dpy, drawable, GLX_SWAP_INTERVAL_EXT, &interval)

    • Maximales Auslagerungsintervall: glXQueryDrawable(dpy, drawable, GLX_MAX_SWAP_INTERVAL_EXT, &maxInterval)

    • Disable Vsync: set interval zu 0

  2. GLX_MESA_swap_control

    • Set Swap-Intervall pro-Kontext: glXSwapIntervalMESA(interval)

    • aktuellen Swap-Intervall Get: glXGetSwapIntervalMESA()

    • Get maximalen Swap-Intervall: ungestützt

    • Disable Vsync: set interval zu 0

  3. GLX_SGI_swap_control

    • Set Swap-Intervall: glXSwapIntervalSGI(interval).

    • Erhalten aktuellen Swap Intervall: ungestützten

    • Intervall maximale Swap Erhalten: ungestützten

    • Disable Vsync: ungestützten (interval==0 ein Fehler)

Für adaptive Vsync siehe OpenGL wiki.