Monday, July 27, 2015

OpenGL ESのextensionを機種別に簡単に確認できるページ

http://www.gpuinfo.org/
知る限り、最も使いやすそうなページ。機種別のエクステンションはもちろん、エクステンションに対応した機種を一覧にして見られます。OpenGL ES CapsViewerというアプリで取得した情報をこのサイトにアップロードできます。Androidのみ対応のようです。

最近ではESではないOpenGL、Vulkanにも対応しています。Vulkan用のAndroidアプリはHardware CapsViewer for Vulkanで、同様に端末のVulkanのスペックをアップロードできるようになっています。
(2017/11/5 URLを更新、OpenGLとVulkanへの対応した旨を追記)

https://gfxbench.com/result.jsp
Android, iOSはもちろん、PCやOSXのOpenGLの結果も見られます。GFXBenchというベンチマークのサイトで、extensionはちょっと見つけにくい場所にあります。各機種の結果ページのInfoタブの3D APIに下向きの三角形のボタンがあり、そこを押すとextensionが見られます。

Sunday, July 26, 2015

OpenGL ES 2.0でhalf float textureは使えるか?

結論から書くと、QualcommのAdrenoならいけるかもしれません。でもhalf float textureはOpenGL ES 3.0以上でしか使わないと決めてしまったほうがよさそうです。

ES 2.0におけるhalf float textureはextension扱いになり、OES_texture_half_floatがあれば使えます。OpenGL ES 2.0とOpenGL ES 3.0でglTexImage2Dのパラメータが違うのが面倒ですが、以下のように分岐すればいいだけなので、生成そのものは難しくありません。



問題は、OES_texture_half_floatはhalf float textureの生成を保証するだけで、half float textureに対するレンダリングまで保証しない事です。half float textureへのレンダリングは EXT_color_buffer_half_float という別のextensionあれば可能になるようです。

http://stackoverflow.com/questions/8621095/how-to-use-gl-half-float-oes-typed-textures-in-ios

これは、PowerVR SGX 544MP2搭載のAcer Iconia B1-730HD タブレットではその通りになりました。OES_texture_half_floatはあってEXT_color_buffer_half_floatが無い為か、glDrawElementsの段階でGL_INVALID_FRAMEBUFFER_OPERATIONというエラーを出しました。しかし、EXT_color_buffer_half_floatが存在しない手元のAdreno 220(IM-A770K)ではhalf float textureにレンダリングが出来たり、ちぐはぐなことになっています。

また、ES 2.0のARM Mali GPUの場合はOES_texture_half_floatそのものが無いようです。

extensionを見て切り分けができないのは困ったことです。しかしそれ以上にhalf float textureの用途はレンダーターゲットが大部分だと思うので、OES_texture_half_floatという拡張名を見て「OpenGL ES 2.0でhalf float textureにレンダリング出来る!」と思ったプログラマが貴重な時間を空転させてしまうのが最も大きな問題ではないかと思う次第です。

ただし、OpenGL ES 2.0時代のGPUは帯域幅も非力なので、仮にhalf float textureにレンダリングできたとしても効果を活かせる程凝ったことができなかったかもしれません。

Tuesday, July 7, 2015

OpenGL ES 2.0のglBindAttribLocationと、ES 3.0のInput Layout Qualifiers

OpenGL ES 3.0以降では、GLSLから頂点属性の入力位置をlayoutから始まる構文で指定することが出来ます。これをKhronosの公式文書ではInput Layout Qualifiersと呼んでいます。



OpenGL ES 2.0の場合はInput Layout Qualifiersが無いのでGLSLにlocationを記述できませんが、glBindAttribLocationでC側から同じ事ができます。glLinkProgramの直前にglBindAttribLocationを使って頂点属性の名前とlocationを任意に指定できます。



ただし、Input Layout Qualifiersを使う場合Cはlocationの番号だけ知っていればよいのに対し、glBindAttribLocationを使うと名前と番号の両方をCから指定するので冗長な感じがします。

GLSLでlocationを指定せず、glBindAttribLocationもしないとglLinkProgramの時点で自動的にlocationが振り分けられます。この場合、glGetAttribLocationでlocationを問い合わせる必要があります。



こうするとES2.0でもES3.0でも動く上、名前のみで頂点attributeを結び付けられる為に分かり易いという利点があります。いいことずくめのようですが、locationの割り当てが実装依存で予想できない為、複数シェーダでlocationを共有できないという欠点があります。同じ頂点バッファを複数のシェーダで描画する場合、シェーダを切り替える毎にglGetAttribLocationで問い合わせる煩雑さがあります。

この煩雑さはES 3.0でVAO(Vertex Array Object)を使いはじめると特に顕著です。シェーダ毎にlocationが異なるとVAOをシェーダー毎に作り直さなければいけません。一つのVAOを複数のシェーダで使いまわす為にはlocationの番号を固定する必要があります。

ある程度の規模のフレームワークを作ることを考えると、glBindAttribLocationかInput Layout Qualifiersを使い、"position"は0番、"normal"は1番などと、あらかじめlocationを決めておくとうまく書けそうです。

(2016/03/29 追記)
使いやすいフレームワークのためのもっといい方法を思いついたので書きました。
http://glhub.blogspot.kr/2016/03/opengldirectx.html