Android OpenGL ES application (1)
OpenGL has become a "standard" for 3D because it can be used across platforms and has rich interfaces. Almost all 3D games on mobile phones are related to OpenGL.
Of course, Microsoft has direct X, but it can only be used on the Microsoft platform.
OpenGL is implemented in c/c ++ at the underlying layer, and encapsulated class libraries are used in JAVA. Android provides the following interface packages to meet the requirements of 3D technology.
The Android platform uses the OpenGL ES subset to process images. Currently, OpenGL ES uses 2.0, and rarely uses 1.0. 3.0 is not yet popular.
First, write and determine whether Android devices support OpenGL 2.0.
GLHelper. java adds a code method to determine whether version 2.0 is supported.
public static boolean enableOpenGL2(Activity act) {final ActivityManager mg = (ActivityManager) act.getSystemService(Context.ACTIVITY_SERVICE);ConfigurationInfo configuration = mg.getDeviceConfigurationInfo();boolean b = configuration.reqGlEsVersion >= 0x20000);return b;}
We need to extend the android. opengl. GLSurfaceView class to draw images on SurfaceView. Let's look at the source code and find that this class actually extends SurfaceView's write encapsulation.
Public class MyOpenGLView extends GLSurfaceView {// This class is empty first. This time there is not much code public MyOpenGLView (Context context) {super (context);} public MyOpenGLView (Context context, attributeSet attrs) {super (context, attrs );}}
We encapsulate various processing methods.
Public class GLData {public GLData () {} public static float [] singelTriangles = {// defines two triangles to form a square, Because openGL ES can only be a vertex, line and triangle-0.3f,-0.3f, 0.3f, 0.3f,-0.3f, 0.3f,-0.3f,-0.3f, 0.3f,-0.3f, 0.3f, 0.3f };}
OpenGL ES is in the range of [-] In the Android coordinate system.
Write two simple vertex pasters and segment pasters.
<喎?http: www.bkjia.com kf ware vc " target="_blank" class="keylink"> VcD4KPHA + PC9wPgo8cHJlIGNsYXNzPQ = "brush: java;"> public class GLScript {public GLScript () {} public static final String vertex1 = "attribute vec4 mPosition; \ n "+" void main () \ n "+" {\ n "+" gl_Position = mPosition; \ n "+"} \ n "; public static final String fragment1 = "precision mediump float; \ n" + "uniform vec4 mColor; \ n" + "void main () {gl_FragColor = mColor; \ n }";}
Vec4 mPosition indicates that a 4-component (x, y, z, w) vertex is defined, and then paid to the gl_Position built-in variable. OpenGL will compile and automatically process the vertex.
Vec4 mColor indicates a color component RGBA. The last one is transparency, that is, red, green, and blue.
The scripting language is the core of OpenGL ES, and many rendering effects require script processing.
GLHelper. java: code method for adding and compiling scripts.
Public static int compileScript (int type, String script) {int objID = GLES20.glCreateShader (type); // create a coloring object, TYPE indicates that the vertex shader and fragment shader if (objID = 0) {// 0 indicates that return 0 is incorrect;} gles?glshadersource (objID, script ); // pass the script code to the OpenGL engine gles‑glcompileshader (objID); // start to compile int [] status = new int [1]; gles‑glgetshaderiv (objID, gles‑gl _ COMPILE_STATUS, status, 0); // check whether the compilation result is incorrect. Log. d ("OPENGL", "compileScript status info:" + GLES20.glGetShaderInfoLog (objID); if (status [0] = 0) {GLES20.glDeleteShader (objID ); // An error occurred while deleting the object. Log. e ("OPENGL", "Error Compile Script:" + script); return 0;} return objID ;}
If the compilation is successful, we will associate the OpenGL ES program.
Public static int linkGL () {int programId = GLES20.glCreateProgram (); // create a program if (programId = 0) {Log. e ("OPENGL", "Error Create Link Program"); return 0;} return programId;} public static int linkAttach (int vertexsharder, int fragmentsharder) {int programId = linkGL (); Combine (programId, vertexsharder); // associate GLES20.glAttachShader (programId, fragmentsharder) with the Shadow; // associate GLES20.glLinkProg with the Shadow. Ram (programId); // link the program to int status [] = new int [1]; GLES20.glGetProgramiv (programId, gles1_gl _ LINK_STATUS, status, 0 ); // check whether an error occurs. Log. d ("OPENGL", "linkAttach link status is" + GLES20.glGetProgramInfoLog (programId); if (status [0] = 0) {Log. e ("OPENGL", "link status is error. "); gles+gldeleteprogram (programId); return 0;} return programId ;}
Finally, we verify if the program has an error.
public static boolean checkProgram(int programId){GLES20.glValidateProgram(programId);int status[] = new int[1];GLES20.glGetProgramiv(programId,GLES20.GL_VALIDATE_STATUS, status,0);if (status[0] == 0) {Log.e("OPENGL","program is error");return false;}return true;}
The above code is written in GLHelper. java,
We add the code to the rendering class Renderer.
Rendering class
Public class MyOpenGLRenderer implements Renderer {public static FloatBuffer verDataBuffer; int colorLocation; int positionLocation; public MyOpenGLRenderer () {// Request direct memory space and use the native byte sequence verDataBuffer = ByteBuffer. allocateDirect (4 * GLData. singelTriangles. length ). order (ByteOrder. nativeOrder ()). asFloatBuffer (); verDataBuffer. put (GLData. singelTriangles); // This is a square and will be pasted with code .} @ Overridepublic void onDrawFrame (GL10 arg0) {// This method will re-paint gles1_glclear (gles1_gl _ COLOR_BUFFER_BIT); then (colorLocation, 0f, 0f, 0F, 0f ); // The color is black and will be passed to colorlocationgles?gldrawarrays (gles=gl _ TRIANGLES, 0, 6); // draw a triangle, there are 6 vertices, so starting from} @ Overridepublic void onSurfaceChanged (GL10 arg0, int w, int h) {gles?glviewport (0, 0, w, h );} @ Overridepublic void onSurfaceCreated (GL10 arg0, EGLConfig arg1) {gles?glclearcolor (1F, 1F, 1F, 0.0F); // the following code is organized and compiled using the GLHelper class. int vertexsharder = GLHelper. compileScript (gles‑gl _ VERTEX_SHADER, GLScript. vertex1); int fragmentsharder = GLHelper. compileScript (gles1_gl _ FRAGMENT_SHADER, GLScript. fragment1); int programId = GLHelper. linkAttach (vertexsharder, fragmentsharder); boolean isOK = GLHelper. checkProgram (programId); if (isOK) {Log. d ("", "start draw .............. "); gles‑gluseprogram (programId); // we start to use this program colorLocation = gles‑glgetuniformlocation (programId," mColor "); // obtain the variable location, which can be understood as the memory address, openGL will obtain the data positionLocation = GLES20.glGetAttribLocation (programId, "mPosition"); verDataBuffer in this address. position (0); // The data start end reads gles‑glvertexattribpointer (positionLocation, 2, gles‑gl _ FLOAT, false, 0, verDataBuffer ); // This area associates vertex data with variables. gles?glablevertexattribarray (positionLocation); // This area enables the use of vertex arrays }}}
The last part of the Activity code.
Private MyOpenGLView gLView; private boolean openglable; @ Overrideprotected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); if (GLHelper. enableOpenGL2 (this) {openglable = true;} Log. d ("", "OpenGL is Enable:" + openglable); gLView = new MyOpenGLView (this); gLView. setEGLContextClientVersion (2); // you can use OpenGL ES 2.0gLView.setRenderer (new MyOpenGLRenderer (); setContentView (gLView );}
The running result is a square in the middle.
Getting started with OpenGL ES is relatively complicated, because function calls and JAVA, and C ++ libraries are not the same.
3D is not only complicated with a coordinate Z, but also with many rendering technologies.
Project Structure: