package edu.union; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; import java.nio.IntBuffer; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.opengl.GLU; import android.opengl.GLSurfaceView; import android.view.KeyEvent; import android.view.MotionEvent; public abstract class GLTutorialBase extends GLSurfaceView implements GLSurfaceView.Renderer { protected Context context; int width; int height; int fps; float box[] = new float[] { // FRONT 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, // BACK -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, // LEFT -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, // RIGHT 0.5f, -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, // TOP -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, // BOTTOM -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, }; float texCoords[] = new float[] { // FRONT 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, // BACK 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, // LEFT 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, // RIGHT 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, // TOP 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, // BOTTOM 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f }; FloatBuffer cubeBuff; FloatBuffer texBuff; /** * Make a direct NIO FloatBuffer from an array of floats * @param arr The array * @return The newly created FloatBuffer */ protected static FloatBuffer makeFloatBuffer(float[] arr) { ByteBuffer bb = ByteBuffer.allocateDirect(arr.length*4); bb.order(ByteOrder.nativeOrder()); FloatBuffer fb = bb.asFloatBuffer(); makeFloatBuffer(fb, arr); return fb; } protected static void makeFloatBuffer(FloatBuffer fb, float[] arr) { fb.put(arr); fb.position(0); } /** * Make a direct NIO IntBuffer from an array of ints * @param arr The array * @return The newly created IntBuffer */ protected static IntBuffer makeFloatBuffer(int[] arr) { ByteBuffer bb = ByteBuffer.allocateDirect(arr.length*4); bb.order(ByteOrder.nativeOrder()); IntBuffer ib = bb.asIntBuffer(); ib.put(arr); ib.position(0); return ib; } protected static ByteBuffer makeByteBuffer(Bitmap bmp) { ByteBuffer bb = ByteBuffer.allocateDirect(bmp.getHeight()*bmp.getWidth()*4); bb.order(ByteOrder.BIG_ENDIAN); IntBuffer ib = bb.asIntBuffer(); for (int y = 0; y < bmp.getHeight(); y++) for (int x=0;x<bmp.getWidth();x++) { int pix = bmp.getPixel(x, bmp.getHeight()-y-1); // Convert ARGB -> RGBA byte alpha = (byte)((pix >> 24)&0xFF); byte red = (byte)((pix >> 16)&0xFF); byte green = (byte)((pix >> 8)&0xFF); byte blue = (byte)((pix)&0xFF); ib.put(((red&0xFF) << 24) | ((green&0xFF) << 16) | ((blue&0xFF) << 8) | ((alpha&0xFF))); } ib.position(0); bb.position(0); return bb; } protected int loadTexture(GL10 gl, int resource) { return loadTexture(gl, BitmapFactory.decodeResource(context.getResources(), resource)); } /** * Create a texture and send it to the graphics system * @param gl The GL object * @param bmp The bitmap of the texture * @param reverseRGB Should the RGB values be reversed? (necessary workaround for loading .pngs...) * @return The newly created identifier for the texture. */ protected static int loadTexture(GL10 gl, Bitmap bmp) { int[] tmp_tex = new int[1]; gl.glGenTextures(1, tmp_tex, 0); int tex = tmp_tex[0]; loadTexture(tex, GL10.GL_TEXTURE_2D, bmp, gl); return tex; } public void loadTexture(int texture, int type, int resource, GL10 gl) { loadTexture(texture, type, BitmapFactory.decodeResource(context.getResources(), resource), gl); } static public void loadTexture(int texture, int type, Bitmap bmp, GL10 gl) { loadTexture(texture, type, bmp.getWidth(), bmp.getHeight(), makeByteBuffer(bmp), gl); } static public void loadTexture(int texture, int type, int width, int height, ByteBuffer bb, GL10 gl) { gl.glBindTexture(type, texture); gl.glTexImage2D(type, 0, GL10.GL_RGBA, width, height, 0, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, null); gl.glTexSubImage2D(type, 0, 0, 0, width, height, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, bb); gl.glTexParameterf(type, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR); gl.glTexParameterf(type, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR); } /** * Constructor */ public GLTutorialBase(Context context) { this(context, -1); } /** * Constructor for animated views * @param c The View's context * @param fps The frames per second for the animation. */ public GLTutorialBase(Context context, int fps) { super(context); this.context = context; this.fps = fps; cubeBuff = makeFloatBuffer(box); texBuff = makeFloatBuffer(texCoords); } public void setupCube(GL10 gl) { gl.glVertexPointer(3, GL10.GL_FLOAT, 0, cubeBuff); gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, texBuff); gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); } public void drawCube(GL10 gl) { gl.glColor4f(1.0f, 1, 1, 1.0f); 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.0f, 1, 1.0f); 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.0f, 1.0f); 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); } public void onSurfaceCreated(GL10 gl, EGLConfig config) { } public void onSurfaceChanged(GL10 gl, int w, int h) { this.width = w; this.height = h; gl.glMatrixMode(GL10.GL_PROJECTION); gl.glLoadIdentity(); gl.glViewport(0,0,w,h); GLU.gluPerspective(gl, 45.0f, ((float)w)/h, 1f, 100f); init(gl); } protected void init(GL10 gl) {} }