TriangleRenderer.java revision 9bd30f05e890b213e97b838e04024d8cd232dbc0
1package com.android.gldual; 2 3import java.nio.ByteBuffer; 4import java.nio.ByteOrder; 5import java.nio.FloatBuffer; 6import java.nio.ShortBuffer; 7 8import javax.microedition.khronos.egl.EGLConfig; 9import javax.microedition.khronos.opengles.GL10; 10 11import android.opengl.GLSurfaceView; 12import android.opengl.GLU; 13import android.os.SystemClock; 14 15public class TriangleRenderer implements GLSurfaceView.Renderer{ 16 17 public TriangleRenderer() { 18 mTriangle = new Triangle(); 19 } 20 21 public void onSurfaceCreated(GL10 gl, EGLConfig config) { 22 /* 23 * By default, OpenGL enables features that improve quality 24 * but reduce performance. One might want to tweak that 25 * especially on software renderer. 26 */ 27 gl.glDisable(GL10.GL_DITHER); 28 29 /* 30 * Some one-time OpenGL initialization can be made here 31 * probably based on features of this particular context 32 */ 33 gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, 34 GL10.GL_FASTEST); 35 36 gl.glClearColor(.5f, .5f, .5f, 1); 37 gl.glShadeModel(GL10.GL_SMOOTH); 38 } 39 40 public void onDrawFrame(GL10 gl) { 41 /* 42 * By default, OpenGL enables features that improve quality 43 * but reduce performance. One might want to tweak that 44 * especially on software renderer. 45 */ 46 gl.glDisable(GL10.GL_DITHER); 47 48 /* 49 * Usually, the first thing one might want to do is to clear 50 * the screen. The most efficient way of doing this is to use 51 * glClear(). 52 */ 53 54 gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); 55 56 /* 57 * Now we're ready to draw some 3D objects 58 */ 59 60 gl.glMatrixMode(GL10.GL_MODELVIEW); 61 gl.glLoadIdentity(); 62 63 GLU.gluLookAt(gl, 0, 0, -5, 0f, 0f, 0f, 0f, 1.0f, 0.0f); 64 65 gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); 66 67 long time = SystemClock.uptimeMillis() % 4000L; 68 float angle = 0.090f * ((int) time); 69 70 gl.glRotatef(angle, 0, 0, 1.0f); 71 72 mTriangle.draw(gl); 73 } 74 75 public void onSurfaceChanged(GL10 gl, int w, int h) { 76 gl.glViewport(0, 0, w, h); 77 78 /* 79 * Set our projection matrix. This doesn't have to be done 80 * each time we draw, but usually a new projection needs to 81 * be set when the viewport is resized. 82 */ 83 84 float ratio = (float) w / h; 85 gl.glMatrixMode(GL10.GL_PROJECTION); 86 gl.glLoadIdentity(); 87 gl.glFrustumf(-ratio, ratio, -1, 1, 3, 7); 88 89 } 90 91 private Triangle mTriangle; 92} 93 94class Triangle { 95 public Triangle() { 96 97 // Buffers to be passed to gl*Pointer() functions 98 // must be direct, i.e., they must be placed on the 99 // native heap where the garbage collector cannot 100 // move them. 101 // 102 // Buffers with multi-byte datatypes (e.g., short, int, float) 103 // must have their byte order set to native order 104 105 ByteBuffer vbb = ByteBuffer.allocateDirect(VERTS * 3 * 4); 106 vbb.order(ByteOrder.nativeOrder()); 107 mFVertexBuffer = vbb.asFloatBuffer(); 108 109 ByteBuffer tbb = ByteBuffer.allocateDirect(VERTS * 2 * 4); 110 tbb.order(ByteOrder.nativeOrder()); 111 112 ByteBuffer ibb = ByteBuffer.allocateDirect(VERTS * 2); 113 ibb.order(ByteOrder.nativeOrder()); 114 mIndexBuffer = ibb.asShortBuffer(); 115 116 // A unit-sided equalateral triangle centered on the origin. 117 float[] coords = { 118 // X, Y, Z 119 -0.5f, -0.25f, 0, 120 0.5f, -0.25f, 0, 121 0.0f, 0.559016994f, 0 122 }; 123 124 for (int i = 0; i < VERTS; i++) { 125 for(int j = 0; j < 3; j++) { 126 mFVertexBuffer.put(coords[i*3+j] * 2.0f); 127 } 128 } 129 130 for(int i = 0; i < VERTS; i++) { 131 mIndexBuffer.put((short) i); 132 } 133 134 mFVertexBuffer.position(0); 135 mIndexBuffer.position(0); 136 } 137 138 public void draw(GL10 gl) { 139 gl.glFrontFace(GL10.GL_CCW); 140 gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mFVertexBuffer); 141 gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, VERTS, 142 GL10.GL_UNSIGNED_SHORT, mIndexBuffer); 143 } 144 145 private final static int VERTS = 3; 146 147 private FloatBuffer mFVertexBuffer; 148 private ShortBuffer mIndexBuffer; 149} 150