OpenGL ES For Android Graphics Programming
OpenGL ES For Android Graphics Programming
Android offers support for 2D and 3D graphics with the OpenGL ES API. OpenGL ES is just a variation of OpenGL specifically designed for embedded systems. Since Android 1.0, the OpenGL ES 1.0 and 1.1 APIs have been included. The support for OpenGL ES 2.0 started from Android 2.2. This tutorial presents the basics for working on OpenGL ES software in Android by working through a few examples.
height) GLSurfaceView is a view class which you use to draw the graphics objects. You will also need it to capture user interaction events. Now you can instantiate this view class and call setRenderer with the renderer implementation you must provide.
setContentView(mView); } public boolean onTouchEvent(MotionEvent event) { return mRenderer.onTouchEvent(event); } } We will implement a Renderer interface with our own MyRenderer below. Because onSurfaceCreated, onSurfaceChanged and onTouchEvent will pretty much remain the same in other implementations, they will not be relisted later. This example basically has a list of five vertices representing a pyramid with vertex indices of 0, 1, 2, 3 at the base and 4 at the top.In setAllBuffers, each vertex component is a float value. Since a float value equals 4 bytes, byte buffer length needs to be multiplied by 4. Similarly, the border index is a short value and thus byte buffer length needs to be multiplied by 2. Border color is set to solid green. The main code to render all the lines is: gl.glDrawElements(GL10.GL_LINES, mNumOfTriangleBorderIndices, GL10.GL_UNSIGNED_SHORT, mTriangleBorderIndicesBuffer); Figure 1 shows the result, a wireframe pyramid. class MyRenderer implements Renderer { private Context mContext; private FloatBuffer mVertexBuffer = null; private ShortBuffer mTriangleBorderIndicesBuffer = null; private int mNumOfTriangleBorderIndices = 0; public float mAngleX = 0.0f; public float mAngleY = 0.0f; public float mAngleZ = 0.0f; private float mPreviousX; private float mPreviousY; private final float TOUCH_SCALE_FACTOR = 0.6f; public MyRenderer(Context context) { mContext = context; } public void onDrawFrame(GL10 gl) { gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glMatrixMode(GL10.GL_MODELVIEW); gl.glLoadIdentity(); gl.glTranslatef(0.0f, gl.glRotatef(mAngleX, gl.glRotatef(mAngleY, gl.glRotatef(mAngleZ, 0.0f, 1, 0, 0, 1, 0, 0, -3.0f); 0); 0); 1);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mVertexBuffer); // Set line color to green 1.0f, 0.0f, 1.0f); gl.glColor4f(0.0f,
// Draw all lines gl.glDrawElements(GL10.GL_LINES, mNumOfTriangleBorderIndices, GL10.GL_UNSIGNED_SHORT, mTriangleBorderIndicesBuffer); } public void onSurfaceCreated(GL10 gl, EGLConfig config) { gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST); gl.glEnable(GL10.GL_DEPTH_TEST); gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); // Get all the buffers ready setAllBuffers(); } public void onSurfaceChanged(GL10 gl, int width, int height) { gl.glViewport(0, 0, width, height); float aspect = (float)width / height; gl.glMatrixMode(GL10.GL_PROJECTION); gl.glLoadIdentity(); gl.glFrustumf(-aspect, aspect, -1.0f, 1.0f, 1.0f, 10.0f); } private void setAllBuffers(){ // Set vertex buffer float vertexlist[] = { -1.0f, 0.0f, -1.0f, 1.0f, 0.0f, -1.0f,
-1.0f,
0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 2.0f, 0.0f, }; ByteBuffer vbb = ByteBuffer.allocateDirect(vertexlist.length * 4); vbb.order(ByteOrder.nativeOrder()); mVertexBuffer = vbb.asFloatBuffer(); mVertexBuffer.put(vertexlist); mVertexBuffer.position(0); // Set triangle border buffer with vertex indices short trigborderindexlist[] = { 4, 0, 4, 1, 4, 2, 4, 3, 0, 1, 1, 3, 3, 2, 2, 0, 0, 3 }; mNumOfTriangleBorderIndices = trigborderindexlist.length; ByteBuffer tbibb = ByteBuffer.allocateDirect(trigborderindexlist.length * 2); tbibb.order(ByteOrder.nativeOrder()); mTriangleBorderIndicesBuffer = tbibb.asShortBuffer(); mTriangleBorderIndicesBuffer.put(trigborderindexlist); mTriangleBorderIndicesBuffer.position(0); } public boolean onTouchEvent(MotionEvent e) { float x = e.getX(); float y = e.getY(); switch (e.getAction()) { case MotionEvent.ACTION_MOVE: float dx = x - mPreviousX; float dy = y - mPreviousY; mAngleY = (mAngleY + (int)(dx * TOUCH_SCALE_FACTOR) + 360) % 360; mAngleX = (mAngleX + (int)(dy * TOUCH_SCALE_FACTOR) + 360) % 360; break; } mPreviousX = x; mPreviousY = y; return true; } }