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が見られます。
Monday, July 27, 2015
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にレンダリングできたとしても効果を活かせる程凝ったことができなかったかもしれません。
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
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
Sunday, June 7, 2015
Android NDKでC++11のstd::chronoを使った時間計測
今まで以下のような秒単位の時間計測関数を、Android用とWindows用にそれぞれ作って使っていました。
今更ながら、C++11のstd::chronoでどちらでも動く関数を書けることに気づき、以下のように書きなおしました。
static auto startが妙ですが、こうするとGetTimeの初回呼び出し時の時間をstartに記録できます。あとは毎回のGetTimeの呼び出しでstartからの経過時間を秒単位で返します。
#include <chrono> で "fatal error: chrono: No such file or directory"というエラーが出てしまう場合、build.gradleでgnustlを使うよう設定する必要があります。build.gradleの一部を抜粋します。
"stlport_static"ではだめで、"gnustl_static"を使う必要があるようです。android-ndk-r10d\sources\cxx-stl\stlport\stlportにはchronoが入っていないのに対し、android-ndk-r10d\sources\cxx-stl\gnu-libstdc++\4.9\includeには入っていました。
Labels:
Android,
Android Studio,
C++,
C++11,
Japanese,
Visual Studio
Monday, June 1, 2015
Evan WallaceさんのWebGL Waterのソースを読んでみた
https://github.com/evanw/webgl-water
このレポジトリをローカルに取ってきてじっくり読んでみました。
このレポジトリをローカルに取ってきてじっくり読んでみました。
波紋の作り方
浮動小数点数テクスチャをグリッドとして使っています。RGBAそれぞれを別の意味で使います。Rは水面の高さ、Gは水面の上下方向の加速度、BAは法線を格納するのに使います。
各グリッドのシミュレーションは以下の2つのルールで行います。
- 上下左右の隣接4グリッドの高さの平均が自分の高さと異なる場合、周囲に高さを合わせるように加速度を調節します。
- 各グリッドは自身の加速度によってのみ上下します。
グリッドは当然四角形ですが、上のルールだけで放射状に広がる波紋が出来るのが不思議です。
水面の法線の格納方法
シミュレーションが終わったらレンダリング前に各グリッドの法線を求め、上と同じテクスチャのBに法線のX、Aに法線のZを格納します。Yが格納されていませんが、法線は長さが常に1なので、ピタゴラスの定理と同じ原理でXとZからYを推測できます。
この方法の欠点は符号を復元できないことで、ここにXやZではなくYを省略する理由があります。WebGL WaterではY軸が上方向を向いており、常に正の方向になります。対してXとZは符号も保存する必要があります。
コースティック
水面が一切波立っていない場合と、水面が波立っている場合に分けて太陽光を水面で屈折させ、底または壁との衝突点を求めます。これを水面のグリッド全体で行い、波立っていない場合に比べて隣接グリッドの衝突点と自分の衝突点の距離が変化するかを見ます。広がった場合は光の密度が減り、狭まった場合は光の密度が増えると判断します。
密度の計算ですが、dFdx関数とdFdy関数を使うのがユニークです。つまり、各グリッドの波立っている場合と波立っていない場合の衝突点の計算を頂点シェーダで行い、それぞれvaryingでフラグメントシェーダに渡します。隣接グリッドの情報を直接読みに行くのではなくvaryingの変化量を見るだけなので追加のテクスチャフェッチが発生せず、高速に動作しそうです。
WebGLの拡張機能
浮動小数点数のテクスチャを使うため、OES_texture_float 拡張を使っています。
また、dFdx関数とdFdy関数を使うため、OES_standard_derivatives 拡張を使っています。
まとめ
簡潔で無駄の無いコードで、こんなきれいなエフェクトが作れるのはすごいですね。
Saturday, May 23, 2015
Android StudioのGUIを使わずにビルド→インストール→起動
以下のようなバッチファイルをgradlew.batと同じ位置に作っておくことで、Android Studioを起動せずともコマンドライン又はエクスプローラからビルド、インストール、起動ができるようになります。NDKを使用している場合のビルドまで問題なく出来ました。
※ パッケージ名は、com.pinotnoir.adamasを、アクティビティ名はcommon.pinotnoir.glactivity.PinotGLActivityを置き換えてください。
ところで、"ADB server didn't ACK" というエラーに悩まされていたのですが、原因はNsight Tegra Visual Studio Editionでした。これが内部でADBをつかっているため衝突するようです。Visual Stuidio起動中に上のバッチファイルが使えない場合、Visual Studioを終了すると使えるようになりました。
Nsight Tegra Visual Studio Editionを一時停止することはできないようです。Visual StudioとAndroid Studioを同時に使いつつ、Nsight Tegraも使いたい場合、面倒なことになりそうです。Nsight Tegraをアンインストールすると衝突は起こらなくなりました。
※ パッケージ名は、com.pinotnoir.adamasを、アクティビティ名はcommon.pinotnoir.glactivity.PinotGLActivityを置き換えてください。
ところで、"ADB server didn't ACK" というエラーに悩まされていたのですが、原因はNsight Tegra Visual Studio Editionでした。これが内部でADBをつかっているため衝突するようです。Visual Stuidio起動中に上のバッチファイルが使えない場合、Visual Studioを終了すると使えるようになりました。

Nsight Tegra Visual Studio Editionを一時停止することはできないようです。Visual StudioとAndroid Studioを同時に使いつつ、Nsight Tegraも使いたい場合、面倒なことになりそうです。Nsight Tegraをアンインストールすると衝突は起こらなくなりました。
Thursday, May 14, 2015
GitHubのDirectXTKをgit submoduleとして組み込む
MicrosoftのGitHubアカウントでDirectXTKが公開されています。gitのsubmoduleとして組み込めるので格段に管理しやすくなりそうです。早速組み込んでみました。
$ git submodule init
$ git submodule add https://github.com/Microsoft/DirectXTK.git DirectXTK
$ git commit -m "DirectXTK added as a submodule"
自分のレポジトリに外部のgitレポジトリの参照を加えることで、(半自動的に)一緒にチェックアウトできるようになります。自分のレポジトリを肥大化せずに外部モジュールを取り込めるわけです。また、参照にはバージョンも含まれているのでバージョンを取り違えてビルドに失敗することもありません。何より外部モジュールの組み込み方をgitが標準化したという側面が大きいです。
当然ながら、取り込みたいモジュールがgitレポジトリとして公開されているのが前提条件になるのですが、MicrosoftもGitHubでプロジェクトを公開してくれるようになりました。ありがたいですね。
submoduleは以下が詳しいです。
→ Git のさまざまなツール - サブモジュール
→ https://github.com/yorung/dx11x
D3DXやDirectX SDKを使わないモダンなDirectX11で.xファイルを読み込んで表示するプログラムです。スキニングも含めてアニメーションもひととおり対応しています。
組み込み方
git bashからDirectXTKを組み込みたいプロジェクトのディレクトリに移動し、以下のように入力すればDirectXTKフォルダ以下にDirectXTKのプロジェクトファイルが生成され、DirectXTKを参照するコミットを生成できます。
$ git submodule init
$ git submodule add https://github.com/Microsoft/DirectXTK.git DirectXTK
$ git commit -m "DirectXTK added as a submodule"
submoduleの何が良いのか
自分のレポジトリに外部のgitレポジトリの参照を加えることで、(半自動的に)一緒にチェックアウトできるようになります。自分のレポジトリを肥大化せずに外部モジュールを取り込めるわけです。また、参照にはバージョンも含まれているのでバージョンを取り違えてビルドに失敗することもありません。何より外部モジュールの組み込み方をgitが標準化したという側面が大きいです。
当然ながら、取り込みたいモジュールがgitレポジトリとして公開されているのが前提条件になるのですが、MicrosoftもGitHubでプロジェクトを公開してくれるようになりました。ありがたいですね。
submoduleは以下が詳しいです。
→ Git のさまざまなツール - サブモジュール
レポジトリについて
D3DXやDirectX SDKを使わないモダンなDirectX11で.xファイルを読み込んで表示するプログラムです。スキニングも含めてアニメーションもひととおり対応しています。
Subscribe to:
Posts (Atom)