OpenGLによるグラフィック描画

Windowには、OpenGLというグラフィックライブラリが含まれています(初期のWin95などには自分でインストールする必要があります)。OpenGLは、3Dグラフィックプログラミングのためのライブラリで互換ライブラリも含め多くの環境(LinuxMacでも)で利用できるので、アプリケーションのグラフィック描画部分をOpenGLベースで作成しておくと移植が楽かもしれません。

今回は、マイクロソフトのPlathome SDKVC++5付属、マイクロソフトのWebでもオンラインで参照可能)を参考にWindowに実装されているOpenGLで何か絵を描いてOpenGLの使い方を確認してみましょう。

描画準備

 OpenGLは図形描画や3D関連の設定を行うAPIを持っていますが、実際に描画処理を行う部分はプラットフォーム毎に実装されています。Windowsでは、WGLというライブラリで描画を行う「レンダリングコンテキスト」をWindowsのデバイスコンテキストと結びつけ、描画を行うようです。
また、デバイスコンテキストにはピクセル形式などを「ピクセルフォーマット」として設定しておきます。レンダリングコンテキストはスレッド単位で管理され、あるスレッドがあるレンダリングコンテキストを引数にwglMakeCurrent()を呼び出すとそのレンダリングコンテキストがカレントになり、以降そのスレッドのOpenGL API呼び出しはカレントのレンダリングコンテキストに対して効果を持つようです。

 ピクセルフォーマットの設定では、まず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描画機能があるようなので、今後も少しずつ試してみる予定です。

プログラムソース表示


Windowsプログラミング実験室 > プログラミング資料庫