package com.android.droidgraph.renderer; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.HashSet; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL; import javax.microedition.khronos.opengles.GL10; import android.content.Context; import android.graphics.Bitmap; import android.opengl.GLSurfaceView; import android.opengl.GLU; import android.util.Log; import android.view.MotionEvent; import com.android.droidgraph.lighting.LightStudio; import com.android.droidgraph.scene.SGAbstractShape; import com.android.droidgraph.scene.SGGroup; import com.android.droidgraph.scene.SGNode; import com.android.droidgraph.scene.SGView; import com.android.droidgraph.util.GLH; import com.android.droidgraph.util.PrintLogUtil; import com.android.droidgraph.util.SGColorI; import com.android.droidgraph.util.SGLog; import com.android.droidgraph.util.Settings; public class SGRenderer implements GLSurfaceView.Renderer { // for debug PrintLogUtil log = new PrintLogUtil(); private String TAG = "SGRenderer"; private float[] background = { 0f, 0f, 0f, 1f }; private int renderMode = GLSurfaceView.RENDERMODE_WHEN_DIRTY; private SGGroup sceneGroup; private float lx = 0f; private float ly = 0f; private LightStudio mLightStudio; private Settings mSettings; public SGRenderer(SGView view, Settings settings) { mSettings = settings; mSettings.setRenderer(this); mLightStudio = new LightStudio(mSettings); } @Override public void onSurfaceCreated(GL10 gl, EGLConfig eglc) { GLH.setGL(gl); mSettings.setGL(gl); //Settings gl.glDisable(GL10.GL_DITHER); //Disable dithering ( NEW ) gl.glEnable(GL10.GL_TEXTURE_2D); //Enable Texture Mapping gl.glShadeModel(GL10.GL_SMOOTH); //Enable Smooth Shading gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f); //Black Background gl.glClearDepthf(1.0f); //Depth Buffer Setup gl.glEnable(GL10.GL_DEPTH_TEST); //Enables Depth Testing gl.glDepthFunc(GL10.GL_LEQUAL); //The Type Of Depth Testing To Do //Perspective Calculations gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST); mLightStudio.load(gl); sceneGroup.load(gl); } @Override public void onSurfaceChanged(GL10 gl, int width, int height) { if (height == 0) { // Prevent A Divide By Zero By height = 1; // Making Height Equal One } gl.glViewport(0, 0, width, height); // Reset The Current Viewport gl.glMatrixMode(GL10.GL_PROJECTION); // Select The Projection Matrix gl.glLoadIdentity(); // Reset The Projection Matrix // Calculate The Aspect Ratio Of The Window GLU.gluPerspective(gl, 45.0f, (float) width / (float) height, 0.1f, 100.0f); gl.glMatrixMode(GL10.GL_MODELVIEW); // Select The Modelview Matrix gl.glLoadIdentity(); // Reset The Modelview Matrix mSettings.setScreenDimensions(width, height); } @Override public void onDrawFrame(GL10 gl) { checkGLError(gl); // Clear Screen And Depth Buffer gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); gl.glLoadIdentity(); // Reset The Current Modelview Matrix gl.glClearColor(background[0],background[1],background[2],background[3]); GLU.gluLookAt(gl, lx, ly, 5, 0f, 0f, 0f, 0f, 1.0f, 0.0f); mLightStudio.render(gl); // Draw the root of the scene sceneGroup.render(gl); // call any kill methods to end the drawing cycle mLightStudio.killRender(gl); if (mSettings.pick()) { pickReadPixels(gl, 1, 1); } } private void pickReadPixels(GL10 gl, int height, int width) { boolean screenshot = mSettings.pick(); float x = mSettings.getPickPoint()[0]; float y = mSettings.getPickPoint()[1]; if (screenshot) { int screenshotSize = 1; ByteBuffer bb = ByteBuffer.allocateDirect(screenshotSize * 4); bb.order(ByteOrder.nativeOrder()); gl.glReadPixels((int) x, mSettings.getScreenHeight() - (int) y, width, height, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, bb); int pixelsBuffer[] = new int[screenshotSize]; bb.asIntBuffer().get(pixelsBuffer); bb = null; Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565); bitmap.setPixels(pixelsBuffer, screenshotSize - width, -width, 0, 0, width, height); Log.d(TAG, "" + bitmap.getPixel(0, 0)); pixelsBuffer = null; mSettings.pick(false); } } public void setSceneGroup(SGNode group) { // SGGroup sggroup = (SGGroup) group; sceneGroup = (SGGroup) group; } public void setLookAtX(float x) { this.lx = x; } public void setLookAtY(float y) { this.ly = y; } public void setRenderMode(int mode) { if (mode == 0 || renderMode == 1) { renderMode = mode; } else { SGLog.error("render mode must be 0 - GLSurfaceView.RENDERMODE_CONTINUOUSLY, or 1 - GLSurfaceView.RENDERMODE_WHEN_DIRTY"); } } public void setContext(Context context) { mSettings.setContext(context); } public LightStudio getLightStudio() { return mLightStudio; } public void processSelection(MotionEvent e, SGColorI inputColor) { HashSet<SGAbstractShape> gNodeIDMap = mSettings.getNodeIDMap(); for(SGAbstractShape node : gNodeIDMap) { if(inputColor.equals(node.getColorID())){ node.setSelected(true); } } } static void checkGLError(GL gl) { int error = ((GL10) gl).glGetError(); if (error != GL10.GL_NO_ERROR) { throw new RuntimeException("GLError 0x" + Integer.toHexString(error)); } } }