Displaying Graphical Elements with OpenGL ES
In this example we shall show you how to display graphical elements with OpenGL ES on Android.
First off, 3D graphics happens in the Cartesian Coordinate System. That means that the coordinate system used has three dimensions. X, Y and Z. Traditionally X goes from left to right, Y from bottom to top, and Z from me into the screen so to speak.
We shall draw a triangle with OpenGL in this example. A triangle is defined by 3 vertices. The coordinates of the vertices is not measured in pixels. We will use float to represent the values and they will be relative to each other.
To display graphical elements with OpenGL ES, in this example a triangle, perform the following steps:
- Create a class named GlRenderer that implements Android GLSurfaceView Renderer
- Implement the onDrawFrame, onSurfaceChanged, onSurfaceCreated methods
- Create the graphical element, class named Triangle
- Create a draw method for the triangle with the GL context
- Create an Android activity (here named Run)
- Use the Android GLSurfaceView to draw the various objects on it
These are demonstrated in the code snippet(s) that follow.
package net.obviam.opengl;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.opengl.GLU;
import android.opengl.GLSurfaceView.Renderer;
public class GlRenderer implements Renderer {
private Triangle triangle; // the triangle to be drawn
/** Constructor to set the handed over context */
public GlRenderer() {
this.triangle = new Triangle();
}
@Override
public void onDrawFrame(GL10 gl) {
// clear Screen and Depth Buffer
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
// Reset the Modelview Matrix
gl.glLoadIdentity();
// Drawing
gl.glTranslatef(0.0f, 0.0f, -5.0f); // move 5 units INTO the screen
// is the same as moving the camera 5 units away
// gl.glScalef(0.5f, 0.5f, 0.5f); // scale the triangle to 50%
// otherwise it will be too large
triangle.draw(gl); // Draw the triangle
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
if(height == 0) { //Prevent A Divide By Zero By
height = 1; //Making Height Equal One
}
gl.glViewport(0, 0, width, height); //Reset The Current Viewport
gl.glMatrixMode(GL10.GL_PROJECTION); //Select The Projection Matrix
gl.glLoadIdentity(); //Reset The Projection Matrix
//Calculate The Aspect Ratio Of The Window
GLU.gluPerspective(gl, 45.0f, (float)width / (float)height, 0.1f, 100.0f);
gl.glMatrixMode(GL10.GL_MODELVIEW); //Select The Modelview Matrix
gl.glLoadIdentity(); //Reset The Modelview Matrix
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
}
}package net.obviam.opengl;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.opengles.GL10;
public class Triangle {
private FloatBuffer vertexBuffer; // buffer holding the vertices
private float vertices[] = {
-0.5f, -0.5f, 0.0f, // V1 - first vertex (x,y,z)
0.5f, -0.5f, 0.0f, // V2 - second vertex
0.0f, 0.5f, 0.0f // V3 - third vertex
};
public Triangle() {
// a float has 4 bytes so we allocate for each coordinate 4 bytes
ByteBuffer vertexByteBuffer = ByteBuffer.allocateDirect(vertices.length * 4);
vertexByteBuffer.order(ByteOrder.nativeOrder());
// allocates the memory from the byte buffer
vertexBuffer = vertexByteBuffer.asFloatBuffer();
// fill the vertexBuffer with the vertices
vertexBuffer.put(vertices);
// set the cursor position to the beginning of the buffer
vertexBuffer.position(0);
}
/** The draw method for the triangle with the GL context */
public void draw(GL10 gl) {
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
// set the colour for the background
// gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
// to show the color (paint the screen) we need to clear the color buffer
// gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
// set the colour for the triangle
gl.glColor4f(0.0f, 1.0f, 0.0f, 0.5f);
// Point to our vertex buffer
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
// Draw the vertices as triangle strip
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length / 3);
//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
}
}package net.obviam.opengl;
import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;
public class Run extends Activity {
/** The OpenGL view */
private GLSurfaceView glSurfaceView;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// requesting to turn the title OFF
requestWindowFeature(Window.FEATURE_NO_TITLE);
// making it full screen
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
// Initiate the Open GL view and
// create an instance with this activity
glSurfaceView = new GLSurfaceView(this);
// set our renderer to be the main renderer with
// the current activity context
glSurfaceView.setRenderer(new GlRenderer());
setContentView(glSurfaceView);
}
/**
* Remember to resume the glSurface
*/
@Override
protected void onResume() {
super.onResume();
glSurfaceView.onResume();
}
/**
* Also pause the glSurface
*/
@Override
protected void onPause() {
super.onPause();
glSurfaceView.onPause();
}
}
This was an example of how to display Graphical Elements with OpenGL ES on Android.
Related Article:
Reference: OpenGL ES Android – Displaying Graphical Elements (Primitives) from our JCG partner Tamas Jano at the “Against The Grain” blog.

