OpenGLの開発環境をセットアップ


1. 前提事項

 本書は、OpenGLの開発環境を構築した際の作業メモになります。 環境の構成は、以下を前提とします。

 ※ Windows SDK は、Visual Studio 2005に対応した最後のバージョンを使用しています。

 記述範囲は、コンパイルとリンクが成功する所までとなります。

 OpenGL 1.1以降のAPI が利用可能になる環境を目標とします。

 尚、拡張API を利用する場合、対応状況を注意深く確認して実装する必要がある点に注意してください。

2. 結論

 最初は、Microsoft が提供しているOpenGL 1.1までを範囲としてAPI を利用するのが良いです。

 OpenGL 1.2 以降のAPIを利用するにしても、OpenGL 1.1のAPI を利用する為の環境が必要となります。

 今回の実験で再認識したことは、やはり拡張API を利用すると環境に依存する問題を孕んでしまうことです。
 実験した環境だと【wglCreateContextAttribsARB】のエントリポイント取得に失敗しました。

3. セットアップ

3-1. 作業の全体像

 作業項目は、以下の通りとなります。

  1. Windows SDK をインストール
  2. OpenGL Extensions API のヘッダファイルを配置
  3. ソースコードからヘッダファイルをインクルード
  4. OpenGL Extensions API をwglGetProcAddressで取得
  5. OpenGL API のインポートライブラリをリンク
3-2. Windows SDK をインストール

 Microsoft Download Center からWindows SDK を入手して、セットアッププログラムを使ってインストールします。

3-3. OpenGL Extensions ヘッダファイルを配置

 OpenGL.org のOpenGL Extensions Registoryページから以下のヘッダファイルをファイルに保存します。
 ヘッダファイルの配置場所は不問です。 但し、そのディレクトリにコンパイラのインクルードパスを通す必要があります。

 このヘッダファイルは、OpenGL 1.2以降の拡張API や列挙値などを宣言・定義しています。
 換言すればOpenGL 1.1 以前の宣言と定義は、Windows SDK が提供するヘッダファイルで行っています。
 この為、Windows SDK のヘッダファイルが必要になります。

3-4. ソースコードからヘッダファイルをインクルード

 ポイントだけサンプルコードを示します。

#define GL_GLEXT_PROTOTYPES
#define WGL_WGLEXT_PROTOTYPES

#include <gl/gl.h>
#include <gl/glu.h>
#include <gl/glext.h>
#include <gl/wglext.h>

 GLAPI マクロは、関数のインポート宣言です。 この一行で関数プロトタイプにインポート宣言が付与されます。
 GL_GLEXT_PROTOTYPESマクロを宣言することで関数プロトタイプが宣言されます。 WGL_WGLEXT_PROTOTYPESマクロも同様です。
 インクルード宣言の一行目は、OpenGL 1.1 のAPI などを宣言するヘッダファイルです。
 インクルード宣言の二行目は、OpenGL 1.1 のユーティリティAPI などを宣言するヘッダファイルです。
 インクルード宣言の三行目は、OpenGL 1.2 以降のAPI などを宣言するヘッダファイルです。
 インクルード宣言の四行目は、OpenGL 1.2 以降のAPI などを宣言するヘッダファイルです。 三行目との違いは調べていません。

3-5. OpenGL Extensions API をwglGetProcAddressで取得

 wglGetProcAddress()は、実行時にOpenGL32.dll のAPI アドレスを取得する関数です。
 API のエントリポイントを実行時に取得して、以後は関数ポインタを通じてAPI にアクセスする方式となります。
 これを必要な全てのAPI に対して繰り返すことでAPI が利用可能になります。

wglCreateContextAttribsARB =
(PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress(TEXT("wglCreateContextAttribsARB"));

 wglGetProcAddress()を使う必要があるのはインポートライブラリが提供されていないことが原因です
 この為にAPI がスタティックリンクできません。

 エントリポイント解決のコーディングを省略したい場合は、glewを使うことで解決できるようです。 但し、glewはオープンソースです。
 ハードウェアベンダであるnVidiaもOpenGL SDK を提供していましたが、これも内部的にglewを利用しているようでした。

 類似する事柄に「#importディレクティブを使用する」方法も考えられますが、OpenGL32.dllに#import を利用するための情報(=タイプライブラリ)が含まれていないのだと推測しています。  (恐らくは#import がOCX などを取り込む為の機能なのだと考えています。)
 ただ、あまり深くは追っていませんので、若しかすると方法があるかもしれません。

3-6. OpenGL API のインポートライブラリをリンク

 以下のインポートライブラリをリンクします。

opengl32.lib
Glu32.lib

 どちらもOpenGL 1.1 のインポートライブラリになります。 glu*()のAPI を利用しない場合は、Glu32.libは不要です。
 glu*()にカメラ視点計算の関数が提供されているので、普通は利用する筈です。

 OpenGL 1.2 以降のAPI は、実行時にAPI エントリポイントを解決する為、リンク設定は不要です。

4. まとめ

 OpenGLには、DirectX のように頂点バッファを一括して送るAPI は存在しないようです。
 座標系もOpenGLとDirectXでは(確かZ座標軸の方向が)異なります。

 両者の互換性を吸収するライブラリを検討している方へ助言としては、断念した方が良いです。
 最低でも頂点バッファの頂点座標とテクスチャ座標を変換する仕組みを実装する必要が生じます。

 OpenGLは、設計思想にクライアント−サーバモデルを入れて、ネットワーク越しにサーバを配置可能なようにしています。
 この為にDirectXのような頂点バッファで一括送信といった概念が無いのだと考えています。(※1.2 以降もそうなのかは知りません)

 何にしろどれも困難な違いではありません。
 ですが、こういった小さな所が違う為に結果的に多くの課題を積み上げていきますので、実現する目的に合ったライブラリのみを利用することをお勧めします。

 締めの言葉を書いて終わりとします。

「あのさ?将来的に移植する気があるの?その努力は将来的に利用するの?将来も残っているの?」


付録. 補足説明

 WGL: Windows に依存したOpenGL API群を指す


作成日:2010/11/04