OpenglES2.0 for Android: Another talk about texture mapping

Source: Internet
Author: User

OpenglES2.0 for Android: Further discussion on texture mapping preface
In the previous section we implemented a simple texture mapping example-a simple map, this section we do some slightly more complicated examples, and finally give us a texture in front of the cube.

Texture stretching
Repeat stretch mode
This is a frequently used texture stretching method, often used to draw a number of repeating elements, such as when we are in the game to draw a grid-style map. Using the repeated stretching method allows the texture to be flattened according to the target
The size of the polygon is automatically repeated so that neither the effect of the texture map nor the memory can be saved. As shown in the following:


The implementation is very simple, we go back to the previous section of the project, find our texture of the tool class Texturehelper.java, modified as follows (Texturehelper.java):
Package Com.cumt.utils;import Android.content.context;import Android.graphics.bitmap;import Android.graphics.bitmapfactory;import Android.opengl.gles20;import Android.opengl.glutils;import Android.util.Log ;p Ublic class Texturehelper {public static final String TAG = "Texturehelper";p ublic static int loadtexture (Context contex T,int Resourceid,boolean isrepeat) {/* * First step: Create texture Object */final int[] Textureobjectid = new int[1];//used to store returned texture objects Idgles20.glge Ntextures (1,textureobjectid, 0); if (textureobjectid[0] = = 0) {//If return is 0, the creation fails if (Loggerconfig.on) {LOG.W (TAG, "Could not Generate a new Opengl texture object ");} return 0;} /* * Step two: Load the bitmap data and bind to the texture */final bitmapfactory.options Options = new Bitmapfactory.options (); options.inscaled = False;//ope NGL requires a non-compressed form of raw Data final Bitmap Bitmap = Bitmapfactory.decoderesource (Context.getresources (), resourceId, options); Bitmap = = null) {if (Loggerconfig.on) {LOG.W (TAG, "ResourceId:" +resourceid+ "could not being decoded");} Gles20.gldeletetextures (1, textureobjectid, 0); return 0;}gles20.glbindtexture (gles20.gl_texture_2d,textureobjectid[0]);//bind by Texture ID if (isrepeat) {Gles20.gltexparameterf (gles20.gl_texture_2d, gles20.gl_texture_wrap_s, gles20.gl_repeat); Gles20.gltexparameterf (gles20.gl_texture_2d, gles20.gl_texture_wrap_t, gles20.gl_repeat);} /* * Step three: Set texture filtering *///set to three linear filter gles20.gltexparameteri (gles20.gl_texture_2d, GLES20.GL_TEXTURE_MIN_FILTER,GLES20.GL _linear_mipmap_linear)///set to double linear filter gles20.gltexparameteri (gles20.gl_texture_2d, Gles20.gl_texture_mag_filter, Gles20.gl_linear);/* * Fourth step: Load texture to OpenGL and return ID */glutils.teximage2d (gles20.gl_texture_2d, 0, bitmap, 0); Bitmap.recycle ( ); Gles20.glgeneratemipmap (gles20.gl_texture_2d); return textureobjectid[0];}}

We have only made two changes, first loadtexture a new Boolean parameter isrepeat, the following more Isrepeat value to determine whether to set a repeating stretch. If Isrepeat is true, the call is:
Gles20.gltexparameterf (gles20.gl_texture_2d, gles20.gl_texture_wrap_s, gles20.gl_repeat);
Gles20.gltexparameterf (gles20.gl_texture_2d, gles20.gl_texture_wrap_t, gles20.gl_repeat);

The set texture is set to repeat extrude in S and T latitude.
Let's set the drawing 4*4, we just change the vertex coordinates in Square.java to the texture coordinates as follows:
Rectangle vertex coordinate  and texture coordinate    static float squarecoords[] = {//Draw as a triangular fan    //x     y       s   t    -0.5f,  0.5f,  0, 0,//top left          0.5f,  0.5f  ,  4, 0,//top right          0.5f, -0.5f  , 4,  4,//Bottom Right         -0.5f, -0.5f  ,  0, 4};  Bottom Left  

At this point our texture is in the s-axis range of 0 to 4, and the T-axis is 0 to 4, so the texture repeats four times in the s-axis direction and repeats four times in the T-axis direction. The following uses the Loadtexture method when passed in true, run to see the above effect.
Intercept Stretch mode
Change the code under the IF (isrepeat) condition in the texture tool class above to:
if (isrepeat) {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);}
The other code does not change. We set the s-axis direction and the T-axis direction to intercept the stretch, which works as follows:


It can be seen that the edges of the texture in the s-axis direction and the T-axis are stretched. Of course, you can also set the direction of the s-axis to repeat stretching, in the T-axis direction for the intercept stretch.
if (isrepeat) {gles20.gltexparameterf (gles20.gl_texture_2d, gles20.gl_texture_wrap_s, gles20.gl_repeat); Gles20.gltexparameterf (gles20.gl_texture_2d, gles20.gl_texture_wrap_t, Gles20.gl_clamp_to_edge);}

;
Cube Add texture
In front of the two-dimensional graphic mapping, in fact, for three-dimensional objects are the same. The key is to find the relationship between vertex coordinates and texture coordinates. Next we'll add textures to the cube we last painted.
First, copy the texture tool class from our previous section to the cube's tool class, modifying the vertex shader and fragment shader as follows:
Vertex_shader_cube.glsluniform mat4 u_matrix;attribute vec4 a_position;  Attribute VEC2 a_texturecoordinates;varying vec2 v_texturecoordinates;void Main ()                    {                                  gl_position = U_matrix * A_ Position;    V_texturecoordinates = a_texturecoordinates;}  

Fragment_shader_cube.glslprecision Mediump float; Uniform sampler2d u_textureunit;       Varying vec2 v_texturecoordinates;void main ()                    {                                  Gl_fragcolor = texture2d (U_textureunit, v_texturecoordinates );                                       }

Finally, we modify our cube class, add texture coordinates, pass in texture coordinate data, and so on, as in the previous section, we look directly at the code:
Package Com.cumt.shape;import static Android.opengl.gles20.gl_texture0;import static android.opengl.GLES20.GL_ Texture_2d;import static android.opengl.gles20.glactivetexture;import static android.opengl.GLES20.glBindTexture; Import static Android.opengl.gles20.gluniform1i;import Java.nio.bytebuffer;import Java.nio.byteorder;import Java.nio.floatbuffer;import Com.cumt.openglescubewen.r;import Com.cumt.utils.matrixstate;import Com.cumt.utils.shaderhelper;import Com.cumt.utils.textresourcereader;import Com.cumt.utils.texturehelper;import Android.content.context;import Android.opengl.gles20;public class Cube {//vertex coordinates private floatbuffer vertexbuffer; Private Context context;//float type of bytes private static final int bytes_per_float = 4;//Total 72 vertex coordinates, each polygon contains 12 vertex coordinates private    static final int position_component_count = The number of coordinates of each vertex in the 6*12;//array private static final int coords_per_vertex = 3; Number of values per color in the color array private static final string a_position = "A_position";p rivate static final String U_matrix = "U_matrix";p rivate int umatrixlocation;private int apositionlocation;private int program;private static final int texture_ Coordiantes_component_count = 2; A texture coordinate contains the number of elements private static final int STRIDE = (Coords_per_vertex + texture_coordiantes_component_count) * Bytes_per_ Float;private static final String a_texture_coordinates = "a_texturecoordinates";//Texture private static final string u_    Texture_unit = "U_textureunit";//texture private int utextureunitlocation;    private int atexturecoordinates;        private int texture; static float vertices[] = {//x Y Z S t//front 0,0,1.0f, 0.5f,0.5f, 1.0f,1.0f,1.0f, 1.0f,0, -1.0f,           1.0f,1.0f, 0,0, 0,0,1.0f, 0.5f,0.5f, -1.0f,1.0f,1.0f, 0,0, -1.0f,-1.0f,1.0f, 0,1.0f, 0,0,1.0f,    0.5f,0.5f, -1.0f,-1.0f,1.0f, 0,1.0f, 1.0f,-1.0f,1.0f, 1.0f,1.0f, 0,0,1.0f, 0.5f,0.5f, 1.0f,-1.0f,1.0f, 1.0f,1.0f, 1.0f,1.0f,1.0f, 1.0f,0,//back 0,0,-1.0f, 0.5f,0.5f, 1.0f,1.0f,-1.0f, 1.0f,0, 1.0f,-1.0f,-1.0f, 1.0f,1.0f, 0,0,-1.0f, 0.5f,0.5f, 1.0f,-1.0f,-1.0f, 1.0f,1.0f,    -1.0f,-1.0f,-1.0f, 0,1.0f, 0,0,-1.0f, 0.5f,0.5f, -1.0f,-1.0f,-1.0f, 0,1.0f, -1.0f,1.0f,-1.0f, 0, 0, 0,0,-1.0f, 0.5f,0.5f, -1.0f,1.0f,-1.0f, 0,0, 1.0f,1.0f,-1.0f, 1.0f,0,//left -1.0f,0,0, 0. 5f,0.5f, -1.0f,1.0f,1.0f, 1.0f,0, -1.0f,1.0f,-1.0f, 0,0, -1.0f,0,0, 0.5f,0.5f, -1.0f,1.0f,-1.0f , 0,0, -1.0f,-1.0f,-1.0f, 0,1.0f, -1.0f,0,0, 0.5f,0.5f, -1.0f,-1.0f,-1.0f, 0,1.0f, -1.0f,-1.0f,1. 0f, 1.0f,1.0f, -1.0f,0,0, 0.5f,0.5f, -1.0f,-1.0f,1.0f, 1.0f,1.0f, -1.0f,1.0f,1.0f, 1.0f,0,//Right Face 1.0f,0,0, 0.5f,0.5f, 1.0f,1.0f,1.0f, 0,0, 1.0f,-1.0f,1.0f, 0,1.0f, 1.0f,0,0, 0. 5f,0.5f, 1.0f,-1.0f,1.0f, 0,1.0f, 1.0f,-1.0f,-1.0f, 1.0f,1.0f, 1.0f,0,0, 0.5f,0.5f, 1.0f,-1.0f, -1.0f, 1.0f,1.0f, 1.0f,1.0f,-1.0f, 1.0f,0, 1.0f,0,0, 0.5f,0.5f, 1.0f,1.0f,-1.0f, 1.0f,0, 1.0f,1.0f,1.0f, 0, 0,        Above 0,1.0f,0, 0.5f,0.5f, 1.0f,1.0f,1.0f, 1.0f,0, 1.0f,1.0f,-1.0f, 1.0f,1.0f, 0,1.0f,0, 0.5f,0.5f, 1.0f,1.0f,-1.0f, 1.0f,1.0f, -1.0f,1.0f,-1.0f, 0,1.0f, 0,1.0f,0, 0.5f,0.5f, -1.0f, 1.0f,-1.0f, 0,1.0f, -1.0f,1.0f,1.0f, 0,0, 0,1.0f,0, 0.5f,0.5f, -1.0f,1.0f,1.0f, 0,0, 1.0f,1.0f, 1.0f, 1.0f,0,//0,-1.0f,0, 0.5f,0.5f, 1.0f,-1.0f,1.0f, 1.0f,0, -1.0f,-1.0f,1.0f, 0, 0, 0,-1.    0f,0, 0.5f,0.5f, -1.0f,-1.0f,1.0f, 0,0, -1.0f,-1.0f,-1.0f, 0,1.0f, 0,-1.0f,0, 0.5f,0.5f, -1.0f,-1.0f,-1.0f, 0,1.0f, 1.0f,-1.0f,-1.0f, 1.0f,1.0f, 0,-1.0f,0, 0.5f,0.5f, 1.0f,-1.0f,-1.0f, 1.0 f,1.0f, 1.0f,-1.0f,1.0f, 1.0f,0,};p ublic Cube (context context) {This.context = Context;vertexbuffer = Bytebuffer. Allocatedirect (vertices.Length * bytes_per_float). Order (Byteorder.nativeorder ()). Asfloatbuffer ();        Add coordinates to the Floatbuffer vertexbuffer.put (vertices);                Set buffer, starting at the first coordinate to read vertexbuffer.position (0);        Getprogram (); apositionlocation = Gles20.glgetattriblocation (program, a_position); umatrixlocation = Gles20.glgetuniformlocation ( program, U_matrix); atexturecoordinates = Gles20.glgetattriblocation (program, a_texture_coordinates); utextureunitlocation = Gles20.glgetattriblocation (program, u_texture_unit); TEXTURE = Texturehelper.loadtexture (        context, r.drawable.umei,false);//Set the active texture unit to texture unit 0.        Glactivetexture (GL_TEXTURE0);        Bind the texture to this unit.        Glbindtexture (gl_texture_2d, TEXTURE);         Tell the texture uniform sampler to use this texture in the shader by//telling it to read from texture unit 0.        Gluniform1i (utextureunitlocation, 0); ---------incoming vertex data data gles20.glvertexattribpointer(Apositionlocation, Coords_per_vertex,gles20.gl_float, False, STRIDE, vertexbuffer); Gles20.glenablevertexattribarray (apositionlocation);//The setting starts reading from the second element because the texture coordinates are vertexbuffer.position starting from the second element ( Coords_per_vertex); Gles20.glvertexattribpointer (Atexturecoordinates, Texture_coordiantes_component_count,gles20.gl_float, False, STRIDE, VertexBuffer); Gles20.glenablevertexattribarray (atexturecoordinates);} Get program private void Getprogram () {//Get vertex shader text String Vertexshadersource = Textresourcereader.readtextfilefro    Mresource (context, r.raw.vertex_shader_cube); Get fragment shader text string fragmentshadersource = Textresourcereader.readtextfilefromresource (Context, R.raw.fragment_ Shader_cube);//Get program Idprogram = Shaderhelper.buildprogram (Vertexshadersource, Fragmentshadersource);    Gles20.gluseprogram (program); } public void Draw () {GLES20.GLUNIFORMMATRIX4FV (umatrixlocation, 1, False, Matrixstate.getfinalmatrix (), 0);    Gles20.gldrawarrays (gles20.gl_triangles, 0, Position_component_count);}} 

The result of the operation is as follows (screen orientation is set to landscape):


Here, as mentioned above, the key is to find the coordinates of the vertex coordinate with the texture of the corresponding. We take the positive as an example, we actually need to determine the texture coordinates of the five vertices according to the way we draw them, the five vertices are :------------------------------------------------------------------------------------------------------------------------ -----------------------------Upper left corner (-1, -1,1) lower left corner ( -1,1,1) Upper right corner (1,-1, 1)Lower right Corner (1, 1, 1) center point (0, 0, 1)---------------------------------------------------------------------------------------- The coordinates of the corresponding texture of the--------------------------------------------------------------are: (0, 1) (0, 0) (1, 1) (1, 0), 0.5, 0 .5) Note that the St coordinate of the upper-left corner of the texture is not (0,0) but (0,1) otherwise we draw the texture to be drawn upside-down.



OpenglES2.0 for Android: Re-talk about texture mapping

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.