package edu.union; import java.nio.FloatBuffer; import javax.microedition.khronos.opengles.GL10; import android.content.Context; import android.opengl.GLU; import android.view.KeyEvent; /** * Approximately corresponds to: http://www.zeuscmd.com/tutorials/opengles/25-Reflections.php * @author bburns * */ public class GLTutorialEleven extends GLTutorialBase { float y = 1.5f; float lightAmbient[] = new float[] { 0.2f, 0.3f, 0.6f, 1.0f }; float lightDiffuse[] = new float[] { 0.6f, 0.6f, 0.6f, 1.0f }; float[] lightPos = new float[] {0,0,3,1}; float matAmbient[] = new float[] { 0.6f, 0.6f, 0.6f, 1.0f }; float matDiffuse[] = new float[] { 0.6f, 0.6f, 0.6f, 1.0f }; float white[] = new float[] { 1f, 1f, 1f, 1.0f}; float trans[] = new float[] { 1f, 1f, 1f, 0.3f}; 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[] floorVertices = new float[] { -3.0f, 0.0f, 3.0f, 3.0f, 0.0f, 3.0f, -3.0f, 0.0f,-3.0f, 3.0f, 0.0f,-3.0f }; FloatBuffer cubeBuff; FloatBuffer floorBuff; public GLTutorialEleven(Context c) { super(c, 20); cubeBuff = makeFloatBuffer(box); floorBuff = makeFloatBuffer(floorVertices); } protected void init(GL10 gl) { gl.glEnable(GL10.GL_LIGHTING); gl.glEnable(GL10.GL_LIGHT0); gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_AMBIENT, matAmbient, 0); gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_DIFFUSE, matDiffuse, 0); gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_AMBIENT, lightAmbient, 0); gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_DIFFUSE, lightDiffuse, 0); gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_POSITION, lightPos, 0); gl.glEnable(GL10.GL_DEPTH_TEST); gl.glDepthFunc(GL10.GL_LEQUAL); gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f); gl.glClearDepthf(1.0f); gl.glEnable(GL10.GL_CULL_FACE); gl.glShadeModel(GL10.GL_SMOOTH); gl.glClearStencil(0); } float xrot = 0.0f; float yrot = 0.0f; public void onDrawFrame(GL10 gl) { gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT | GL10.GL_STENCIL_BUFFER_BIT); gl.glMatrixMode(GL10.GL_MODELVIEW); gl.glLoadIdentity(); GLU.gluLookAt(gl, 0, 3, 7, 0, 0, 0, 0, 1, 0); // Draw the floor into the stencil buffer. gl.glDisable(GL10.GL_DEPTH_TEST); gl.glColorMask(false, false, false, false); gl.glDepthMask(false); gl.glEnable(GL10.GL_STENCIL_TEST); gl.glStencilOp(GL10.GL_REPLACE, GL10.GL_REPLACE, GL10.GL_REPLACE); gl.glStencilFunc(GL10.GL_ALWAYS, 1, 0xffffffff); gl.glVertexPointer(3, GL10.GL_FLOAT, 0, floorBuff); gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_DIFFUSE, white, 0); gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_AMBIENT, white, 0); gl.glNormal3f(0,1,0); gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4); // Draw the reflection gl.glColorMask(true, true, true, true); gl.glDepthMask(true); gl.glEnable(GL10.GL_DEPTH_TEST); gl.glStencilFunc(GL10.GL_EQUAL, 1, 0xffffffff); gl.glStencilOp(GL10.GL_KEEP, GL10.GL_KEEP, GL10.GL_KEEP); gl.glPushMatrix(); gl.glScalef(1.0f, -1f, 1f); gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_POSITION, lightPos, 0); gl.glCullFace(GL10.GL_FRONT); setupCube(gl); gl.glPushMatrix(); gl.glTranslatef(0.0f,y,-1.0f); gl.glRotatef(xrot, 1, 0, 0); gl.glRotatef(yrot, 0, 1, 0); drawCube(gl); gl.glPopMatrix(); gl.glCullFace(GL10.GL_BACK); gl.glPopMatrix(); gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_POSITION, lightPos, 0); gl.glDisable(GL10.GL_STENCIL_TEST); // Draw the floor for real. gl.glEnable(GL10.GL_BLEND); gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA); gl.glVertexPointer(3, GL10.GL_FLOAT, 0, floorBuff); gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_DIFFUSE, trans, 0); gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_AMBIENT, trans, 0); gl.glNormal3f(0,1,0); gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4); gl.glDisable(GL10.GL_BLEND); setupCube(gl); gl.glPushMatrix(); gl.glTranslatef(0.0f,y,-1.0f); gl.glRotatef(xrot, 1, 0, 0); gl.glRotatef(yrot, 0, 1, 0); // Draw the non-reflected cube drawCube(gl); gl.glPopMatrix(); xrot+=1.0f; yrot+=0.5f; } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (event.getKeyCode() == KeyEvent.KEYCODE_DPAD_UP) { y+=0.1; invalidate(); } else if (event.getKeyCode() == KeyEvent.KEYCODE_DPAD_DOWN) { if (y > 0.5) y-=0.1; invalidate(); } return super.onKeyDown(keyCode, event); } }