2

Vsync を OpenGL アプリケーションで動作させるのに必死に苦労しています。重要な統計は次のとおりです。

私は Windows を使用しており、C++ OpenGL でコーディングしています。また、OpenGL コンテキスト (ダブル バッファリング) に FreeGLUT を使用しています。Windows でスワップ バッファが垂直同期を待機するには、wglSwapIntervalEXT() を呼び出す必要があることを認識しています。

私のコードはこれを呼び出します (以下で説明します) が、まだ縦方向の引き裂きが発生しています。私がそれを止めることができた唯一の方法は glFinish() を呼び出すことです。もちろん、これには重大なパフォーマンスのペナルティが伴います。

main() 関数の関連部分は次のようになります。

//Initiating glut window
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize (initial_window_width, initial_window_height);
glutInitWindowPosition (100, 100);
int glut_window_hWnd = glutCreateWindow(window_title.c_str()); 

//Setting up swap intervals
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");
}

wglSwapIntervalEXT (1)

init ();

glutMainLoop();    ///Starting the glut loop
return(0);

wglInitSwapControlARB 関数からの戻り値は true であるため、拡張機能がサポートされていることを指摘しておく必要があります。

4

3 に答える 3

7

わかりました-ここで受けた多大な支援と、私自身の何時間もの調査とそれをいじることの間に、私にとってうまくいく解決策を含むいくつかのことを発見しました(他の人がこの問題に遭遇した場合)。

まず、私は freeGLUT を使用していました。コードを GLFW に変換しましたが、結果は同じでした。これは API の問題ではありませんでした。私のように時間を無駄にしないでください。

少なくとも私のプログラムでは、 wglSwapIntervalEXT(1) を使用しても垂直方向のテアリングは停止しません。これが、解決するのが非常に頭痛の種になる原因でした。

NVIDIA ドライバーを VSYNC = ON に設定すると、まだテアリングが発生していました (これは、役に立たない SwapInterval(1) と同等であるため) - しかし、正しく設定されていたため、ドライバーは本来あるべきことを実行していました。私はまだ涙を流していたので、それを知りません。

そこで、NVIDIA ドライバーを VSYNC = 'アプリケーション設定' に設定し、いつも使用していた 1 の代わりに wglSwapIntervalEXT(60) を使用しました。これは、約 1Hz のリフレッシュ レートを提供していたため、実際に機能していることがわかりました。

wglSwapIntervalEXT(1) が画面を垂直同期しない理由はわかりませんが、wglSwapIntervalEXT(2) には目的の効果がありますが、明らかに非効率的なフレームを 1 つおきにレンダリングしています。

VSYNCを無効にすると、glFinishはティアリングに役立ちませんが、有効にすると有効になることがわかりました(誰かがそれが素晴らしい理由を説明できる場合)。

要約すると、 wglSwapIntervalEXT(1) を設定して glFinish() を有効にすると、ティアリングはなくなりましたが、その理由はまだわかりません。

これが私のアプリのパフォーマンス統計です(FPSが60未満になるように意図的にロードされています):

  • wglSwapIntervalEXT(0) = ティアリング = 58 FPS
  • wglSwapIntervalEXT(1) = ティアリング = 58 FPS
  • wglSwapIntervalEXT(2) = テアリングなし = 30 FPS
  • wglSwapIntervalEXT(1) + glFinish = テアリングなし = 52 FPS

これが将来誰かに役立つことを願っています。ご助力いただきありがとうございます。

于 2014-01-22T12:04:04.700 に答える