C#2.0時代のゲームプログラミング(47) 〜 OpenGLは商用開発の夢を見ない?! (4)

少し書き急ぎすぎたかも知れない。今回はOpenGL extensionについてFAQ的なことからおさらいする。


OpenGLのextensionはglGetString(GL_EXTENSIONS);とやって文字列として取得する。文字列ってところが気持ち悪い。Extensionsには一意なnumberが割り振られているのだから、numberの配列がもらえたほうがいい。でもそうなっていない。そうなっていないものは仕方がないのだけど、同じ内容のextensionに対して異なる拡張名(extension name)が割り振られることがある。これがしばしば問題になる。


例えば、Riko(Rubyから3D描画を行なうライブラリ)の作者の日記より


う、でもNV_texture_rectangleとEXT_texture_rectangleとARB_texture_rectangleなんかは
どれで判断したらいいのかわからん。つか無理か。

まあ結局は速度は気にしないことにして、Ruby側でフックかけるとそこに有無判定した拡張名を
渡すことにした。

これは誰もがつまずく問題なのだけど、この人が何のことを言っているのかわかりにくいと思うので、順を追って解説する。


OpenGL extensionsにはARB_texture_rectangleという制限付きNPOTテクスチャを持つ拡張がある。ところが、NV_texture_rectangleやEXT_texture_rectangleというのもある。これらは同じ内容であり、定数としての値も同じである。NVとついているのは、NVIDIAが最初に自分のハードのために用意した拡張だと言うことだ。ところが、これはいいぞということで、サードパーティにも受け入れられた。このとき接頭辞がEXTに変わった。内容は同じなので定数値は変わらない。そしていよいよOpenGLの業界団体であるARBに受け入れられた。このときめでたくARB_texture_rectangleという名前になる。内容は同じなのでこれまた定数値は変わらない。


要するにすべて同じ内容で、定数・機能の上からは区別がつかない。拡張名のみが異なる。じゃあ、最終形であるARB_texture_rectangleで判別すればいいんじゃないの?と言われるかも知れないが、ARB_texture_rectangleが策定される前に発売されたビデオカードはglGetString(GL_EXTENSIONS);で当然のことながらNV_texture_rectangleやEXT_texture_rectangleを返す。要するに本当にtexture_rectangle拡張に対応させる気ならばこの3つの拡張名のいずれかひとつでも存在するかをチェックする必要がある。


EXTとARBとで内容が微妙に違っていて異なるnumberが割り振られている可能性だって無いとは言い切れないので、ひとつひとつ定数が同じ値かどうかを確かめなくてはならない。こういうのがゲームの実装者負担になると結構辛いものがある。Extensionを使うごとにこんな手間がかかるのは嫌だ。本当は、ゲームライブラリならば、このような手間を吸収してこそライブラリとしての価値があると思うのだけども、Rikoの作者が目指しているのは薄いOpenGLのwrapperのようなので、ここでその是非をとやかく言わないことにする。


結局のところ、OpenGL Extensionsは拡張名を文字列で返すというとんでもない仕様なので、一段クッションをかませて、numberにmappingして(ライブラリの)ユーザーに返すなどとするのが親切なのではないかとは思う。