views:

113

answers:

1

Hello,

I'm having a problem rendering a background texture in my iPhone app. The following images show the problem:

http://www.tojamgames.com/wp-content/uploads/2010/09/background_layer1.png

tojamgames.com/wp-content/uploads/2010/09/IMG_0246.png (can't make this a link, sorry)

First one is the correct image, the second one is the one that has been drawn with OpenGL ES (yes, it is smaller, I cropped it manually in a photo editor to remove some of the game UI interface. You can get the idea of the distortion effect pretty clearly from this, though). Obviously, the lines of distortion across rendered texture aren't ideal. Here's my code that sets up opengl, loads the texture, and renders the image - any help would be great!! Sorry this is long, but I'm trying to provide as much info as possible :-P

OpenGL Initialization:

glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
glShadeModel(GL_FLAT);
glDisable(GL_DITHER);
glDisable(GL_LIGHTING);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrthof(0, screenBounds.size.width, 0, screenBounds.size.height, -1, 1);

glMatrixMode(GL_MODELVIEW);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND_SRC);
glEnableClientState(GL_VERTEX_ARRAY);

glDisable(GL_DEPTH_TEST);

glClearColor(1.0f, 1.0f, 1.0f, 0.0f);

Texture Loading:

glGenTextures(1, &_name);
glGetIntegerv(GL_TEXTURE_BINDING_2D, &saveName);
glBindTexture(GL_TEXTURE_2D, _name);

glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);

Drawing Scene

[EAGLContext setCurrentContext:context];
glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);


glViewport(0, 0, screenBounds.size.width , screenBounds.size.height);

// texture images have pre-multiplied alpha, so use this blend function
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);

[backgroundImage drawAtPoint:CGPointMake(0,0)];

// more game-specific stuff you don't need to see :-P

glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
[context presentRenderbuffer:GL_RENDERBUFFER_OES];

Finally, drawing the image itself (within the drawAtPoint method call)

// grab texture coordinates - maxS & maxT are the width & height in the POT texture
// that contain our NPOT image
GLfloat  coordinates[] = {  0,  0,
_maxS,         0,
    0,  _maxT,
_maxS,         _maxT  };

GLfloat screenHeight = [[UIScreen mainScreen] bounds].size.height;

// adjust the vertices of the quad so they're contained within the bounding rect of the
// image in the game, subtracting from screenHeight to invert the OpenGL coordinate system
GLfloat vertices[] = { rect.origin.x, screenHeight - rect.origin.y, 0.0,
rect.origin.x + rect.size.width, screenHeight - rect.origin.y, 0.0,
rect.origin.x, screenHeight - (rect.origin.y + rect.size.height), 0.0,
rect.origin.x + rect.size.width, screenHeight - (rect.origin.y + rect.size.height), 0.0 };

glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnable(GL_TEXTURE_2D);

glBindTexture(GL_TEXTURE_2D, _name);
glVertexPointer(3, GL_FLOAT, 0, vertices);
glTexCoordPointer(2, GL_FLOAT, 0, coordinates);

glEnable(GL_BLEND);

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

glDisable(GL_BLEND);

glDisable(GL_TEXTURE_2D);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);

Again, sorry this is long, but hopefully it provides enough that someone can see where I messed up!!! Thank you SO much!

Tom

A: 

That looks like color quantization. Is the kEAGLDrawablePropertyColorFormat property of your view set to kEAGLColorFormatRGB565? If so, see if changing it to kEAGLColorFormatRGBA8 resolves your issue.

Pivot
Thanks, Pivot, but the kEAGLDrawablePropertyColorFormat property is in fact kEAGLColorFormatRGBA8. If it helps any - I don't see this problem on the iPhone simulator, just on a device (but all devices i've tested, including 3G, 3GS, iPad)
Tojo
What are you using to decode your PNGs into the data pointer you hand to glTexImage2D?
Pivot
I'm using the Texture2D class provided by Apple in some of their examples. I've modified it slightly in the drawing section, but, I'm creating the Texture just via the initWithImage:(UIImage*) method. It basically allocates enough space for the image according to its pixel format and creates a CGBitmapContext and draws the UIImage onto it.
Tojo
Found the problem by looking more closely at the textures. The image in question had no transparency, so the Texture 2D code was trying to interpret it as RGB565. Going ahead and just interpreting everything as RGBA8 fixed it. It wasn't the view that was the problem, it was in fact the loading the data pointer - Pivot got me looking the right direction so you get the answer :)
Tojo