package de.tudarmstadt.informatik.hostage.ui2.fragment.opengl; import java.io.IOException; import java.io.InputStream; import java.util.Scanner; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; import android.content.res.AssetManager; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.opengl.GLES20; import android.opengl.GLSurfaceView.Renderer; import android.opengl.GLUtils; import android.opengl.Matrix; import android.util.Log; public class ThreatIndicatorGLRenderer implements Renderer { private static int threatLevel = 0; public static void setThreatLevel(int level) { threatLevel = level; } public static AssetManager assets; private int width; private int height; private float aspectRatio; private int program; private float [] modelview; private float [] projection; private float [] mvp; private AnimatedMesh androidMesh = null; private AnimatedMesh beeMesh = null; private int androidTexture; private int beeTexture; public ThreatIndicatorGLRenderer() {} public int loadTexture(String filePath) { Bitmap bitmap = null; try { bitmap = BitmapFactory.decodeStream(assets.open(filePath)); } catch (IOException e) { e.printStackTrace(); return 0; } int[] names = {0}; GLES20.glGenTextures(1, names, 0); int tex = names[0]; GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, tex); GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0); bitmap.recycle(); // memory is now gpu -> free it GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, tex); return tex; } public void onSurfaceCreated(GL10 arg0, EGLConfig arg1) { GLES20.glClearColor(1.0f, 1.0f, 1.0f, 1.0f); GLES20.glEnable(GLES20.GL_DEPTH_TEST); GLES20.glEnable(GLES20.GL_CULL_FACE); GLES20.glEnable(GLES20.GL_TEXTURE_2D); try { InputStream is = assets.open("meshes/android.amh"); androidMesh = new AnimatedMesh(is); } catch (IOException e) { Log.e("gl", "Couldn't open android mesh"); } androidTexture = loadTexture("textures/android-tex.png"); try { InputStream is = assets.open("meshes/bee.amh"); beeMesh = new AnimatedMesh(is); } catch (IOException e) { Log.e("gl", "Couldn't open bee mesh"); } beeTexture = loadTexture("textures/bee-tex.png"); modelview = new float[16]; Matrix.setIdentityM(modelview, 0); projection = new float[16]; mvp = new float[16]; String vertexSource = "attribute vec3 position; void main() {gl_Position = vec4(position, 1.0);}"; String fragmentSource = "void main() {gl_FragColor = vec4(1.0, 0.0, 1.0, 1.0);}"; try { vertexSource = inputStreamToString(assets.open("shaders/skinned.vert")); } catch (IOException e) { e.printStackTrace(); } try {fragmentSource = inputStreamToString(assets.open("shaders/skinned.frag")); } catch (IOException e) { e.printStackTrace(); } program = loadProgram(vertexSource, fragmentSource); } static float beeAnimation = 0.0f; private float[] mixColor(float alpha, float[] color1, float[] color2) { float[] color3 = new float[4]; color3[0] = (1.0f - alpha) * color1[0] + alpha * color2[0]; color3[1] = (1.0f - alpha) * color1[1] + alpha * color2[1]; color3[2] = (1.0f - alpha) * color1[2] + alpha * color2[2]; color3[3] = (1.0f - alpha) * color1[3] + alpha * color2[3]; return color3; } public void onDrawFrame(GL10 arg0) { GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); GLES20.glUseProgram(program); int colorUniformLoc = GLES20.glGetUniformLocation(program, "color"); int textureUniformLoc = GLES20.glGetUniformLocation(program, "texture"); int mvpUniformLoc = GLES20.glGetUniformLocation(program, "mvp"); //final float[] androidColor = {165.0f / 255.0f, 202.0f / 255.0f, 57.0f / 255.0f, 1.0f}; // ok final float[] whiteColor = {1.0f, 1.0f, 1.0f, 1.0f}; final float[] redColor = {2.0f, 0.4f, 0.2f, 1.0f}; final float[] yellowColor = {1.0f, 1.0f, 0.0f, 1.0f}; float[] color = mixColor(0.5f + 0.5f * (float)Math.sin(0.2f * beeAnimation), whiteColor, redColor); GLES20.glUniform4fv(colorUniformLoc, 1, color, 0); Log.i("gl", color[0]+" "+color[1]+" "+color[2]+" "+color[3]); GLES20.glUniform1i(textureUniformLoc, 0); Matrix.setIdentityM(modelview, 0); Matrix.translateM(modelview, 0, 0.0f, -0.5f, -2.0f); Matrix.rotateM(modelview, 0, -80.0f, 1.0f, 0.0f, 0.0f); Matrix.multiplyMM(mvp, 0, projection, 0, modelview, 0); GLES20.glUniformMatrix4fv(mvpUniformLoc, 1, false, mvp, 0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, androidTexture); androidMesh.tick(); androidMesh.draw(program); GLES20.glUniform4fv(colorUniformLoc, 1, whiteColor, 0); beeAnimation += 1.0f; float beeSize = 0.2f; Matrix.rotateM(modelview, 0, -4.0f * beeAnimation, 0.0f, 0.0f, 1.0f); Matrix.translateM(modelview, 0, 0.6f, 0.0f, 0.7f + 0.1f * (float)Math.sin(0.2f * beeAnimation)); Matrix.rotateM(modelview, 0, 20.0f * (float)Math.cos(0.2f * beeAnimation), 1.0f, 0.0f, 0.0f); Matrix.scaleM(modelview, 0, beeSize, beeSize, beeSize); Matrix.multiplyMM(mvp, 0, projection, 0, modelview, 0); GLES20.glUniformMatrix4fv(mvpUniformLoc, 1, false, mvp, 0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, beeTexture); beeMesh.tick(); beeMesh.draw(program); } public void onSurfaceChanged(GL10 arg0, int w, int h) { width = w; height = h; aspectRatio = (float)w / (float)h; Matrix.orthoM(projection, 0, -aspectRatio, aspectRatio, -1.0f, 1.0f, -1.0f, 1.0f); float near = 0.1f; float fov = 2.0f; Matrix.frustumM(projection, 0, near * -aspectRatio, near * aspectRatio, -near, near, fov * near, 100.0f); GLES20.glViewport(0, 0, width, height); } // see http://stackoverflow.com/questions/309424/read-convert-an-inputstream-to-a-string private static String inputStreamToString(InputStream is) { Scanner scanner = new Scanner(is); Scanner s = scanner.useDelimiter("\\A"); String result = s.hasNext() ? s.next() : ""; scanner.close(); return result; } public static int loadShader(int type, String source) { int shader = GLES20.glCreateShader(type); GLES20.glShaderSource(shader, source); GLES20.glCompileShader(shader); Log.i("gl", GLES20.glGetShaderInfoLog(shader)); return shader; } public static int loadProgram(String vertexSource, String fragmentSource) { int program = GLES20.glCreateProgram(); GLES20.glAttachShader(program, loadShader(GLES20.GL_VERTEX_SHADER, vertexSource)); GLES20.glAttachShader(program, loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource)); GLES20.glLinkProgram(program); return program; } }