CS185c
Chris Pollett
Nov. 4, 2009
package org.pollett; import javax.microedition.khronos.egl.EGL10; import javax.microedition.khronos.egl.EGL11; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.egl.EGLContext; import javax.microedition.khronos.egl.EGLDisplay; import javax.microedition.khronos.egl.EGLSurface; import javax.microedition.khronos.opengles.GL10; import android.app.Activity; import android.content.Context; import android.os.Bundle; import android.view.SurfaceHolder; import android.view.SurfaceView; public class OpenGLTest extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(new GLView(this)); } }
class GLView extends SurfaceView implements SurfaceHolder.Callback { GLView(Context context) { super(context); getHolder().addCallback(this); // we will be called if surface // created or destroyed // set up hardware acceleration if possible getHolder().setType(SurfaceHolder.SURFACE_TYPE_GPU); } public void surfaceCreated(SurfaceHolder holder) { } public void surfaceDestroyed(SurfaceHolder holder) { } public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { // should implement to handle window resizing }
private GLThread glThread; public void surfaceCreated(SurfaceHolder holder) { glThread = new GLThread(this); glThread.start(); } public void surfaceDestroyed(SurfaceHolder holder) { glThread.requestExitAndWait(); glThread = null; }
class GLThread extends Thread { private final GLView view; private boolean done = false; GLThread(GLView view) { this.view = view; } @Override public void run() { while(!done) { //draw a frame } } public void requestExitAndWait() { //called when surface is destroyed //Tell the thread to quit done = true; try { join(); } catch(InterruptedException ex) { } } }
@Override public void run() { // Init OpenGL EGL10 egl = (EGL10)EGLContext.getEGL(); // create and initialize a display handle EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); int[] version = new int[2]; egl.eglInitialize(display, version); //set up that we want 16 bits of color and how they are split into rgb EGLConfig[] configs = new EGLConfig[1]; int[] configSpec = { EGL10.EGL_RED_SIZE, 5, EGL10.EGL_GREEN_SIZE, 6, EGL10.EGL_BLUE_SIZE, 5, EGL10.EGL_DEPTH_SIZE, 16, EGL10.EGL_NONE}; int[] numConfig = new int[1]; egl.eglChooseConfig(display, configSpec, configs, 1, numConfig); EGLConfig config = configs[0]; //using the config stuff we create a context and a surface EGLContext glc = egl.eglCreateContext(display, config, EGL10.EGL_NO_CONTEXT, null); EGLSurface surface = egl.eglCreateWindowSurface(display, config, view.getHolder(), null); egl.eglMakeCurrent(display, surface, surface, glc); //create an interface into openGL GL10 gl = (GL10)(glc.getGL()); init(gl); //will describe in a bit //loop until asked to quit while(!done) { //draw a frame (describe in a minute) drawFrame(gl); egl.eglSwapBuffers(display, surface); //Error Handling if(egl.eglGetError() == EGL11.EGL_CONTEXT_LOST) { Context c = view.getContext(); if(c instanceof Activity) { ((Activity) c).finish(); } } } //Free OpenGL resources egl.eglMakeCurrent(display, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT); egl.eglDestroySurface(display, surface); egl.eglDestroyContext(display, glc); egl.eglTerminate(display); }
private void init(GL10 gl) { //define the view frustrum gl.glViewport(0, 0, view.getWidth(), view.getHeight()); gl.glMatrixMode(GL10.GL_PROJECTION); gl.glLoadIdentity(); float ratio = (float) view.getWidth() / view.getHeight(); //set viewing angle of view frustrum. ratio of its width to // height, near and far clipping planes GLU.gluPerspective(gl, 45.0f, ratio, 1, 100); //pixels farther than those already drawn ignored gl.glEnable(GL10.GL_DEPTH_TEST); gl.glDepthFunc(GL10.GL_LEQUAL); gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); }
private void drawFrame(GL10 gl) { //clear screen to black gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); //Position model so can see gl.glMatrixMode(GL10.GL_MODELVIEW); gl.glLoadIdentity(); gl.glTranslatef(0, 0, -3.0f); }
class GLCube { private final IntBuffer mVertexBuffer; GLCube() { int one = 65536; int half = one/2; int vertices[] = { //Front -half, -half, half, half, -half, half, -half, half, half, half, half, half, //Back -half, -half, -half, -half, half, -half, half, -half, -half, half, half, -half, //Left -half, -half, half, -half, half, half, -half, -half, -half, -half, half, -half, //Right half, -half, -half, half, half, -half, half, -half, half, half, half, half, //Top -half, half, half, half, half, half, -half, half, -half, half, half, -half, //Bottom -half, -half, half, -half, -half, -half, half, -half, half, half, -half, -half }; ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4); vbb.order(ByteOrder.nativeOrder()); mVertexBuffer = vbb.asIntBuffer(); mVertexBuffer.put(vertices); mVertexBuffer.position(0); } void draw(GL10 gl) { gl.glVertexPointer(3, GL10.GL_FIXED, 0, mVertexBuffer); gl.glColor4f(1, 1, 1, 1); gl.glNormal3f(0, 0, 1); gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4); gl.glNormal3f(0, 0, -1); gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 4, 4); gl.glColor4f(1, 1, 1, 1); gl.glNormal3f(-1, 0, 0); gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 8, 4); gl.glNormal3f(1, 0, 0); gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 12, 4); gl.glColor4f(1, 1, 1, 1); gl.glNormal3f(0, 1, 0); gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 16, 4); gl.glNormal3f(0, -1, 0); gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 20, 4); } }
private final GLCube cube = new GLCube();to our GLThreadclass.
private void drawFrame(GL10 gl)
{
//clear screen to black
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
//Position model so can see
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
gl.glTranslatef(0, 0, -3.0f);
cube.draw(gl);
}