====== The OpenGL Extension Wrangler Library ======
原文 //[[http://glew.sourceforge.net/]]//
The OpenGL Extension Wrangler Library (GLEW)は、C/C++で書かれたクロスプラットフォームでオープンソースのOpenGL拡張読み込みライブラリです。
GLEWは対象となる環境で、どのOpenGL拡張がサポートされているかを特定するための効率的なランタイム機構を提供します。
OpenGLのコア機能や拡張機能は1つのヘッダファイルで公開されています。
GLEWはWindows, Linux, Mac OS X, FreeBSD, Irix, Solarisを含む、様々なOS上で検証されています。
===== 基本的な使い方 =====
==== GLEWの初期化 ====
はじめに、有効なOpenGLレンダリングコンテクストを作成し、それからglewInit()
を呼んで拡張機能へのエントリーポイントを初期化します。
glewInit()
がGLEW_OK
を返してきたならば初期化は成功で、拡張機能をOpenGLのコア機能と同等に利用することができます:
#include
#include
...
glutInit(&argc, argv);
glutCreateWindow("GLEW Test");
GLenum err = glewInit();
if (GLEW_OK != err)
{
/* 問題発生: glewInit 失敗。何か深刻な事態が発生している。 */
fprintf(stderr, "Error: %s\n", glewGetErrorString(err));
...
}
fprintf(stdout, "Status: Using GLEW %s\n", glewGetString(GLEW_VERSION));
==== 拡張機能の検査 ====
GLEW 1.1.0から、GLEW_拡張名
という書式の大域変数を問い合わせることで、あなたの環境で拡張が使用可能かどうか個々に判断することができるようになりました:
if (GLEW_ARB_vertex_program)
{
/* ここでは ARB_vertex_program 拡張を安全に使用する事ができる。 */
glGenProgramsARB(...);
}
**GLEW 1.0.xでは、この用途には大域構造体が使用されていました。
リリースごとのバイナリ互換を確実にするために、この構造体は対応する変数群に置き換えて下さい。**
同様に、OpenGLコア機能の確認を行う事も出来ます。
例えば、OpenGL 1.3に対応しているかどうかを見るには、以下のようにします:
if (GLEW_VERSION_1_3)
{
/* おめでとう! OpenGL 1.3 をサポートしている! */
}
通常は、GLEW_拡張名
またはGLEW_VERSION_バージョン
の真偽値を確認します。
入力文字列から拡張の確認を行うことも可能です。
1.3.0リリースからは、glewIsSupport
を使用することで、要求する中核機能や拡張機能が使用可能かどうかを確認することができます:
if (glewIsSupported("GL_VERSION_1_4 GL_ARB_point_sprite"))
{
/* 素晴らしい, OpenGL 1.4 とポイントスプライト機能を持っている。 */
}
OpenGL拡張専用としてglewGetExtension
は、(今よりも)遅い(確認)手段を提供します(GLEW 1.0.x〜1.2.x)。
**1.3.0リリースで、glewGetExtensionはglewIsSupportedに置き換えられました。**
if (glewGetExtension("GL_ARB_fragment_program"))
{
/* ARB_fragment_program に対応しているようだ。 */
}
==== 実験的なドライバについて ====
GLEWはグラフィックスドライバから、対応するOpenGL拡張の情報を取得します。
しかしながら、実験的なドライバや準リリースのドライバは、利用可能な全ての拡張の情報を、標準的な機構を通しては報告してこない可能性があります。この場合、GLEWはその拡張は未対応であると返します。
この状況を回避するには、glewInit
を呼ぶ前に大域フラグglewExperimental
を、GL_TRUE
に設定します。すると、有効なエントリーポイントを持つ全ての拡張の公開が保証されます。
==== 特定プラットフォームの拡張 ====
プラットフォーム固有の拡張は、2つのヘッダファイル:wglew.hとglxew.hに分けられ、それぞれ利用可能なWGLとGLXの拡張を定義しています。
特定の拡張に対応しているかどうかを調べるには、WGLEW_拡張名
またはGLXEW_拡張名
を問い合わせます。例:
#include
if (WGLEW_ARB_pbuffer)
{
/* OK, pbuffer が使用可能。 */
}
else
{
/* 残念, このプラットフォームでは pbuffer は動かない。 */
}
もう1つの方法として、wglewIsSupported
またはglxewIsSupported
を使い、文字列から拡張を確認します:
if (wglewIsSupported("WGL_ARB_pbuffer"))
{
/* OK, pbuffer が使用可能。 */
}
==== ユーティリティ ====
GLEWは2つのコマンドラインユーティリティを提供します: 1つは利用可能な拡張とvisualsのリストを作成するもので、もう1つは拡張のエントリーポイントの検証を行うものです。
=== visualinfo: extensions and visuals ===
visualinfo
はglxinfo
の拡張版です。
Windows用のバージョンは、visualinfo.txt
というファイルが作られ、それにはOpenGL、WGL、GLUのそれぞれで使用可能な拡張が、ビジュアル(別名ピクセル形式)の表と一緒に含まれます。
PbufferとMRTで使えるビジュアルも同様に含まれます。
詳しい使い方については、visualinfo -h
と打って下さい。
=== glewinfo: 拡張検証ユーティリティ ===
glewinfo
で、使用するプラットフォームが対応する、拡張のエントリーポイントを検証することが出来ます。
Windows用のバージョンは、結果をglewinfo.txt
というテキストファイルで報告します。
UNIX用のバージョンでは、結果はstdout
に表示されます。
Windowsでの使い方:
glewinfo [-pf ]
には、表示可能なピクセル形式IDを入れます。
UNIXでの使い方:
glewinfo [-display ] [-visual ]
にはX11のディスプレイ番号が、には表示可能なビジュアルIDを入れます。
===== 応用的な使い方 =====
==== 自動コード生成 ====
リリース1.1.0から、ソースコードとドキュメントの一部が、OpenGL拡張仕様書から2ステップで自動的に生成されるようになりました。
第1ステップでは、仕様書ファイルをOpenGLレジストリからダウンロードし、パースします。
記述子の雛形が各々の拡張から生成されます。
これら記述子は単純でコンパクトな形式で、拡張の名前、仕様へのリンクURL、トークン、関数宣言、typedef、構造体定義を含む、ソースコードとドキュメントを生成するのに必要な全ての情報を持ちます。
第2ステップでは、ライブラリやglewinfoのソースと同様に、ヘッダファイルがその記述子ファイルから生成されます。
コード生成スクリプトはautoというサブディレクトリに配置されます。
コード生成スクリプトは、GNU make, wget, perlを必要とします。
Windowsでこれらツールを利用するための最も簡単な方法は、Cygwinをインストールすることですが、ルートディレクトリは必ずバイナリモードでマウントする必要があります。
auto
ディレクトリの中に作られたmakefileは、以下のビルドターゲットを提供します:
| make| 記述子からソースファイルを作成します。\\ 記述子が存在しなければ、それらを仕様書ファイルから作成します。\\ もし仕様書ファイルが存在しなければ、それらをOpenGLリポジトリからダウンロードします。 |
| make clean| ソースファイルを削除します。 |
| make clobber| ソースファイルと記述子を削除します。 |
| make destroy| ソースファイル、記述子、仕様書ファイルを削除します。|
| make custom| auto/custom.txtで列挙される拡張からソースファイルを作成します。\\ 詳細は「独自コード生成」をご覧下さい。|
=== 新しい拡張の追加 ===
新しい拡張を追加するには、その拡張の記述子ファイルをaudo/coreディレクトリに作成し、autoディレクトリでmake clean; make
と打ち、コード生成スクリプトを再実行します。
記述子ファイルの形式は以下のようになります。
[]で囲まれている要素はオプションです。
[]
[ ]
[ ]
...
[]
[]
...
[]
[]
...
試しにauto/code
の中にあるファイルの1つを見て下さい。
typedefと関数宣言がセミコロンで終わる必要がない点に注意して下さい。
=== 独自コード生成 ===
GLEW 1.3.0から、auto/custom.txt
に一覧を明記することで、どの拡張をライブラリに含めるかを制御する事ができるようになりました。
これは、全ての拡張が必要でない時や、ソースファイルのサイズを削減したい時に便利です。
auto
ディレクトリでmake clean; make custom
と打ち込んで、拡張の独自リストを有効にするスクリプトを再実行して下さい。
For example, the following is the list of extensions needed to get GLEW and the utilities to compile.
WGL_ARB_extensions_string
WGL_ARB_multisample
WGL_ARB_pixel_format
WGL_ARB_pbuffer
WGL_EXT_extensions_string
WGL_ATI_pixel_format_float
WGL_NV_float_buffer
==== 複数のレンダリングコンテキスト (GLEW MX) ====
リリース1.2.0から、異なる画面形式(different capabilities)も可能でスレッドセーフな、複数レンダリングコンテキストを利用することが出来ます。
これは大多数のユーザーには必要なく、異なるバージョン間の互換性維持の為にバイナリリリースには含まれていません。
複数のコンテキスト対応を追加するには、以下のようにします:
- GLEW_MX
プリプロセッサフラグを定義して、GLEWをコンパイル及び使用します。
- 各々のレンダリングコンテキストごとにGLEWContext
オブジェクトを生成します。これはレンダリングコンテキストが存在する限り、利用可能です。
- glewGetContext()
というマクロまたは関数を定義します。これはGLEWContext
オブジェクトへのポインタを返すもので、オブジェクトはOpenGL/WGL/GLX呼び出しの何れかで発生するレンダリングコンテキストと関連付けられます。この割り当て機構(dispatch mechanism)は原始的ですが、一般的です。
- 確実に、各々のレンダリングコンテキストでGLEWContext
オブジェクトを生成した後にglewInit()
を呼び出して下さい。GLEWContext
へのポインタはglewGetContext()
によって返され、大域メモリまたはスレッドの局所メモリに属さなければならない点に注意して下さい。
MSDNのWGLについての文献によれば、異なるピクセル形式を使うレンダリングコンテキスト毎に、エントリーポイントを初期化しなければなりません。
例えば、Microsoftが実装した標準的なソフトウェアOpenGLのピクセル形式と、ハードウェアアクセラレーションが効くピクセル形式は異なる画面形式(different capabilities)を持ちます。
**GLEWは、デフォルトではこの要求を無視し、コンテキスト毎のエントリーポイントは定義しません(ですが、上で記述した段階を経る事で使う事ができます)。**
なぜならば、全てのハードウェアアクセラレーションの効くピクセル形式は、同じエントリポイントと機能(capabilities)を提供するからです。
Assuming a global namespace for the entry points works in most situations, because typically all hardware accelerated pixel formats provide the same entry points and capabilities.
これは、複数コンテキスト版のGLEWを使用しないのであれば、glewInit()
をプログラム中で一度だけ─あるいは、より正確にはプロセス毎に1回呼ぶ必要がある、ということを意味します。
==== 名前空間の分離 ====
同じシンボルを含むライブラリをリンクする際の名前の衝突を避けるため、拡張のエントリーポイントは分離された名前空間で宣言しています(リリース1.1.0以上)。
これは、等価なGLEWの関数をOpenGLの関数の別名とすることで、実現します。
例えば、glFancyFunction
は単純にglewFancyFunction
の別名です。
分離された名前空間は、トークンと関数ポインタ定義には影響を与えません。
==== 既知の問題 ====
GLEWはGLUTとの互換性のためにGLX 1.2を必要とします。