Android Java で OpenGL ES 2.0 を使う

Android の OpenGL ES 2.0 対応は OS 2.0 Eclair からです。
まず NDK で使えるようになり、2.2 Froyo (API Level 8) では Java からも
呼び出せるようになっています。
実際に使ってみました。

2.0 への切り替えは GLSurfaceView の setEGLContextClientVersion( 2 ) です。

public class MarkerView extends GLSurfaceView {
    public MarkerView( Context context ) {
        super( context );
        setEGLContextClientVersion( 2 );    // GLES 2.0
        setRenderer( new MarkerRenderer( context ) );
    }
}

GLSurfaceView.Renderer には GL10 の interface が引数で渡されますが使いません。
android.opengl.GLES20 の static メソッドをそのまま呼び出します。

public class MarkerRenderer implements GLSurfaceView.Renderer {

  ~

    public void onSurfaceChanged( GL10 ugl, int w, int h ) {
        GLES20.glViewport( 0, 0, w, h );
    }

    public void onDrawFrame( GL10 ugl ) {
        GLES20.glClearColor( 0.0f, 0.0f, 0.5f, 0.0f );
        GLES20.glClear( GLES20.GL_COLOR_BUFFER_BIT|GLES20.GL_DEPTH_BUFFER_BIT );

        GLES20.glEnable( GLES20.GL_CULL_FACE );
        GLES20.glFrontFace( GLES20.GL_CW );
        GLES20.glCullFace( GLES20.GL_BACK );

        ~
        GLES20.glBindBuffer( GLES20.GL_ELEMENT_ARRAY_BUFFER, ibuffer );
        GLES20.glDrawElements( GLES20.GL_TRIANGLES, 6, GLES20.GL_UNSIGNED_SHORT, 0 ); // ← できない
    }
}

試してみて気がついたのですが、Android 2.2 の Java からは
VertexBuffer/IndexBuffer (VBO) が使えないようです。

glVertexAttribPointer() や glDrawElements() の最後の引数に、
NULL やアドレスのオフセットを与えることができないからです。

Android 2.3 (API Level 9) では修正されており、足りない命令が追加
されていました。

↓また下のスライドに説明があります。

io2011-opengl-for-android

Android 2.2 の場合は、glVertexAttribPointer() / glDrawElements()
の 2命令を jni (NDK) を使って自分で作ればこの問題を回避できるそうです。

Android Java で OpenGL ES 2.0 を使う” に1件のフィードバックがあります

  1. chototsu

    あ・・・そういう方法があったのですね。私は2.2の時はVertex Array を使うようにしていました。
    ただ、Tegra2ではVBOもVAもほとんど速度差が無いようです。他のチップでは差があるのでしょうか。

コメントは停止中です。