Windowには、OpenGLというグラフィックライブラリが含まれています(初期のWin95などには自分でインストールする必要があります)。OpenGLは、3Dグラフィックプログラミングのためのライブラリで互換ライブラリも含め多くの環境(LinuxやMacでも)で利用できるので、アプリケーションのグラフィック描画部分をOpenGLベースで作成しておくと移植が楽かもしれません。 今回は、マイクロソフトのPlathome SDK(VC++5付属、マイクロソフトのWebでもオンラインで参照可能)を参考にWindowに実装されているOpenGLで何か絵を描いてOpenGLの使い方を確認してみましょう。 描画準備 OpenGLは図形描画や3D関連の設定を行うAPIを持っていますが、実際に描画処理を行う部分はプラットフォーム毎に実装されています。Windowsでは、WGLというライブラリで描画を行う「レンダリングコンテキスト」をWindowsのデバイスコンテキストと結びつけ、描画を行うようです。 ピクセルフォーマットの設定では、まずPIXELFORMATDESCRIPTOR構造体で利用するピクセルフォーマットを設定します。続いて、この構造体をOpenGLで描画するデバイスコンテキストのハンドルと共にChoosePixelFormat()に渡し、デバイスコンテキストに適合するピクセルフォーマットを取得します。今回は、Platform SDKのサンプルにあるPIXELFORMATDESCRIPTOR構造体をそのまま使い、メインウインドウのデバイスコンテキストに描画する事にしました。 PIXELFORMATDESCRIPTOR構造体の例(Platform SDK-ChoosePixelFormatの項より) PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd 1, // version number PFD_DRAW_TO_WINDOW | // support window PFD_SUPPORT_OPENGL | // support OpenGL PFD_DOUBLEBUFFER, // double buffered PFD_TYPE_RGBA, // RGBA type 24, // 24-bit color depth 0, 0, 0, 0, 0, 0, // color bits ignored 0, // no alpha buffer 0, // shift bit ignored 0, // no accumulation buffer 0, 0, 0, 0, // accum bits ignored 32, // 32-bit z-buffer 0, // no stencil buffer 0, // no auxiliary buffer PFD_MAIN_PLANE, // main layer 0, // reserved 0, 0, 0 // layer masks ignored }; デバイスコンテキストにピクセルフォーマットを設定するには、ChoosePixelFormat()が返した値を利用してSetPixelFormat()を呼び出します。これで、デバイスコンテキストにピクセルフォーマットが設定されたので、そのデバイスコンテキストからwglCreateContext()でレンダリングコンテキストを作成し、そのレンダリングコンテキストをwglMakeCurrent()でカレントにすれば描画準備は完了です。 case WM_CREATE: WinDC=GetDC(hwnd); pixelFormat=ChoosePixelFormat(WinDC,&pfd); SetPixelFormat(WinDC,pixelFormat,&pfd); hRC=wglCreateContext(WinDC); wglMakeCurrent(WinDC,hRC); 描画処理OpenGLによる描画は、ウインドウのデバイスコンテキストに対する描画同様WM_PAINTに対する応答として行うようにしました。まず、画面を暗い緑でクリアしてから四角形を描いてみましょう。 glClearColor(0.0, 0.4, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); glRectd(-0.5,-0.5,0.5,0.5); glClearColor()でクリアする色を設定したら、glClearで描画用のバッファをクリアします。OpenGLでは、ダブルバッファを用いて一度バックバッファに描画してからそれを画面に転送する事でちらつきを抑えた描画を行えるようになっていますが、そのバックバッファをクリアするわけです。バックバッファをクリアしたら、glRectd()で四角形を描きます。デフォルトの座標系は、ウインドウのクライアント領域全体が(-1, -1)〜(1, 1)になっているようです。つまり、ウインドウのサイズによって描画される四角形の大きさや縦横比が変わるわけですね。 バックバッファへの描画コマンドを指定し終わったらglFlush()でそのコマンドを確実に実行して、SwapBuffers()でバックバッファとフロントバッファを切り替える事でバックバッファの内容を画面に出力します。 glFlush(); SwapBuffers(WinDC); プログラムの終了時には、レンダリングコンテキストをカレントから外して削除します。 wglMakeCurrent(WinDC,0); wglDeleteContext(hRC); プログラムプログラムをビルドする時は、プロジェクトの設定でopengl32.libをリンクしてください。実行すると、緑色に塗りつぶされたウインドウが出てきて中に四角形が描かれるでしょう。 OpenGLには高度な3D描画機能があるようなので、今後も少しずつ試してみる予定です。 |