Hi .... Dear All .... Today I am uploading a superb example of OpenGL ES.
In this example i am drawing a Triangle using OpenGL ES.
What is OpenGL ES???
• Android
provides many tools for creating handy and great looking user interface for the
applications.
• The
OpenGL ES APIs, which comes as part of Android, has many helper classes and
methods that assist in displaying high-end and animated graphics.
• Most
of the android phones come with a dedicated Graphical Processing Unit (GPU);
hence the compositing and rendering can be accelerated using this additional
hardware.
•Let
us now see how to use OpenGL ES APIs to define and draw shapes.
Steps to use the APIs:
1.
Define shapes that will be rendered on screen – Eg: Triangle, Rectangle.
2.
Create our renderer android.opengl.GLSurfaceView.Renderer to render the shape on Surface View.
3.
Extend the android.opengl.GLSurfaceView to create our own surface on which the
shapes will be composed.
4.
Finally create an Activity that will show these Graphic shapes by using above
View.
Lets start with step 1
package com.exam.ravi.graphicsex2; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; import android.opengl.GLES20; /** * A two-dimensional triangle for use as a drawn object in OpenGL ES 2.0. */
public class Triangle { private final String shaderCode = "uniform mat4 uMVPMatrix;" + "attribute vec4 vPosition;" + "void main() {" + " gl_Position = uMVPMatrix * vPosition;" + "}"; private final String fragShaderCode = "precision mediump float;" + "uniform vec4 vColor;" + "void main() {" + " gl_FragColor = vColor;" + "}"; private final FloatBuffer vertexBuffer; private final int anInt; private int mpositionhandle; private int mcolorhandle; private int mmvpmatrixhandle; static final int COORDS_PER_VERTEX = 3; static float triangleCoords[] = { 0.0f, 0.622008459f, 0.0f, // top
-0.5f, -0.311004243f, 0.0f, // bottom left
0.5f, -0.311004243f, 0.0f // bottom right };
private final int vertexcount = triangleCoords.length / COORDS_PER_VERTEX; private final int vertexstride = COORDS_PER_VERTEX * 4; // 4 bytes per vertex float color[] = { 0.63671875f, 0.76953125f, 0.22265625f, 0.0f }; public Triangle() { ByteBuffer byteBuffer = ByteBuffer.allocateDirect( triangleCoords.length * 4); byteBuffer.order(ByteOrder.nativeOrder()); vertexBuffer = byteBuffer.asFloatBuffer(); vertexBuffer.put(triangleCoords); vertexBuffer.position(0); int vertexShader = MyRenderer.loadShader( GLES20.GL_VERTEX_SHADER, shaderCode); int fragmentShader = MyRenderer.loadShader( GLES20.GL_FRAGMENT_SHADER, fragShaderCode); anInt = GLES20.glCreateProgram(); GLES20.glAttachShader(anInt, vertexShader); GLES20.glAttachShader(anInt, fragmentShader); GLES20.glLinkProgram(anInt); } /** * Encapsulates the OpenGL ES instructions for drawing this shape. *
* @param mvpMatrix - The Model View Project matrix in which to draw
* this shape. */ public void draw(float[] mvpMatrix) { GLES20.glUseProgram(anInt); mpositionhandle = GLES20.glGetAttribLocation(anInt, "vPosition"); GLES20.glEnableVertexAttribArray(mpositionhandle); GLES20.glVertexAttribPointer( mpositionhandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, vertexstride, vertexBuffer); mcolorhandle = GLES20.glGetUniformLocation(anInt, "vColor"); GLES20.glUniform4fv(mcolorhandle, 1, color, 0); mmvpmatrixhandle = GLES20.glGetUniformLocation(anInt, "uMVPMatrix"); MyRenderer.checkGlError("glGetUniformLocation"); GLES20.glUniformMatrix4fv(mmvpmatrixhandle, 1, false, mvpMatrix, 0); MyRenderer.checkGlError("glUniformMatrix4fv"); GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexcount); GLES20.glDisableVertexAttribArray(mpositionhandle); } }
Step II
package com.exam.ravi.graphicsex2; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; import android.opengl.GLES20; import android.opengl.GLSurfaceView; import android.opengl.Matrix; import android.util.Log; public class MyRenderer implements GLSurfaceView.Renderer { private static final String TAG = "MyRenderer"; private Triangle mTriangle; private final float[] mMVPMatrix = new float[16]; private final float[] mProjectionMatrix = new float[16]; private final float[] mViewMatrix = new float[16]; private final float[] mRotationMatrix = new float[16]; private float mAngle; @Overridepublic void onSurfaceCreated(GL10 unused, EGLConfig config) { GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f); mTriangle = new Triangle(); } @Overridepublic void onDrawFrame(GL10 unused) { float[] scratch = new float[16]; GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); Matrix.setLookAtM(mViewMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f); Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0); Matrix.setRotateM(mRotationMatrix, 0, mAngle, 0, 0, 1.0f); Matrix.multiplyMM(scratch, 0, mMVPMatrix, 0, mRotationMatrix, 0); mTriangle.draw(scratch); } @Override public void onSurfaceChanged(GL10 unused, int width, int height) { GLES20.glViewport(0, 0, width, height); float ratio = (float) width / height; Matrix.frustumM(mProjectionMatrix, 0, -ratio, ratio, -1, 1, 3, 7); } /** * Utility method for compiling a OpenGL shader.* * <p><strong>Note:</strong> When developing shaders, use the checkGlError()* method to debug shader coding errors.</p> * * @param type - Vertex or fragment shader type.* @param shaderCode - String containing the shader code.* @return - Returns an id for the shader. */public static int loadShader(int type, String shaderCode){ int shader = GLES20.glCreateShader(type); GLES20.glShaderSource(shader, shaderCode); GLES20.glCompileShader(shader); return shader; } /** * Utility method for debugging OpenGL calls. Provide the name of the call* just after making it: * * <pre>* mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");* MyRenderer.checkGlError("glGetUniformLocation");</pre>* * If the operation is not successful, the check throws an error. ** @param glOperation - Name of the OpenGL call to check. */public static void checkGlError(String glOperation) { int error; while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) { Log.e(TAG, glOperation + ": glError " + error); throw new RuntimeException(glOperation + ": glError " + error); } } /** * Returns the rotation angle of the triangle shape (mTriangle). ** @return - A float representing the rotation angle. */public float getAngle() { return mAngle; } public void setAngle(float angle) { mAngle = angle; } }Step IIIpackage com.exam.ravi.graphicsex2; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.opengl.GLSurfaceView; public class MainActivity extends AppCompatActivity { private GLSurfaceView glSurfaceView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); glSurfaceView = new MySurfaceView(this); setContentView(glSurfaceView); } @Override protected void onPause() { super.onPause(); glSurfaceView.onPause(); } @Override protected void onResume() { super.onResume(); glSurfaceView.onResume(); } }Step IVpackage com.exam.ravi.graphicsex2; import android.content.Context; import android.opengl.GLSurfaceView; import android.view.MotionEvent; public class MySurfaceView extends GLSurfaceView { private final MyRenderer mRenderer; public MySurfaceView(Context context) { super(context); setEGLContextClientVersion(2); mRenderer = new MyRenderer(); setRenderer(mRenderer); setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY); } }Output will be like