views:

354

answers:

2

Whats the recommended way of displaying a background image in an OpenGL ES app.

  1. UIImage added to view hierarchy underneath glview?
  2. image drawn in OpenGL draw routine from texture in memory?

Are there any performance / memory considerations to take account of?

+2  A: 

glDrawTexOES the best choice.

thanks, what's the OES stand for? is is aimed at opengles on the iphone or opengl in general. Is there any example code floating about?
PeanutPower
See example at http://iphone-3d-programming.labs.oreilly.com/ch07.html#ch07_id35816945 Be careful,"This extension is not supported under OpenGL ES 2.0.", so for u will need another solution for iPhone 3GS.
Why is it the best choice?
Rob Jones
GL_OES_draw_texture shortcuts the need to pass triangles/quads and such. Look at http://www.khronos.org/registry/gles/extensions/OES/OES_draw_texture.txt . This extension defines a mechanism for writing pixel rectangles from one or more textures to a rectangular region of the screen. This capability is useful for fast rendering of background paintings, bitmapped font glyphs, and 2D framing elements in games. This extension is primarily intended for use with OpenGL ES.
+1  A: 

I like to load a texture using Apple's Texture2D class. Create a quad (two triangles, six vertices) that maps to the corners of the screen. Then you map the texture coordinates to the vertices, pass that to glDrawArrays and go. I actually have a Class that takes a frame in CG Coordinates, converts that to OpenGL Coordinates and then draws the image in the frame.

Let's say you have a struct like this:

struct {
  GLfloat x;             // OpenGL X Coordinate
  GLfloat y;             // OpenGL Y Coordinate
  GLfloat z;             // OpenGL Z Coordinate
  GLfloat s;             // Texture S Coordinate
  Glfloat t;             // Texture T Coordinate
} vertexData;

And an array of vertex data like this:

struct vertexData verts[6];

And you have a Texture2D object:

 texture = [[Texture2D alloc] initWithImage:[UIImage imageNamed:image] filter:filter pixelFormat:pixelFormat];

So, now you have to fill in the vertex array. Assuming 3D, x range [-1, 1] and y range [-1, 1], origin for z, then you would initialize your vertices like this:

verts[0].x = verts[1].x = verts[5].x = -1.0;
verts[2].x = verts[3].x = verts[4].x = 1.0;

verts[0].y = verts[2].y = verts[4].y = 1.0;
verts[1].y = verts[3].y = verts[5].y = -1.0;

verts[0].z = verts[1].z = verts[2].z = 0.0;
verts[3].z = verts[4].z = verts[5].z = 0.0;

verts[0].s = verts[1].s = verts[5].s = tlxf;
verts[2].s = verts[3].s = verts[4].s = trxf;

verts[0].t = verts[2].t = verts[4].t = ttyf;
verts[1].t = verts[3].t = verts[5].t = tbyf;

Finally, you need to draw:

glBindTexture(GL_TEXTURE_2D, texture.name);
glVertexPointer(3, GL_FLOAT, sizeof(struct vertexData), &verts[0].x);
glTexCoordPointer(2, GL_FLOAT, sizeof(struct vertexData), &verts[0].s);
glDrawArrays(GL_TRIANGLES, 0, 6);

I'm leaving out any details about setting up OpenGL. I assume you've done that if you're getting this far.

There are tons of performance and memory constraints to think about when working in OpenGL, but I wouldn't recommend getting too worried about them just yet. Once you get it working, profile it with the OpenGL Instrument to see if have any performance issues, then deal with those.

Apple has a really good document describing best practices, and there are some useful questions on SO as well. I'm sure you will be able to search for them once you know what you're up against (if anything).

Rob Jones
And all this is just for background image ?.. glDrawTexOES is much more convenient for background images. Using hand coded quad for background image is overkill.
Did you miss the part where I said this is all wrapped in a class? You know, because drawing a background image is just a special case of drawing an image. I tried to break that down a bit for the op rather than present the whole class.
Rob Jones
"Did you miss the part where I said this is all wrapped in a class?" it's good to have a wrapper, but it's not so good to pester OpenGL ES stack with superfluous operations.
Alexander is right, the best choice is glDrawTexOES. And for your solution Rob, using GL_TRIANGLES in this case is not the best choice either but rather go with GL_TRIANGLE_STRIP for reducing the size of the buffer transfer to the GL-hardware. Anyways, that is basically all nitpicking as we are talking about one single draw and not zillions.
Till