Texture2D and other transparent objects

Apprentice
Posts: 6
Joined: 2009.04
Post: #1
Hi all! Smile

Well, i have a problem.
I use Texture2D to simply create a string to display on screen. When i try to place a trasparent object in front of it, it simply doesn't render.

I've followed all the hints about OpenGL-ES transparency (rendering the transparent objects sorted by depth), but can't do anything well.

If i disable the string rendering, the other object is showed as well.
If i place the string near than the object, they're both showed as well.

What's wrong with that?

Here's a brief code description:

Code:
- (void)drawView {
    
    [EAGLContext setCurrentContext:context];
    
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
    glViewport(0, 0, backingWidth, backingHeight);
    
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
    glMatrixMode(GL_MODELVIEW);
    

    // ---
    
    
    [self drawScritta];
    
    [self drawPause];
    
    // ---
    
    glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
    [context presentRenderbuffer:GL_RENDERBUFFER_OES];
}


- (void)drawScritta {

    glLoadIdentity();
    
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    
    glColor4f(1.0, 1.0,    1.0, 0.9);
    
    if (testTex == nil)
        testTex = [[Texture2D alloc] initWithString:@"Hi mum!" dimensions:CGSizeMake(64, 64) alignment:UITextAlignmentCenter fontName:@"Helvetica" fontSize:14];
    
    // text will need blending
    glEnable(GL_BLEND);
    
    CGRect bounds = [self bounds];
    
    // 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)];
    
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    
//    glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
    
}


-(void) drawPause {
    
    const GLfloat squareVertices[] = {
        -1.0f, -1.0f,
        1.0f, -1.0f,
        -1.0f, 1.0f,
        1.0f, 1.0f,
    };
    
    const GLfloat squareColors[] = {
        1.0, 0.0, 0.0, 0.8,
        1.0, 0.0, 0.0, 0.8,
        1.0, 0.0, 0.0, 0.8,
        1.0, 0.0, 0.0, 0.8
    };
    
    
    glLoadIdentity();
    glColor4f(1.0, 1.0, 1.0, 1.0);
    glTranslatef(160.0, 240.0, -10.0);
    
    glScalef(160.0, 240.0, 0.0);
    
    glVertexPointer(2, GL_FLOAT, 0, squareVertices);
    glEnableClientState(GL_VERTEX_ARRAY);
    
    glColorPointer(4, GL_FLOAT, 0, squareColors);
    glEnableClientState(GL_COLOR_ARRAY);
    
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    
    glDisableClientState(GL_COLOR_ARRAY);

}

2 Notes:
[LIST]
[*] i've changed Texture2D::drawAtPoint to draw at -20.0 depth (Z axe).
[*] when setupping the view, i do a glOrthof(0.0f, 320.0f, 480.0f, 0.0f, 0.1f, 1000.0f);
[/LIST]

Thanks in advance! ;)
Quote this message in a reply
Apprentice
Posts: 6
Joined: 2009.04
Post: #2
Update: even trying to display an image via Texture2D is not working.
If i just use this code in drawview:

Code:
- (void)drawView {
    
    [EAGLContext setCurrentContext:context];
    
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);

    glViewport(0, 0, backingWidth, backingHeight);

    
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
    glMatrixMode(GL_MODELVIEW);
    


    // ---
    
    //Initialize OpenGL states
    glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
    glEnable(GL_TEXTURE_2D);
    
    CGRect            bounds;
    
    bounds = [self bounds];
    
//    glLoadIdentity();

    // all textures need these
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    
    if (backgroundTex == nil)
        backgroundTex = [[Texture2D alloc] initWithImage:[UIImage imageNamed:@"test.png"]];
    
    // background doesn't need blending
    glDisable(GL_BLEND);
    
    //[backgroundTex drawInRect:bounds];
    [backgroundTex drawInRect:CGRectMake(0.0, 0.0, 300.0, 300.0)];
    

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

Nothing got displayed, so i suppose there's something wrong in my code.
Quote this message in a reply
Moderator
Posts: 133
Joined: 2008.05
Post: #3
I don't see a call to glOrthof anywhere in there. You should also be setting the modelview matrix to the identity matrix at the top of your frame. In the second block of code, it doesn't matter, but in the first, it does.
Quote this message in a reply
Moderator
Posts: 3,579
Joined: 2003.06
Post: #4
I didn't look at your first post very carefully, but your second one should work, so work that one out first. You should probably remove your modification in Texture2D to draw at -20.0f on the Z axis, back to zero. And just to be sure we're on the same page with your projection, you should try this (just added the projection setup to your drawView method):

Code:
//Initialize OpenGL states
    glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
    glEnable(GL_TEXTURE_2D);
    
    CGRect            bounds;
    
    bounds = [self bounds];
    
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrthof(0, bounds.size.width, 0, bounds.size.height, -1, 1);
    glMatrixMode(GL_MODELVIEW);
    
    glLoadIdentity();

    // all textures need these
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);

You can try this for your drawView:

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);
    
    if (backgroundTex == nil)
        backgroundTex = [[Texture2D alloc] initWithImage:[UIImage imageNamed:@"test.png"]];

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

    glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
    [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);
    
    glColor4f(1.0f, 0.5f, 0.5f, 1.0f);

    // 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
Apprentice
Posts: 6
Joined: 2009.04
Post: #5
Thanks for your reply!

Anyway, let me give you first the code that i use to setup the view before drawing anything:

Code:
- (void)setupView {
    const GLfloat zNear = 0.1, zFar = 1000.0, fieldOfView = 60.0;
    
    glEnable(GL_DEPTH_TEST);
    glMatrixMode(GL_PROJECTION);

    glLoadIdentity();
    glRotatef(90.0f, 0.0f, 0.0f, 1.0f);
    
    // Setup Orthographic Projection for the 320 x 480 of the iPhone screen
    glOrthof(0.0f, 480.0f, 320.0f, 0.0f, zNear, zFar);
    
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
}

As you can see, i change the Projection Matrix because i'm running in landscape mode.
Considering that code, i think everything should work, so i don't understand what's wrong.

@AnotherJake: i've tried what you told me to do (obviously changing mi glOrthof() call), but nothing changed. Can it be caused by the version of Texture2D i'm using? I found it in the cocos2d project repository.

Thanks in advance
Quote this message in a reply
Apprentice
Posts: 6
Joined: 2009.04
Post: #6
And of course, the png i'm using has both height and width as power of two.
Quote this message in a reply
Apprentice
Posts: 6
Joined: 2009.04
Post: #7
Solved the image rendering Smile

I've made a mistake changing Texture2D::drawInRect method and forgot to place the correct blend function for it.
Now remains the first real problem: when i use those textures, i cant place a transparent object in front of them.
Quote this message in a reply
Moderator
Posts: 3,579
Joined: 2003.06
Post: #8
What do you mean by placing it in front? Are you drawing it after the other objects, or are you trying to use the depth buffer? Looking at your initial code it looks like you're trying to use the depth buffer. Is this for 2D? If so, you don't need to use the depth buffer.
Quote this message in a reply
Apprentice
Posts: 6
Joined: 2009.04
Post: #9
Yes, i'm using it because i need some 3D stuffs.

Anyway, i solved even the second problem. This code:

Quote:-(void) drawPause {

const GLfloat squareVertices[] = {
-1.0f, -1.0f,
1.0f, -1.0f,
-1.0f, 1.0f,
1.0f, 1.0f,
};

/*
const GLfloat squareColors[] = {
1.0, 0.0, 0.0, 1.0,
1.0, 0.0, 0.0, 1.0,
1.0, 0.0, 0.0, 1.0,
1.0, 0.0, 0.0, 1.0
}; */

const GLfloat squareColors[] = {
1.0, 0.0, 0.0, 0.8,
1.0, 0.0, 0.0, 0.8,
1.0, 0.0, 0.0, 0.8,
1.0, 0.0, 0.0, 0.8
};

const GLshort squareTextureCoords[] = {
0, 1,
0, 0,
1, 0,
1, 1
};




glDisable(GL_TEXTURE_2D);

glPushMatrix();

{
glColor4f(1.0, 1.0, 1.0, 1.0);
glTranslatef(240.0, 160.0, -10.0);

glScalef(240.0, 160.0, 0.0);

glVertexPointer(2, GL_FLOAT, 0, squareVertices);
glEnableClientState(GL_VERTEX_ARRAY);

glColorPointer(4, GL_FLOAT, 0, squareColors);
glEnableClientState(GL_COLOR_ARRAY);

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

glDisableClientState(GL_COLOR_ARRAY);
}

glPopMatrix();
}

Doesn't work without the glDisable(GL_TEXTURE_2D).
Could you please explain me why?

Thanks Smile
Quote this message in a reply
Moderator
Posts: 3,579
Joined: 2003.06
Post: #10
kappolo Wrote:Doesn't work without the glDisable(GL_TEXTURE_2D).
Could you please explain me why?

Do you have your GL_TEXTURE_COORD_ARRAY client state enabled somewhere else? Because I don't see it enabled in drawPause, and it won't work without it.

Also, it looks like your texture coordinates don't match your vertices. Probably should be more like:

Code:
const GLshort squareTextureCoords[] = {
    0, 0,
    1, 0,
    0, 1,
    1, 1
    };

Also, you don't need the vertex color array if you're just using the same color on each vertex. Simply use glColor4f(1.0f, 0.0f, 0.0f, 0.8f) if you want it to be red and slightly translucent (which is apparently what you want, according to your color array). Remember, OpenGL is a state machine, so whatever environment color you set will continue to be used until it is set to something else.
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Texture2d crash lander ajrs84 0 2,913 Apr 1, 2012 08:54 AM
Last Post: ajrs84
  Problem using Texture2D sub-section bendell 0 2,543 Mar 20, 2010 02:06 AM
Last Post: bendell
  Create a texture2d with contents of other textures godexsoft 6 4,850 Nov 12, 2009 10:24 PM
Last Post: godexsoft
  OpenGL ES and Texture2D Talyn 37 32,655 Jul 30, 2009 09:34 AM
Last Post: Splat21
  Texture2d with strings kendric 10 5,612 Jul 14, 2009 09:28 PM
Last Post: warmi