Back to project page ExpertAndroid.
The source code is released under:
MIT License
If you think the Android project ExpertAndroid listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
package com.iuriio.demos.expertandroid.ch9openglexperiments; // w w w .j a va 2s . c o m import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; import android.content.Context; import android.content.res.AssetManager; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.opengl.GLES20; import android.opengl.GLUtils; import android.opengl.GLSurfaceView.Renderer; import android.opengl.Matrix; import android.util.Log; //filename: ES20SingleTextureAbstractRenderer.java public abstract class ES20SingleTextureAbstractRenderer implements Renderer { public static String TAG = "ES20AbstractRenderer"; private float[] mMMatrix = new float[16]; private float[] mCurrentModelMatrix = new float[16]; private float[] mProjMatrix = new float[16]; private float[] mVMatrix = new float[16]; private float[] mMVPMatrix = new float[16]; private float[] mTempModelMatrix = new float[16]; private int mProgram; private int muMVPMatrixHandle; private int maPositionHandle; private int maTextureHandle; private int mu2DSamplerTexture; public ES20SingleTextureAbstractRenderer() { initializeMatrices(); } protected int getTextureHandle() { return maTextureHandle; } public void onSurfaceCreated(GL10 gl, EGLConfig eglConfig) { prepareSurface(gl,eglConfig); } public void prepareSurface(GL10 gl, EGLConfig eglConfig) { Log.d(TAG,"preparing surface"); mProgram = createProgram( this.getVertexShaderCodeString(), this.getFragmentShaderCodeString()); if (mProgram == 0) { return; } Log.d(TAG,"Getting position handle:aPosition"); maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition"); checkGlError("glGetAttribLocation aPosition"); if (maPositionHandle == -1) { throw new RuntimeException("Could not get attrib location for aPosition"); } //Get texture handle Log.d(TAG,"Getting texture handle:aTextureCoordinate"); maTextureHandle = GLES20.glGetAttribLocation(mProgram, "aTextureCoordinate"); checkGlError("glGetAttribLocation aTextureCoordinate"); if (maTextureHandle == -1) { throw new RuntimeException("Could not get attrib location for aTextureHandle"); } //Get uniform matrix handle Log.d(TAG,"Getting matrix handle:uMVPMatrix"); muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix"); checkGlError("glGetUniformLocation uMVPMatrix"); if (muMVPMatrixHandle == -1) { throw new RuntimeException("Could not get attrib location for uMVPMatrix"); } //Get uniform texture handle Log.d(TAG,"Getting texture 2D sampler handle"); mu2DSamplerTexture = GLES20.glGetUniformLocation(mProgram, "s_2DtextureSampler"); checkGlError("glGetUniformLocation s_2DtextureSampler"); if (mu2DSamplerTexture == -1) { throw new RuntimeException("Could not get attrib location for texture sampler"); } this.prepareTexture(); //this.bindTextureSamplerToTextureId(); Log.d(TAG,"set look at matrix: view matrix"); //Matrix.setIdentityM(mVMatrix, 0); Matrix.setLookAtM(mVMatrix, 0, 0, 0, -5, 0f, 0f, 0f, 0f, 1.0f, 0.0f); } //Override this method to spcify your //your own frustum. protected FrustumDimensions getFrustumDimensions() { return FrustumDimensions.getDefault(); } public void onSurfaceChanged(GL10 gl, int w, int h) { Log.d(TAG,"surface changed. Setting matrix frustum: projection matrix"); GLES20.glViewport(0, 0, w, h); float ratio = (float) w / h; FrustumDimensions fd = this.getFrustumDimensions(); //Matrix.setIdentityM(mProjMatrix, 0); Matrix.frustumM(mProjMatrix, 0, ratio * fd.bottom, ratio * fd.top, fd.bottom, fd.top, fd.near, fd.far); } public void onDrawFrame(GL10 gl) { //Move it to surface crated ater textyure prep //Log.d(TAG,"set look at matrix: view matrix"); //Matrix.setIdentityM(mVMatrix, 0); //Matrix.setLookAtM(mVMatrix, 0, 0, 0, 5, 0f, 0f, 0f, 0f, 1.0f, 0.0f); Log.d(TAG,"base drawframe"); GLES20.glClearColor(0.0f, 0.0f, 1.0f, 1.0f); GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT); GLES20.glUseProgram(mProgram); //Log.e(TAG, GLES20.glGetProgramInfoLog(mProgram)); checkGlError("glUseProgram"); //texture support //this.prepareTexture(); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureID); GLES20.glUniform1i(mu2DSamplerTexture, 0); draw(gl,this.maPositionHandle); } private int createProgram(String vertexSource, String fragmentSource) { int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource); if (vertexShader == 0) { return 0; } Log.d(TAG,"vertex shader created"); int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource); if (pixelShader == 0) { return 0; } Log.d(TAG,"fragment shader created"); int program = GLES20.glCreateProgram(); if (program != 0) { Log.d(TAG,"program created"); GLES20.glAttachShader(program, vertexShader); checkGlError("glAttachShader"); GLES20.glAttachShader(program, pixelShader); checkGlError("glAttachShader"); GLES20.glLinkProgram(program); int[] linkStatus = new int[1]; GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0); if (linkStatus[0] != GLES20.GL_TRUE) { Log.e(TAG, "Could not link program: "); Log.e(TAG, GLES20.glGetProgramInfoLog(program)); GLES20.glDeleteProgram(program); program = 0; } } return program; } private int loadShader(int shaderType, String source) { int shader = GLES20.glCreateShader(shaderType); if (shader != 0) { GLES20.glShaderSource(shader, source); GLES20.glCompileShader(shader); int[] compiled = new int[1]; GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0); if (compiled[0] == 0) { Log.e(TAG, "Could not compile shader " + shaderType + ":"); Log.e(TAG, GLES20.glGetShaderInfoLog(shader)); GLES20.glDeleteShader(shader); shader = 0; } } return shader; } protected void checkGlError(String op) { int error; while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) { Log.e(TAG, op + ": glError " + error); throw new RuntimeException(op + ": glError " + error); } } public void initializeMatrices() { Matrix.setIdentityM(this.mCurrentModelMatrix, 0); Matrix.setIdentityM(mTempModelMatrix, 0); Matrix.setIdentityM(mMMatrix, 0); Matrix.setIdentityM(mMVPMatrix, 0); } public void trnslate(float x, float y, float z) { Matrix.setIdentityM(mTempModelMatrix, 0); Matrix.translateM(this.mTempModelMatrix,0,x,y,z); Matrix.multiplyMM(this.mCurrentModelMatrix, 0, this.mTempModelMatrix, 0, this.mCurrentModelMatrix, 0); } public void rotate(float angle, float x, float y, float z) { //Matrix.rotateM(this.mTranslateMatrix,0,this.mTranslateMatrix,0,angle,x,y,z); Matrix.setIdentityM(mTempModelMatrix, 0); Matrix.rotateM(this.mTempModelMatrix,0,angle,x,y,z); Matrix.multiplyMM(this.mCurrentModelMatrix, 0, this.mTempModelMatrix, 0, this.mCurrentModelMatrix, 0); } public void scale(float xFactor, float yFactor, float zFactor) { //Matrix.rotateM(this.mTranslateMatrix,0,this.mTranslateMatrix,0,angle,x,y,z); Matrix.setIdentityM(mTempModelMatrix, 0); Matrix.scaleM(this.mTempModelMatrix,0,xFactor,yFactor,zFactor); Matrix.multiplyMM(this.mCurrentModelMatrix, 0, this.mTempModelMatrix, 0, this.mCurrentModelMatrix, 0); } protected void setupMatrices() { Matrix.setIdentityM(mMMatrix, 0); //translate the model combo next Matrix.multiplyMM(mMVPMatrix, 0, this.mCurrentModelMatrix, 0, mMMatrix, 0); //translate eye coordinates first Matrix.multiplyMM(mMVPMatrix, 0, this.mVMatrix, 0, mMVPMatrix, 0); //Project it: screen coordinates Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0); GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0); } protected void setupMatrices1() { Matrix.setIdentityM(mMMatrix, 0); //translate eye coordinates first Matrix.multiplyMM(mMVPMatrix, 0, this.mVMatrix, 0, mMMatrix, 0); //translate the model combo next Matrix.multiplyMM(mMVPMatrix, 0, this.mCurrentModelMatrix, 0, mMVPMatrix, 0); //Project it: screen coordinates Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0); GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0); } protected abstract void draw(GL10 gl, int positionHandle); private static final String DEF_VERTEX_SHADER_FILENAME = "def_vertex_shader.txt"; private static final String DEF_FRAGMENT_SHADER_FILENAME = "def_fragment_shader.txt"; public String getDefaultVertexShaderCodeString() { return this.getStringFromAssetFile(DEF_VERTEX_SHADER_FILENAME); } public String getDefaultFragmentShaderCodeString() { return this.getStringFromAssetFile(DEF_FRAGMENT_SHADER_FILENAME); } protected String getVertexShaderCodeString() { String vertexShader = "uniform mat4 uMVPMatrix;\n" + "attribute vec4 aPosition;\n" + "void main() {\n" + " gl_Position = uMVPMatrix * aPosition;\n" + "}\n"; return vertexShader; } protected String getFragmentShaderCodeString() { String fragmentShader = "void main() {\n" + " gl_FragColor = vec4(0.5, 0.25, 0.5, 1.0);\n" + "}\n"; return fragmentShader; } public String getStringFromAssetFile(String filename) { Context ctx = MyApplication.m_appContext; if ( ctx == null) { throw new RuntimeException("Sorry your app context is null"); } try { AssetManager am = ctx.getAssets(); InputStream is = am.open(filename); String s = convertStreamToString(is); is.close(); return s; } catch (IOException x) { throw new RuntimeException("Sorry not able to read filename:" + filename,x); } } //Optimize later. This may not be an efficient read private String convertStreamToString(InputStream is) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); int i = is.read(); while (i != -1) { baos.write(i); i = is.read(); } return baos.toString(); } //********************************************** //* Texture support //********************************************** int mTextureID; int mImageResourceId = R.raw.robot; //Make sure it is initialized before calling this //method public int getTextureID() { return mTextureID; } public void bindTextureSamplerToTextureId() { GLES20.glUniform1i(mu2DSamplerTexture, mTextureID); } //Ultimately this code prepares the //texture ID mTextureID //creates it, binds it public void prepareTexture() { //GLES20.glEnable(GLES20.GL_TEXTURE_2D); int[] textures = new int[1]; GLES20.glGenTextures(1, textures, 0); mTextureID = textures[0]; GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureID); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_REPEAT); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_REPEAT); //These may have been different in 2.0 //GLES20.glTexEnvf(GLES20.GL_TEXTURE_ENV, GLES20.GL_TEXTURE_ENV_MODE, // GLES20.GL_REPLACE); final BitmapFactory.Options options = new BitmapFactory.Options(); options.inScaled = false; // No pre-scaling // Read in the resource final Bitmap bitmap = BitmapFactory.decodeResource( MyApplication.m_appContext.getResources(), this.mImageResourceId, options); GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0); bitmap.recycle(); } }//eof-main-class