{"id":643,"date":"2011-10-06T21:37:00","date_gmt":"2011-10-06T21:37:00","guid":{"rendered":"http:\/\/www.javacodegeeks.com\/2012\/10\/android-game-development-opengl-texture-mapping.html"},"modified":"2012-10-21T20:31:36","modified_gmt":"2012-10-21T20:31:36","slug":"android-game-development-opengl-texture","status":"publish","type":"post","link":"https:\/\/www.javacodegeeks.com\/2011\/10\/android-game-development-opengl-texture.html","title":{"rendered":"Android Game Development \u2013 OpenGL Texture Mapping"},"content":{"rendered":"<div dir=\"ltr\" style=\"text-align: left\">In the previous two articles (<a href=\"http:\/\/www.javacodegeeks.com\/2011\/09\/android-game-development-switching-from.html\">article 1<\/a> and <a href=\"http:\/\/www.javacodegeeks.com\/2011\/10\/android-game-development-displaying.html\">article 2<\/a>) I have tried to introduce OpenGL ES on android. Now let\u2019s take it further and build on them. In this article we will create a billboard (which is a square) and we will apply a texture onto it. A texture is nothing more than a bitmap image. When we work in 2D we set the Z coordinate to 0. We\u2019ll cover 3D later. This is very useful to use in 2D games and is the preferred way to display images using OpenGL. It is very fast indeed.<\/p>\n<p>In the previous articles we managed to display triangles. How to display a square then? A square is composed of 2 triangles.<\/p>\n<p>The following diagram shows you this:<\/p>\n<table align=\"center\" cellpadding=\"0\" cellspacing=\"0\" class=\"tr-caption-container\" style=\"margin-left: auto;margin-right: auto;text-align: center\">\n<tbody>\n<tr>\n<td style=\"text-align: center\"><a href=\"http:\/\/obviam.net\/wp-content\/uploads\/2011\/01\/Square-Triangles.png\"><img decoding=\"async\" border=\"0\" src=\"http:\/\/obviam.net\/wp-content\/uploads\/2011\/01\/Square-Triangles.png\" \/><\/a><\/td>\n<\/tr>\n<tr>\n<td class=\"tr-caption\" style=\"text-align: center\"><span class=\"Apple-style-span\" style=\"font-size: small\">Square from Triangles<\/span><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>There is an interesting thing to note here. The square is <strong>ABDC<\/strong> instead of the usual <strong>ABCD<\/strong>. Why is that? Because of how OpenGL chains triangles together.<\/p>\n<p>What you see here is a <em><a href=\"http:\/\/en.wikipedia.org\/wiki\/Triangle_strip\">triangle strip<\/a><\/em>. A triangle strip is a series of connected triangles, 2 triangles in our case.<\/p>\n<p>OpenGL draws the following triangle strip (which is a square) using the vertices in the following order:<\/p>\n<p><strong>Triangle 1:<\/strong> V1 -&gt; V2 -&gt; V3<\/p>\n<p><strong>Triangle 2:<\/strong> V3 -&gt; V2 -&gt; V4<\/p>\n<table align=\"center\" cellpadding=\"0\" cellspacing=\"0\" class=\"tr-caption-container\" style=\"margin-left: auto;margin-right: auto;text-align: center\">\n<tbody>\n<tr>\n<td style=\"text-align: center\"><a href=\"http:\/\/obviam.net\/wp-content\/uploads\/2011\/01\/Square-Triangles-2.png\"><img decoding=\"async\" border=\"0\" src=\"http:\/\/obviam.net\/wp-content\/uploads\/2011\/01\/Square-Triangles-2.png\" \/><\/a><\/td>\n<\/tr>\n<tr>\n<td class=\"tr-caption\" style=\"text-align: center\"><span class=\"Apple-style-span\" style=\"font-size: small\">Triangle Strip<\/span><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>It draws the first triangle using the vertices in order, then it takes the last vertex from the previous triangle and uses the last side of the triangle as the basis for the new triangle.<\/p>\n<p>This also has benefits: we eliminate redundant data from the memory.<\/p>\n<p>Grab the <a href=\"http:\/\/obviam.net\/source_code\/obviam.opengl.p02.tgz\">project<\/a> from the previous article and create a new class called <strong>Square<\/strong>.<\/p>\n<p>If you compare the <strong>Square<\/strong> class with the <strong>Triangle<\/strong> class, you will notice <em>just one<\/em> difference:<\/p>\n<pre class=\"brush: java; highlight: [13,14,15,16,17,18];\">package net.obviam.opengl;\r\n\r\nimport java.nio.ByteBuffer;\r\nimport java.nio.ByteOrder;\r\nimport java.nio.FloatBuffer;\r\n\r\nimport javax.microedition.khronos.opengles.GL10;\r\n\r\npublic class Square {\r\n\r\n\tprivate FloatBuffer vertexBuffer;\t\/\/ buffer holding the vertices\r\n\r\n\tprivate float vertices[] = {\r\n\t\t\t-1.0f, -1.0f,  0.0f,\t\t\/\/ V1 - bottom left\r\n\t\t\t-1.0f,  1.0f,  0.0f,\t\t\/\/ V2 - top left\r\n\t\t\t 1.0f, -1.0f,  0.0f,\t\t\/\/ V3 - bottom right\r\n\t\t\t 1.0f,  1.0f,  0.0f\t\t\t\/\/ V4 - top right\r\n\t};\r\n\r\n\tpublic Square() {\r\n\t\t\/\/ a float has 4 bytes so we allocate for each coordinate 4 bytes\r\n\t\tByteBuffer vertexByteBuffer = ByteBuffer.allocateDirect(vertices.length * 4);\r\n\t\tvertexByteBuffer.order(ByteOrder.nativeOrder());\r\n\r\n\t\t\/\/ allocates the memory from the byte buffer\r\n\t\tvertexBuffer = vertexByteBuffer.asFloatBuffer();\r\n\r\n\t\t\/\/ fill the vertexBuffer with the vertices\r\n\t\tvertexBuffer.put(vertices);\r\n\r\n\t\t\/\/ set the cursor position to the beginning of the buffer\r\n\t\tvertexBuffer.position(0);\r\n\t}\r\n\r\n\t\/** The draw method for the square with the GL context *\/\r\n\tpublic void draw(GL10 gl) {\r\n\t\tgl.glEnableClientState(GL10.GL_VERTEX_ARRAY);\r\n\r\n\t\t\/\/ set the colour for the square\r\n\t\tgl.glColor4f(0.0f, 1.0f, 0.0f, 0.5f);\r\n\r\n\t\t\/\/ Point to our vertex buffer\r\n\t\tgl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);\r\n\r\n\t\t\/\/ Draw the vertices as triangle strip\r\n\t\tgl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length \/ 3);\r\n\r\n\t\t\/\/Disable the client state before leaving\r\n\t\tgl.glDisableClientState(GL10.GL_VERTEX_ARRAY);\r\n\t}\r\n}\r\n<\/pre>\n<p>The difference is in the highlighted lines (13-18). That\u2019s right, we\u2019ve added one more vertex to the <strong>vertices<\/strong> array.<\/p>\n<p>Now change the <strong>GlRenderer<\/strong> so instead of a <strong>Triangle<\/strong> we use a <strong>Square<\/strong>.<\/p>\n<pre class=\"brush: java;\">package net.obviam.opengl;\r\n\r\nimport javax.microedition.khronos.egl.EGLConfig;\r\nimport javax.microedition.khronos.opengles.GL10;\r\n\r\nimport android.opengl.GLU;\r\nimport android.opengl.GLSurfaceView.Renderer;\r\n\r\npublic class GlRenderer implements Renderer {\r\n\r\n\tprivate Square \t\tsquare;\t\t\/\/ the square\r\n\r\n\t\/** Constructor to set the handed over context *\/\r\n\tpublic GlRenderer() {\r\n\t\tthis.square\t\t= new Square();\r\n\t}\r\n\r\n\t@Override\r\n\tpublic void onDrawFrame(GL10 gl) {\r\n\t\t\/\/ clear Screen and Depth Buffer\r\n\t\tgl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);\r\n\r\n\t\t\/\/ Reset the Modelview Matrix\r\n\t\tgl.glLoadIdentity();\r\n\r\n\t\t\/\/ Drawing\r\n\t\tgl.glTranslatef(0.0f, 0.0f, -5.0f);\t\t\/\/ move 5 units INTO the screen\r\n\t\t\t\t\t\t\t\t\t\t\t\t\/\/ is the same as moving the camera 5 units away\r\n\t\tsquare.draw(gl);\t\t\t\t\t\t\/\/ Draw the triangle\r\n\r\n\t}\r\n\r\n\t@Override\r\n\tpublic void onSurfaceChanged(GL10 gl, int width, int height) {\r\n\t\tif(height == 0) { \t\t\t\t\t\t\/\/Prevent A Divide By Zero By\r\n\t\t\theight = 1; \t\t\t\t\t\t\/\/Making Height Equal One\r\n\t\t}\r\n\r\n\t\tgl.glViewport(0, 0, width, height); \t\/\/Reset The Current Viewport\r\n\t\tgl.glMatrixMode(GL10.GL_PROJECTION); \t\/\/Select The Projection Matrix\r\n\t\tgl.glLoadIdentity(); \t\t\t\t\t\/\/Reset The Projection Matrix\r\n\r\n\t\t\/\/Calculate The Aspect Ratio Of The Window\r\n\t\tGLU.gluPerspective(gl, 45.0f, (float)width \/ (float)height, 0.1f, 100.0f);\r\n\r\n\t\tgl.glMatrixMode(GL10.GL_MODELVIEW); \t\/\/Select The Modelview Matrix\r\n\t\tgl.glLoadIdentity(); \t\t\t\t\t\/\/Reset The Modelview Matrix\r\n\t}\r\n\r\n\t@Override\r\n\tpublic void onSurfaceCreated(GL10 gl, EGLConfig config) {\r\n\t}\r\n}\r\n<\/pre>\n<p>Running this will produce the following result:<\/p>\n<table align=\"center\" cellpadding=\"0\" cellspacing=\"0\" class=\"tr-caption-container\" style=\"margin-left: auto;margin-right: auto;text-align: center\">\n<tbody>\n<tr>\n<td style=\"text-align: center\"><a href=\"http:\/\/obviam.net\/wp-content\/uploads\/2011\/01\/Screen-shot-2011-01-26-at-01.58.37.png\"><img decoding=\"async\" border=\"0\" height=\"320\" src=\"http:\/\/obviam.net\/wp-content\/uploads\/2011\/01\/Screen-shot-2011-01-26-at-01.58.37.png\" width=\"220\" \/><\/a><\/td>\n<\/tr>\n<tr>\n<td class=\"tr-caption\" style=\"text-align: center\"><span class=\"Apple-style-span\" style=\"font-size: small\">Triangle Strip forming a Square<\/span><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Examining this, the <strong>draw()<\/strong> method in the <strong>Square<\/strong> class should make sense now.<\/p>\n<pre class=\"brush: java;\">\tpublic void draw(GL10 gl) {\r\n\t\tgl.glEnableClientState(GL10.GL_VERTEX_ARRAY);\r\n\r\n\t\t\/\/ set the colour for the square\r\n\t\tgl.glColor4f(0.0f, 1.0f, 0.0f, 0.5f);\r\n\r\n\t\t\/\/ Point to our vertex buffer\r\n\t\tgl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);\r\n\r\n\t\t\/\/ Draw the vertices as triangle strip\r\n\t\tgl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length \/ 3);\r\n\r\n\t\t\/\/Disable the client state before leaving\r\n\t\tgl.glDisableClientState(GL10.GL_VERTEX_ARRAY);\r\n\t}\r\n<\/pre>\n<p>First we enable OpenGL to use a vertex array for rendering. Our vertex array contains the vertices for our square.<div style=\"display:inline-block; margin: 15px 0;\"> <div id=\"adngin-JavaCodeGeeks_incontent_video-0\" style=\"display:inline-block;\"><\/div> <\/div><\/p>\n<p><strong>gl.glVertexPointer<\/strong> (line 5) tells the opengl renderer from where to take the vertices and of what type they are.<\/p>\n<p>The first parameter tells how many coordinates are used for a vertex. We use 3 (x,y,z). The second parameter tells that the values are of type <strong>float<\/strong>.<\/p>\n<p>The 3rd parameter is the offset between the vertices in the array. It is called the <em>strife<\/em>. We have a tightly packed array so it is <em>0<\/em>.<\/p>\n<p>Finally the last parameter tells where the vertices are held. Of course it is our buffer <strong> vertexBuffer<\/strong>.<\/p>\n<p><strong>gl.glDrawArrays<\/strong> in line 11 tells OpenGL to draw the primitive. What kind of primitive? The one specified in the first parameter: <strong>GL10.GL_TRIANGLE_STRIP<\/strong>. It takes the vertices from the previously set vertex buffer and it follows the rules of the triangle strips described earlier.<\/p>\n<p>The second parameter specifies the starting index for the vertices in the array.<\/p>\n<p>The 3rd parameter tells OpenGL, how many vertices to use for the polygon, about to be rendered. Because in the previous statement (<strong>gl.glVertexPointer<\/strong>) we specified that 3 coordinates define a vertex, we will provide the length of our vertex array divided by 3. There are 9 elements in the array defining 3 vertices.<\/p>\n<p><strong>glDisableClientState(GL10.GL_VERTEX_ARRAY)<\/strong> disables the state of rendering from an array containing the vertices.<\/p>\n<p>Think of <strong>glEnableClientState<\/strong> and <strong>glDisableClientState<\/strong> as <strong>begin &#8230; end<\/strong> statements in a program. We basically enter subroutines in the OpenGL renderer. Once we entered a routine, we set up variables (the vertex buffer, the colour, etc) and we execute other subroutines (draw vertices). After we\u2019re done, we exit the subroutine. We work in isolation inside the renderer.<\/p>\n<p>Make sure you run the application at this stage and understand what is going on.<\/p>\n<h2>  Creating the Texture<\/h2>\n<p>Now the fun part. Let\u2019s load up an image and create a texture. A texture IS an image.<\/p>\n<p>To find out how you can load up images in your android app, check out <a href=\"http:\/\/www.javacodegeeks.com\/2011\/07\/android-game-development-displaying.html\">this article<\/a>.<\/p>\n<p>We will be working with the <strong>Square<\/strong> class as we want to apply the texture to the square.<\/p>\n<p>We need to load up the image, tell the opengl renderer that we want to use it as a texture, and finally we will tell the renderer where exactly onto our primitive (square) to display it.<\/p>\n<p>Think of it as if you were putting a foil onto a window or a wall. I provide you with a foil containing an image of the size of the window and tell you to cover the window with it, so the top left corner of the foil will be on the top left corner of the window. That is it, let\u2019s get to work.<\/p>\n<p>OpenGL uses the vertices to work out where to put stuff. So we need to create an array for the image. But this time, this will be 2D as a bitmap is like a sheet of paper, a flat plane.<\/p>\n<p>Add the coordinate array for the texture.<\/p>\n<pre class=\"brush: java;\">\tprivate FloatBuffer textureBuffer;\t\/\/ buffer holding the texture coordinates\r\n\tprivate float texture[] = {\r\n\t\t\t\/\/ Mapping coordinates for the vertices\r\n\t\t\t0.0f, 1.0f,\t\t\/\/ top left\t\t(V2)\r\n\t\t\t0.0f, 0.0f,\t\t\/\/ bottom left\t(V1)\r\n\t\t\t1.0f, 1.0f,\t\t\/\/ top right\t(V4)\r\n\t\t\t1.0f, 0.0f\t\t\/\/ bottom right\t(V3)\r\n\t};\r\n<\/pre>\n<p>We need to create the <strong>textureBuffer<\/strong> in a similar way to the <strong>vertexBuffer<\/strong>. This happens in the constructor and we\u2019ll just reuse the <strong>byteBuffer<\/strong>. Check the new constructor:<\/p>\n<pre class=\"brush: java;\">\tpublic Square() {\r\n\t\tByteBuffer byteBuffer = ByteBuffer.allocateDirect(vertices.length * 4);\r\n\t\tbyteBuffer.order(ByteOrder.nativeOrder());\r\n\t\tvertexBuffer = byteBuffer.asFloatBuffer();\r\n\t\tvertexBuffer.put(vertices);\r\n\t\tvertexBuffer.position(0);\r\n\r\n\t\tbyteBuffer = ByteBuffer.allocateDirect(texture.length * 4);\r\n\t\tbyteBuffer.order(ByteOrder.nativeOrder());\r\n\t\ttextureBuffer = byteBuffer.asFloatBuffer();\r\n\t\ttextureBuffer.put(texture);\r\n\t\ttextureBuffer.position(0);\r\n\t}\r\n<\/pre>\n<p>We will add an important method to the <strong>Square<\/strong> class. The <strong>loadGLTexture<\/strong> method. This will be called from the renderer when it starts up. It happens in the <strong>onSurfaceCreated<\/strong> method. This will load up the image from the disk and bind it to a texture in the OpenGL repository. It will basically assign an internal ID for the processed image and will be used by the OpenGL API to identify it among other textures.<\/p>\n<pre class=\"brush: java;\">\t\/** The texture pointer *\/\r\n\tprivate int[] textures = new int[1];\r\n\r\n\tpublic void loadGLTexture(GL10 gl, Context context) {\r\n\t\t\/\/ loading texture\r\n\t\tBitmap bitmap = BitmapFactory.decodeResource(context.getResources(),\r\n\t\t\t\tR.drawable.android);\r\n\r\n\t\t\/\/ generate one texture pointer\r\n\t\tgl.glGenTextures(1, textures, 0);\r\n\t\t\/\/ ...and bind it to our array\r\n\t\tgl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);\r\n\r\n\t\t\/\/ create nearest filtered texture\r\n\t\tgl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);\r\n\t\tgl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);\r\n\r\n\t\t\/\/ Use Android GLUtils to specify a two-dimensional texture image from our bitmap\r\n\t\tGLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);\r\n\r\n\t\t\/\/ Clean up\r\n\t\tbitmap.recycle();\r\n\t}\r\n<\/pre>\n<p>We need a texture pointer array. This is where OpenGL will store the names of the textures we will use in our application. Because we have just one image, we will create an array of size 1. <\/p>\n<p>Line <strong>06<\/strong> loads the <em>android<\/em> bitmap which was previously copied into the <strong>\/res\/drawable-mdpi<\/strong> directory, so the ID is already generated.<\/p>\n<p>A note about this bitmap. It is encouraged to be square. It helps a lot with scaling. So make sure your bitmaps for textures are squares (6\u00d76, 12\u00d712, 128\u00d7128, etc.). If not square, make sure the width and height are powers of 2 (2, 4, 8, 16, 32, \u2026). You can have a bitmap 128\u00d7512 and it is perfectly usable and it is optimised.<\/p>\n<p>Line <strong>10<\/strong> generates the names for the textures. In our case generates one name and stores it in the <strong>textures<\/strong> array. Even if it says <em>name<\/em>, it actually generates an <strong>int<\/strong>. A bit confusing, but it is how it is.<\/p>\n<p>Line <strong>12<\/strong> binds the texture with the newly generated name (texture[0]). What this means is, that anything using textures in this subroutine, will use the bound texture. It practically activates the texture. A bound texture is the active texture. If we would have had multiple textures and multiple squares to use them, we would have had to bind (activate) the appropriate textures for each square just before they were used to activate them.<br \/>\nLines <strong>15<\/strong> and <strong>16<\/strong> set some filters to be used with for texture. We have just told OpenGL what types of filters to use when it needs to shrink or expand the texture to cover the square. We have chosen some basic algorithms on how to scale the image. Don\u2019t have to worry about this now. <\/p>\n<p>In line <strong>19<\/strong> we use Android\u2019s utilities to specify the 2D texture image for our bitmap. It creates the image (texture) internally in its native format based on our bitmap.<\/p>\n<p>in line <strong>22<\/strong> we free up the memory. This you should not forget as memory on a device is very limited and images are big.<\/p>\n<p>Now let\u2019s see how the <strong>draw()<\/strong> method has been modified.<\/p>\n<pre class=\"brush: java;\">\tpublic void draw(GL10 gl) {\r\n\t\t\/\/ bind the previously generated texture\r\n\t\tgl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);\r\n\r\n\t\t\/\/ Point to our buffers\r\n\t\tgl.glEnableClientState(GL10.GL_VERTEX_ARRAY);\r\n\t\tgl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);\r\n\r\n\t\t\/\/ Set the face rotation\r\n\t\tgl.glFrontFace(GL10.GL_CW);\r\n\r\n\t\t\/\/ Point to our vertex buffer\r\n\t\tgl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);\r\n\t\tgl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);\r\n\r\n\t\t\/\/ Draw the vertices as triangle strip\r\n\t\tgl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length \/ 3);\r\n\r\n\t\t\/\/Disable the client state before leaving\r\n\t\tgl.glDisableClientState(GL10.GL_VERTEX_ARRAY);\r\n\t\tgl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);\r\n\t}\r\n}\r\n<\/pre>\n<p>It\u2019s not a huge modification from the previous article. The additions are documented and do the following:<\/p>\n<p>Line <strong>03<\/strong> binds (activates) the texture with the name (integer ID) stored in <strong>textures[0]<\/strong>.<\/p>\n<p>Line <strong>07<\/strong> enables the texture mapping in the current OpenGL context.<\/p>\n<p>Line <strong>14<\/strong> provides the OpenGL context with the texture coordinates.<br \/>\nAfter drawing the primitive with textures, we switch off the texture mapping along with the primitive rendering.<\/p>\n<h3>  Important \u2013 UV Mapping<\/h3>\n<p>If you look carefully, the vertex order in the texture mapping coordinates array doesn\u2019t follow the order present in the square\u2019s vertex coordinates array.<\/p>\n<p>There is a very good explanation of texture mapping coordinates here: <a href=\"http:\/\/iphonedevelopment.blogspot.com\/2009\/05\/opengl-es-from-ground-up-part-6_25.html\">http:\/\/iphonedevelopment.blogspot.com\/2009\/05\/opengl-es-from-ground-up-part-6_25.html<\/a>.<\/p>\n<p>I will try to explain it quickly though. Examine the following diagram.<\/p>\n<table align=\"center\" cellpadding=\"0\" cellspacing=\"0\" class=\"tr-caption-container\" style=\"margin-left: auto;margin-right: auto;text-align: center\">\n<tbody>\n<tr>\n<td style=\"text-align: center\"><a href=\"http:\/\/obviam.net\/wp-content\/uploads\/2011\/01\/UVMapping.png\"><img decoding=\"async\" border=\"0\" height=\"192\" src=\"http:\/\/obviam.net\/wp-content\/uploads\/2011\/01\/UVMapping.png\" width=\"320\" \/><\/a><\/td>\n<\/tr>\n<tr>\n<td class=\"tr-caption\" style=\"text-align: center\"><span class=\"Apple-style-span\" style=\"font-size: small\">Square and Texture Coordinates Ordering<\/span><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The square is composed of 2 triangles and the vertices are in the following order.<\/p>\n<p>1 \u2013 bottom left<\/p>\n<p>2 \u2013 bottom right<\/p>\n<p>3 \u2013 top left<\/p>\n<p>4 \u2013 top right<\/p>\n<p>Notice the counter clockwise path.<\/p>\n<p>The texture coordinates will be in the order: 1 -&gt; 3 -&gt; 2 -&gt; 4<\/p>\n<p>Just bear this mapping in mind and rotate it if you start your shape from a different corner. To read up on UV mapping check the <a href=\"http:\/\/en.wikipedia.org\/wiki\/UV_mapping\">wikipedia entry<\/a> or search the net for it.<\/p>\n<p>For the final part, to make this work, we need to provide the context to our renderer so we can load up the texture at startup.<\/p>\n<p>The <strong>onSurfaceCreated<\/strong> method will look like this. <\/p>\n<pre class=\"brush: java;\">\tpublic void onSurfaceCreated(GL10 gl, EGLConfig config) {\r\n\t\t\/\/ Load the texture for the square\r\n\t\tsquare.loadGLTexture(gl, this.context);\r\n\r\n\t\tgl.glEnable(GL10.GL_TEXTURE_2D);\t\t\t\/\/Enable Texture Mapping ( NEW )\r\n\t\tgl.glShadeModel(GL10.GL_SMOOTH); \t\t\t\/\/Enable Smooth Shading\r\n\t\tgl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f); \t\/\/Black Background\r\n\t\tgl.glClearDepthf(1.0f); \t\t\t\t\t\/\/Depth Buffer Setup\r\n\t\tgl.glEnable(GL10.GL_DEPTH_TEST); \t\t\t\/\/Enables Depth Testing\r\n\t\tgl.glDepthFunc(GL10.GL_LEQUAL); \t\t\t\/\/The Type Of Depth Testing To Do\r\n\r\n\t\t\/\/Really Nice Perspective Calculations\r\n\t\tgl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);\r\n\t}\r\n<\/pre>\n<p>Line <strong>03<\/strong> loads the texture. The rest of the lines just configure the renderer with some values. You don\u2019t have to worry about them now. <\/p>\n<p>You will need to provide the application context to the <strong>Square<\/strong> object, because the object itself loads the texture and needs to know the path to the bitmap.<\/p>\n<p>Just provide the context to the renderer in the <strong>Run<\/strong> activity\u2019s <strong>onCreate<\/strong> method (<strong>glSurfaceView.setRenderer(new GlRenderer(this));<\/strong>) and it\u2019s done.<\/p>\n<p>Make sure the renderer has the context declared and set via the constructor.<\/p>\n<p>Excerpt from the <strong>GlRendered<\/strong> class.<\/p>\n<pre class=\"brush: java;\">\tprivate Square \t\tsquare;\t\t\/\/ the square\r\n\tprivate Context \tcontext;\r\n\r\n\t\/** Constructor to set the handed over context *\/\r\n\tpublic GlRenderer(Context context) {\r\n\t\tthis.context = context;\r\n\r\n\t\t\/\/ initialise the square\r\n\t\tthis.square = new Square();\r\n\t}\r\n<\/pre>\n<p>If you run the code you should see the square with a nice android laid on top of it.<\/p>\n<table align=\"center\" cellpadding=\"0\" cellspacing=\"0\" class=\"tr-caption-container\" style=\"margin-left: auto;margin-right: auto;text-align: center\">\n<tbody>\n<tr>\n<td style=\"text-align: center\"><a href=\"http:\/\/obviam.net\/wp-content\/uploads\/2011\/01\/android_textre.png\"><img decoding=\"async\" border=\"0\" height=\"320\" src=\"http:\/\/obviam.net\/wp-content\/uploads\/2011\/01\/android_textre.png\" width=\"221\" \/><\/a><\/td>\n<\/tr>\n<tr>\n<td class=\"tr-caption\" style=\"text-align: center\"><span class=\"Apple-style-span\" style=\"font-size: small\">Square with Android Texture<\/span><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Download the source code and project <a href=\"http:\/\/obviam.net\/source_code\/obviam.opengl.p03.tgz\">here (obviam.opengl.p03.tgz).<\/a><\/p>\n<p><strong>Reference:<\/strong>&nbsp;<a href=\"http:\/\/obviam.net\/index.php\/texture-mapping-opengl-android-displaying-images-using-opengl-and-squares\/\">Texture Mapping \u2013 OpenGL Android (Displaying Images using OpenGL and Squares)<\/a>&nbsp;from our&nbsp;<a href=\"http:\/\/www.javacodegeeks.com\/p\/jcg.html\">JCG<\/a>&nbsp;partner Tamas Jano&nbsp;from &#8220;<a href=\"http:\/\/obviam.net\/\">Against The Grain<\/a>&#8221; blog.<\/p>\n<div style=\"margin: 0px\">Do not forget to check out our new <strong><i>Android Game<\/i><\/strong> <strong><i><a href=\"http:\/\/www.javacodegeeks.com\/2011\/06\/jcg-studios-arkdroid-official-launch.html\">ArkDroid<\/a>&nbsp;<span class=\"Apple-style-span\" style=\"font-weight: normal\"><span class=\"Apple-style-span\" style=\"font-style: normal\">(screenshots below)<\/span><\/span><\/i><\/strong>. You feedback will be more than helpful!<\/div>\n<div class=\"separator\" style=\"clear: both;text-align: center\"><a href=\"http:\/\/1.bp.blogspot.com\/-sEqMxR7YZnY\/ThBGdHcIYnI\/AAAAAAAAABs\/S6iKs2lycyk\/s1600\/multiple_sticky.jpg\"><img decoding=\"async\" border=\"0\" height=\"200\" src=\"http:\/\/1.bp.blogspot.com\/-sEqMxR7YZnY\/ThBGdHcIYnI\/AAAAAAAAABs\/S6iKs2lycyk\/s200\/multiple_sticky.jpg\" width=\"133\" \/><\/a><a href=\"http:\/\/3.bp.blogspot.com\/-n99pqdxWzqM\/ThBFy-5CGmI\/AAAAAAAAABg\/LfSrtmW-RaQ\/s1600\/multiple_laser.jpg\"><img decoding=\"async\" border=\"0\" height=\"200\" src=\"http:\/\/3.bp.blogspot.com\/-n99pqdxWzqM\/ThBFy-5CGmI\/AAAAAAAAABg\/LfSrtmW-RaQ\/s200\/multiple_laser.jpg\" width=\"133\" \/><\/a><a href=\"http:\/\/1.bp.blogspot.com\/-0dr410FpxAA\/TgdJc44bfvI\/AAAAAAAAADg\/GyMLvayT_rc\/s1600\/arkdroid_ingame.jpg\"><img decoding=\"async\" border=\"0\" height=\"200\" src=\"http:\/\/1.bp.blogspot.com\/-0dr410FpxAA\/TgdJc44bfvI\/AAAAAAAAADg\/GyMLvayT_rc\/s200\/arkdroid_ingame.jpg\" width=\"133\" \/><\/a><\/div>\n<div style=\"margin: 0px\"><strong>Related Articles:<\/strong><\/div>\n<ul style=\"text-align: left\">\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/06\/android-game-development-tutorials.html\">Android Game Development Tutorials Introduction<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/07\/android-game-development-game-idea.html\">Android Game Development &#8211; The Game Idea<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/07\/android-game-development-create-project.html\">Android Game Development &#8211; Create The Project<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/07\/android-game-development-basic-game.html\">Android Game Development &#8211; A Basic Game Architecture<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/07\/android-game-development-basic-game_05.html\">Android Game Development &#8211; A Basic Game Loop<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/07\/android-game-development-displaying.html\">Android Game Development &#8211; Displaying Images with Android<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/07\/android-game-development-moving-images.html\">Android Game Development &#8211; Moving Images on Screen<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/07\/android-game-development-game-loop.html\">Android Game Development &#8211; The Game Loop<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/07\/android-game-development-measuring-fps.html\">Android Game Development &#8211; Measuring FPS<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/07\/android-game-development-sprite.html\">Android Game Development &#8211; Sprite Animation<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/08\/android-game-development-particle.html\">Android Game Development &#8211; Particle Explosion<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/08\/android-game-development-design-in-game.html\">Android Game Development &#8211; Design In-game Entities &#8211; The Strategy Pattern<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/09\/android-game-development-using-bitmap.html\">Android Game Development &#8211; Using Bitmap Fonts<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/09\/android-game-development-switching-from.html\">Android Game Development &#8211; Switching from Canvas to OpenGL ES<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/10\/android-game-development-displaying.html\">Android Game Development \u2013 Displaying Graphical Elements (Primitives) with OpenGL ES<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/10\/android-game-development-design-in-game.html\">Android Game Development \u2013 Design In-game Entities \u2013 The State Pattern<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/?tag=android-games\">Android Games Article Series<\/a><\/li>\n<\/ul>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>In the previous two articles (article 1 and article 2) I have tried to introduce OpenGL ES on android. Now let\u2019s take it further and build on them. In this article we will create a billboard (which is a square) and we will apply a texture onto it. A texture is nothing more than a &hellip;<\/p>\n","protected":false},"author":27,"featured_media":46,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12],"tags":[],"class_list":["post-643","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-android-games"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Android Game Development \u2013 OpenGL Texture Mapping - Java Code Geeks<\/title>\n<meta name=\"description\" content=\"In the previous two articles (article 1 and article 2) I have tried to introduce OpenGL ES on android. Now let\u2019s take it further and build on them. In\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.javacodegeeks.com\/2011\/10\/android-game-development-opengl-texture.html\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Android Game Development \u2013 OpenGL Texture Mapping - Java Code Geeks\" \/>\n<meta property=\"og:description\" content=\"In the previous two articles (article 1 and article 2) I have tried to introduce OpenGL ES on android. Now let\u2019s take it further and build on them. In\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.javacodegeeks.com\/2011\/10\/android-game-development-opengl-texture.html\" \/>\n<meta property=\"og:site_name\" content=\"Java Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/javacodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2011-10-06T21:37:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2012-10-21T20:31:36+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/android-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Impaler\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:site\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Impaler\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"13 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/10\\\/android-game-development-opengl-texture.html#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/10\\\/android-game-development-opengl-texture.html\"},\"author\":{\"name\":\"Impaler\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/6bad1a2db4fb0129703629617c049f8c\"},\"headline\":\"Android Game Development \u2013 OpenGL Texture Mapping\",\"datePublished\":\"2011-10-06T21:37:00+00:00\",\"dateModified\":\"2012-10-21T20:31:36+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/10\\\/android-game-development-opengl-texture.html\"},\"wordCount\":1847,\"commentCount\":5,\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/10\\\/android-game-development-opengl-texture.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/android-logo.jpg\",\"articleSection\":[\"Android Games\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/10\\\/android-game-development-opengl-texture.html#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/10\\\/android-game-development-opengl-texture.html\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/10\\\/android-game-development-opengl-texture.html\",\"name\":\"Android Game Development \u2013 OpenGL Texture Mapping - Java Code Geeks\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/10\\\/android-game-development-opengl-texture.html#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/10\\\/android-game-development-opengl-texture.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/android-logo.jpg\",\"datePublished\":\"2011-10-06T21:37:00+00:00\",\"dateModified\":\"2012-10-21T20:31:36+00:00\",\"description\":\"In the previous two articles (article 1 and article 2) I have tried to introduce OpenGL ES on android. Now let\u2019s take it further and build on them. In\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/10\\\/android-game-development-opengl-texture.html#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/10\\\/android-game-development-opengl-texture.html\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/10\\\/android-game-development-opengl-texture.html#primaryimage\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/android-logo.jpg\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/android-logo.jpg\",\"width\":150,\"height\":150},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/10\\\/android-game-development-opengl-texture.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Android\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/android\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Android Games\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/android\\\/android-games\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"Android Game Development \u2013 OpenGL Texture Mapping\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"name\":\"Java Code Geeks\",\"description\":\"Java Developers Resource Center\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"alternateName\":\"JCG\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.javacodegeeks.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/javacodegeeks\",\"https:\\\/\\\/x.com\\\/javacodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/6bad1a2db4fb0129703629617c049f8c\",\"name\":\"Impaler\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/def7cf34ac1eee0f6c2de98be951379d6bf14fd498acf7d3864e2e570ece357c?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/def7cf34ac1eee0f6c2de98be951379d6bf14fd498acf7d3864e2e570ece357c?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/def7cf34ac1eee0f6c2de98be951379d6bf14fd498acf7d3864e2e570ece357c?s=96&d=mm&r=g\",\"caption\":\"Impaler\"},\"sameAs\":[\"http:\\\/\\\/obviam.net\\\/\"],\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/author\\\/Impaler\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Android Game Development \u2013 OpenGL Texture Mapping - Java Code Geeks","description":"In the previous two articles (article 1 and article 2) I have tried to introduce OpenGL ES on android. Now let\u2019s take it further and build on them. In","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.javacodegeeks.com\/2011\/10\/android-game-development-opengl-texture.html","og_locale":"en_US","og_type":"article","og_title":"Android Game Development \u2013 OpenGL Texture Mapping - Java Code Geeks","og_description":"In the previous two articles (article 1 and article 2) I have tried to introduce OpenGL ES on android. Now let\u2019s take it further and build on them. In","og_url":"https:\/\/www.javacodegeeks.com\/2011\/10\/android-game-development-opengl-texture.html","og_site_name":"Java Code Geeks","article_publisher":"https:\/\/www.facebook.com\/javacodegeeks","article_published_time":"2011-10-06T21:37:00+00:00","article_modified_time":"2012-10-21T20:31:36+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/android-logo.jpg","type":"image\/jpeg"}],"author":"Impaler","twitter_card":"summary_large_image","twitter_creator":"@javacodegeeks","twitter_site":"@javacodegeeks","twitter_misc":{"Written by":"Impaler","Est. reading time":"13 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.javacodegeeks.com\/2011\/10\/android-game-development-opengl-texture.html#article","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/2011\/10\/android-game-development-opengl-texture.html"},"author":{"name":"Impaler","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/6bad1a2db4fb0129703629617c049f8c"},"headline":"Android Game Development \u2013 OpenGL Texture Mapping","datePublished":"2011-10-06T21:37:00+00:00","dateModified":"2012-10-21T20:31:36+00:00","mainEntityOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2011\/10\/android-game-development-opengl-texture.html"},"wordCount":1847,"commentCount":5,"publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2011\/10\/android-game-development-opengl-texture.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/android-logo.jpg","articleSection":["Android Games"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.javacodegeeks.com\/2011\/10\/android-game-development-opengl-texture.html#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.javacodegeeks.com\/2011\/10\/android-game-development-opengl-texture.html","url":"https:\/\/www.javacodegeeks.com\/2011\/10\/android-game-development-opengl-texture.html","name":"Android Game Development \u2013 OpenGL Texture Mapping - Java Code Geeks","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2011\/10\/android-game-development-opengl-texture.html#primaryimage"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2011\/10\/android-game-development-opengl-texture.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/android-logo.jpg","datePublished":"2011-10-06T21:37:00+00:00","dateModified":"2012-10-21T20:31:36+00:00","description":"In the previous two articles (article 1 and article 2) I have tried to introduce OpenGL ES on android. Now let\u2019s take it further and build on them. In","breadcrumb":{"@id":"https:\/\/www.javacodegeeks.com\/2011\/10\/android-game-development-opengl-texture.html#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.javacodegeeks.com\/2011\/10\/android-game-development-opengl-texture.html"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/2011\/10\/android-game-development-opengl-texture.html#primaryimage","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/android-logo.jpg","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/android-logo.jpg","width":150,"height":150},{"@type":"BreadcrumbList","@id":"https:\/\/www.javacodegeeks.com\/2011\/10\/android-game-development-opengl-texture.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.javacodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Android","item":"https:\/\/www.javacodegeeks.com\/category\/android"},{"@type":"ListItem","position":3,"name":"Android Games","item":"https:\/\/www.javacodegeeks.com\/category\/android\/android-games"},{"@type":"ListItem","position":4,"name":"Android Game Development \u2013 OpenGL Texture Mapping"}]},{"@type":"WebSite","@id":"https:\/\/www.javacodegeeks.com\/#website","url":"https:\/\/www.javacodegeeks.com\/","name":"Java Code Geeks","description":"Java Developers Resource Center","publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"alternateName":"JCG","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.javacodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.javacodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.javacodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/javacodegeeks","https:\/\/x.com\/javacodegeeks"]},{"@type":"Person","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/6bad1a2db4fb0129703629617c049f8c","name":"Impaler","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/def7cf34ac1eee0f6c2de98be951379d6bf14fd498acf7d3864e2e570ece357c?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/def7cf34ac1eee0f6c2de98be951379d6bf14fd498acf7d3864e2e570ece357c?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/def7cf34ac1eee0f6c2de98be951379d6bf14fd498acf7d3864e2e570ece357c?s=96&d=mm&r=g","caption":"Impaler"},"sameAs":["http:\/\/obviam.net\/"],"url":"https:\/\/www.javacodegeeks.com\/author\/Impaler"}]}},"_links":{"self":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/643","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/users\/27"}],"replies":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/comments?post=643"}],"version-history":[{"count":0,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/643\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media\/46"}],"wp:attachment":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media?parent=643"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/categories?post=643"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/tags?post=643"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}