I. Summary
By accident, I saw this tutorial on Android Developers and made it step by step. Below is a record.
Ii. How to draw OpenGL ES in Android
To use OpenGL to draw images in Android applications, we must create a view container. The most direct method is implement.GLSurfaceView
AndGlsurfaceview. Renderer.The former is the container, and the latter controls the rendered content in the view.
There are two other methods: surfaceview and textureview, but they are a little complicated.
Final effect:
Iii. Necessary statements
Add the following code to the manifest file:
<uses-feature android:glEsVersion="0x00020000" android:required="true" /> <supports-gl-texture android:name="GL_OES_compressed_ETC1_RGB8_texture" /> <supports-gl-texture android:name="GL_OES_compressed_paletted_texture" />
The previous section declares the OpenGL version, and the last two lines indicate the Texture type.
4. Main Activity Type
package com.example.opengles;import android.opengl.GLSurfaceView;import android.os.Bundle;import android.app.Activity;import android.content.Context;import android.view.Menu;public class OpenGLActivity extends Activity {private GLSurfaceView mGLView;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);mGLView = new MyGLSurfaceView(this);setContentView(mGLView);}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {getMenuInflater().inflate(R.menu.activity_open_gl, menu);return true;}@Overrideprotected void onPause() {super.onPause();// The following call pauses the rendering thread.// If your OpenGL application is memory intensive,// you should consider de-allocating objects that// consume significant memory here.mGLView.onPause();}@Overrideprotected void onResume() {super.onResume();// The following call resumes a paused rendering thread.// If you de-allocated graphic objects for onPause()// this is a good place to re-allocate them.mGLView.onResume();}}class MyGLSurfaceView extends GLSurfaceView {public MyGLSurfaceView(Context context){super(context);// Create an OpenGL ES 2.0 context.setEGLContextClientVersion(2);// Set the Renderer for drawing on the GLSurfaceViewsetRenderer(new MyRender());// Render the view only when there is a change in the drawing datasetRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);}}
Iv. Renderer
package com.example.opengles;import java.nio.ByteBuffer;import java.nio.ByteOrder;import java.nio.FloatBuffer;import javax.microedition.khronos.egl.EGLConfig;import javax.microedition.khronos.opengles.GL10;import android.opengl.GLES20;import android.opengl.GLSurfaceView;public class MyRender implements GLSurfaceView.Renderer {private Triangle mTriangle;@Overridepublic void onDrawFrame(GL10 gl) {// TODO Auto-generated method stub // Draw background color GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); // Draw triangle mTriangle.draw();}@Overridepublic void onSurfaceChanged(GL10 gl, int width, int height) {// TODO Auto-generated method stub // Adjust the viewport based on geometry changes, // such as screen rotation GLES20.glViewport(0, 0, width, height);} public static int loadShader(int type, String shaderCode){ // create a vertex shader type (GLES20.GL_VERTEX_SHADER) // or a fragment shader type (GLES20.GL_FRAGMENT_SHADER) int shader = GLES20.glCreateShader(type); // add the source code to the shader and compile it GLES20.glShaderSource(shader, shaderCode); GLES20.glCompileShader(shader); return shader; }@Overridepublic void onSurfaceCreated(GL10 gl, EGLConfig config) {// TODO Auto-generated method stub // Set the background frame color GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f); mTriangle = new Triangle();}}class Triangle { private final String vertexShaderCode = "attribute vec4 vPosition;" + "void main() {" + " gl_Position = vPosition;" + "}"; private final String fragmentShaderCode = "precision mediump float;" + "uniform vec4 vColor;" + "void main() {" + " gl_FragColor = vColor;" + "}"; private final FloatBuffer vertexBuffer; private final int mProgram; private int mPositionHandle; private int mColorHandle; // number of coordinates per vertex in this array static final int COORDS_PER_VERTEX = 3; static float triangleCoords[] = { // in counterclockwise order: 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; // bytes per vertex // Set color with red, green, blue and alpha (opacity) values float color[] = { 0.63671875f, 0.76953125f, 0.22265625f, 1.0f }; public Triangle() { // initialize vertex byte buffer for shape coordinates ByteBuffer bb = ByteBuffer.allocateDirect( // (number of coordinate values * 4 bytes per float) triangleCoords.length * 4); // use the device hardware's native byte order bb.order(ByteOrder.nativeOrder()); // create a floating point buffer from the ByteBuffer vertexBuffer = bb.asFloatBuffer(); // add the coordinates to the FloatBuffer vertexBuffer.put(triangleCoords); // set the buffer to read the first coordinate vertexBuffer.position(0); // prepare shaders and OpenGL program int vertexShader = MyRender.loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode); int fragmentShader = MyRender.loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode); mProgram = GLES20.glCreateProgram(); // create empty OpenGL Program GLES20.glAttachShader(mProgram, vertexShader); // add the vertex shader to program GLES20.glAttachShader(mProgram, fragmentShader); // add the fragment shader to program GLES20.glLinkProgram(mProgram); // create OpenGL program executables } public void draw() { // Add program to OpenGL environment GLES20.glUseProgram(mProgram); // get handle to vertex shader's vPosition member mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition"); // Enable a handle to the triangle vertices GLES20.glEnableVertexAttribArray(mPositionHandle); // Prepare the triangle coordinate data GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, vertexStride, vertexBuffer); // get handle to fragment shader's vColor member mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor"); // Set color for drawing the triangle GLES20.glUniform4fv(mColorHandle, 1, color, 0); // Draw the triangle GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount); // Disable vertex array GLES20.glDisableVertexAttribArray(mPositionHandle); }}
The three most important functions in this class are:
onSurfaceCreated()
-
Initialize the OpenGL Environment
onDrawFrame()
-
Draw View
onSurfaceChanged()
-
Is the paintgl () in QT OpenGL familiar with view changes ()
, Resizegl (),Initializegl ().At the end of the operation, a triangle will be drawn on the screen and shaderlanguage will be used. This will be copied directly. Of course, you can also use the original definition points to define the color for drawing.
Note: OpenGL programs cannot run in the simulator and need to be debugged by a real machine.
V. References
Android develop: http://developer.android.com/training/graphics/opengl/environment.html