デバイス固有情報の取得
久しぶりの更新なので軽めのネタで肩慣らしをしようかと思います.
サマリはこんな感じになります.
それではさっくりいきましょう.
デバイス情報の取得
取得できるデバイス情報には、以下のようなものがある.
GL_MAX_VERTEX_ATTRIBS | シェーダーで利用できる、頂点属性の最大数 |
GL_MAX_VARYING_VECTORS | varying 変数で利用できる、ベクトルの最大数 |
GL_MAX_VERTEX_UNIFORM_VECTORS | バーテックスシェーダーで利用できる、uniform(ベクトル)の最大数 |
GL_MAX_FRAGMENT_UNIFORM_VECTORS | フラグメントシェーダーで利用できる、uniform(ベクトル)の最大数 |
GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS | バーテックスシェーダーで利用できる、テクスチャユニットの最大数 |
GL_MAX_TEXTURE_IMAGE_UNITS | フラグメントシェーダーで利用できる、テクスチャユニットの最大数 |
GL_MAX_TEXTURE_SIZE | テクスチャの最大の幅と高さ |
GL_MAX_CUBE_MAP_TEXTURE_SIZE | キューブテクスチャの最大幅と高さ |
GL_MAX_RENDERBUFFER_SIZE | レンダーバッファの最大幅と高さ |
GL_MAX_VIEWPORT_DIMS | ビューポートの最大幅と高さ |
このあたりは、gl.h に書かれているので標準的に取得出来ると思う.
使い方は、glGetIntegerv を利用して、次のように取得する.
GLint a_val;
// 頂点点属性の最大数
glGetIntegerv( GL_MAX_VERTEX_ATTRIBS, &a_val );
少しだけわかりづらい点としては、ビューポートの最大幅と高さで、これは、
// ビューポートの最大幅 GLint a_dimes[2]; glGetIntegerv( GL_MAX_VIEWPORT_DIMS, a_dimes); a_viewport_width = a_dimes[0]; a_viewport_height = a_dimes[1];
のように取得すれば良い.
uniform/varying変数のベクトル最大数とパッキングルール
バーテックスシェーダー/フラグメントシェーダーを利用していると、uniform変数やvarying変数がどの程度利用できるのかが気になる.
ここで前述の GL_MAX_VARYING_VECTORS 等を利用すると、それぞれの変数で利用できるベクトルの最大数が取得出来るが、これを活用するためにはパッキングルールの理解が必要となる.
まず、パッキングルールがなくとも理解できる最大数の利用方法を考えてみる.
iPad2 にて、GL_MAX_VERTEX_UNIFORM_VECTORS の値を取得すると 128 という値が返ってくる.
これは vec4 変数が 128個使えるという意味で、仮にすべて mat4 として利用した場合には(mat4 は、vec4 * 4なので)32個のmat4が利用できることを意味している.
理解のために、コードと表を記しておく.
uniform vec4 v; uniform mat4 m;
添え字 | x | y | z | w |
[0] | v.x | v.y | v.z | v.w |
[1] | m[0].x | m[0].y | m[0].z | m[0].w |
[2] | m[1].x | m[1].y | m[1].z | m[1].w |
[3] | m[2].x | m[2].y | m[2].z | m[2].w |
[4] | m[3].x | m[3].y | m[3].z | m[3].w |
# ここから、バーテックスシェーダーで行いたい場合には、32個の行列パレットが利用でき
# そうだということがわかる.
もしここですべてを vec3 変数として利用したい場合、vec4 = (4要素) / vec3 = (3要素)なので128個のvec3変数しか利用できなさそうに思える.
イメージとしては次の表を思い浮かべると良い.
これだと、あからさまに利用していないw成分がもったいないので、物理的な格納領域にたいしてどのように変数を割り当てるのかを決めるパッキングルールというものがある.
パッキングルールのイメージを次の表で記す.
uniform vec4 v[130];
添え字 | x | y | z | w |
[0] | v[0].x | v[0].y | v[0].z | v[128].x |
[1] | v[1].x | v[1].y | v[1].z | v[128].y |
[2] | v[2].x | v[2].y | v[2].z | v[128].z |
[3] | v[3].x | v[3].y | v[3].z | v[129].x |
[4] | v[4].x | v[4].y | v[4].z | v[129].y |
… | ||||
[127] | v[127].x | v[127].y | v[127].z | - |
とりあつかうプログラマはどのようにパッキングが行われるのかを意識する必要がないが、このルールの存在を知らないと利用できる変数の数で損をする可能性があるので存在は覚えておく必要がある.
(拡張)機能の有無
glGetIntegerv を利用*せず*に調べる必要がある値も存在する.
たとえば、
GL_OES_depth_texture | depth texure の作成が行えるか? |
GL_OES_depth24 | 24bit 形式の depth バッファが作成できるか? |
GL_OES_texture_half_float | half float 形式のテクスチャが作成できるか? |
GL_OES_texture_float | float 形式のテクスチャが生成できるか? |
GL_HALF_FLOAT_OES | half float のサポートされているか? |
のようなことを調べることができる.
上の表は、私が興味があることだけを書き出しただけなので、詳しく知りたい場合には glext.h を眺めてみたほうがよい.
これらは、主に拡張機能の有無なので、glext.h にマクロとして定義されているので次のように使えば良い(と思う)
// depth texure の作成が行えるか? #ifdef GL_OES_depth_texture bool a_support_depth_textre = (GL_OES_depth_texture != 0); #else bool a_support_depth_textre = false; #endif
ただし、これらの機能の有無を調べたい場合、コード自体をマクロで処理することになることが多いので変数として扱う意味は薄い点と、所詮マクロなのでコンパイル単位でしか判断が行えない点に注意をする必要がある.
具体的にに言えば、HalfFloat が利用できる場合、"GLhalf" などの型が利用できるが、これは glext.h 内で
#if GL_OES_texture_half_float typedef unsigned short GLhalf; #endif
このように typedef されているだけなので、環境によってはコンパイルエラーになる可能性がある.
iPad2におけるデバイス情報
手元にある iPad2 で調べた結果を以下に表にする.
GL_MAX_VERTEX_ATTRIBS | 16 |
GL_MAX_VARYING_VECTORS | 8 |
GL_MAX_VERTEX_UNIFORM_VECTORS | 128 |
GL_MAX_FRAGMENT_UNIFORM_VECTORS | 64 |
GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS | 0 |
GL_MAX_TEXTURE_IMAGE_UNITS | 8 |
GL_MAX_TEXTURE_SIZE | 4096 |
GL_MAX_CUBE_MAP_TEXTURE_SIZE | 4096 |
GL_MAX_RENDERBUFFER_SIZE | 4096 |
GL_MAX_VIEWPORT_DIMS | 4096 |
GL_OES_depth_texture | 1 |
GL_OES_depth24 | 1 |
GL_OES_texture_half_float | 1 |
GL_OES_texture_float | 1 |
GL_HALF_FLOAT_OES | 1 |
まとめ
OpenGL ES2.0 のデバイス固有情報の取得を行いました.
パッキングルールに関しては、『OpenGL ES2.0 プログラミングガイド』(p.92 5.6 uniform変数とvarying変数のパッキング)を参考にしました.
また、今回の内容と直接関係ありませんが、この本には巻末の付録に "GL_HALF_FLOAT_OES"の解説が載っており、浮動小数を半浮動小数に(相互)変換するコードが示されておりとても役にたっています.
iOS のデバイス固有情報の取得に関しては、Appleが公開している『iOS OpenGL ESプログラミングガイド』を参考にしました.
iPad2のデバイス情報を覗いてみると、"GL_OES_texture_half_float"が有効になっていたりと意外な発見がありました.
実は詳しいことをわかっていないのですが、おそらく HalfFloat のフォーマットのテクスチャが取り扱えるってことですよね?
レンダリングターゲットにはできるのかな?
描画速度はおいとくとしても、iOSデバイスでHDRレンダリングが出来たらちょっと楽しそうです.
- 作者: Aaftab Munshi,Dan Ginsburg,Dave Shreiner,アフタブ・ムンシ,ダン・ギンズバーグ,デーブ・シュライナー,松田晃一
- 出版社/メーカー: ピアソン桐原
- 発売日: 2009/11/01
- メディア: 単行本
- 購入: 2人 クリック: 107回
- この商品を含むブログ (25件) を見る