## Texture Mapping – OpenGL Android (Displaying Images using OpenGL and Squares)

In the previous two articles (article 1 and article 2) I have tried to introduce OpenGL ES on android. Now let’s 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’ll 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.

In the previous articles we managed to display triangles. How to display a square then? A square is composed of 2 triangles.

The following diagram shows you this:

Square from Triangles

There is an interesting thing to note here. The square is ABDC instead of the usual ABCD. Why is that? Because of how OpenGL chains triangles together.
What you see here is a triangle strip. A triangle strip is a series of connected triangles, 2 triangles in our case.

OpenGL draws the following triangle strip (which is a square) using the vertices in the following order:
Triangle 1: V1 -> V2 -> V3
Triangle 2: V3 -> V2 -> V4

Triangle Strip

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.
This also has benefits: we eliminate redundant data from the memory.

Grab the project from the previous article and create a new class called `Square`.

If you compare the `Square` class with the `Triangle` class, you will notice just one difference:

```package net.obviam.opengl;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import javax.microedition.khronos.opengles.GL10;

public class Square {

private FloatBuffer vertexBuffer;	// buffer holding the vertices

private float vertices[] = {
-1.0f, -1.0f,  0.0f,		// V1 - bottom left
-1.0f,  1.0f,  0.0f,		// V2 - top left
1.0f, -1.0f,  0.0f,		// V3 - bottom right
1.0f,  1.0f,  0.0f			// V4 - top right
};

public Square() {
// a float has 4 bytes so we allocate for each coordinate 4 bytes
ByteBuffer vertexByteBuffer = ByteBuffer.allocateDirect(vertices.length * 4);
vertexByteBuffer.order(ByteOrder.nativeOrder());

// allocates the memory from the byte buffer
vertexBuffer = vertexByteBuffer.asFloatBuffer();

// fill the vertexBuffer with the vertices
vertexBuffer.put(vertices);

// set the cursor position to the beginning of the buffer
vertexBuffer.position(0);
}

/** The draw method for the square with the GL context */
public void draw(GL10 gl) {
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

// set the colour for the square
gl.glColor4f(0.0f, 1.0f, 0.0f, 0.5f);

// Point to our vertex buffer
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);

// Draw the vertices as triangle strip
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length / 3);

//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
}
}
```

The difference is in the highlighted lines (13-18). That’s right, we’ve added one more vertex to the `vertices` array.
Now change the `GlRenderer` so instead of a `Triangle` we use a `Square`.

```package net.obviam.opengl;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.opengl.GLU;
import android.opengl.GLSurfaceView.Renderer;

public class GlRenderer implements Renderer {

private Square 		square;		// the square

/** Constructor to set the handed over context */
public GlRenderer() {
this.square		= new Square();
}

@Override
public void onDrawFrame(GL10 gl) {
// clear Screen and Depth Buffer
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

// Reset the Modelview Matrix

// Drawing
gl.glTranslatef(0.0f, 0.0f, -5.0f);		// move 5 units INTO the screen
// is the same as moving the camera 5 units away
square.draw(gl);						// Draw the triangle

}

@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
if(height == 0) { 						//Prevent A Divide By Zero By
height = 1; 						//Making Height Equal One
}

gl.glViewport(0, 0, width, height); 	//Reset The Current Viewport
gl.glMatrixMode(GL10.GL_PROJECTION); 	//Select The Projection Matrix

//Calculate The Aspect Ratio Of The Window
GLU.gluPerspective(gl, 45.0f, (float)width / (float)height, 0.1f, 100.0f);

gl.glMatrixMode(GL10.GL_MODELVIEW); 	//Select The Modelview Matrix
}

@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
}
}
```

Running this will produce the following result:

Triangle Strip forming a Square

Examining this, the `draw()` method in the `Square` class should make sense now.

```	public void draw(GL10 gl) {
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

// set the colour for the square
gl.glColor4f(0.0f, 1.0f, 0.0f, 0.5f);

// Point to our vertex buffer
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);

// Draw the vertices as triangle strip
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length / 3);

//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
}
```

First we enable OpenGL to use a vertex array for rendering. Our vertex array contains the vertices for our square.
`gl.glVertexPointer` (line 5) tells the opengl renderer from where to take the vertices and of what type they are.
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 `float`.
The 3rd parameter is the offset between the vertices in the array. It is called the strife. We have a tightly packed array so it is 0.
Finally the last parameter tells where the vertices are held. Of course it is our buffer ` vertexBuffer`.

`gl.glDrawArrays` in line 11 tells OpenGL to draw the primitive. What kind of primitive? The one specified in the first parameter: `GL10.GL_TRIANGLE_STRIP`. It takes the vertices from the previously set vertex buffer and it follows the rules of the triangle strips described earlier.
The second parameter specifies the starting index for the vertices in the array.
The 3rd parameter tells OpenGL, how many vertices to use for the polygon, about to be rendered. Because in the previous statement (`gl.glVertexPointer`) 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.

`glDisableClientState(GL10.GL_VERTEX_ARRAY)` disables the state of rendering from an array containing the vertices.

Think of `glEnableClientState` and `glDisableClientState` as `begin ... end` 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’re done, we exit the subroutine. We work in isolation inside the renderer.

Make sure you run the application at this stage and understand what is going on.

#### Creating the Texture

Now the fun part. Let’s load up an image and create a texture. A texture IS an image.

We will be working with the `Square` class as we want to apply the texture to the square.

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.
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’s get to work.

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.
Add the coordinate array for the texture.

```	private FloatBuffer textureBuffer;	// buffer holding the texture coordinates
private float texture[] = {
// Mapping coordinates for the vertices
0.0f, 1.0f,		// top left		(V2)
0.0f, 0.0f,		// bottom left	(V1)
1.0f, 1.0f,		// top right	(V4)
1.0f, 0.0f		// bottom right	(V3)
};
```

We need to create the `textureBuffer` in a similar way to the `vertexBuffer`. This happens in the constructor and we’ll just reuse the `byteBuffer`. Check the new constructor:

```	public Square() {
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(vertices.length * 4);
byteBuffer.order(ByteOrder.nativeOrder());
vertexBuffer = byteBuffer.asFloatBuffer();
vertexBuffer.put(vertices);
vertexBuffer.position(0);

byteBuffer = ByteBuffer.allocateDirect(texture.length * 4);
byteBuffer.order(ByteOrder.nativeOrder());
textureBuffer = byteBuffer.asFloatBuffer();
textureBuffer.put(texture);
textureBuffer.position(0);
}
```

We will add an important method to the `Square` class. The `loadGLTexture` method. This will be called from the renderer when it starts up. It happens in the `onSurfaceCreated` 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.

```	/** The texture pointer */
private int[] textures = new int[1];

public void loadGLTexture(GL10 gl, Context context) {
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(),
R.drawable.android);

// generate one texture pointer
gl.glGenTextures(1, textures, 0);
// ...and bind it to our array
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);

// create nearest filtered texture
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);

// Use Android GLUtils to specify a two-dimensional texture image from our bitmap
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);

// Clean up
bitmap.recycle();
}
```

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.

Line 06 loads the android bitmap which was previously copied into the `/res/drawable-mdpi` directory, so the ID is already generated.
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×6, 12×12, 128×128, etc.). If not square, make sure the width and height are powers of 2 (2, 4, 8, 16, 32, …). You can have a bitmap 128×512 and it is perfectly usable and it is optimised.

Line 10 generates the names for the textures. In our case generates one name and stores it in the `textures` array. Even if it says name, it actually generates an `int`. A bit confusing, but it is how it is.

Line 12 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.

Lines 15 and 16 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’t have to worry about this now.

In line 19 we use Android’s utilities to specify the 2D texture image for our bitmap. It creates the image (texture) internally in its native format based on our bitmap.

in line 22 we free up the memory. This you should not forget as memory on a device is very limited and images are big.

Now let’s see how the `draw()` method has been modified.

```	public void draw(GL10 gl) {
// bind the previously generated texture
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);

// Point to our buffers
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

// Set the face rotation
gl.glFrontFace(GL10.GL_CW);

// Point to our vertex buffer
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);

// Draw the vertices as triangle strip
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length / 3);

//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
}
}
```

It’s not a huge modification from the previous article. The additions are documented and do the following:
Line 03 binds (activates) the texture with the name (integer ID) stored in `textures[0]`.
Line 07 enables the texture mapping in the current OpenGL context.
Line 14 provides the OpenGL context with the texture coordinates.

After drawing the primitive with textures, we switch off the texture mapping along with the primitive rendering.

##### Important – UV Mapping

If you look carefully, the vertex order in the texture mapping coordinates array doesn’t follow the order present in the square’s vertex coordinates array.

There is a very good explanation of texture mapping coordinates here: http://iphonedevelopment.blogspot.com/2009/05/opengl-es-from-ground-up-part-6_25.html.

I will try to explain it quickly though. Examine the following diagram.

Square and Texture Coordinates Ordering

The square is composed of 2 triangles and the vertices are in the following order.
1 – bottom left
2 – bottom right
3 – top left
4 – top right
Notice the counter clockwise path.
The texture coordinates will be in the order: 1 -> 3 -> 2 -> 4

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 wikipedia entry or search the net for it.

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.
The `onSurfaceCreated` method will look like this.

```	public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// Load the texture for the square

gl.glEnable(GL10.GL_TEXTURE_2D);			//Enable Texture Mapping ( NEW )
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f); 	//Black Background
gl.glClearDepthf(1.0f); 					//Depth Buffer Setup
gl.glEnable(GL10.GL_DEPTH_TEST); 			//Enables Depth Testing
gl.glDepthFunc(GL10.GL_LEQUAL); 			//The Type Of Depth Testing To Do

//Really Nice Perspective Calculations
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
}
```

Line 03 loads the texture. The rest of the lines just configure the renderer with some values. You don’t have to worry about them now.

You will need to provide the application context to the `Square` object, because the object itself loads the texture and needs to know the path to the bitmap.
Just provide the context to the renderer in the `Run` activity’s `onCreate` method (`glSurfaceView.setRenderer(new GlRenderer(this));`) and it’s done.

Make sure the renderer has the context declared and set via the constructor.
Excerpt from the `GlRendered` class.

```	private Square 		square;		// the square
private Context 	context;

/** Constructor to set the handed over context */
public GlRenderer(Context context) {
this.context = context;

// initialise the square
this.square = new Square();
}
```

If you run the code you should see the square with a nice android laid on top of it.

Square with Android Texture

#### 62 Responses - Add Yours+

1. Art says:

Awesome tutorial!

Unfortunately, when I’m trying to render 200 small objects it works extremely slowly. I have Galaxy Note2
As an example, my old iphone 4 did this job flawlessly fast.
Do we have any hidden setup somewhere?

Thanks.

2. AndroidF says:

It works fine in android emulator, but it DOESN’T show anythig under ASUS Transformer Pad Infinity TF700
Why?

3. Topher LaFata says:

Cool tutorial.

I just wanted to mention something that had me confused for a second.

In your first tutorial you talk about CCW winding being the default for a front facing polygon.

In this tutorial you define the first triangle strip as CW which would cause the square to be culled if back face culling were enabled.

I tight make more sense to continue with your CCW approach started with the first tutorial and define the square as :

//CCW winding on first one determines this is front facing
private float vertices[] = {
-1.0f, -1.0f, 0.0f, // V1 – bottom left
1.0f, -1.0f, 0.0f, // V3 – bottom right
-1.0f, 1.0f, 0.0f, // V2 – top left
1.0f, 1.0f, 0.0f // V4 – top right
};

Thanks for the good work!

• Glen says:

Yes I was confused by this too, as the previous tutorial mentions that vertices are defined Counter clockwise for front facing, and clockwise for back facing polygons.

Thank you Topher for confirming that I read it right too.

4. Renjith K N says:

Hi , Thanks for the nice tutorials, Any one please provide some tutorials/Sample codes or even links to tuts for sprite animation using opengl es

5. BioHazard says:

EVRIKA !!!

I was allmost killing myself ! after 3 days of leaving Canvas and learning OpenGL methods to implement game engine.

The web is full of OpenGL tutorials full of trash and many of them unfinished and many of them lead to wrong way for 2D OpenGL game engine implementation methotds. The big wrong point is using G11Ext for making games. AS THEY DONT ROTATE : D

Annd annd then i found this tutorial from other tutorial which i found from youtube game sample video link lol.

Annd just 15 minute ago I discovered the way I can ROTATE, MOVE AND RESIZE shapes with its sprites ! ! ! hahah

So as many of readers are asking after reading this GREAT tutorial how to move and resize and rotate sprites I added some code in the draw method yet I dont know is it correct way for doint this or not but the fact is it wokrs !

/** The draw method for the square with the GL context */
public void draw (GL10 gl, int image)
{
gl.glPushMatrix(); //<— PUT IN TOP !!!

gl.glScalef (4f, 2f, 1f); // ADJUST SIZE !!! <—–
//gl.glRotatef (60, 1f, 1f, 1f); // ROTATE !!!
//gl.glTranslatef (1f, 1f, 1f); //MOVE !!!

// bind the previously generated texture
gl.glBindTexture(GL10.GL_TEXTURE_2D, image);

// Point to our buffers
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

// set the colour for the square
gl.glColor4f (0.0f, 1.0f, 0.0f, 0.5f);

// Set the face rotation
gl.glFrontFace(GL10.GL_CW);

// Point to our vertex buffer
gl.glVertexPointer (3, GL10.GL_FLOAT, 0, shape.buffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, texture.buffer);

// Draw the vertices as triangle strip
gl.glDrawArrays (GL10.GL_TRIANGLE_STRIP, 0, shape.vertex.length / 3);

// Disable the client state before leaving
gl.glDisableClientState (GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

gl.glPopMatrix(); // PUT IN BOTTOM !!!
}

discovering this functions helped me tutorial http://www.morrowland.com/apron/tutorials/gl/gl_matrix.php

So many thanks to this blog for pointing me out the only true way…

+1 android simpliest 2d opengl game engine in 1 week…

6. ugur says:

First of all thank you for this great tutorial.

I have a question if you can help me. I did this tutorial without any problems. But i want to do that:

The square has to be full screen on device so the texture too.

How can i do that?

7. redalin says:

Great tutorial, but i have a little problem. I neet to use OpenGL on a single FrameLayout and not on the whole screen. How could i use this tutorial to load a texture into that framelayout?

8. redalin says:

Hi, great tutorial, but i have a little problem. I neet to use OpenGL on a single FrameLayout and not on the whole screen. How could i use this tutorial to load a texture into that framelayout?

9. Chris says:

Do you have an example that uses more than one surface with different textures? I am seeing a similar thing to what Prasad had way back when, it’s difficult to find tutorials for that next step in texture mapping. So eg draw a square somewhere with a texture, and a circle somewhere else with smooth surface only.

10. Dill says:

Great tutorials..

Fix for the white square,

gl.glEnable(GL10.GL_TEXTURE_2D);

to the Square.draw() method..

works flawlessly…

Cheers.. and keep’em coming…

Dill

11. Joseph T says:

Great Tutorial, but on the Droid 2 a Power of 2 image seems to be required. (2^X x 2^Y where x and y may be equal.)

12. jtantillo says:

Great Tutorial, but I wasn’t able to get it work until I used a PoT (Power of Two) image on the Motorola Droid 2.

13. Erik says:

I am new to JAVA and android, and i have been fumbling all around the internet looking for a good OpenGL tutorial only to be disenchanted everywhere i looked, until now.. GREAT F’N set of tutorials.. very well explained.. Feels easy now.. You ROCK!

oh one question.. i was able to get your android.png laoded when i changed the method:

InputStream is = mContext.getResources().openRawResource(R.drawable.android);

bitmap = BitmapFactory.decodeStream(is);

before that i was getting the white square problem but then when i switch to a different png in the same drawable folder, i get the white square again.. any ideas?

thanks

14. joe GL says:

Are you sure your square and texture coordinates ordering is correct?

private float vertices[] = { //makes a Z shape in your pic
-1.0f, -1.0f, 0.0f, // V1 – bottom left
-1.0f, 1.0f, 0.0f, // V2 – top left
1.0f, -1.0f, 0.0f, // V3 – bottom right
1.0f, 1.0f, 0.0f // V4 – top right
};
//the above points make an N shape

private float texture[] = { //makes an N shape in your pic
3
// Mapping coordinates for the vertices
0.0f, 1.0f, // top left (V2)
0.0f, 0.0f, // bottom left (V1)
1.0f, 1.0f, // top right (V4)
1.0f, 0.0f // bottom right (V3)
};
//the above points make a backwards N shape

I mention this because Im having a devil of a time aligning the texture.

15. James says:

This tutorial is great.
I have one thing to add. I was getting the white square only problem and none of the above suggestions worked for me. After much investigation I found an alternate syntax of loading the bitmap that fixed the problem for me:

InputStream is = mContext.getResources().openRawResource(R.drawable.android);

bitmap = BitmapFactory.decodeStream(is);

• Santiago says:

Would this

InputStream is = mContext.getResources().openRawResource(R.drawable.android);

bitmap = BitmapFactory.decodeStream(is);

count towards the 16mb app limit? I’m trying to store large pictures as bitmaps and hitting RAM limits, but I read that GL textures are outside that limit.

• Impaler says:

It depends on the device how much memory you have, but the bitmap object is added to he heap memory first and when you upload it to the GL context it gets into the native memory (the VRAM is shared with the actual RAM on mobile devices).

16. carlos says:

how can I put two squares in different places using different textures and how can I trasformar the squares into rectangles

17. carlos says:

I want to creat an app and i want to use a 800*480 image as a background and 2 retangules with texture, the texture must use trasparencies, like png ou gif, text and sound (mp3 or midi)

can any one tell me how to trasforme the square in to a rectangles and how do I put 2 rectangles with diferente texture in diferente places?
or else how can I put two squares in different places using different textures,

18. praveen says:

can u tell me the code hoe to read a txt file and plot the graph from it using openGL

19. Mellowg says:

You are awesome. Very clearly explained. This was most useful to me. You are a very good teacher. I am so grateful. Thank you.

20. simplykid says:

I followed your articles from the start.
Thanks, they’re great tutorials indeed.

But I wonder, if I’m about to switch the 2D programing from previous lesson, I can see where I can put/replace where render method, though I’m not so sure, but I don’t know where to put the update() method.

If you had already mentioned it in one of these articles, may be i have missed it.
Can you help me telling where put these method, update() and also render() method?

21. geeta says:

Hey I have tried to draw a bitmap in texture. I have done same coding. But when i am running it i am getting error ie.

10-18 12:02:31.393: ERROR/AndroidRuntime(879): FATAL EXCEPTION: GLThread 8
10-18 12:02:31.393: ERROR/AndroidRuntime(879): java.lang.NullPointerException
10-18 12:02:31.393: ERROR/AndroidRuntime(879): at com.example.geeta.GlRenderer.onSurfaceCreated(GlRenderer.java:60)

22. i have problem in this code its showing null pointer exception. i have downloaded this code and run my eclipse its working fine. i try to add this code are in my live wallpaper.but i have to saw triangle but i can’t able to load image when ever i load my its showing null pointer exception i put all the code for exactly but i don’t know where i’m doing wrong.

i change my image location in to drawable-nodpi but that time also showing null pointer exception.

this is my logcat output

10-14 11:43:43.118: ERROR/AndroidRuntime(3050): FATAL EXCEPTION: GLThread 9
10-14 11:43:43.118: ERROR/AndroidRuntime(3050): java.lang.NullPointerException
10-14 11:43:43.118: ERROR/AndroidRuntime(3050): at frankandrobot.glwallpapervideodemo.com.VideoRenderer.onSurfaceCreated(VideoRenderer.java:77)
10-14 11:43:56.398: WARN/Email(1452): Exception detected: Read error: I/O error during system call, Connection reset by peer
10-14 11:43:56.398: WARN/Email(1452): Last network activities:
10-14 11:43:56.398: WARN/Email(1452): * OK Gimap ready for requests from 115.111.177.222 g2if3342858pbc.293
10-14 11:43:56.398: WARN/Email(1452): 1 CAPABILITY
10-14 11:43:56.398: WARN/Email(1452): * CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID XLIST CHILDREN X-GM-EXT-1 XYZZY SASL-IR AUTH=XOAUTH
10-14 11:43:56.398: WARN/Email(1452): 1 OK Thats all she wrote! g2if3342858pbc.293
10-14 11:43:56.398: WARN/Email(1452): 2 ID (“name” “com.android.email” “os” “android” “os-version” “2.2; FRF91″ “vendor” “nvidia” “x-android-device-model” “INB-10/n” “AGUID” “+TIbwSeLDHum85UXux4T+QJD51g=”)

23. [...] have tried to map the texture as it is taught here and here with no success. I really don’t know what to do to get some letters drawn on the [...]

24. bibster says:

I have the same question as Daniel.
I tried defining a second Square (square2) and drawing it after moving the viewport but all I got was a white square displayed (no sign of square1 or the android?
Great series of articles by the way.

25. gurumoorthy says:

Hi every one any know how to 3dsphere i need some tutorial for that..

26. gurumoorthy says:

hai every one kindly post some tutorial for how to draw 3dsphere in opengl i have searched many tutorial but i can’t exact one

thank u all…….

27. daniel says:

how do I load multiple images?

28. daniel says:

this is very helpful, thank you !! ^^

29. Rob says:

Have you had a look at Honeycomb yet?
There’s a class called SurfaceTexture that allows streaming from a camera feed to a texture.

If you do take a look and get it working let me know.

30. tek911 says:

Thanks for the tutorials. They have made my transition from XNA to android a nice transition. That being said, i have a question in regard to transitioning from canvas to opengl es. In the canvas example, I have a moving images that moves to the users touch and snaps back to original location when done.

In making the jump to opengl i’m not 100% sure how to load an image without mapping it to a primitive (aka billboard) so that i can take advantage of the transparent nature of an png image i have (aka i want to see the background through the portions of the image that are empty). Beginner question im sure but just trying to get a better understanding. Thanks!

31. cloudjubei says:

Thanks very much for these tutes.
This was the best thing out of everything there is on the web to understand OpenGl ES for Android. I actually finally know what I’m doing!
Thanks a lot!

32. I tried to run this project on a Samsung Galaxy, but only a white rectangle is shown. I have cleaned and rebuild the project. I have created a directory called res\drawable-nodpi like suggested and put the images there, but I still only see a white rectangle. The texture is shown on the emulator, but not on the Samsung Galaxy. What do I have to see the texture on the device?

33. I tried to run this project on a Samsung Galaxy, but only a white rectangle is shown. I have cleaned and rebuilt the project. I have created a directory called res\drawable-nodpi like suggested and put the images there, but I still only see a white rectangle. The texture is shown on the emulator, but not on the Samsung Galaxy. What do I have to see the texture on the device?

• Impaler says:

Have you deleted the resource from its original location, mdpi?

As of android 2.2 there is support extra high density screens and extra large screens too.

If deleting the original from mdpi does not work, try putting it into res/drawable-hdpi or res/drawable-xhdpi and give it a go then.

Although moving it to nodpi should fix that problem as it is independent of the screen.

• It worked when I deleted the resource from its original location, mdpi. Sorry for the double posting, I thought that my thread would appear at the end of the page, so I didn’t see it first. That is why I posted the same thing 2 times.

34. Ignacio says:

This is exactly the tutorial I was looking for. Thank you very much!

35. Oscar says:

Great Tutorial!
Just what i was looking for. Keep on writing it.

Thanks!

36. Sylver says:

Hello, I was wondering… I have read all your tutorials and they are just extraordinary.
I was excited and did a bunch of modifications to make the guy shoot bullets.
But when I saw this, I was worried if after building my game, when I try to switch to OpenGL, it might be extremely different in structure?

Should I stop my game project and wait until I learn all the OpenGL basic to start building up on that? or can I just switch with a few modifications?

Thank you very much! Wonderful tutorial !!

• Impaler says:

Hi there,

You don’t have to worry about OpenGL when you design your game elements. Ideally the only method that will change is the `render` method.
If you decouple the update from the graphics, you should be fine. Focus on having a good design and when you are confident with OpenGL, you will switch to it without affecting anything else.

So just carry on experimenting and do not worry.
I

• Sylver says:

Perfect!
Now I can restart my mediocre project hehe

37. Ciprian says:

why don’t you use gluOrtho2D instead of gluPerspective ?

• Impaler says:

I didn’t know about the gluOrtho2D until now.
I looked it up and indeed it is the way to do it.

38. Ruairi says:

I’m a beginner to game and Android development. I’ve been creating a little game on both Windows Phone 7 and Android. XNA is so simple and I was afraid to mess around with OpenGL in Android as I though the port would be too difficult. I was using Canvas all along like a fool!!! This has been so helpful. Now the cloud has been lifted I’m beginning to enjoy developing with android and OpenGL more than I did with XNA. Thanks so much for this.

• Roxie says:

I just hope whoever writes these keeps wrtinig more!

hi

i have displayed a triangle shape and a rectangle shape here i have mapped a texture on rectangle but the texture also mapping on shape.what is the resolution for this one

please any one can resolve my problem.if u resolve please send replay to ensisinfo42@gmail.com..

plzzzzzzzzzzzzzzzz

• Impaler says:

Could you share some code with us so we can have a look?

40. ShaunK says:

Just wanted to say that you have saved me hours of trial and error with this post. Much appreciated!

41. vinaykumarmp says:

Hi,

I am able to get texture mapping on emulator but failed on the actual device (tried on droid x and samsung tab).

Even i have create new drawable folder in the res_dir.

Can also send a reply to my mail id : mp.vinaykumar@gmail.com

Thks,
Vinay

• Impaler says:

Did you make sure that the size (width and height) of the image is a power of 2? The height must not be equal with the width. It can be something like 64×128 for example.
As Antonio pointed it out earlier, this might be the case.

• Jonatas says:

Why te width cannot be equal to the height?
I’m reading a DICOM image, 512×512, and only show a white square.

42. emolaus says:

Thank you so much for a great introduction! OpenGL is a jungle and this was just perfect. Cheers!

43. Antonio says:

First of all, thank you very much. One of the nicest posts about this on the net. Regarding the sample project, it showed up a only white square. Then I realized that my handset (Milestone 2, Android2.2) requires textures of width/height that match 2^n. The sample image you provided is 310×310. After resizing it to 64×64, for example, it worked perfectly.

• Impaler says:

I have mentioned this in the article yet I have not adhered to this rule.
I have changed the texture size to 256×256.

Thanks for pointing it out!

44. vlk says:

Hi, nice tutorial, but if I run this app on nexus one, I see only white square. where is the problem?
thanks.

• semajhan says:

Go to your res -> drawable and create a new folder named drawable-nodpi and put the images in there.

• vlk says:

nice, thanks

• vlk says:

nice, here was the problem, thanks

45. Elliott says:

oh ho ho, very very nice. been waiting for this!

• Michael says: