web-dev-qa-db-ja.com

OpenGLで垂直同期を有効にする方法は?

垂直同期をどのように有効にしますか?

glEnable(GL_VSYNC)のような単純なものですか? (ただし、glEnableが受け入れるオプションにはGL_VSYNCなどのようなものはありません)。

またはopenglでこれを行う標準的な方法はありませんか?

36
hasen

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()を呼び出す必要があります。

43
eugensk00

[〜#〜] wgl [〜#〜]の場合は answer by eugensk で説明されています。

[〜#〜] cgl [〜#〜](MacOSX) this answer to another SO質問。

[〜#〜] egl [〜#〜]には eglSwapInterval() 関数がありますが、明らかに( this および this )引き裂きのない結果を保証するものではありません。指定された期間だけ待機します(ドライバーが壊れているためだけかもしれません)。

[〜#〜] glx [〜#〜](X11を使用するLinuxなど)には、程度の異なる、少なくとも3つの同様の拡張機能があります機能の。現在、OpenGL wikiには1つしかリストされていませんが、Mesa <= 10.5.9(およびそれ以上)ではサポートされていません。以下は、ほとんどの機能が完全な拡張機能(OpenGL wikiにリストされています)から最小のものです。

  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()

    • 最大スワップ間隔を取得:unsupported

    • Vsyncを無効にします:intervalを0に設定します

  3. GLX_SGI_swap_control

    • スワップ間隔を設定します:glXSwapIntervalSGI(interval)

    • 現在のスワップ間隔を取得:unsupported

    • 最大スワップ間隔を取得:unsupported

    • Vsyncを無効にします:unsupportedinterval==0はエラーです)

適応Vsyncについては、 OpenGL wiki を参照してください。

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

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

「wglSwapIntervalEXT(1)を使用してvsyncを有効にし、wglSwapIntervalEXT(0)を使用してvsyncを無効にします。」

「1のスワップ間隔は、フロントバッファーとバックバッファーをスワップする前に1つのvブランクを待機するようGPUに指示します。0のスワップインターバルは、GPUがvブランクを決して待機しないことを指定します」

0
Puddle