OpenglES2.0 for Android: Draw a rectangle.
in the previous section we drew a triangle, and we completed the rectangle drawing on the basis of the previous section.
OK, start doing it, first create a new class--square (Square.java) under the shape directory in the previous section of the project, and then define the coordinates of the four vertices of the rectangle, at which point the code is as follows (Square.java):
<span style= "FONT-SIZE:14PX;" >package Com.cumt.shape;public class Square {//float type bytes private static final int bytes_per_float = 4;//The number of coordinates for each vertex in the array c4/>static final int coords_per_vertex = 2;//rectangle vertex coordinate static float squarecoords[] = { -0.5f, 0.5f, //top left - 0.5f, -0.5f, //Bottom left 0.5f, -0.5f, //Bottom right 0.5f, 0.5f};//Top right}</span>
As in the previous section, we need to convert the data of float[] to Floatbuffer, where the code is as follows (Square.java):
<span Style= "FONT-SIZE:14PX;" >package com.cumt.shape;import java.nio.bytebuffer;import Java.nio.byteorder;import java.nio.FloatBuffer;import Android.content.context;public class Square {private Context context;//float type of bytes private static final int bytes_per_ FLOAT = number of coordinates for each vertex in the 4;//array static final int coords_per_vertex = 2;//rectangle vertex coordinate static float squarecoords[] = { -0.5f, 0.5f, Top left-0.5f, -0.5f,//Bottom left 0.5f, -0.5f,//Bottom right 0.5f, 0.5f}; Top Rightprivate Floatbuffer vertexbuffer;public Square (context context) {This.context = Context;vertexbuffer = Bytebu Ffer. Allocatedirect (Squarecoords.length * bytes_per_float). Order (Byteorder.nativeorder ()). Asfloatbuffer (); Add coordinates to the Floatbuffer vertexbuffer.put (squarecoords); Set buffer, starting at the first coordinate to read vertexbuffer.position (0);}} </span>
The next step is to write the shader, read and compile, link, get the program ID of the operation, we still use the previous section of the shader is good, the other process is the same as the previous section, here is no longer explained,copy it and use it ~ ~, of course, you want to further encapsulate the shader operation better. Now the Code (SQUARE.JAVA):
<span style= "FONT-SIZE:14PX;" >package com.cumt.shape;import java.nio.bytebuffer;import Java.nio.byteorder;import java.nio.FloatBuffer;import Com.cumt.openglestwo_test_one. R;import Com.cumt.utils.shaderhelper;import Com.cumt.utils.textresourcereader;import Android.content.Context; Import Android.opengl.gles20;public class Square {private Context context;//float type of bytes private static final int Bytes_ per_float = number of coordinates for each vertex in the 4;//array static final int coords_per_vertex = 2;//rectangle vertex coordinate static FLOAT squarecoords[] = { -0.5f, 0.5 F,//Top left-0.5f, -0.5f,//Bottom left 0.5f, -0.5f,//Bottom right 0.5f, 0.5f}; Top Rightprivate floatbuffer vertexbuffer;//------------First step: Define two tags, the same as the variable names in the shader Code,//------------The first is the variable name of the vertex shader, The second one is the variable name of the fragment shader private static final string a_position = "A_position";p rivate static final String u_color = "U_color";//----- -------The second step: Define two IDs, we are the pass ID to achieve the transfer of data, this is similar to the previous//------------the meaning of the ID of the program, the private int ucolorlocation;private int apositionlocation;private int program;//Save program's Idpublic Square (context context) {This.context = context; VertexBuffer = Bytebuffer. Allocatedirect (Squarecoords.length * bytes_per_float). Order (Byteorder.nativeorder ()) . Asfloatbuffer (); Add coordinates to the Floatbuffer vertexbuffer.put (squarecoords); Set buffer, starting at the first coordinate to read vertexbuffer.position (0); Getprogram (); ----------Step Three: Get these two IDs, which are obtained through the previously defined tags ucolorlocation = gles20.glgetuniformlocation (program, u_color); apositionloc ation = Gles20.glgetattriblocation (program, a_position);//---------Fifth step: Incoming data Gles20.glvertexattribpointer ( Apositionlocation, Coords_per_vertex,gles20.gl_float, False, 0, vertexbuffer); Gles20.glenablevertexattribarray (apositionlocation);} Get program private void Getprogram () {//Get vertex shader text String Vertexshadersource = Textresourcereader.readtextfilefro Mresource (context, r.raw.simple_vertex_shader); Get fragment shader text string fragmentshadersource = TextresourceReader.readtextfilefromresource (context, r.raw.simple_fragment_shader);//Get program's Idprogram = Shaderhelper.buildprogram (Vertexshadersource, Fragmentshadersource); Gles20.gluseprogram (program); }}</span>
The next step is to draw, which is the focus of our section, how do we draw a rectangle? We know that there are 3 types of drawing supported in Opengles: points, lines, triangles, and one or more drawing methods for each class. So let's draw a rectangle, is there a variety of ways to draw it? The answer is yes. We'll first draw the rectangle in the way of the line segment.
several ways to draw a segment:
Gl_lines: The incoming vertices are plotted in order, 22 are organized into segments, and if the number of vertices is odd, the last vertex is automatically ignored.
Gl_line_strip: Draw incoming vertices in sequence , sequentially
Gl_line_loop: The incoming vertices are drawn sequentially in order, but the last vertex is connected to the first, forming a segment ring
we will draw this rectangle in the Gl_line_loop way, add the Draw method, and the code is as follows (Square.java):
<span style= "FONT-SIZE:14PX;" >package com.cumt.shape;import java.nio.bytebuffer;import Java.nio.byteorder;import java.nio.FloatBuffer;import Com.cumt.openglestwo_test_one. R;import Com.cumt.utils.shaderhelper;import Com.cumt.utils.textresourcereader;import Android.content.Context; Import Android.opengl.gles20;public class Square {private Context context;//float type of bytes private static final int Bytes_ per_float = number of coordinates for each vertex in the 4;//array static final int coords_per_vertex = 2;//rectangle vertex coordinate static FLOAT squarecoords[] = { -0.5f, 0.5 F,//Top left-0.5f, -0.5f,//Bottom left 0.5f, -0.5f,//Bottom right 0.5f, 0.5f}; Top Rightprivate floatbuffer vertexbuffer;//------------First step: Define two tags, the same as the variable names in the shader Code,//------------The first is the variable name of the vertex shader, The second one is the variable name of the fragment shader private static final string a_position = "A_position";p rivate static final String u_color = "U_color";//----- -------The second step: Define two IDs, we are the pass ID to achieve the transfer of data, this is similar to the previous//------------the meaning of the ID of the program, the private int ucolorlocation;private int apositionlocation;private int program;//Save program's id//---------Fourth step: Define the number of coordinate elements, there are three vertices private static final int Position_component_count = 4;public Square (context context) {This.context = Context;vertexbuffer = Bytebuffer. Allocate Direct (Squarecoords.length * bytes_per_float). Order (Byteorder.nativeorder ()). Asfloatbuffer (); Add coordinates to the Floatbuffer vertexbuffer.put (squarecoords); Set buffer, starting at the first coordinate to read vertexbuffer.position (0); Getprogram (); ----------Step Three: Get these two IDs, which are obtained through the previously defined tags ucolorlocation = gles20.glgetuniformlocation (program, u_color); apositionloc ation = Gles20.glgetattriblocation (program, a_position);//---------Fifth step: Incoming data Gles20.glvertexattribpointer ( Apositionlocation, Coords_per_vertex,gles20.gl_float, False, 0, vertexbuffer); Gles20.glenablevertexattribarray (apositionlocation);} Get program private void Getprogram () {//Get vertex shader text String Vertexshadersource = Textresourcereader.readtextfilefro Mresource (Context, R.raw.simple_vertex_shader); Get fragment shader text string fragmentshadersource = Textresourcereader.readtextfilefromresource (Context, R.raw.simple_ Fragment_shader);//Get program Idprogram = Shaderhelper.buildprogram (Vertexshadersource, Fragmentshadersource); Gles20.gluseprogram (program); }//Draw public void Draw () {gles20.gluniform4f (ucolorlocation, 0.0f, 0.0f, 1.0f, 1.0f) in Gl_line_loop mode; Gles20.gldrawarrays (gles20.gl_line_loop, 0, Position_component_count); }}</span>
Finally create the object in Myrender, call draw to draw, the code is as follows (Myrender.java):
<span style= "FONT-SIZE:14PX;" >package Com.cumt.render;import Javax.microedition.khronos.egl.eglconfig;import Javax.microedition.khronos.opengles.gl10;import Com.cumt.shape.square;import Com.cumt.shape.Triangle;import Android.content.context;import Android.opengl.glsurfaceview.renderer;import android.util.log;import Static Android.opengl.gles20.glclear;import static Android.opengl.gles20.glclearcolor;import Static Android.opengl.gles20.glviewport;import static Android.opengl.gles20.gl_color_buffer_bit;public class MyRender Implements Renderer {private Context context;public Myrender (context context) {This.context = context;} Defines the triangle object triangle triangle; Square square;public void onsurfacecreated (GL10 gl, EGLConfig config) {log.w ("Myrender", "onsurfacecreated");//TODO Auto-generated method Stub//first: Set the color to clear the screen, the first three parameters corresponding to red and green blue, the last one corresponding Alphaglclearcolor (0.0f, 0.0f, 0.0f, 0.0f);//triangle = New Triangle (context); square = new Square (context);} public void onsurfacechanged (GL10 gl, int width, int Height) {log.w ("Myrender", "onsurfacechanged");//TODO auto-generated method Stub//second: Set viewport size, That tells OpenGL what surface size Glviewport (0,0,width,height) can be used for rendering;} public void Ondrawframe (GL10 gl) {LOG.W ("Myrender", "ondrawframe");//TODO auto-generated method Stub//third: Empty screen, Erases all colors on the screen, fills the entire screen glclear (gl_color_buffer_bit) with the color defined previously glclearcolor,//Draws the triangle//triangle.draw (); Square.draw ();}} </span>
Operation Result:
Well, it seems unclear, we change the background color to white, the Myrender.java onsurfacecreated method of Glclearcolor (0.0f, 0.0f, 0.0f, 0.0f) to Glclearcolor (1 .0f, 1.0f, 1.0f, 0.0f);
run it again:
See we actually draw a rectangular box with no coloring in the middle. Let's use the triangle to draw the way.
several ways to draw triangles:
Gl_trianggles: Draws the incoming vertices into a triangle that doesn't consist of 3 groups
Gl_triangle_trip: The incoming vertices are made in the order of three groups of triangles, the last two vertices of the first three vertices as the top two vertices of the next triangle,For example, there are V0 v1 v2 v3 Four vertex order arrangement, then V0 v1 v2 form a triangle, v1,v2,v3 form a triangle.
Gl_triangle_fan: The form of a triangular fan that makes the first vertex of the incoming vertex data the center point, and the other points as the edge points to draw a series of adjacent triangles that make up the sector.
We first use the first way to draw this rectangle, at this time we need to draw two triangles, so we need 6 vertex data, we copy the Square.java, renamed to Square2.java,first modify the vertex data, then modify the drawing method, the code and the steps (see */*/comment in the code) as follows (Square2.java):
<span style= "FONT-SIZE:14PX;" >package com.cumt.shape;import java.nio.bytebuffer;import Java.nio.byteorder;import java.nio.FloatBuffer;import Com.cumt.openglestwo_test_one. R;import Com.cumt.utils.shaderhelper;import Com.cumt.utils.textresourcereader;import Android.content.Context; Import Android.opengl.gles20;public class Square2 {private Context context;//float type bytes private static final int Bytes_ per_float = number of coordinates of each vertex in the 4;//array static final int coords_per_vertex = 2; /*------------------First step: Modify vertex data-------------------------*///rectangle vertex coordinates static float squarecoords[] = { -0.5f, 0.5f,//Top Left 0.5f, 0.5f,//Top right-0.5f, -0.5f,//Bottom left-0.5f, -0.5f,//Bottom left 0.5f, -0.5f,// Bottom right 0.5f, 0.5f}; Top Rightprivate Floatbuffer vertexbuffer; ------------The first is the variable name of the vertex shader, the second is the variable name of the fragment shader private static final String a_position = "A_position";p rivate static final String U_color = "U_color";//------------a private int that has the same meaning as the program's ID ucolorlocation;private int apositionlocation;private int program;//Save program's id/*------------------the second step: Modify the number of vertices-------------------------*/private static final int position_component_count = 6;public Square2 (context context) {This.context = Context;vertexbuffer = Bytebuffer. Allocatedirect (Squarecoords.length * BYTES_PER_FLOAT). Order (Byte Order.nativeorder ()). Asfloatbuffer (); Add coordinates to the Floatbuffer vertexbuffer.put (squarecoords); Set buffer, starting at the first coordinate to read vertexbuffer.position (0); Getprogram (); ucolorlocation = Gles20.glgetuniformlocation (program, u_color); apositionlocation = Gles20.glgetattriblocation ( program, a_position); Gles20.glvertexattribpointer (Apositionlocation, Coords_per_vertex,gles20.gl_float, False, 0, VertexBuffer); Gles20.glenablevertexattribarray (apositionlocation);} Get program private void Getprogram () {//Get vertex shader text String Vertexshadersource = Textresourcereader.readtextfilefro Mresource (Context, R.raw.simpLe_vertex_shader); Get fragment shader text string fragmentshadersource = Textresourcereader.readtextfilefromresource (Context, R.raw.simple_ Fragment_shader);//Get program Idprogram = Shaderhelper.buildprogram (Vertexshadersource, Fragmentshadersource); Gles20.gluseprogram (program); //Gl_line_loop Draw public void Draw () {gles20.gluniform4f (ucolorlocation, 0.0f, 0.0f, 1.0f, 1.0f);/*---------- --------Step Three: Modify the Drawing Method-------------------------*/gles20.gldrawarrays (gles20.gl_triangles, 0, Position_component_ COUNT); }}</span>
Then in the Myrender class you can new the object and call its draw method to draw, run the effect:
Although this approach satisfies our needs, but results in redundancy of the data, we can use the latter two plotting methods to solve this problem. Here are the data and draw methods for the latter two ways:
Gl_triangle_strip Way:
<span style= "FONT-SIZE:14PX;" >//gl_triangle_strip static float squarecoords[] = { -0.5f, 0.5f, //top left 0.5f, 0.5f , Top right -0.5f, -0.5f , //Bottom left 0.5f, -0.5f };//bottom right private static final I NT Position_component_count = 4; public void Draw () {gles20.gluniform4f (ucolorlocation, 0.0f, 0.0f, 1.0f, 1.0f); Gles20.gldrawarrays (Gles20.gl_triangle_strip, 0, Position_component_count); } </span>
Gl_triangle_fan Way:
<span style= "FONT-SIZE:14PX;" >//gl_triangle_fan to note the order of points (try bottom right and bottom left swap locations to see if the drawing is still a rectangle) static float squarecoords[] = { -0.5f, 0.5f, //top left 0.5f, 0.5f ,//top right 0.5f, -0.5f ,//Bottom right -0.5f, -0.5f< c9/>}; Bottom left private static final int position_component_count = 4; public void Draw () {gles20.gluniform4f (ucolorlocation, 0.0f, 0.0f, 1.0f, 1.0f); Gles20.gldrawarrays (Gles20.gl_triangle_fan, 0, Position_component_count); } </span>
OpenglES2.0 for Android: Draw a rectangle.