Messing with OpenGL ES (in Android)

The emulator vs the physical machines


  • gl.glLineWidth is ignored in the HTC Magic (all lines have width = 1.0), whereas it is honoured on the emulator
  • it also seems like the emulator performs some sort of polygon clipping instead of culling triangles when at least one of the vertexes is out of the frustrum -- so you get different output in some cases

Drawing text with OpenGL ES' glDrawTexfOES vs the classic OpenGL orthogonal view methods

There's no need for setting an orthogonal view when using glDrawTexfOES for drawing text into the screen, since it seems to be ignoring any existing view or projection matrix and simply drawing into the screen buffer (and that's probably why it is so fast!).

So no more structures like this:


gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glPushMatrix();
gl.glLoadIdentity();
gl.glViewport(0, 0, canvasWidth, canvasHeight);
gl.glOrthof(-halfCanvasWidth, halfCanvasWidth, -halfCanvasHeight, halfCanvasHeight, 1.0f, 200.0f);

// draw text here

gl.glPopMatrix();

It will get reduced to just...


// draw text here

Interestingly though, if you're using fog you'll need to turn it off or you may not see the text. So we'll end up with this:


gl.glDisable(GL10.GL_FOG);
// draw text here

Modifying the buffers after they have been created

In classic OpenGL immediate mode we use glBegin/glEnd liberally. But we can't keep on going on like that with OpenGL ES: we are forced to convert our glBegin/glEnd calls to the glDrawArrays or glDrawElements style.

I believed that this would derive in only being able to show [boring] static geometry, but I have been messing with buffers and found out that you can for example modify the vertex buffers once they have been allocated and the data put into them. So you can not only do this:


ByteBuffer bb;

bb = ByteBuffer.allocateDirect(vertices.length * 4); // 4 bytes per value
bb.order(ByteOrder.nativeOrder());
mVerticesBuffer = bb.asFloatBuffer();
mVerticesBuffer.put(vertices);
mVerticesBuffer.position(0);

but you could even do this afterwards:


for(int i = 0; i < mVerticesBuffer.limit(); i++)
{
    mVerticesBuffer.put(i, (float)(Math.random() - Math.random()));
}

Or in other words: buffer[index] = value is buffer.put(index, value) in buffer terms.

I haven't tried adding more elements (the above example doesn't add more, just replaces the current vertex values with randomized ones). The performance doesn't seem to plummet (FPS counter shows a decent 57-60 fps) when changing all 24 vertices in my test mesh, in every frame. But I haven't tried with larger models. And I'm not sure about the possible concurrency issues that might arise either. So it's up to you if you want to use this -- it feels a bit hackish to me :D