Learning OpenGLES 2.0 is easier on Android than on iOS because we can directly focus on OpenGLES implementation rather than wasting time on making the EGL bingings working properly. EGL stuffs are taken care of by android.opengl.GLSurfaceView.

OpenGL ES2.0 API is provided by ‘android.opengl.GLES20’ package.

The naming convention sticks to the C version. Functions are implemented as static in GLES20 package. So they can be called like GLES20.function_name(). For example, the mappings are as follows from C to the Android Java version:

glClearColor(0.5f, 0.5f, 0.5f, 1.0f) -->> GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) -->> GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT)

For debugging we can can use ‘android.util.Log’ package. Example, Log.d(“TAG name like Program name”, “Surface Created”). These debugging logs can be observed in LogCat window. There are also other functions in Log like Log.e(), Log.i() etc. For making our lives easier there is also a Matrix class - android.opengl.Matrix. Remember these are Column Major Order Matrices. Example,

Matrix.setIdentityM(mModelMatrix, 0);
Matrix.translateM(mModelMatrix, 0, 0, 0, -3f);
Matrix.rotateM(mModelMatrix, 0, angleInDegrees, 0, 1, 0);
Matrix.translateM(mModelMatrix, 0, 0, 0, 1.5f);

We can multiply two matrices by Matrix.multiplyMM(). We can multiply a matrix by a vector using Matrix.multiplyMV(). Other useful functions: Setting up View Matrix:

Matrix.setLookAtM(mViewMatrix, 0, eyeX, eyeY, eyeZ, lookX, lookY, lookZ, upX, upY, upZ)

Setting up Perspective Projection Matrix:

Matrix.frustumM(mProjectionMatrix, 0, left, right, bottom, top, near, far)

The object data is stored in Buffer objects like FloatBuffer. For example,

Float[] positions = {...............}; // Has x,y,z positions of all vertices
FloatBuffer mPositionBuffer; // from java.nio.FloatBuffer
mPositionBuffer = ByteBuffer.allocateDirect(mBytesPerFloat * positions.length).order(ByteOrder.nativeOrder()).asFloatBuffer();
mPositionBuffer.put(objData.positions).position(0);

Now the template for the renderer class (the class which implements GLSurfaceView.Renderer):

Constructor()
{
    Gather object's data
}

OnSurfaceCreated()
{
    Create shaders and programs
    Set View Matrix.
    Other initializations.
    Call glClearColor()
}

OnSurfaceChanged(unusedArg, width, height)
{
    Call glViewport()
    Set Projection Matrix (since the width and height is available over here)
}

OnDrawFrame()
{
    Call glClear()
    draw calls go over here
}

Using textures is also easier as Android provides many helper classes. A template for generating textures (returns texture handle):


private int createTexture(Context ctx, int imgResId) // imgResId = R.drawable.filename</span></pre>
{
    int[] tempHandle = new int[1];
    Bitmap img = null;
    img = BitmapFactory.decodeResource(ctx.getResources(), imgResId);

    GLES20.glGenTextures(.....);
    GLES20.glTexParameteri(......);
    GLES20.glTexParameteri(......); //as many GLES20.glTexParameteri()as u need

    GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, img, 0);

    img.recycle();
    return tempHandle[0];
}