OpenGL ES and Texture2D

Member
Posts: 215
Joined: 2008.06
Post: #1
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.

Mac users swear by their computers, PC users swear at their computers. ~Unknown

iSayz
Quote this message in a reply
Member
Posts: 215
Joined: 2008.06
Post: #2
Hello? Anyone? I can't seem to get Texture2D to work no matter what I try. I'll get some code up sometime soon.

Mac users swear by their computers, PC users swear at their computers. ~Unknown

iSayz
Quote this message in a reply
Apprentice
Posts: 8
Joined: 2008.12
Post: #3
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.
Quote this message in a reply
Moderator
Posts: 3,579
Joined: 2003.06
Post: #4
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.
Quote this message in a reply
Member
Posts: 215
Joined: 2008.06
Post: #5
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!

Mac users swear by their computers, PC users swear at their computers. ~Unknown

iSayz
Quote this message in a reply
Member
Posts: 215
Joined: 2008.06
Post: #6
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!

Mac users swear by their computers, PC users swear at their computers. ~Unknown

iSayz
Quote this message in a reply
Moderator
Posts: 3,579
Joined: 2003.06
Post: #7
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.
Quote this message in a reply
Member
Posts: 215
Joined: 2008.06
Post: #8
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.

Mac users swear by their computers, PC users swear at their computers. ~Unknown

iSayz
Quote this message in a reply
Moderator
Posts: 3,579
Joined: 2003.06
Post: #9
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
}
Quote this message in a reply
Member
Posts: 215
Joined: 2008.06
Post: #10
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.

Mac users swear by their computers, PC users swear at their computers. ~Unknown

iSayz
Quote this message in a reply
Moderator
Posts: 3,579
Joined: 2003.06
Post: #11
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.
Quote this message in a reply
Member
Posts: 215
Joined: 2008.06
Post: #12
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?

Mac users swear by their computers, PC users swear at their computers. ~Unknown

iSayz
Quote this message in a reply
Moderator
Posts: 3,579
Joined: 2003.06
Post: #13
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.
Quote this message in a reply
Member
Posts: 215
Joined: 2008.06
Post: #14
AnotherJake Wrote:I'll try to whip up a small example using that template in a little bit.

Cool. Thanks, man. You're awesome.

Mac users swear by their computers, PC users swear at their computers. ~Unknown

iSayz
Quote this message in a reply
Moderator
Posts: 3,579
Joined: 2003.06
Post: #15
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];
}
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Texture2d crash lander ajrs84 0 2,880 Apr 1, 2012 08:54 AM
Last Post: ajrs84
  Problem using Texture2D sub-section bendell 0 2,522 Mar 20, 2010 02:06 AM
Last Post: bendell
  Create a texture2d with contents of other textures godexsoft 6 4,772 Nov 12, 2009 10:24 PM
Last Post: godexsoft
  Texture2d with strings kendric 10 5,564 Jul 14, 2009 09:28 PM
Last Post: warmi
  Texture2D and other transparent objects kappolo 9 6,608 Apr 17, 2009 12:07 PM
Last Post: AnotherJake