OpenGLはプラットフォーム非依存
コノルさんの勉強会ではiPhoneでのOpenGL ESアプリを作ることを目標に、基本的な描画、テクスチャ、バンプマッピング、マルチテクスチャまでを勉強しました。
このブログはおさらいという意味で、勉強会のソースをアリの目でもう一度追学習してみようと考えています。
OpenGL自体はプラットフォーム非依存で、実際に画面に表示するウィンドウを作るなどという部分は含まれていません。そのあたりを扱う有名なライブラリに、glutなどがありますし、本家でもEGLという、プラットフォーム依存部分のインターフェースを規定しているものもあるようです(iOSでのEAGLViewはEGLのApple実装らしい)。
iOSではglutは使えませんから、私も参考書などにあるソースがそのまま動かなかったりして戸惑いました。逆にEAGLViewは当然他の環境にはありませんので、この記事はiOSでのOpenGL ES1.1をターゲットにしていますが、iPhone独自部分についてはあまり深く追わず、OpenGL ES1.1として一般的な内容になるように心がけてみます。
2011年2月16日水曜日
2011年2月14日月曜日
OpenGL勉強会まとめ(1) OpenGLとは何か
わかりにくいOpenGL
言わずと知れた3D API、OpenGL。巷では、OpenGLはステートマシンだとか、クライアント&サーバー型だとかいう説明がされていますが、それにしても分かり難くないでしょうか。こう書くんだよ、というサンプルをアレンジして使ってみるのですが、それぞれの命令が何に対して働きかけているものなのか、どうも命令が整理されていないように感じるのです。
例えば、頂点配列を定義するのはglVertexPointer、カレントカラーを指定するのはglColor、というAPIがあるのですが、その設定値を読み出すのは両方共glGetというAPIです。さらに読み出す値の型によってインターフェースを分けています。
整数型の値ならば glGetIntegerv
浮動小数点の値ならば glGetFloatv
などと機能的なまとまりでなく、型によってAPIが分かれています。いったいどうしてなのか。私はこれはソフトウェア的な思想ではないように思うのです。
OpenGLはデバイスドライバの成れの果て?
それはOpenGL自体の設計が古い(1992年頃)というのもあるのですが、私はOpenGLを3DグラフィックアクセラレータのLSIのレジスタを抽象化したデバイスドライバのようなものだと捉えています。基本はSGIが使用していた描画回路をもとに標準化されたのではないかと思います。
一般的に、LSIには機能を制御するレジスタ群があり、ここに値を書き込んだり、読み出したりすることで制御を行います。
それでソフトウェアにはドライバというレイヤを設けてこのハードウェアを抽象化して使いやすくするわけです。そのドライバの中でも基本的な機能に、レジスタの読み書きがあります。レジスタにはそのレジスタの機能を表す名前をつけ、その名前を元にレジスタを読み書きするAPIを設けます。
先程のOpenGLのglGetがこの読み込みAPIに当たります。ものすごく低位なレイヤのAPIをそのまま標準化してしまったわけです。
また、レジスタはハードウェアのブロックに直結しているだけあって、ある機能を実現するためのモノがあっちこっちに分散していたりします。○○機能を有効にするために、xxxxレジスタとyyyyレジスタのbitどこそこを1にする、とかです。このへんもOpenGLの手数の多さと似ています。
余談ですがLSIのレジスタはメモリと違い、すべてのレジスタが書き込みできるとは限らず、読み出ししか出来ないものや、あるタイミングで勝手にクリアされたりするものもあります。
OpenGLの付き合い方が分かってきた
そんな目でOpenGLをみてみると、上記の特徴も、
というようにしっくりする気がします。
描画命令というよりも、LSIの制御シーケンスを書いていると思えばよいのです。(と言って納得していただけるのは組込み系経験のある人だけかもしれませんが…笑)
これC++のクラスにでもしたくなりますね(笑) そのうちするかもしれません。
これからしばらく、OpenGLについての勉強をかねて、使い方を俯瞰していきたいと思います。
言わずと知れた3D API、OpenGL。巷では、OpenGLはステートマシンだとか、クライアント&サーバー型だとかいう説明がされていますが、それにしても分かり難くないでしょうか。こう書くんだよ、というサンプルをアレンジして使ってみるのですが、それぞれの命令が何に対して働きかけているものなのか、どうも命令が整理されていないように感じるのです。
例えば、頂点配列を定義するのはglVertexPointer、カレントカラーを指定するのはglColor、というAPIがあるのですが、その設定値を読み出すのは両方共glGetというAPIです。さらに読み出す値の型によってインターフェースを分けています。
整数型の値ならば glGetIntegerv
浮動小数点の値ならば glGetFloatv
などと機能的なまとまりでなく、型によってAPIが分かれています。いったいどうしてなのか。私はこれはソフトウェア的な思想ではないように思うのです。
OpenGLはデバイスドライバの成れの果て?
それはOpenGL自体の設計が古い(1992年頃)というのもあるのですが、私はOpenGLを3DグラフィックアクセラレータのLSIのレジスタを抽象化したデバイスドライバのようなものだと捉えています。基本はSGIが使用していた描画回路をもとに標準化されたのではないかと思います。
一般的に、LSIには機能を制御するレジスタ群があり、ここに値を書き込んだり、読み出したりすることで制御を行います。
xxxx番地のbit0に1を書きこむと描画開始、などと決まっています。またレジスタには値を記憶したり、読み出したり、またLSIの処理状態によって勝手に変化するものがあったりします。どれがどういう機能を持つかはLSIのユーザーズマニュアルのレジスタマップを参照しますが、これでは分かりにくいしハードの仕様がちょっと変わっただけでソフトウェアのかなりの部分を変更しなくてはいません。
それでソフトウェアにはドライバというレイヤを設けてこのハードウェアを抽象化して使いやすくするわけです。そのドライバの中でも基本的な機能に、レジスタの読み書きがあります。レジスタにはそのレジスタの機能を表す名前をつけ、その名前を元にレジスタを読み書きするAPIを設けます。
先程のOpenGLのglGetがこの読み込みAPIに当たります。ものすごく低位なレイヤのAPIをそのまま標準化してしまったわけです。
また、レジスタはハードウェアのブロックに直結しているだけあって、ある機能を実現するためのモノがあっちこっちに分散していたりします。○○機能を有効にするために、xxxxレジスタとyyyyレジスタのbitどこそこを1にする、とかです。このへんもOpenGLの手数の多さと似ています。
余談ですがLSIのレジスタはメモリと違い、すべてのレジスタが書き込みできるとは限らず、読み出ししか出来ないものや、あるタイミングで勝手にクリアされたりするものもあります。
OpenGLの付き合い方が分かってきた
そんな目でOpenGLをみてみると、上記の特徴も、
- ステートマシンである
- クライアント&サーバー型である
というようにしっくりする気がします。
描画命令というよりも、LSIの制御シーケンスを書いていると思えばよいのです。(と言って納得していただけるのは組込み系経験のある人だけかもしれませんが…笑)
これC++のクラスにでもしたくなりますね(笑) そのうちするかもしれません。
これからしばらく、OpenGLについての勉強をかねて、使い方を俯瞰していきたいと思います。
2011年2月11日金曜日
OpenGL勉強会まとめ
OpenGL勉強会まとめ
先日、Conolさん主催のOpenGL勉強会に参加してきました。
自分でも勉強しているんですが、OpenGLって日本語のリファレンスとか少ないです。
「こう書けば、こうなる」的にパターンで覚えて行くのもいいんですけど、昔から仕組みを理解しないと納得がいかないタイプなので、まずは勉強会で使ったAPIを整理して、構造を推測して見ることにします。
Posted from dPad on my iPad ゆうぞら
先日、Conolさん主催のOpenGL勉強会に参加してきました。
自分でも勉強しているんですが、OpenGLって日本語のリファレンスとか少ないです。
「こう書けば、こうなる」的にパターンで覚えて行くのもいいんですけど、昔から仕組みを理解しないと納得がいかないタイプなので、まずは勉強会で使ったAPIを整理して、構造を推測して見ることにします。
Posted from dPad on my iPad ゆうぞら
登録:
投稿 (Atom)