Topic : iPhone: OpenGL ES Texturing

Topic Archived This topic has been archived - replies are not allowed.


This question is answered. "Helpful" answers available: 0 . "Solved" answers available: 1 .



            Permlink
            Replies : 7 - Pages : 1 - Last Post : Jan 22, 2009 6:49 PM by: Anton Delprado
Macmenace

Posts: 52
From: Redmond, WA
Registered: Mar 19, 2008
iPhone: OpenGL ES Texturing
Posted: Aug 6, 2008 12:20 PM
 

I just began writing an iPhone game and I'm having difficulties displaying multiple textures.

Only the last texture I generate is appearing and all the textures I generated previously appear white.

Here is major rendering functions so far, is there anything that stands out as incorrect?

//Generates textures for a game object
  • (void)GenerateTextures:(Hairball::Objects)Obj
{
CGImageRef spriteImage;
CGContextRef spriteContext;
GLubyte *spriteData;
size_t width, height;
GLuint *tempTex;

// Creates a Core Graphics image from an image file
switch (Obj)
{
case Hairball::PLAYER:
spriteImage = UIImage imageNamed:@"Sprite.png".CGImage;
tempTex = &(TextureArray[0]);
break;

case Hairball::BACKGROUND:
spriteImage = UIImage imageNamed:@"BG1.png".CGImage;
tempTex = &(TextureArray[1]);
break;

case Hairball::HUD:
spriteImage = UIImage imageNamed:@"Icon.png".CGImage;
tempTex = &(TextureArray[2]);
break;

default:
break;
}

// Get the width and height of the image
width = CGImageGetWidth(spriteImage);
height = CGImageGetHeight(spriteImage);

if(spriteImage)
{
// Allocated memory needed for the bitmap context
spriteData = (GLubyte *) malloc(width * height * 4);
// Uses the bitmatp creation function provided by the Core Graphics framework.
spriteContext = CGBitmapContextCreate(spriteData, width, height, 8, width * 4, CGImageGetColorSpace(spriteImage), kCGImageAlphaPremultipliedLast);
// After you create the context, you can draw the sprite image to the context.
CGContextDrawImage(spriteContext, CGRectMake(0.0, 0.0, (CGFloat)width, (CGFloat)height), spriteImage);
// You don't need the context at this point, so you need to release it to avoid memory leaks.
CGContextRelease(spriteContext);
// Use OpenGL ES to generate a name for the texture.
glGenTextures(1, tempTex);
// Bind the texture name.
glBindTexture(GL_TEXTURE_2D, *tempTex);
// Speidfy a 2D texture image, provideing the a pointer to the image data in memory
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, spriteData);
// Release the image data
free(spriteData);
}
}

//Inits OpenGl for drawing

  • (void)setupView
{
//Creates object Manager to handle
ObjectMgr = new ObjectManager();

//Create Objects

GameObject* Object1 = new GameObject(Hairball::BACKGROUND, 0.0f, 0.0f, 0.0f, 0.0f, 3.2f, 3.2f);
ObjectMgr->AddToList(Object1);

GameObject* Object2 = new GameObject(Hairball::PLAYER, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f);
ObjectMgr->AddToList(Object2);

//Generate all textures
self GenerateTextures:Hairball::PLAYER;
self GenerateTextures:Hairball::BACKGROUND;

//For each obj assign a texture
std::list<GameObject*>::iterator Object = (ObjectMgr->mObjectList.begin());
std::list<GameObject*>::iterator End = (ObjectMgr->mObjectList.end());

//For each game object
while(Object != End)
{
//Apply texture to each object
switch ((*Object)->mObjectType)
{
case Hairball::PLAYER: (*Object)->mSpriteTexture = TextureArray[0]; break;

case Hairball::BACKGROUND: (*Object)->mSpriteTexture = TextureArray[1]; break;

case Hairball::HUD: (*Object)->mSpriteTexture = TextureArray[2]; break;

default:
break;
}
++Object;
}

// Clears the view with grey
glClearColor(0.5f, 0.5f, 0.5f, 1.0f);

// Set the texture parameters to use a minifying filter and a linear filer (weighted average)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

// Enable use of the texture
glEnable(GL_TEXTURE_2D);
// Set a blending function to use
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
// Enable blending
glEnable(GL_BLEND);
}

  • (void)drawView
{
EAGLContext setCurrentContext:context;

glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
glViewport(0, 0, backingWidth, backingHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrthof(-1.0f, 1.0f, -1.5f, 1.5f, -1.0f, 1.0f);
glMatrixMode(GL_MODELVIEW);

//Clear the backbuffer
glClear(GL_COLOR_BUFFER_BIT);

std::list<GameObject*>::iterator Object = (ObjectMgr->mObjectList.begin());
std::list<GameObject*>::iterator End = (ObjectMgr->mObjectList.end());

//For each game object
while(Object != End)
{
// Bind the texture name.
glBindTexture(GL_TEXTURE_2D, (*Object)->mSpriteTexture);

//apply transformations
glPushMatrix();
glTranslatef((*Object)->mPosition.x, (*Object)->mPosition.y, (*Object)->mPosition.z);
glRotatef((*Object)->mRotation, 0.0f, 0.0f, 1.0f);

(*Object)->mRotation += 0.5f; //Rotate

//Get current sprites verticies
glVertexPointer(2, GL_FLOAT, 0, (*Object)->mSpriteVertices);
glEnableClientState(GL_VERTEX_ARRAY);
//Get current sprites tex coords
glTexCoordPointer(2, GL_SHORT, 0, (*Object)->mSpriteTexcoords);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
//Render the vertex array
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

//pop the transformation matrix
glPopMatrix();
++Object;
}

glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
context presentRenderbuffer:GL_RENDERBUFFER_OES;
}

Mac Pro, Two 3GHz Dual-Core Intel Xeon, 410 GB HD, NVIDIA 8800 GT   Mac OS X (10.5.4)   Macbook Air, 1.6GHz Core 2 Duo, 80GB HD, 2GB RAM  
malkia

Posts: 8
From: Santa Monica, CA
Registered: Jun 11, 2008
Re: iPhone: OpenGL ES Texturing
Posted: Aug 6, 2008 12:44 PM   in response to: Macmenace
Helpful

It might help if you print (or debug) what the texture names are:

For example, print, or see the value of (*Object)->mSpriteTexture

glBindTexture(GL_TEXTURE_2D, (*Object)->mSpriteTexture);

Also check your texture coordinates.

Couldn't find anything else wrong with it though.

Try also exchanging:

self GenerateTextures:Hairball::PLAYER;
self GenerateTextures:Hairball::BACKGROUND;

To

self GenerateTextures:Hairball::BACKGROUND;
self GenerateTextures:Hairball::PLAYER;

MBP 2.6 GHz, 4 GB   Windows XP    
Tod Kuykendall


Posts: 1,081
From: San Diego
Registered: Oct 11, 2000
Re: iPhone: OpenGL ES Texturing
Posted: Aug 6, 2008 12:53 PM   in response to: Macmenace
Helpful

Only the last texture I generate is appearing and all the textures I generated previously appear white.

Everytime I've seen the blazing white texture it means your texture didn't load. Sanity check that each texture is actually loading and can be drawn individually because I bet you're missing at least one.

HTH,

=Tod

PS If you bracket your code with matching { code } tags (without the spaces) you'll get readable code posted which will help a ton.

G5/2.0x2, Dual XServes x2, XRAID, beige G3 501Mhz      
Macmenace

Posts: 52
From: Redmond, WA
Registered: Mar 19, 2008
Re: iPhone: OpenGL ES Texturing
Posted: Aug 6, 2008 1:28 PM   in response to: malkia
 

The value generated by glGenTextures() in (*Object)->mSpriteTexture for the BACKGROUND object is 1 and for the sprite object it is 2. Which appear to be correct values?

If I exchange:

self GenerateTextures:Hairball::PLAYER;
self GenerateTextures:Hairball::BACKGROUND;

To

self GenerateTextures:Hairball::BACKGROUND;
self GenerateTextures:Hairball::PLAYER;

then my scene goes from this:
http://img207.imageshack.us/img207/8229/picture1nf6.png

to this:
http://img253.imageshack.us/img253/5282/picture2gr8.png

So both textures draw, just not at the same time?

Oh, here it is formatted better:

//Generates textures for a game object
- (void)GenerateTextures:(Hairball::Objects)Obj
{
	CGImageRef spriteImage;
	CGContextRef spriteContext;
	GLubyte *spriteData;
	size_t	width, height;
	int texIndex = 0;
 
	
	// Creates a Core Graphics image from an image file
	switch (Obj) 
	{
		case Hairball::PLAYER:
			spriteImage = [UIImage imageNamed:@"Sprite.png"].CGImage;
			texIndex = 0;
			break;
			
		case Hairball::BACKGROUND:
			spriteImage = [UIImage imageNamed:@"BG1.png"].CGImage;
			texIndex = 1;
			break;
			
		case Hairball::HUD:
			spriteImage = [UIImage imageNamed:@"Icon.png"].CGImage;
			texIndex = 2;
			break;
			
		default:
			break;
	}
	
	// Get the width and height of the image
	width = CGImageGetWidth(spriteImage);
	height = CGImageGetHeight(spriteImage);
	
	if(spriteImage)
	{
		// Allocated memory needed for the bitmap context
		spriteData = (GLubyte *) malloc(width * height * 4);
		// Uses the bitmatp creation function provided by the Core Graphics framework. 
		spriteContext = CGBitmapContextCreate(spriteData, width, height, 8, width * 4, CGImageGetColorSpace(spriteImage), kCGImageAlphaPremultipliedLast);
		// After you create the context, you can draw the sprite image to the context.
		CGContextDrawImage(spriteContext, CGRectMake(0.0, 0.0, (CGFloat)width, (CGFloat)height), spriteImage);
		// You don't need the context at this point, so you need to release it to avoid memory leaks.
		CGContextRelease(spriteContext);
		// Bind the texture name. 
		glBindTexture(GL_TEXTURE_2D, TextureArray[texIndex]);
		// Speidfy a 2D texture image, provideing the a pointer to the image data in memory
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, spriteData);
		// Release the image data
		free(spriteData);
	}
}
 
 
//Inits OpenGl for drawing
- (void)setupView
{		
	//Creates object Manager to handle
    ObjectMgr = new ObjectManager();
	
	//Create Objects
	GameObject* Object1 = new GameObject(Hairball::BACKGROUND, 0.0f, 0.0f, 0.0f, 0.0f, 3.2f, 3.2f);
	ObjectMgr->AddToList(Object1);
	
	GameObject* Object2 = new GameObject(Hairball::PLAYER, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f);
	ObjectMgr->AddToList(Object2);
	
 
	//Generate all textures
	glGenTextures(NUMTEXTURES, TextureArray);	// Use OpenGL ES to generate a name for the texture.
	[self GenerateTextures:Hairball::BACKGROUND];
	[self GenerateTextures:Hairball::PLAYER];
	
	//For each obj assign a texture
	std::list<GameObject*>::iterator Object = (ObjectMgr->mObjectList.begin());
	std::list<GameObject*>::iterator End = (ObjectMgr->mObjectList.end());
	
	//For each game object
	while(Object != End)
	{
		//Apply texture to each object
		switch ((*Object)->mObjectType) 
		{
			case Hairball::PLAYER:     (*Object)->mSpriteTexture = TextureArray[0]; break;
				
			case Hairball::BACKGROUND: (*Object)->mSpriteTexture = TextureArray[1]; break;
			
			case Hairball::HUD:        (*Object)->mSpriteTexture = TextureArray[2]; break;
				
			default:
				break;
		}
		++Object;
	}
	
	// Clears the view with grey
	glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
 
	// Set the texture parameters to use a minifying filter and a linear filer (weighted average)
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
		
	// Enable use of the texture
	glEnable(GL_TEXTURE_2D);
	// Set a blending function to use
	glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
	// Enable blending
	glEnable(GL_BLEND);
}
 
- (void)drawView 
{
	[EAGLContext setCurrentContext:context];
	
	glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
	glViewport(0, 0, backingWidth, backingHeight);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrthof(-1.0f, 1.0f, -1.5f, 1.5f, -1.0f, 1.0f);
	glMatrixMode(GL_MODELVIEW);
	
	//Clear the backbuffer
	glClear(GL_COLOR_BUFFER_BIT);
	
	std::list<GameObject*>::iterator Object = (ObjectMgr->mObjectList.begin());
	std::list<GameObject*>::iterator End = (ObjectMgr->mObjectList.end());
	
	//For each game object
	while(Object != End)
	{
		// Bind the texture name.
		glBindTexture(GL_TEXTURE_2D, (*Object)->mSpriteTexture);
		
	    //apply transformations
	    glPushMatrix();
	    glTranslatef((*Object)->mPosition.x, (*Object)->mPosition.y, (*Object)->mPosition.z);
	    glRotatef((*Object)->mRotation, 0.0f, 0.0f, 1.0f);
	
	    //(*Object)->mRotation += 0.5f; //Rotate
	
	    //Get current sprites verticies
	    glVertexPointer(2, GL_FLOAT, 0, (*Object)->mSpriteVertices);
	    glEnableClientState(GL_VERTEX_ARRAY);
	    //Get current sprites tex coords
	    glTexCoordPointer(2, GL_SHORT, 0, (*Object)->mSpriteTexcoords);
	    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
	    //Render the vertex array
	    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
	
	    //pop the transformation matrix
	    glPopMatrix();
		++Object;
	}
	
	glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
	[context presentRenderbuffer:GL_RENDERBUFFER_OES];
}
 
 


Mac Pro, Two 3GHz Dual-Core Intel Xeon, 410 GB HD, ATI X1900 XT &#38; NVIDIA 7300 GT   Mac OS X (10.5.2)   Macbook Air, 1.6GHz Core 2 Duo, 80GB HD, 2GB RAM  
Macmenace

Posts: 52
From: Redmond, WA
Registered: Mar 19, 2008
Re: iPhone: OpenGL ES Texturing
Posted: Aug 6, 2008 8:02 PM   in response to: Tod Kuykendall
 

One odd thing I've noticed if I replace
		// Bind the texture name.
		glBindTexture(GL_TEXTURE_2D, (*Object)->mSpriteTexture); 


with

		// Bind the texture name.
		glBindTexture(GL_TEXTURE_2D, TextureArray[0];); 


Both my objects are textured with the same texture, which is expected.

But, if I make it:
		// Bind the texture name.
		glBindTexture(GL_TEXTURE_2D, TextureArray[0];); 


I just get two non-textured objects. So
 glBindTexture(GL_TEXTURE_2D, TextureArray[texIndex]); 
is always placing the texture name at the first index of my TextureArray?

Mac Pro, Two 3GHz Dual-Core Intel Xeon, 410 GB HD, NVIDIA 7300 GT   Mac OS X (10.5.2)   Macbook Air, 1.6GHz Core 2 Duo, 80GB HD, 2GB RAM  
Macmenace

Posts: 52
From: Redmond, WA
Registered: Mar 19, 2008
Re: iPhone: OpenGL ES Texturing
Posted: Aug 6, 2008 8:39 PM   in response to: Macmenace
 

I fixed it!

I read up some more on OpenGL texturing and I had to move:

 	// Set the texture parameters to use a minifying filter and a linear filer (weighted average)
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	// Enable use of the texture
	glEnable(GL_TEXTURE_2D);
	// Set a blending function to use
	glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
	// Enable blending
	glEnable(GL_BLEND);


to the bottom of my texture generation function.

Thanks for all the help and suggestions everyone!

Mac Pro, Two 3GHz Dual-Core Intel Xeon, 410 GB HD, NVIDIA 7300 GT   Mac OS X (10.5.2)   Macbook Air, 1.6GHz Core 2 Duo, 80GB HD, 2GB RAM  
Cirineu

Posts: 3
From: Canada
Registered: Oct 22, 2008
Re: iPhone: OpenGL ES Texturing
Posted: Jan 13, 2009 9:49 PM   in response to: Macmenace
 

Wow! I had the same issue. Thanks a lot! Problem fixed!!!

MacBook Pro   Mac OS X (10.5.6)   iPod Touch  
Anton Delprado

Posts: 1
From: Australia
Registered: Jan 22, 2009
Re: iPhone: OpenGL ES Texturing
Posted: Jan 22, 2009 6:49 PM   in response to: Macmenace
 

I had this problem and that fixed it :)

Just to be specific though, glTexParameteri needs to be called once for each texture, the other three functions need only be called once at the bottom of setupView

MacBook   Mac OS X (10.5.6)   .