垂直同期


垂直同期というのは、
ダブルバッファ使用時に
バックバッファの内容をフロントバッファへ転送するタイミングを
モニタの更新周期(たいていは60Hz)に同期させることで、画面のちらつきを抑えるテクニックです。

OepnGLの場合、Windows環境では
"WGL_EXT_swap_control"というWGLのエクステンションとして機能が提供されていて、
垂直同期を有効にすると、
描画後にwglSwapBuffers()を呼び出すと、
モニタ画面が更新されるまでそこで待たされるようになります。
関連する拡張関数は次の2つ。

bool wglSwapIntervalEXT( int interval )
引数intervalで、待機するモニタフレーム数を指定する。
0なら同期無し、1ならモニタの次フレームまで待たされ、
2なら次の次のフレームまで待たされる。
 
int wglGetSwapIntervalEXT();
待機するモニタフレーム数を取得する。
つまりは、SwapIntervalEXTで設定した値を取得する、ということ。

wglのエクステンションになっているので、
"WGL_EXT_swap_control"がサポートされているかどうかを確認した上で
サポートされているなら、使用可能。
・・・なんだけど、実はそのまえに、
"WGL_EXT_extensions_string" というエクステンションもサポートされている必要がある。

というのも、WGL_EXT_swap_control はwglのエクステンションなので
glGetString( GL_EXTENTONS ); ではサポートされているかどうか確認することはできなくて、
その代わりに wglGetExtensionsStringEXT 関数を使用して確認しなければならない。
で、このwglGetExtensionsStringEXT 関数がこれまた
OpenGLの WGL_EXT_extensions_string という WGLのエクステンションなので、
まずは
wglGetProcAddress( "wglGetExtensionsStringEXT" );
と、関数ポインタを取得してみて0以外が返ってくるかどうかで、
使えるかどうか判別することになる。

つまるところ、
手順は以下のようになる。

1.
IntPtr ptr = wglGetProcAddress( "wglGetExtensionsStringEXT" );
をやってみて、wglGetExtensionsStringEXT 関数が使えるかどうかを確認する。

2.
wglGetExtensionsStringEXT 関数にデバイスコンテキストのハンドルを渡して
そのコンテキストでサポートされているWGLエクステンションのリストを取得し、 WGL_EXT_swap_control がサポートされていることを確認する。

3.
wglSwapIntervalEXT 関数で引数に1(またはそれ以上)を指定すれば垂直同期ON、
0を指定すれば、垂直同期OFF。


<back to OpenGL menu>