WebRTCのAndroid側のSDKは、現状OpenGL ES2.0前提になっている。
ES3.0は、Android4.3以降からのようなので、OSの普及率考えるとまあ妥当かもしれない。普通に動画を表示している分にはそんな害があるわけでもないし。
ではどんな時に困るかというと、VR連動などをしたいとき。
gvr-unity-sdkなどはES3.0前提になっている。Unityのビルド設定をES30にしなくてはならない。
WebRTCでリモートから取得したビデオフレームをUnity上のTextureに流し込みたい場合、Unity上の描画スレッドとWebRTCの描画スレッド間で、同じバージョンのEGL Contextを共有しなければならない。
そのためWebRTCのAndroid SDKのコードを以下のようにOpenGL ES3.0に対応させていく必要がある。
- eglCreateContextのバージョン変更
EglBase14.javaの中で以下のように2がハードコードされているのが分かる
int[] contextAttributes = {EGL14.EGL_CONTEXT_CLIENT_VERSION, 2, EGL14.EGL_NONE};
これを3に変えておく。
int[] contextAttributes = {EGL14.EGL_CONTEXT_CLIENT_VERSION, 3, EGL14.EGL_NONE};
EglBase10.javaにも同様の箇所があるので必要なら変えておく。ES3.0前提なのでEglBase14だけ対応しておけば十分かもしれない。
2. CONFIG配列の設定値の変更
EglBase.javaには
private static final int EGL_OPENGL_ES2_BIT = 4;
というように冒頭でES2用のビット値が与えられていて、この値を片っ端から各コンフィグに設定している。
例えばCONFIG_PLAINは以下のようになっている。
public static final int[] CONFIG_PLAIN = {
EGL10.EGL_RED_SIZE, 8,
EGL10.EGL_GREEN_SIZE, 8,
EGL10.EGL_BLUE_SIZE, 8,
EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, // ES2のビット値が設定されてる
EGL10.EGL_NONE
};
ES3のビット値は64 (0x0040) だ。なので以下のようにES3用の値を準備しておく。
private static final int EGL_OPENGL_ES2_BIT = 4;
private static final int EGL_OPENGL_ES3_BIT = 64;
これを使って、このファイル内の全てのコンフィグ設定を置き換えていく
public static final int[] CONFIG_PLAIN = {
EGL10.EGL_RED_SIZE, 8,
EGL10.EGL_GREEN_SIZE, 8,
EGL10.EGL_BLUE_SIZE, 8,
EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT, // ES3に変更
EGL10.EGL_NONE
};
3. Shaderのversion指定
OpenGL ESのバージョンを3.0にしてしまったので、デフォルトのshaderバージョンが変わってしまい、今まで使われていたshaderがそのままで使えない。とりあえず一番簡単な応急処置は#versionプリプロセッサで100を指定することだ。
例えばGlRectDrawer.javaでは、以下のように色々なshaderが定義されている。
private static final String VERTEX_SHADER_STRING =
"varying vec2 interp_tc;\n"
+ "attribute vec4 in_pos;\n"
+ "attribute vec4 in_tc;\n"
+ "\n"
+ "uniform mat4 texMatrix;\n"
+ "\n"
+ "void main() {\n"
+ " gl_Position = in_pos;\n"
+ " interp_tc = (texMatrix * in_tc).xy;\n"
+ "}\n";
これらの全ての先頭に、以下のようにversion指定をつけていけばよい
private static final String VERTEX_SHADER_STRING =
"#version 100\n"
+ "varying vec2 interp_tc;\n"
+ "attribute vec4 in_pos;\n"
+ "attribute vec4 in_tc;\n"
+ "\n"
+ "uniform mat4 texMatrix;\n"
+ "\n"
+ "void main() {\n"
+ " gl_Position = in_pos;\n"
+ " interp_tc = (texMatrix * in_tc).xy;\n"
+ "}\n";
4. GLES20 -> GLES30 (Optional)
以下のようにGLES20クラスが使われているところがたくさんある
GLES20.glShaderSource(shader, source);
GLES20.glCompileShader(shader);
これを全てGLES30に置き換えていく
GLES30.glShaderSource(shader, source);
GLES30.glCompileShader(shader);
が、実はbackward compatibilityがあるとのことなので、置き換えなくても大丈夫だと言われている。自分は書き換えてしまっているが。
Pokemon Goのおかげで、Android4.3より前のサポートを外しやすい世界になってきていることもあり、自分の用途ではもうES3.0前提でもいいかな、と考えているので、これらの書き換えを行って使っていく所存。