iDevGames Forums
OpenGL ES and Texture2D - Printable Version

+- iDevGames Forums (http://www.idevgames.com/forums)
+-- Forum: Development Zone (/forum-3.html)
+--- Forum: iPhone, iPad & iPod Game Development (/forum-11.html)
+--- Thread: OpenGL ES and Texture2D (/thread-2014.html)

Pages: 1 2 3


OpenGL ES and Texture2D - Talyn - Dec 21, 2008 08:56 PM

Hi, trying to use the Texture2D class provided by Apple and it's not cooperating. I have read a few posts on the subject and they provide little extra information for my implementation. My current architecture is as follows:

1. Create object
2. Create Texture2D like so:
Code:
Texture2D* tempTex = [[Texture2D alloc] initWithImage:[[UIImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Tex1" ofType:@"bmp"]]];
3. Assign texture to object through object property
(This is where things get a little sketchy, if I don't call the following, it shows only the background color. If I call the GL functions below, it displays a totally white screen.)
4. Call glEnableClientState for vertex array and texture coord array.
5. Initialize for the scene to be drawn.
6. Move to each object's location.
7. Call each object to draw itself using it's Texture2D field like so:
Code:
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        [texture drawAtPoint:CGPointZero];
        glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
8. Commit the scene and swap.

This method works well for non-textured objects, but as soon as I attempt to use Texture2D, everything falls apart. I understand that without more code, it is going to be difficult to answer in depth, but if there is anything you can see that I am missing, please let me know. Thanks.


OpenGL ES and Texture2D - Talyn - Dec 22, 2008 11:34 PM

Hello? Anyone? I can't seem to get Texture2D to work no matter what I try. I'll get some code up sometime soon.


OpenGL ES and Texture2D - ozirus - Dec 23, 2008 03:18 AM

Hi Talyn,

Although it does not make any use of the Texture2D class, you might want to have a look at the GLSprite example from Apple Sample Code. It describes how to render a textured quad.

Image data is read with the following calls:
- CGBitmapContextCreate()
- CGContextDrawImage()

I hope this helps.


OpenGL ES and Texture2D - AnotherJake - Dec 23, 2008 08:30 AM

Yes, more code might help. There are a few things I noticed though:

- did you glEnable(GL_TEXTURE_2D)?
- Texture2D uses CoreGraphics to load, so your textures get premultiplied alpha, which means you need to use glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA).
- Don't use bmp, use png or jpg instead. Not a big deal, but there is no logical reason to ever use anything else IMHO.


OpenGL ES and Texture2D - Talyn - Dec 23, 2008 12:25 PM

ozirus Wrote:Hi Talyn,

Although it does not make any use of the Texture2D class, you might want to have a look at the GLSprite example from Apple Sample Code. It describes how to render a textured quad.

Image data is read with the following calls:
- CGBitmapContextCreate()
- CGContextDrawImage()

I hope this helps.

Hey thanks! I'll have to look into that. Unfortunately, I'm looking for a light weight wrapper class for texture images, but this may be helpful to look at nonetheless. Thanks!


OpenGL ES and Texture2D - Talyn - Dec 23, 2008 12:26 PM

AnotherJake Wrote:Yes, more code might help. There are a few things I noticed though:

- did you glEnable(GL_TEXTURE_2D)?
- Texture2D uses CoreGraphics to load, so your textures get premultiplied alpha, which means you need to use glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA).
- Don't use bmp, use png or jpg instead. Not a big deal, but there is no logical reason to ever use anything else IMHO.

Ah! I'm using bitmap. Does it die from bitmap images by default? I will have to review my code to see what I set to what and let you know if things change. Thanks!


OpenGL ES and Texture2D - AnotherJake - Dec 23, 2008 06:00 PM

It should work fine with bmp's; I'm just saying that you shouldn't use them. Wink There is very little, if any, reason to use any uncompressed image format. PNG is lossless and compressed. You should use that as your default image format for everything.


OpenGL ES and Texture2D - Talyn - Dec 27, 2008 02:23 AM

Alright. I'm at a total loss here. I've been trying to get Texture2D to work for over 2 days now, and I cannot figure out why it isn't working. Here is some sample code of what I have been doing to test it:

Code:
Texture2D* testTex = [[Texture2D alloc] initWithString:@"TEST" dimensions:CGSizeMake(64, 30) alignment:UITextAlignmentCenter fontName:@"Helvetica" fontSize:14];
    [testTex drawInRect:[self bounds]];
    [testTex drawAtPoint:CGPointZero];
    [testTex drawAtPoint:CGPointMake(50.0f, 50.0f)];
    [testTex drawAtPoint:CGPointMake(1.5f, -1.0f)];
    [testTex drawInRect:[[UIScreen mainScreen] bounds]];
    
    testTex = [[Texture2D alloc] initWithImage:[UIImage imageNamed:@"Background.png"]];
    [testTex drawInRect:[self bounds]];

NONE of this draws anything to the screen. This is in my draw function inside my graphics engine. I keep getting a "The image is NULL" when I try to load in the "Background.png" image. Can anyone point me in the right direction. I'm willing to start posting more code if that's what it takes... Thanks in advance.


OpenGL ES and Texture2D - AnotherJake - Dec 27, 2008 09:01 AM

If that's what you're really using, then it most certainly will not work. There are several issues I see right off the bat. Here is more like what it should be:

Code:
Texture2D    *testTex = nil;
Texture2D    *backgroundTex = nil;

- (void)myDraw
{
    CGRect            bounds;
    
    bounds = [self bounds];
    
    // all textures need these
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glEnable(GL_TEXTURE_2D);
    
    if (backgroundTex == nil)
        backgroundTex = [[Texture2D alloc] initWithImage:[UIImage imageNamed:@"Background.png"]];
    
    // background doesn't need blending
    glDisable(GL_BLEND);
    
    [backgroundTex drawInRect:bounds];
    
    if (testTex == nil)
        testTex = [[Texture2D alloc] initWithString:@"TEST" dimensions:CGSizeMake(64, 64) alignment:UITextAlignmentCenter fontName:@"Helvetica" fontSize:14];
    
    // text will need blending
    glEnable(GL_BLEND);
    
    // text from Texture2D uses A8 tex format, so needs GL_SRC_ALPHA
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    [testTex drawAtPoint:CGPointMake(bounds.size.width * 0.5f, bounds.size.height * 0.5f)];
    
    // switch it back to GL_ONE for other types of images, rather than text because Texture2D uses CG to load, which premultiplies alpha
    glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
    
    // ... other drawing
}



OpenGL ES and Texture2D - Talyn - Dec 27, 2008 11:25 AM

AnotherJake Wrote:If that's what you're really using, then it most certainly will not work. There are several issues I see right off the bat. Here is more like what it should be:

Code:
Texture2D    *testTex = nil;
Texture2D    *backgroundTex = nil;

- (void)myDraw
{
    CGRect            bounds;
    
    bounds = [self bounds];
    
    // all textures need these
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glEnable(GL_TEXTURE_2D);
    
    if (backgroundTex == nil)
        backgroundTex = [[Texture2D alloc] initWithImage:[UIImage imageNamed:@"Background.png"]];
    
    // background doesn't need blending
    glDisable(GL_BLEND);
    
    [backgroundTex drawInRect:bounds];
    
    if (testTex == nil)
        testTex = [[Texture2D alloc] initWithString:@"TEST" dimensions:CGSizeMake(64, 64) alignment:UITextAlignmentCenter fontName:@"Helvetica" fontSize:14];
    
    // text will need blending
    glEnable(GL_BLEND);
    
    // text from Texture2D uses A8 tex format, so needs GL_SRC_ALPHA
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    [testTex drawAtPoint:CGPointMake(bounds.size.width * 0.5f, bounds.size.height * 0.5f)];
    
    // switch it back to GL_ONE for other types of images, rather than text because Texture2D uses CG to load, which premultiplies alpha
    glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
    
    // ... other drawing
}

Thanks a lot AnotherJake! However, even THAT doesn't work. It must be how my render engine is set up, and I'm not going to slave over this for any longer. I think I'm just going to move to libpng and do my own texture loading and drawing. Again, thanks for the help AnotherJake.


OpenGL ES and Texture2D - AnotherJake - Dec 27, 2008 11:43 AM

Talyn Wrote:Thanks a lot AnotherJake! However, even THAT doesn't work. It must be how my render engine is set up, and I'm not going to slave over this for any longer. I think I'm just going to move to libpng and do my own texture loading and drawing. Again, thanks for the help AnotherJake.

Don't give up yet! We'll get it working. Smile

Texture2D works great, and libpng isn't going to magically fix anything. The only bonus you could get out of libpng is that it won't premultiply your alpha, but that doesn't have anything to do with nothing being drawn for you right now. Plus, libpng won't render text for you either, which you get for free with Texture2D.

BTW, if you are still getting the "Image is NULL" issue when you're trying to load your background, that has to be taken care of first. Be sure you have added it to your project under the Resources folder so it gets copied into the app bundle.


OpenGL ES and Texture2D - Talyn - Dec 27, 2008 01:17 PM

AnotherJake Wrote:Don't give up yet! We'll get it working. Smile

Texture2D works great, and libpng isn't going to magically fix anything. The only bonus you could get out of libpng is that it won't premultiply your alpha, but that doesn't have anything to do with nothing being drawn for you right now. Plus, libpng won't render text for you either, which you get for free with Texture2D.

BTW, if you are still getting the "Image is NULL" issue when you're trying to load your background, that has to be taken care of first. Be sure you have added it to your project under the Resources folder so it gets copied into the app bundle.

Alright, alright. I'm less concerned with the background image. I would like to get text working first, because that is more useful to me at this moment. Alright, so my rendering engine for the application in which I am attempting to get this working is a modified EAGLView class from the iPhone OpenGL ES template. So, that means my rendering engine has a UIView superclass and has OGL|ES capabilities. Most importantly, I am able to add subviews to it, so I know that it still functions with some semblance of Apple's prebuilt classes.

The question is now, where to restart?


OpenGL ES and Texture2D - AnotherJake - Dec 27, 2008 01:35 PM

Talyn Wrote:The question is now, where to restart?

I'll try to whip up a small example using that template in a little bit.


OpenGL ES and Texture2D - Talyn - Dec 27, 2008 01:43 PM

AnotherJake Wrote:I'll try to whip up a small example using that template in a little bit.

Cool. Thanks, man. You're awesome.


OpenGL ES and Texture2D - AnotherJake - Dec 27, 2008 02:39 PM

Okay, here we go.

- start a new iPhone project using the "OpenGL ES Application" template
- add Texture2D.h and Texture2D.m to the project (for anyone else reading this: hopefully you already have those because it appears Apple removed CrashLanding from their sample code offerings for some unknown reason)
- add CoreGraphics.framework to the project
- in EAGLView.m, add #import "Texture2D.h"
- optionally add a background texture named Background.png to the Resources group
- in EAGLView.m, replace the drawView method with this:

Code:
Texture2D    *testTex = nil;
Texture2D    *backgroundTex = nil;

- (void)drawView {
    
    CGRect    bounds = [self bounds];

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

    // setup viewport and projection
    glViewport(0, 0, backingWidth, backingHeight);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrthof(0, bounds.size.width, 0, bounds.size.height, -1, 1);
    glMatrixMode(GL_MODELVIEW);

    // texturing will need these
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnable(GL_TEXTURE_2D);

    // clear background to gray (don't need these if you draw a background image, since it will draw over whatever's there)
    glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    /* uncomment to draw a background image instead of gray background
    if (backgroundTex == nil)
        backgroundTex = [[Texture2D alloc] initWithImage:[UIImage imageNamed:@"Background.png"]];

    // background doesn't need blending
    glDisable(GL_BLEND);

    [backgroundTex drawInRect:bounds];
    */

    if (testTex == nil)
        testTex = [[Texture2D alloc] initWithString:@"TEST" dimensions:CGSizeMake(64, 64) alignment:UITextAlignmentCenter fontName:@"Helvetica" fontSize:14];

    // text will need blending
    glEnable(GL_BLEND);

    // text from Texture2D uses A8 tex format, so needs GL_SRC_ALPHA
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    [testTex drawAtPoint:CGPointMake(bounds.size.width * 0.5f, bounds.size.height * 0.5f)];

    // switch it back to GL_ONE for other types of images, rather than text because Texture2D uses CG to load, which premultiplies alpha
    glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);

    // ... do more drawing here

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