OpenGL ES Tutorial for Android – Part VI – Textures

I have started a new updated serie of tutorials on OpenGL ES 2.0 for android. Check them out at: OpenGL ES 2.0

Last tutorial we worked a bit more on meshes and we have also talked about adding colors to our mesh. The most common way of adding colors to your mesh is to add a texture. There is a couple of different steps involved with adding a texture to the mesh I will try to go through them all and explain the basics about them.

Loading bitmaps

First step would be to get a bitmap to generate a texture from. You can get hold of a bitmap in many different ways from downloading, generating or simply just load one from the resources. I’m going with the simplest one for this example witch is loading from the resources.

Bitmap bitmap = BitmapFactory.decodeResource(contect.getResources(),

One other thing about textures is that some hardware requires that the height and width are in the power of 2 (1, 2, 4, 8, 16, 32, 64…). If you run a texture with a size of 30x30pixels on a hardware that don’t support it you will just get a white square (unless you change the default color).

Generating a texture

After we have loaded the bitmap we need to tell OpenGL to actually create the texture.

First thing we need to do is to let OpenGL generate some texture id’s that we will use as handles to the textures later on. In this example we will only have one texture.

// Create an int array with the number of textures we want,
// in this case 1.
int[] textures = new int[1];
// Tell OpenGL to generate textures.
gl.glGenTextures(1, textures, 0);

With the same parameters you can delete the textures:

// Delete a texture.
gl.glDeleteTextures(1, textures, 0)

Now when the texture id’s are generated we need to just like everything else tell OpenGL what to work with. With textures we use the command glBindTexture:

gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);

From this point all commands we call on regarding textures will be applied on to your texture with the generated id.


There is a couple of parameters we need to set on the texture, the first one is to tell OpenGL what to do if the texture need to be shrunk or magnified to match the rendered image.
If the texture is smaller it needs to be magnified that is done with the magnification function:

// Scale up if the texture if smaller.

And how to scale if the texture needs to be scaled down using the minification function.

// scale linearly when image smalled than texture

You need to pass an argument to these functions. I’m only going to show you two of them the rest you can investigate your self ;)

If you want a crisp and clean rendering like this image you need to use the GL10.GL_NEAREST parameter.

If you rather want a blurred image you should use the GL10.GL_LINEAR parameter.

UV Mapping

We will also need to tell OpenGL how to map this image onto the mesh this is done in two steps, fist we need to assign UV coordinates

UV mapping is the way we map the pixels on the bitmap to the vertices in our mesh. The UV coordinates are 0,0 in the upper left and 1,1 is the bottom right, like the left image below. The right image below illustrates how our plane is built. To get the texture mapped correctly we need to map the lower left part of the texture (0,1) to the lower left vertex (0) in our plane and we need to map the the bottom right (1,1) in the texture to the bottom right (1) to the bottom right in our plane and… you get the idea.

We put this mapping into a float array like this:

float textureCoordinates[] = {0.0f, 1.0f,
                              1.0f, 1.0f,
                              0.0f, 0.0f,
                              1.0f, 0.0f };

If we instead used 0.5 instead of 1.0 like this:

float textureCoordinates[] = {0.0f, 0.5f,
                              0.5f, 0.5f,
                              0.0f, 0.0f,
                              0.5f, 0.0f };

The texture will be mapped so the plane will have the upper left part of it.

Back to the glTexParameterf, if we go the other way and uses values higher then 1.0 like this:

float textureCoordinates[] = {0.0f, 2.0f,
                              2.0f, 2.0f,
                              0.0f, 0.0f,
                              2.0f, 0.0f };

We actually tell OpenGL to use part of the texture that does not exist so we need to tell OpenGL what to do with the part that does not exist.

We use the glTexParameterf function to tell OpenGL what to do with the texture. By default OpenGL uses something called GL_REPEAT.

GL_REPEAT means that OpenGL should repeat the texture beyond 1.0.
GL_CLAMP_TO_EDGE means that OpenGL only will draw the image once and after that just repeat the last pixel line the rest of the image.

Since we are working with a 2D texture so we need to tell OpenGL what to do in two directions: GL_TEXTURE_WRAP_S and GL_TEXTURE_WRAP_T.

Below you see a chart with the 4 combinations of GL_REPEAT and GL_CLAMP_TO_EDGE.


This is how we use the glTexParameterf function:


The last thing we need to do is to bind the bitmap we loaded to the texture id we created.

GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);

Using the texture

To be able to use the texture we need just like with everything else create a byte buffer with the UV coordinates:

FloatBuffer byteBuf = ByteBuffer.allocateDirect(texture.length * 4);
textureBuffer = byteBuf.asFloatBuffer();


// Telling OpenGL to enable textures.
// Tell OpenGL where our texture is located.
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
// Tell OpenGL to enable the use of UV coordinates.
// Telling OpenGL where our UV coordinates are.
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);

// ... here goes the rendering of the mesh ...

// Disable the use of UV coordinates.
// Disable the use of textures.

Putting it all together

I’m using a modified version of the code from the previous tutorial. The different is mostly that I renamed some variables and functions and added more comments and all code is now under Apache License. To make the code easier to understand I removed the previous plane and added a new easier one called SimplePlane.

Updating the Mesh class

The first thing we need to do is to update the Mesh class (se.jayway.opengl.tutorial.mesh.Mesh). We need to add the functionality to load and render a texture.

We need to be able to set and store the UV coordinates.

// Our UV texture buffer.
private FloatBuffer mTextureBuffer;

 * Set the texture coordinates.
 * @param textureCoords
protected void setTextureCoordinates(float[] textureCoords) {
	// float is 4 bytes, therefore we multiply the number if
        // vertices with 4.
	ByteBuffer byteBuf = ByteBuffer.allocateDirect(
                                           textureCoords.length * 4);
	mTextureBuffer = byteBuf.asFloatBuffer();

We also need to add functions to set the bitmap and create the texture.

// Our texture id.
private int mTextureId = -1;

// The bitmap we want to load as a texture.
private Bitmap mBitmap;

 * Set the bitmap to load into a texture.
 * @param bitmap
public void loadBitmap(Bitmap bitmap) {
	this.mBitmap = bitmap;
	mShouldLoadTexture = true;

 * Loads the texture.
 * @param gl
private void loadGLTexture(GL10 gl) {
	// Generate one texture pointer...
	int[] textures = new int[1];
	gl.glGenTextures(1, textures, 0);
	mTextureId = textures[0];

	// ...and bind it to our array
	gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureId);

	// Create Nearest Filtered Texture

	// Different possible texture parameters, e.g. GL10.GL_CLAMP_TO_EDGE
	gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S,
	gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,

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

And finally we need to add the call to the texture loading and to actually tell OpenGL to render with this texture. I removed some code so the page would not be so long but you will find the code complete in the attached zip file.

// Indicates if we need to load the texture.
private boolean mShouldLoadTexture = false;

 * Render the mesh.
 * @param gl
 *            the OpenGL context to render to.
public void draw(GL10 gl) {

	// Smooth color
	if (mColorBuffer != null) {
		// Enable the color array buffer to be used during rendering.
		gl.glColorPointer(4, GL10.GL_FLOAT, 0, mColorBuffer);

	if (mShouldLoadTexture) {
		mShouldLoadTexture = false;
	if (mTextureId != -1 && mTextureBuffer != null) {
		// Enable the texture state

		// Point to our buffers
		gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, mTextureBuffer);
		gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureId);

	gl.glTranslatef(x, y, z);


	// Point out the where the color buffer is.
	gl.glDrawElements(GL10.GL_TRIANGLES, mNumOfIndices,
			GL10.GL_UNSIGNED_SHORT, mIndicesBuffer);


	if (mTextureId != -1 && mTextureBuffer != null) {



Creating the SimplePlane class

We also need to create the The code is pretty simple and self-explaining if you have read my previous tutorials. The new element is the textureCoordinates variable.

package se.jayway.opengl.tutorial.mesh;

 * SimplePlane is a setup class for Mesh that creates a plane mesh.
 * @author Per-Erik Bergman (
public class SimplePlane extends Mesh {
	 * Create a plane with a default with and height of 1 unit.
	public SimplePlane() {
		this(1, 1);

	 * Create a plane.
	 * @param width
	 *            the width of the plane.
	 * @param height
	 *            the height of the plane.
	public SimplePlane(float width, float height) {
		// Mapping coordinates for the vertices
		float textureCoordinates[] = { 0.0f, 2.0f, //
				2.0f, 2.0f, //
				0.0f, 0.0f, //
				2.0f, 0.0f, //

		short[] indices = new short[] { 0, 1, 2, 1, 3, 2 };

                float[] vertices = new float[] { -0.5f, -0.5f, 0.0f,
                                                  0.5f, -0.5f, 0.0f,
                                                 -0.5f,  0.5f, 0.0f,
                                                  0.5f, 0.5f, 0.0f };



The info used in this tutorial is collected from:
Android Developers
OpenGL ES 1.1 Reference Pages

You can download the source for this tutorial here: Tutorial_Part_VI
You can also checkout the code from:

Previous tutorial: OpenGL ES Tutorial for Android – Part V – More on Meshes

This Post Has 105 Comments

  1. Lorenz

    Great tutorial..
    thank you very much

  2. JHandal

    Very well explained ,clear as crystal.

    Actually working in 3D .


  3. Axeves

    Tack för hjälpen Per-Erik

  4. Peter

    How would I go about applying this to just 2d shapes (just like the ones in part 3)?

  5. Per-Erik Bergman

    Hi Peter! I’m not sure what you mean. This tutorial adds a texture to a simple 2D shape. This tutorial uses 2D planes just like part 3.

  6. JHandal

    Hi Per-Erik

    The tutorial runs fine in the emulator 2.2,but in the Droid 2.2.1

    the bitmap is not binding (the square is white) and there is not error message.


  7. Per-Erik Bergman

    Hi JHandal!

    Thanks for pointing it out. I forgotten to mention that some hardware requires a texture where the height and width are in the power of 2. Added a section under ‘Loading bitmaps’. And I changed the texture in the zip file as well.

  8. jb

    I really have learned a lot and I would like to thank-you for your efforts.

    I do have a request. It seems there are no good tutorials for 2D Orthogrphic projections anywhere and I feel you would make the most sense of it to the people. :)


  9. Per-Erik Bergman

    Thanks jb, I will consider it.

  10. Paul

    Great tutorials! Thanks!

    In future posts it will be nice to read about shapes interaction with each other, collision detection, gravity etc ;)

  11. Jacques

    Thanks for this great tutorial!

    I have a question. If I render two different objects as meshes and put them in the Group class, the renderer cannot determine, which object is in the front and which is in the back although the depth test is enabled. Would you have a solution for this?


  12. Per-Erik Bergman

    Jacques, you either sort the meshes within that group or use gl.glEnable(GL_DEPTH_TEST) to enable the z-buffer.

  13. Julien

    Hi and thanks for this great tutorial.

    First of all, sorry for my english…
    I try to apply a texture to a cube (helped by your tutorial) but the result is not good because I can’t find the good texture coordonates.

    Here is my code :

    float vertices[] = { -width, -height, -depth, // 0
    width, -height, -depth, // 1
    width, height, -depth, // 2
    -width, height, -depth, // 3
    -width, -height, depth, // 4
    width, -height, depth, // 5
    width, height, depth, // 6
    -width, height, depth, // 7

    short indices[] = {
    0, 4, 5, //haut
    0, 5, 1,
    1, 5, 6, //droit
    1, 6, 2,
    2, 6, 7, //bas
    2, 7, 3,
    3, 7, 4, //gauche
    3, 4, 0,
    4, 7, 6, //devant
    4, 6, 5,
    3, 0, 1, //derriere
    3, 1, 2,

    float textureCoordinates[] = {
    // haut
    0.00f, 1.00f,
    1.00f, 1.00f,
    0.00f, 0.00f,
    1.00f, 0.00f,
    // droit
    0.00f, 1.00f,
    1.00f, 1.00f,
    0.00f, 0.00f,
    1.00f, 0.00f,
    // bas
    0.00f, 1.00f,
    1.00f, 1.00f,
    0.00f, 0.00f,
    1.00f, 0.00f,
    // gauche
    0.00f, 1.00f,
    1.00f, 1.00f,
    0.00f, 0.00f,
    1.00f, 0.00f,
    // devant
    0.00f, 1.00f,
    1.00f, 1.00f,
    0.00f, 0.00f,
    1.00f, 0.00f,
    // derriere
    0.00f, 1.00f,
    1.00f, 1.00f,
    0.00f, 0.00f,
    1.00f, 0.00f,

    So if you can explain me where I’m wrong, it could be nice.

    To finish, may I ask you to make a tutorial about collision detection?

    Thanks again.

  14. Mr. Bowman

    Great tutorial. The UV to Vertex translation was especially helpful, as working with other OpenGL tutorials they don’t seem to explicitly explain that.

    I got this working on a simple plane, but the texture seems to warp around the 2->1 edge (using vertices’s from the UV mapping section) when i rotate the image on the x or y.

    Here are some screenshots:

    Any thoughts on how to prevent this would be great.

  15. Mr. Bowman

    Found the answer to this, if anyone else wants it:
    Add this to your loadTexture method, or whereever you’re setting the other options such as GL_TEXTURE_2D:


    Took quite a bit of googling to find:

  16. paddax

    I have the same problem as JHandal, its working in the emulator but my Galaxy Tab is drawing a white square.

    The image is 128×128

  17. paddax

    I forgot to say what a great tutorial this has been.


  18. Per-Erik Bergman

    Mr Bowman: Sorry for the delay. Yes you use the gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST); this line is in the code since the first tutorial so I didn’t think of it when I made this one. This example is based on the code from the previous example.

  19. Per-Erik Bergman

    paddax: I have no access to a Galaxy Tab so I can’t investigate. If you figure it out please share with the rest of the readers.

  20. ray

    I didn’t have much experience in OpenGL.
    then could i put a .max mode to opengl es?
    What kind of 3d files could add in my android sys?

  21. Per-Erik Bergman

    ray: OpenGL do not have any 3D file parser built in. You will have to find one or make one your self.

  22. Per-Erik Bergman

    paddax: I just tried this tutorial on a Galaxy Tab with no problems.

  23. prasad

    how can we draw a spear in openGL android?
    please publish a example code for it

  24. Josh

    I have the same problem as JHandal and paddax on a Droid. I discovered if I set minSdkVersion to something less than 4 in the manifest, it works. If I set it to 5 or greater, it just draws a white square on my phone but works fine in the emulator. Any idea what would cause this?

  25. Josh

    I’ve solved my own problem. If you put the image in /res/drawable-nodpi/ it works. It seems that if it’s in the nodpi folder Android knows not to scale it, otherwise the OS is scaling the image so it’s no longer a power of two. Not sure why this is dependent on the minSdkVersion in the manifest, though.

  26. Per-Erik Bergman

    prasad: I don’t have the data for drawing a sphere if that what you mean. I usually have a parser and a 3d program for that.

    Josh: I usually put my images in /res/drawable/

  27. vinay

    Thanks, these tutorial helped me a lot.

  28. Per-Erik Bergman

    Julien: Sorry I missed answer your question. Since we map the textures to the vertices and you only can have one UV coordinate per vertex you need to think of the box as six planes so in each corner you will have 3 vertices.

  29. AedonEtLIRA

    How would you go about adding multiple textures?

  30. AedonEtLIRA

    to the same plane?

  31. Steve

    Hi. I’m a little bit further on than this. I’m trying to apply lighting to a scene. Although I have only defined one light, if I have two objects or more, rotated and translated independently, it’s as though each object has it’s own independent light source, rotated and translated as per the individual objects. I’ve tried applying lighting at every stage from the OnSurfaceCreated method, to every conceivable point in the OnDraw method (i.e. every other line is now a commented out call to a temporary applyLighting method). Are you planning to do a tutorial on lighting? This is just doing my head in.

  32. Anton

    Thank you very much for the tutorial, it’s realy great and clear.
    But could you make an extantion of this tutorial and describe how to put a texture on a 3d shape, like cube for example? Using indices, like in this tutorial.

  33. Matt

    Steve, I’m with you on the lighting problems, did you get your head round it ?
    I add one light and nothing is quite as expected when objects are rotated in the scene.

  34. Steve

    Unfortunately not. Right now I’m thinking: “do I have enough to do the basics of what I want to do” and the answer is yes. Lighting will have to wait :(

  35. LB


    i really like the tutorials. i learnt opengl in the past (jogl) but i forgot about it and i want to develop for android now. it really helps!

    can you please make a tutorial for the next topics:
    -specular light.
    -transparent textures on meshes.
    -reflection effect (like a mirror) , without using weird tricks (like creating the same objects flipped) .
    -check out which 3d object is being selected (when you touch the screen) .

  36. Nikhil Belsare


    I was trying to implement a similar functionality using glDrawArrays. However, I’m unable to get it running on Android. I’m trying port an existing iPhone application to Android. The same openGL code works fine on iPhone.

    Has anyone faced similar issue with glDrawArrays?

  37. Paul McEwan

    Great tutorials! However, I have a bit of a problem scaling your solution up.

    I was trying to convert your solution into a 2D sprite engine using the flat textured planes as the sprites.

    Got transparent textures working very easily, but when I try to add more than about 10 textured meshes to the scene it force closes.

    I’m having to load the texture onto each mesh in my array using loadBitmap also, which doesn’t seem right.

    I’m starting to think I should go back to Canvas.drawBitmap again, but it’s so s-l-o-w! :)

  38. Andrei

    Great tutorials, thanks for taking the time to write them!

  39. Zeljko

    Great tutorial!
    It would be nice if you have time to write about model loading.
    md2, 3ds or colada.
    Perfect ending for this tutorial series would be:
    User moving camera around few models (car, house or ..).
    If you add all this I’ll more then glad to donate some money.
    Anyway, thank you so much!

    Zeljko J.

  40. Wagaf

    Thank you for this excellent tutorial !!!

    Like Josh, I had to move the texture to drawable-nodpi (instead of drawable) to the code to work inside my application with android 2.1+.

    I made some quick tests and the problem seems to appear starting from SDK version 4.

  41. S4milli4

    Hey ! I have the same problem than Julien earlier i.e. im trying to texture a cube but im having weird results. Actually I started from the plane example you gave were we had the following bonded values :

    0 -> 0,1
    1 -> 1,1
    2 -> 0,0
    3 -> 1,0

    Then i thought for a cube, we have to include the third dim in the following way :

    0 -> 0,1,0
    1 -> 1,1,0
    2 -> 0,0,0
    3 -> 1,0,0
    4 -> 0,1,1
    5 -> 1,1,1
    6 -> 0,0,1
    7 -> 1,0,1

    Am I right until here ?

  42. S4milli4

    Btw here are my coordonates :

    float textureCoordinates[] = {
    0.0f, 1.0f, 0.0f,
    0.0f, 1.0f, 1.0f,
    1.0f, 1.0f, 1.0f,
    1.0f, 1.0f, 0.0f,

    1.0f, 1.0f, 0.0f,
    1.0f, 1.0f, 1.0f,
    0.0f, 0.0f, 1.0f,
    0.0f, 0.0f, 0.0f,

    0.0f, 0.0f, 0.0f,
    0.0f, 0.0f, 1.0f,
    1.0f, 0.0f, 1.0f,
    1.0f, 0.0f, 0.0f,

    1.0f, 0.0f, 0.0f,
    1.0f, 0.0f, 1.0f,
    0.0f, 1.0f, 1.0f,
    0.0f, 1.0f, 0.0f,

    0.0f, 1.0f, 1.0f,
    1.0f, 0.0f, 1.0f,
    0.0f, 0.0f, 1.0f,
    1.0f, 1.0f, 1.0f,

    1.0f, 0.0f, 0.0f,
    0.0f, 1.0f, 0.0f,
    1.0f, 1.0f, 0.0f,
    0.0f, 0.0f, 0.0f

  43. ABC

    Can we draw a circle over a SimplePlane object?

  44. Bruno

    Hi Per-Erik,

    First of all, thank you for your tutorials. They are fantastic to anyone who wants to start with opengl on android, like me!

    Actually, i’ve a problem that i can’t find the answer.
    I need to use opengl above a camera frame instead of a black background.
    Can you help me, please?

  45. Nayanesh Gupte

    can you give me a link or any ideas or can you post on object detection in android?

  46. Nayanesh Gupte

    how to map screens x,y co-ordinates with openGl Es co-ordinates x,y,z for object detection?

  47. Donny

    Thanks for the tutorial! Couple of quick comments:

    I believe once that you have loaded a texture, then you can safely call bitmap.recycle() to free some resources.

    Also, I’m using PNGs with transparency. If you want the transparency to work, then you have to do the following:

    – In your GLSurfaceView.Renderer onSurfaceCreated, add these lines:
    gl.glBlendFunc(GL10.GL_ONE, GL10.GL_ONE_MINUS_SRC_ALPHA);

    – In your GLSurfaceView constructor, add these lines:
    setEGLConfigChooser(8, 8, 8, 8, 0, 0);

  48. Jonathan Barton

    The OpenGL here is memory hungry. I’ve adapted this code to handle a deck of cards, two sided makes it +110 planes. In this code if you put ” for (int i = 0; i < 130; i++) {" around the "SimplePlane plane = new SimplePlane();" to "renderer.addMesh(plane);" so it creates a lot of models, it will call the GC every 30 seconds or so, freeing up 90,000 objects of 2MB. This lags the application somewhat, and that's before animation.

    Is there anyway to be more polite to the garbage collector?

  49. Jonathan Barton

    Afterthought… Thanks so much for the great tutorial :D
    I didn’t mean to come across as snappy, I just spent 8 hours debugging my code trying to find the leak, until I realized it was from here (no offense) and it didn’t show up with only 1 model like it did with my 130 models :P

    If it helps, I identified these calls as being the greedy ones; gl.glVertexPointer(), gl.glTexCoordPointer() and gl.glDrawElements(). Unfortunately they seem to be rather necessary ones! Perhaps there is a way so that they aren’t called every frame? Or perhaps another way of rendering the textures? In my application ( plug: ) its calling the
    GC every 15 seconds for 100 to 200ms each time.

    Again cheers for all your good work :D

  50. Hachi

    great tutorial.

    But I have a question!

    I have read in a book of OpenGL (not ES) that the texture coords origin are in the left-bottom corner.

    ¿Can Anybody explain this?

  51. giacomo

    fantastici questi tutorial su OpenGl… finalmente qualcuno con il dono della comprensibilità :)

    sorry for posting in my language, but is better an average italian than a horrible english :))

  52. nhan

    can u help me! how to code a sphere in android

  53. Breno

    Pretty nice Tutorial man! I’m on a 2d game project here and some doubts someone here might be able to answer:

    – What I understood until now (maybe Im completely wrong here) is that a 2D game is simply a plane put on screen perpendicular to the camera, and on each frame, a lot of textures are drawn on this plane. Am I right?
    – In that case, what should be the size of the plane (the size of the device’s screen or bigger, so I can pan the camera around?)
    – And what should be the distance of the camera to the plane? My bet here is that if I use orthogonal projection of the plane that distance won’t matter at all… right?

    Thank you!

  54. Helen

    Thanks at all!!!! It it the greatest tutrial!

  55. Zvi Doron

    Hello Per-Erik

    Thank you for your superb tutorials – there is a sore shortage of them on the web!

    Are you planning to continue into the subjects of lighting and normals?

  56. taymless

    Your tutorials are great. I still hope you are planning to add some more, even though it’s been a few months.

    If you do, I’d love to see you cover some interactions. Since not many people are planing to build something that is just eye candy without any interactivity.

  57. CP Gangstaz

    This is the dopest tutorial in the hood!

  58. Chris

    Really nice set of tutorials, really helped to speed my understanding of how to get OpenGL running on Android, next step a 3D MMORPG!

  59. RGB

    The issue with the Galaxy Tab is caused for not using bitmaps with a width or height no power of 2.

  60. Ian

    Brilliant! Thanks. This is a great starting point – and well structured code!

  61. yyfish

    great tutorial, thanks!

    when i add this “android:minSdkVersion=”7″” to the xml file AndroidManifest.xml. and it could not see the textures, just a white box…

    i don’t know why this…

    thanks again.

  62. Mark

    For those having issues with the Textures loading as White Boxes (even with dimensions as a power of 2) be sure to make the calls to gl.glTexParameterf right before you call GLUtils.texImage2D. You CAN’T just call them once from the OnSurfaceCreated on your renderer for example.

  63. shihab

    Thanks for the gr8 tutorial.

    I would like to reconstruct 3d view from set of images. The images are the result of a CT scanner. Can you guide me how to do this? Is it possible in the android?


  64. Helen

    Thank you for your tutorials!
    Please tell us how to add textures to a cube or textures for each segment.
    It would help alot. Best regards!

  65. Helen

    I have a question related to part 4 – textures.
    What are u using your group for in this example?

  66. Karlsson

    I loved the first 6 parts, and now I’m anxiously awaiting the next part… :-) Hope it will be available soon!

  67. niek

    Any thought about making similar tutorials for Open GL ES 2.0?

  68. Mack

    Per-Erik Bergman,
    I greatly appreciate the time and effort you spent releasing these guides. You have saved me my job =)
    Thank you!


  69. Thomas Barrasso

    Fantastic series of tutorials, very comprehensive and useful. Thank you so much!

  70. Daniele

    Very interesting tutorial, but I’m approching to it for solve a question about OpenGL: is it possible to apply 1 texture to frontside of a plane and another to back side?

  71. Charlie

    I would like to add my thanks for this great series of tutorials. You have helped me get my proof-of-concept prototype working in just 4 days!

    I’m having a very Swedish week between these tutorials and reading “The Girl with the Dragon Tattoo”

    Keep up the good, thorough and generous work.

  72. A. Rahman

    Did you worked on OpenGL ES 2.0 ???
    If yes then please reply me via an e-mail.
    Thank you ..

  73. Shathiesh Rao

    Is there any way we can draw texture without loading?
    Is there a way for inputting Bitmap to eglCreateImageKHR as GraphicBuffer?

  74. ayman

    u r my hero

  75. rajesh

    Excellent tutorial,

    Can u please provide with a code to render a sphere.

  76. Prakash M

    Thanks for the tutorials. It greatly helped me to understand basics of opengl.

    -prakash m.

  77. nanthakumar

    Great. very much useful. Thank you for your kind service.

  78. Adao

    Great tutorials. Please write more articles about opengl es, I’ll be glad to donate if has donate button. I’m waiting for your next article, thanks a lot. Wish you happy every day!!!

  79. Miksupiksu

    Thanks for this tutorial! Sure is educational!

    I am having trouble with textures on all Samsung devices: Galaxy, GalaxyII and galaxy Tab.

    The current version of this tutorial doesn’t load the textures on the above devices… =(

    In my own code I (, which doesn’t work either):
    my PNGs are uncompressed, are power of 2, I call gl.glTexParameterf before calling GLUtils.texImage2D.

    In the GLSurfaceView (sub-class) I use:
    setEGLConfigChooser(8, 8, 8, 8, 0, 0);

    This works great on, say, HTC! Now why on earth does this not work on Samsung – please Per-Erik Bergman – you are my only hope!


  80. ExiRouS

    First of all – Thank you for the Great Tutorial!
    Now, a question – is there a way to set the Alpha of the texture ?
    Suppose i need it to animate with Fading in and out….
    Thank you in advance.

  81. Curious

    Is there possible to check after gldeleteTexture that it successfully deleted or not?

  82. Vkrissz


    I read all your tutorials about OpenGL, and they are awesome!

    Thank you very much!

  83. Ammu

    Hi, i have drawn a single image in this open Gl surface view . can u pls help me in grawing gallery of images using open Gl surface view.

  84. Hyper

    Daniele, did you solve your problem ?
    Does anybody knows how to apply two different textures to both sides of one plane ? I’m looking for example or tutorial.
    Jonathan Barton how did you do your deck of cards .? Each card is made from one plane or from two planes ?

  85. caporaltito

    Well, that was a great tutorial but for me it completely leaked my app. My memory is way overused !

  86. Zari


    btw loved the tutorial, u really gave me some basics, i have been banging my head on this OpenGL for about 2 weeks and nothing made any sense. now i think i can gather info from here and knowledge and make use of this and learn more.

    Thankx a lot agian
    one question can i use ur code and create an app and sell it. or it my be in violation with Apache licence.

    plz do reply thankx

  87. Evren Ozturk

    Eric you’ve helped me a lot. With your help and 3 days of googling I’ve started to creating my first Android game. I couldn’t do this that fast without your help. Thank you very much for these usefull tutorials.

  88. Anju Dahiya

    Thank you so much.With your help I learn Open GL ES Concepts just in 1 day. :) :)

  89. Albert

    Thank you so much, Per-Erik.
    Your 6 tutorials help me a lot.

  90. Venge

    Thank you very much for making this info free for all. Helped me a lot.

  91. chiehming

    Great tutorial..
    thank you very much.
    But I have some questions.
    How to combine orientation sensor with this tutorial 3d plane rotation?

  92. rodrigogq

    Thank you very much for this tutorial! It was really straightforward! Great job!

  93. 老徐

    thank you very much.
    i have gotten a lot from your tutorial

  94. FiniteResource

    Great intro.

    I did have a problem when trying to add a second surface object. Seemed to fix it with glPushMatrix() and glPopMatrix() in


    gl.glTranslatef(x, y, z);
    gl.glRotatef(rx, 1, 0, 0);
    gl.glRotatef(ry, 0, 1, 0);
    gl.glRotatef(rz, 0, 0, 1);

    // Point out the where the color buffer is.
    gl.glDrawElements(GL10.GL_TRIANGLES, mNumOfIndices,
    GL10.GL_UNSIGNED_SHORT, mIndicesBuffer);
    // Disable the vertices buffer.


  95. Joe

    Thank you for these series of tutorials. They are great! Would you ever consider in making a tutorial on how to load a 3d object created from Blender, 3DS Max, or Maya and render it on OPENGL ES Android?

  96. wolfbigbig

    Hi and thanks for this great tutorial.
    I have a thorny problem. Now I want render two different planes and with two different texture, What should I do?
    When I make a new plane, Unfortunately It just render one plane. I do not know where the problem lies. Here is my code block.

    public class FontPlane extends Mesh {

    public FontPlane(){

    public FontPlane(float width, float height){
    float textureCoordinates[] = { 0.0f, 2.0f, //
    2.0f, 2.0f, //
    0.0f, 0.0f, //
    2.0f, 0.0f, //

    short[] indices = new short[] { 0, 1, 2, 1, 3, 2 };

    float[] vertices = new float[] { -0.5f, -0.5f, 0.0f, 0.5f, -0.5f, 0.0f,
    -0.5f, 0.5f, 0.0f, 0.5f, 0.5f, 0.0f };


    // Create a new plane.
    FontPlane fontPlane = new FontPlane(1, 1);
    fontPlane.z = 1.5f;
    fontPlane.ry = -65;

    If you want know other codes, let me konw.
    Thank you again.

  97. Jiajun

    Thank you

Leave a Reply