#contents

*Androidエミュレータでの注意点 [#a8d2530d]
AndroidエミュレータでOpenGL ES2.0を動かす場合には、下記の一行が必要になる。

 setEGLConfigChooser(8 , 8, 8, 8, 16, 0);

入れないとクラッシュする。実機の場合は問題ない。

*トラブルシューティング [#w6d86766]
**GL全般 [#y0c16774]
***定数は厳密に [#wd30c1dc]
OpenGL ES 2.0 / OpenGL ES 3.0 の仕様では定数の自動型変換は行われません。よって、0 などでも、floatで利用するなら、0.0 とする。(C言語のような 0.0f はエラー)

***Fragment Shader で lowp を指定した場合に GPU によって演算精度の違いが大きい。 [#v49d6a95]
PowerVR/Tegra は 8bit、Mali-400 は 16bit、Adreno/Vivante は 32bitの精度。
[[参照元:http://dench.flatlib.jp/opengl/gpuspecs?&#precision]]

**OpenGL ES2.0 [#m4d0845d]

***Android 3.0 + Tegra2 [#ad5193f9]
Tegra ドライバのバグで、lowp, mediump, highp 等の記述位置によってエラー。

***PowerVR SGX540の古いドライバ [#wae58f57]
- GPU によって vecN( scalar ) がエラーになる。回避するには、例えば vec3 なら vec3( 0.0 ) ではなく vec3( 0.0, 0.0, 0.0 ) のように記述。
- Vertex Shader で「precision mediump float;」がエラーになる。
- Vertex Shader で precision による float のデフォルト宣言に highp 以外を宣言するとエラー。 デフォルトの宣言が問題なだけで、変数毎の個別の精度宣言は利用できる。

***シェーダーコード内のVersionは先頭に記述 [#u20eb721]
#version はシェーダーコードの 1行目になければなりません

***Adreno 205 で textureフェッチ完了前ではdiscard が使えない [#waf4e11a]
基本的には discardは使わないべき。texture 依存 discard は shader の一番最後なら固まらない。(すべての texture フェッチが終わったあと) varying 依存 discard は texture fetch の前に入れても固まらない。(単にコンパイル時の最適化で texture 命令のあとに配置されたためだと考えられる)

***Adreno 220 で分岐ジャンプが多いとエラー [#x825f093]
Fragment Shader でシェーダー内の分岐ジャンプが多数存在する場合に、コンパイルは通るもののリンクエラーになる。1つの関数では1つのreturnのみにすること。

***Tegra2/3/4 では Fragment Shader の 動的Uniform 配列が使えない [#b80227c3]
Uniform 配列に動的な index を与えることが出来ません。コンパイル時に求まる定数のみ。Tegra2/3/4 ではハードウエア的なバッファが用意されておらず、 Shader Program 内の命令フィールドの定数部分を直接書き換えるソフトウェア実装のため。Vertex Shaderでは問題なし。

***Tegra2/3/4 では Fragment Shader で動的なループがコンパイルエラー [#adc7d432]
その場合は巨大ループを設定しif文を使った動的条件で break させると良い。

***Adreno 320/Adreno 330 では、undefで参照エラー [#yda0e05c]
shader 内で #undef を使うとそのシンボルを再定義することができない。 再定義しても参照エラーが発生

***PowerVR SGX GLSLの関数パラメータ inout が無効 [#ke2e20ba]
inout を使って関数から値を返すことができない。 2つ以上 inout 宣言を行った場合に発生。

***glGetActiveUniformの名前がGPUで違う [#m7d69787]
変数名のあとに “[0]” が付く場合とつかない場合がある。

***Vivante GC860 ではUniform 配列の Location offset が使えない [#r04114ba]
宣言した配列 Uniform への設定 (glUniform4fv 等) で、 Location に offset を指定した部分書き込みができない。

***Adreno 200 / Z430 でフレームバッファを 8888 にすると落ちる [#e0137916]
対処方法としては、Adreno 200 や Z430 の場合はかならずフレームバッファに 565 を選択。

***Adreno 320 で GLSLの gl_FragCoord が 1 pixel ずれる [#s97a38fd]
FragmentShader の gl_FragCoord が、他の GPU と 1pixel ずれる。よってvarying を使って Vertex Shader から値を渡すと正しい結果となる。

**OpenGL ES 3.0 [#fc0ee89a]

***Android 4.3 + Adreno 320の組み合わせ [#wa846b66]
Android 4.3 + Adreno 320 の組み合わせは OpenGL ES 3.0 が利用可能ですが、 OpenGL ES 3.0 で、シェーダーの UniformBlock を使うと落ちる。UniformBlock を使用していない場合は OpenGL ES 3.0 でも問題ない。(Android 4.4では修正済、バージョンチェックで要対応)

**OpenGL [#u5f7c774]
***OpenGLでES Profileを使うときに、GL_ES が宣言されない [#x38503ce]
OpenGL 4.1 の OpenGL ES 2.0 Profile では、 シェーダーバージョン 1.0 を宣言しても GLSL の定数 “GL_ES” が定義され無いので、ESを利用する場合は自分で #define GL_ES を定義する。