ややっこしいWindowsでのOpenGLバージョン処理

相も変わらずOpenGL関係です。WindowModePatchの為にいろいろと調べてみるとWindows上でOpenGLを使う場合、なかなかおもしろい仕掛けがしてあることがわかりびっくり。

このことに言及している記事もありますが、かなり古かったのでこちらも記事にしてみたいと思います。

opengl32.dllが「静的」にサポートしているのはOpenGL1系のみ

Windows上でOpenGLを使っているプログラムはほぼもれなくopengl32.dllをリンクしています。なのでOpenGLの機能を提供しているのはopengl32.dllである、といってもいい「はず」なのですが、そうではなかったのですね。(プログラムによってはglu.dll(glut.dllではない)もリンクしている場合はありますが、ほぼ同じ意味です)

opengl32.dllが「エクスポート可能な関数」として持っている関数群を見ればわかりますが、OpenGL2系以降はありません。OpenGL1系で定義されたものばかりです。しかもopengl32.dllにリンクされている外部DLLになぜかddraw.dllがあることからOpenGL1系をDirectDraw(Direct3D7)が肩代わりしているだろうと言うことまで推察できます。すごい実装の方法だな、と思いながら。

あとは、まさかOpenGLのバージョンが新しくなるたびにopengl32.dllをリリース、というわけにも行かないでしょうからこうなるとopengl32.dllにOpenGL2系以降の機能が実装されていないことになります。はてさて、ではOpenGL2系以降をWindowsで使用するとき、なぜにopengl32.dllがリンクされるのでしょうか?

 

opengl32.dllが実装している「wglGetProcAddress」という関数に鍵がある

そもそも、OpenGLの関数群はすべて「gl」という接頭辞がついているので見分けがつきやすいです。そして、この「wgl」という接頭辞はおそらく「Windows OpenGL」を指しているという推測が成り立ちます。つまりWIndowsだけで使用できるOpenGLの処理ですね。

そしてさらにはその後ろの「GetProcAddress」はWinAPI系のGetProcAddressとほぼ同じ意味、つまり対象の名前で登録されている処理のアドレスを取得する、という意味になります。これがOpenGL2系以降でもopengl32.dllが連結される秘密になります。つまり、各バージョンで定義されているプロシージャのアドレスをwglGetProcAddressで取得してそれをコールすることで対象バージョンのOpenGLを使う、という処理になっているわけです。対応していない処理はNULLを返すことで実装されてないことを示して、実装されている場合はグラフィックドライバが持っているOpenGLのライブラリから必要な関数をとってきて完了、と。なるほどね~

ちなみに、使用可能なOpenGLに関する情報はglGetStringをたたくことでわかります。この場合は文字列で帰ってきますのでatofなどで数字に戻してバージョンチェックをすればOKです。

 

テクスチャのマルチパスレンダリングはOpenGL2.0Externalから

調べてみましたが、FrameBufferという機構を用いてマルチパスレンダリングを行うらしいです。ただ、この機構がOpenGL2.0系本体には実装されていないそうなので、WindowModePatchがOpenGLの可変ウィンドウサイズ処理を実装するならOpenGLの最低バージョンがおそらくOpenGL2.0Externalとなると思います。今現在このバージョンを下回るマシンはほぼ無い(OpenGL2.0系とDirectX9系が対応しているため)とは思いますが、まあ組んでみて考えることにします。もしかするとOpenGL1.0系では使えない可能性もあり、そうなるとその部分はDirectDrawベースという可能性に賭けて処理を組む必要もあるかもしれませんが。

 

LINEで送る
[`fc2` not found]
このエントリーを Google ブックマーク に追加

コメントを残す

メールアドレスが公開されることはありません。

*

この記事のトラックバック用URL