The last review

Narrator: In the last episode, in order to obtain the black dragon’s treasure, brave men gathered to break into the black dragon’s cave

Through all the way hardships, finally passed the fourth copy, what difficulties are waiting for them in front? Watch together


Fifth copy:The help of the dragon

1. Level 1:Let me draw a rectangle

NPC: Hidden quests, puzzle solving: GLes20.gl_triangle_strip draw mode

It is found that there is something wrong with the way that the points drawn counterclockwise seem to connect. It seems that 2->3->4 is drawn first, and 1->2->3 is drawn before 1->2->3 because the triangle of 2->3->4 is covered by the equal triangle of 1->2->3

Static float sCoo [] = {/ / in anticlockwise order 0.5 f, f 0.5, 0.0, f / / upper left - 0.5 f, 0.5 f to 0.0 f, / / lower left 0.5 f, 0.5 f, 0.0 f, / / lower 0.5 f, 0.0f, 0.0f, 0.0f; Float colors [] = new float [] {1 f, 1 f, f 0.0, 1.0, f / / yellow f 0.05882353, 0.09411765 f, f 0.9372549, 1.0, f / 0.19607843 f/blue, 1.0 f, F 0.02745098, 1.0, f / 1.0 f/green, 0.0 f to 1.0 f to 1.0 f, / / purple}; -- -- -- - > [Rectangle# the draw] -- -- -- -- -- -- -- -- -- / / draw the triangle GLES20 glDrawArrays (GLES20 GL_TRIANGLE_STRIP, 0, 4);Copy the code

How can 1->2->3 and 2->3->4 not overlap? — Just click to change the order

1 - > 4 - > 2 - > 3

Static float sCoo [] = {/ / in anticlockwise order 0.5 f, f 0.5, 0.0, f / / 1-0.5 f to 0.5 f to 0.0 f, / / 2. 0.5 f, f 0.5, 0.0, f / / 4. 0.5 f to 0.5 f, 0.0 f, / / 3.};Copy the code

2. Level 2:Draw a pentagon

First, follow the order p1-> P2 -> P3 -> P4 -> P5, see what effect

As expected, first p1-> P2 ->p3-> P4, then five

How do you adjust it? Um… All right, I’m gonna start bragging

I’m just thinking, as long as it’s a square, I can move the P5, and let the P5 float

Static float sCoo [] = {/ / in anticlockwise order 0.5 f, f 0.5, 0.0, f / / p1 0.0 f, f 0.8, 0.0, f/f/p5-0.5, 0.5 f, f 0.0, 0.5 f / / p2, 0.5 f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f;Copy the code

Polygons can also be spelled with triangles, but it’s a bit cumbersome

GL_TRIANGLE_STRIP: draw a triangle with three adjacent vertices


3. Level 3: Indexed Pentagon —glDrawElements

And I thought, well, there’s got to be something that controls the vertices of the triangle, otherwise it’s going to be a lot of trouble

3.1. Simple encapsulation of buffering

The method of buffering vertex data is basically the same.

Float (4 bytes) and short(2 bytes) for now, and we’ll see what happens

Public static FloatBuffer getFloatBuffer(float[] vertexs) {float[] vertexs {float[] vertexs}}  FloatBuffer buffer; / / / each floating point Numbers: coordinate number * 4 bytes ByteBuffer QBB = ByteBuffer. AllocateDirect (vertexs. Length * 4); Qbb.order (byteorder.nativeorder ()); // use the ByteOrder of the native hardware device qbb.order(byteorder.nativeorder ()); // Create floating-point buffer from byte buffer buffer = qbb.asFloatBuffer(); // Add coordinates to FloatBuffer buffer.put(vertexs); // Set the buffer to read the first coordinate buffer.position(0); return buffer; Public static ShortBuffer getShortBuffer(short[]) public static ShortBuffer getShortBuffer(short[]) vertexs) { ShortBuffer buffer; ByteBuffer qbb = ByteBuffer.allocateDirect(vertexs.length * 2); qbb.order(ByteOrder.nativeOrder()); buffer = qbb.asShortBuffer(); buffer.put(vertexs); buffer.position(0); return buffer; }Copy the code

3.2: Control triangle formation by yourself

Let’s count from zero. How do we control the points

The static float sCoo [] = {/ / in anticlockwise order 0.5 f, f 0.5, 0.0, f/f/p0 0.5, 0.5 f, f 0.0, 0.5 f / / p1, 0.5 f, f 0.0, 0.5 f / / p2, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f; Private short[] idx = {0, 4, 3, 1, 3, 0, 1, 2, 3}; // Index buffer idxBuffer = glutils.getShortBuffer (idx); GlDrawElements (glES20.gl_triangles, idx.length, glES20.gl_unsigned_short, idxBuffer);Copy the code


4. Level 4: Hexagon

Why don’t you turn the hexagon so that shouldn’t be a problem

Static float sCoo [] = {/ / in anticlockwise order 0.5 f, f 0.5, 0.0, f/f/p0 1.0, 0.0 f, 0.0 f, / / p1-0.5 f, 0.5 f, f 0.0, 0.5 f / / p2, 0.0 f to 0.5 f,, / / p3 1.0 f, f 0.0, 0.0, f / / p4 0.5 f, f 0.5, 0.0, f / / p5}; Private short[] idx = {0, 1, 5, 1, 5, 2, 2, 5, 4, 2, 3, 4};Copy the code

Sixth Copy:Dragon's space

So when we go over here, we’re almost always in the plane, so we’re going to go solid

The keeper boss is about to make a big move, warriors. Hold on

Level 1: Rotate along the Y-axis

We talked a little bit about transformations in the first video, but if you forget, you can go back and look at them

Here’s the effect of one turn, which is less than half as much

// Rotate matrix.setrotatem (mOpMatrix, 0, currDeg, 0, 1, 0);Copy the code

I let her rotate as she moved, as if she could see something

But it is turned up, wait until the time to turn to talk about the vision of the time to discuss in detail

Matrix.setRotateM(mOpMatrix, 0, currDeg, 0, 1, 0); Matrix. TranslateM (mOpMatrix, 0, currDeg / 360. F, 0, 0).Copy the code


1. The second level: Space Plane

It looks like we’re always going to be 0 on the z axis, so let’s move a little bit, but there are advantages in both paper and photoshop

It looks good on paper (but it’s a big error), there’s a lot of reuse in PS, so let’s look at p0, P1, P2,p3 and start with p0 (-0.5,0.5,0.5), and then determine other points based on symmetry or visual observation.


/ / an array of point static float sCoo [] = {0.5 f, f 0.5, 0.5, f / / p0-0.5 f, 0.5 f, 0.5 f, / / p1-0.5 f, 0.5 f, 0.5 f, / / p2-0.5 f, 0.5 f, Private short[] idx = {0, 1, 3, 1, 2, 3,} float colors[] = new float[]{1f, 1f, 0.0f, 1.0f, 0.05882353f, 0.09411765f, 0.9372549f, 1.0f, 0.19607843f, 1.0f, 0.02745098f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f 1.0 f, / / purple}Copy the code


2. Level 2: Side 2

One side finished, the second side P4, P5, P6, P7 is easy to do, you can see that P0, P1 and P4, P5 are the same

Index a little painting can also see the rule, color and then the four, do not stick can see and we draw a little different, it seems to be the problem of the viewport, but does not affect the graphics itself

Static float sCoo [] = {0.5 f, f 0.5, 0.5, f/f/p0 0.5, 0.5 f, 0.5 f/f/p1-0.5, 0.5, f - 0.5 f/f/p2-0.5, 0.5, f 0.5 f, / / p3-0.5 f, f 0.5, 0.5, f/f/p4 0.5, 0.5 f, 0.5 f, / / p5 f 0.5, 0.5 f, f 0.5, 0.5 f / / p6, 0.5 f, 0.5 f, / / will be / / index array private short [] independence idx = {0, 1, 3, 1, 2, 3, 0 + 4, 1 + 4, 3 + 4, 1 + 4, 2 + 4, 3 + 4,Copy the code

3. Level 3: The Other Side

For the sake of illustration, I have given names to each side: A, B, C, D, E, F

Static float sCoo [] = {/ / a-side - 0.5 f, f 0.5, 0.5, f/f/p0 0.5, 0.5 f, 0.5 f/f/p1-0.5, 0.5, f - 0.5 f/f/p2-0.5, 0.5, f 0.5 f, / / p3 / / B side - 0.5 f, f 0.5, 0.5, f/f/p4 0.5, 0.5 f, 0.5 f, / / p5 f 0.5, 0.5 f, 0.5 f, / / p6 0.5 f, f 0.5, 0.5, f / / will be / / C 0.5 f, F 0.5, 0.5, f / / p8 f 0.5, 0.5 f, f, 0.5 0.5 f / / p9, - 0.5 f to 0.5 f, / / p10 f 0.5, 0.5 f to 0.5 f, / / p11 / / D interface - 0.5 f, 0.5 f, 0.5 f, / / p12 0.5 f, f 0.5, 0.5, f / / p13 f 0.5, 0.5 f to 0.5 f, / / p14-0.5 f, 0.5 f to 0.5 f, / / p15 / f/E surface - 0.5, 0.5 f, f 0.5, 0.5 f / / p16, 0.5 f to 0.5 f,,, / / p17 0.5 f to 0.5 f, 0.5 f, / / p18 0.5 f to 0.5 f to 0.5 f, / / p19 / / f to 0.5 f, 0.5 f to 0.5 f, / / p20-0.5 f, 0.5 f, 0.5 f, / / p21 f 0.5, - 0.5 f to 0.5 f, / / p22 f 0.5, 0.5 f to 0.5 f, / / p23}; / / index array private short [] independence idx = {0, 1, 3, / / A 1, 2, 3, 0 + 4, 1 + 4, 3 + 4, / / B 1 + 4, 2 + 4, 3 + 4, 0 + 4 * 2, 1 + 4 * 2, 3 + 4 * 2,//C 1 + 4 * 2, 2 + 4 * 2, 3 + 4 * 2, 0 + 4 * 3, 1 + 4 * 3, 3 + 4 * 3,//D 1 + 4 * 3, 2 + 4 * 3, 3 + 4 * 3, 0 + 4 * 4, 1 + 4 * 4, 3 + 4 * 4,//E 1 + 4 * 4, 2 + 4 * 4, 3 + 4 * 4, 0 + 4 * 5, 1 + 4 * 5, 3 + 4 * 5,//F 1 + 4 * 5, 2 + 4 * 5, 3 + 4 * 5, 3 + 4 * 5, Float colors[] = new float[]{float colors[] = new float[]{float colors[] = new float[]{float colors[] = new float[]{ 1.0 f, f 0.02745098, 1.0, f / 1.0 f/green, 0.0 f to 1.0 f to 1.0 f, / / purple / / B 1 f, 1 f, f, 0.0 1.0 f, 0.05882353 f / / yellow, 0.09411765 f, 0.9372549f, 1.0f, 0.02745098f, 1.0f, 0.9372549f, 1.0f, 0.02745098f, 1.0f, 0.9372549f, 0.9f, 1.0f, 0.02745098f, 1.0f, 0.0f, 0.0f 1.0f, 0.05882353f, 0.09411765f, 0.9372549f, 1.0f, 0.19607843f, 1.0f, 0.02745098f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f 1f, 1f, 0.05882353f, 0.09411765f, 0.9372549f, 1.0f, 0.19607843f, 1.0f, 0.02745098f, //E 1f, 1f, 0.05882353f, 0.09411765f, 0.9372549f, 0.05882353f, 0.09411765f, 0.9372549f, 1.0 f / 0.19607843 f/blue, 1.0 f, f 0.02745098, 1.0, f / 1.0 f/green, 0.0 f, f 1.0, 1.0, f / / purple / / f 1 f, 1 f, f 0.0, 1.0, f / / yellow 0.05882353 f, 0.09411765f, 0.9372549f, 1.0f, 0.02745098f, 1.0f, 0.02745098f, 1.0f, 0.02745098f, 1.0f, 0.02745098f, 1.0f;Copy the code


Seventh copy:Dragon lamella

The cube in Copy 6 is not very satisfying, the viewing Angle is not very good,

This copy takes a look at the camera and the projection and the matrix


1. Level 1: Adjusting the camera

When you start with your eyes at (0, 0, -3), look at the picture below and you will know why you have trouble drawing the face

Because the camera’s in the back and it’s straight, so it looks straight…

SetLookAtM (mViewMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f); setLookAtM(mViewMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 1.0f, 0.0f);Copy the code

Now I’m going to go back to the top (2,2,-5).

// Set camera position (view Matrix) matrix.setLookatm (mViewMatrix, 0, 2f, 2f, -5.0f, 0f, 0f, 0f, 0f, 1.0f, 0.0f);Copy the code


2. Level 2: Spin attempt, draw according to viewport on paper

// Initialize matrix.setrotatem (mOpMatrix, 0, 130, 0, 1, 0);Copy the code

And then when you look at the drawing process, it’s the same as on paper, so the viewport is very important


Copy 8:Dragon dress LEVEL1

Color more boring, let’s texture, experienced so much, look back, feeling a lot

This copy will simply recognize the texture, and there will be advanced dragon costume later


1. Level 1: Triangle map

Baidu for an hour, the leng is not the whole tile understand, the logic of the narrative is not good, they are paste a code finished,

It’s ok to post a complete one, but it’s all piece by piece code… Now I’m going to go through the simplest triangle map flow, first move the view to (0,0, -3) otherwise it will be deformed


1.1: Chip coderect_texture.frag
precision mediump float; varying vec2 aCoordinate; // Uniform sampler2D vTexture; Void main() {gl_FragColor=texture2D(vTexture,aCoordinate); }Copy the code

1.2: Vertex code:rect_texture.vert
attribute vec3 vPosition; // Vertex coordinates uniform MAT4 uMVPMatrix; Vec2 vCoordinate attribute vec2 vCoordinate; // Varying vec2 aCoordinate; Void main() {gl_Position = uMVPMatrix*vec4(vPosition,1); aCoordinate=vCoordinate; }Copy the code

1.3: Texture triangle:TextureRectangle

I replaced the color handle with the texture handle

Drawing again accept a map id, GLES20. GlActiveTexture (GLES20. GL_TEXTURE0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texId); Two lines of code map the rest of the same, the most important thing is how to get the map ID

/** * Author: Zhang Feng Jieteilie <br/> * Time: 2019/1/90009:20:09 <br/> * Email: [email protected]<br/> * Description: Public class TextureRectangle {private static final String TAG = "Triangle"; private Context mContext; private int mProgram; //OpenGL ES private int mPositionHandle; Private int mColorHandle; Private int muMVPMatrixHandle; // Private FloatBuffer vertexBuffer; Private final int vertexStride = COORDS_PER_VERTEX * 4; // 3*4=12 static final int COORDS_PER_VERTEX = 3; Static final int c = 1; static final int c = 1; Static float sCoo[] = {// p0-c, -c, 0.0f, // p0-c, -c, 0.0f, // p1 c, -c, 0.0f, // p2}; Private final float[] textureCoo = {0.0f,0.0f, 0.0f,1.0f, 1.0f,0.0f, 0.0f,}; static final int TEXTURE_PER_VERTEX = 2; Private final int vertexTextureStride = TEXTURE_PER_VERTEX * 4; // Count the values of each vertex in the array. // 4*4=16 private ShortBuffer idxBuffer; Private short[] idx = {1, 2, 3,}; private FloatBuffer mTextureCooBuffer; public TextureRectangle(Context context) { mContext = context; // Initialize the vertex byte buffer bufferData(); // Buffer the vertex data initProgram(); // Initialize the OpenGL ES program} /** * bufferData */ private void bufferData() {vertexBuffer = Glutil.getFloatBuffer (sCoo); mTextureCooBuffer = GLUtil.getFloatBuffer(textureCoo); idxBuffer = GLUtil.getShortBuffer(idx); } /** * initialize OpenGL ES */ private void initProgram() {//// vertexShader int vertexShader = glutil.loadshaderassets (mContext, GLES20.GL_VERTEX_SHADER, "rect_texture.vert"); Int fragmentShader = Glutil.loadShaderAssets (mContext, gles20.gl_fragment_shader, "rect_texture.frag"); mProgram = GLES20.glCreateProgram(); // Create an empty OpenGL ES program gles20.glAttachShader (mProgram, vertexShader); // Add vertex shader gles20.glAttachShader (mProgram, fragmentShader); GLES20. GlLinkProgram (mProgram); / / create an executable OpenGL ES project / / handle to obtain the vertex shader vPosition members mPositionHandle = GLES20. GlGetAttribLocation (mProgram, "vPosition"); / / get the fragment shader vColor members handle mColorHandle = GLES20. GlGetAttribLocation (mProgram, "vCoordinate"); / / procurement procedures in the total transformation matrix uMVPMatrix members handle muMVPMatrixHandle = GLES20. GlGetUniformLocation (mProgram, "uMVPMatrix"); } public void draw(float[] mvpMatrix, int texId) {// Add the program to OpenGL ES gles20.gluseProgram (mProgram); / / handle to enable the triangle vertices GLES20. GlEnableVertexAttribArray (mPositionHandle); / / handle to enable triangle vertex color GLES20. GlEnableVertexAttribArray (mColorHandle); / / vertex matrix GLES20. GlUniformMatrix4fv (muMVPMatrixHandle, 1, false, mvpMatrix, 0). / / prepare triangle vertex coordinates data GLES20 glVertexAttribPointer (mPositionHandle, / / int indx, GL_FLOAT,//int type, type false,// Boolean normalized,// Whether to normalize vertexStride,// int Stride, / / span vertexBuffer); . / / Java nio Buffer PTR / / the Buffer / / prepare triangle vertex color data GLES20 glVertexAttribPointer (mColorHandle TEXTURE_PER_VERTEX, GLES20.GL_FLOAT, false, vertexTextureStride, mTextureCooBuffer); // Bind texture gles20.glActiveTexture (gles20.gl_texture0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texId); GlDrawElements (glES20.gl_triangles, idx.length, glES20.gl_unsigned_short, idxBuffer); // Disable the vertex array: // Disable the generic vertex array specified by index. // By default, all client functions are disabled, including all generic vertex property arrays. // If enabled, the values in the universal vertex property array are accessed, / / and vertex array the call command (such as glDrawArrays or glDrawElements) used to render the GLES20. GlDisableVertexAttribArray (mPositionHandle); }}Copy the code

1.4: Load the texture

I encapsulated two methods in GLUtil

@param resId * @param resId * @param resId * @param resId * @return texture id */ public static int loadTexture(Context CTX, int resId) { Bitmap bitmap = BitmapFactory.decodeResource(ctx.getResources(), resId); return loadTexture(ctx, bitmap); } / bitmap loading texture * * * * @ param CTX Context * @ param bitmap bitmap * @ return texture id * / public static int loadTexture (Context CTX, // Textures = new int[1]; // Textures = new int[1]; // Textures = new int[1]; GLES20. GlGenTextures (1, textures, 0); int textureId = textures[0]; GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId); 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_CLAMP_TO_EDGE); GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); // Actually load the texture (texture type, texture hierarchy, texture image, texture border size) glutils. texImage2D(gles20.gl_texture_2D, 0, bitmap, 0); bitmap.recycle(); Return textureId; // Return textureId; }Copy the code

1.5: Use texturesGLRenderer.java
private int textureId; ---->[GLRenderer#onSurfaceCreated]------ textureId = GLUtil.loadTexture(mContext, R.mipmap.mian_a); ---->[GLRenderer#onDrawFrame]------ mtexturerectangle. draw(mMVPMatrix,textureId); // Use textures to drawCopy the code


2. Level 2: Rectangular texture

This is a send points, no other, coordinate change on the line

Static float sCoo [] = {/ / in anticlockwise order - c, c, f 0.0, / / p0 - c - c and 0.0 f / / p1, c - c, 0.0 f, / / p2 c, c, f 0.0, / / p3}; Private final float[] textureCoo = {0.0f,0.0f, 0.0f,1.0f, 1.0f,1.0f, 0.0f,1.0f, 1.0f,1.0f, 0.0f,1.0f, 1.0f,0.0f, 1.0f,1.0f,}; Private short[] idx = {1, 2, 3, 0, 1, 3,};Copy the code

If you are interested, you can move the point of the map coordinate system and have a look at it


NPC: Congratulations to the brave man who conquered the eighth instale. please use your cube to open the black Dragon gate

Since then, you will formally step into the black dragon territory, I wish you a smooth journey to the cube embedded in the door, the door opened, in front of the unexpectedly…

OK, this episode is over. Stay tuned for our next episode, "Light of the Pyro.

Postscript: Jie wen standard

1. Growth record and Errata of this paper
Program source code The date of note
V0.1 – making The 2018-1-11 The gl-ES Saga of Android Multimedia episode 2 – Puzzle Cube
2. More about me
Pen name QQ WeChat hobby
Zhang Feng Jie te Li 1981462002 zdl1994328 language
My lot My Jane books I’m the nuggets Personal website