|
Replies
:
7
-
Pages
:
1
-
Last Post
:
Jan 22, 2009 6:49 PM
by: Anton Delprado
|
|
|
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
{
//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);
}
{
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
|
|
Posts:
8
From:
Santa Monica, CA
Registered:
Jun 11, 2008
|
|
|
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
|
|
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 & NVIDIA 7300 GT
Mac OS X (10.5.2)
Macbook Air, 1.6GHz Core 2 Duo, 80GB HD, 2GB RAM
|
|
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
|
|
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
|
|
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
|
|
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)
.
|
|
|