43

垂直同期を有効にするにはどうすればよいですか?

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

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

4

4 に答える 4

45

Windows には OpenGL 拡張メソッドがありwglSwapIntervalEXTます。b2b3 http://www.gamedev.net/community/forums/topic.asp?topic_id=360862による投稿から:

Windows で作業している場合は、機能を使用するために拡張機能を使用する必要があり wglSwapIntervalExtます。これは wgext.h で定義されています。glext.h ファイルもダウンロードする必要があります。wgext ファイルでは、Windows 固有の拡張機能のすべてのエントリ ポイントが宣言されています。このような関数はすべてプレフィックス wgl で始まります。公開されているすべての拡張機能に関する詳細情報を取得するには、OpenGL 拡張レジストリを調べてください。

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

于 2009-02-26T05:33:28.753 に答える
6

WGLケースはeugensk00 による回答で説明されています。

CGL (MacOSX) については、別の SO の質問に対するこの回答を参照してください。

EGLにはeglSwapInterval ()関数がありますが、どうやら ( thisおよびthisを参照) テアリングのない結果を保証するものではなく、指定された期間だけ待機します (ドライバーが壊れているためかもしれません)。

GLX (X11 を搭載した Linux など) には、機能の程度が異なる、少なくとも 3 つの同様の拡張機能があります。OpenGL wiki には現在、Mesa <= 10.5.9 (およびおそらくそれ以降) ではサポートされていない 1 つだけがリストされています。以下は、ほとんどの機能が完全な拡張機能 (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)

    • 垂直同期を無効intervalにする: 0 に設定

  2. GLX_MESA_swap_control

    • コンテキストごとにスワップ間隔を設定します。glXSwapIntervalMESA(interval)

    • 現在のスワップ間隔を取得:glXGetSwapIntervalMESA()

    • 最大スワップ間隔の取得:サポートされていません

    • 垂直同期を無効intervalにする: 0 に設定

  3. GLX_SGI_swap_control

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

    • 現在のスワップ間隔の取得:サポートされていません

    • 最大スワップ間隔の取得:サポートされていません

    • 垂直同期を無効にする:サポートされていません(interval==0はエラーです)

アダプティブ Vsync については、OpenGL wikiを参照してください。

于 2016-08-12T09:43:06.560 に答える