OpenGL ES alpha blending

Nibbie
Posts: 3
Joined: 2009.07
Post: #1
I just got started on OpenGL ES today, but I've been doing 3D programming for a while, so everything has been going swimmingly, except for one glitch: How do you get alpha to display on textures? I rendered the image of a ball on a 2D plane, which you can flick around the screen with you finger and it will bounce off walls, but the parts of the image that should be alpha 0.0 are simply black.

Here's what it looks like in XCode:
[Image: ec6b2f204a.png]
XCode seems to understand that there's alpha there, as it greys out all alpha sections.

Here's what it looks like in the Simulator and on my iPod:
[Image: e5cbdd947f.png]

How do I fix this? Is there something in OpenGL ES that I need to enable to get it to recognize alpha?
Quote this message in a reply
Member
Posts: 166
Joined: 2009.04
Post: #2
Well, there are a lot of things ... for instance you need to enable alpha blending..

Can't really say what's wrong unless you show us your code.
Quote this message in a reply
Nibbie
Posts: 3
Joined: 2009.07
Post: #3
My code is pretty basic. It's the Apple OpenGL template with some code for loading in a texture, and then some code to render that texture on a plane. I think all I'm missing is turning on alpha blending (what's the syntax for turning on alpha blending?), but in any case, here is the loadTextures code:

Code:
-(void)loadTextures {
    CGImageRef textureImage = [UIImage imageNamed:@"checkerplate.png"].CGImage;
    if (textureImage == nil) {
        NSLog(@"Failed to load texture image");
        return;
    }
    NSInteger texWidth = CGImageGetWidth(textureImage);
    NSInteger texHeight = CGImageGetHeight(textureImage);
    GLubyte *textureData = (GLubyte *)malloc(texWidth * texHeight * 4);
    CGContextRef textureContext = CGBitmapContextCreate(textureData,
                                                        texWidth,
                                                        texHeight,
                                                        8, texWidth * 4,
                                                        CGImageGetColorSpace(textureImage),
                                                        kCGImageAlphaPremultipliedLast);
    
    CGContextDrawImage(textureContext,
                       CGRectMake(0.0, 0.0, (float)texWidth, (float)texHeight),
                       textureImage);
    
    CGContextRelease(textureContext);
    
    glGenTextures(1, &textures[0]);
    
    glBindTexture(GL_TEXTURE_2D, textures[0]);
    
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureData);
    
    free(textureData);
    
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glEnable(GL_TEXTURE_2D);
}

and here's drawView, though I doubt that this has much relevance to what I'm trying to do:

Code:
- (void)drawView {
    
    [EAGLContext setCurrentContext:context];
    
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
    glViewport(0, 0, backingWidth, backingHeight);
    
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glRotatef(-90.0, 0.0, 0.0, 1.0);
    glOrthof(-1.5f, 1.5f, -1.0f, 1.0f, -1.0f, 1.0f);
    glTranslatef(-1.5, -1.0, 0.0);
    glMatrixMode(GL_MODELVIEW);
    
    glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    
    const GLfloat squareVertices[] = {
        -0.25, 0.25, 0.0,            // Top left
        -0.25, -0.25, 0.0,           // Bottom left
        0.25, -0.25, 0.0,            // Bottom right
        0.25, 0.25, 0.0              // Top right
    };
    const GLfloat squareTextureCoords[] = {
        0.0, 1.0,
        0.0, 0.0,
        1.0, 0.0,
        1.0, 1.0
    };
    
    glPushMatrix();
    glColor4f(1.0, 1.0, 1.0, 1.0);
    glTranslatef(newLocation[0], newLocation[1], 0.0);
    glVertexPointer(3, GL_FLOAT, 0, squareVertices);
    glEnableClientState(GL_VERTEX_ARRAY);
    
    glTexCoordPointer(2, GL_FLOAT, 0, squareTextureCoords);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    
    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    glPopMatrix();
    
    glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
    [context presentRenderbuffer:GL_RENDERBUFFER_OES];
}
Quote this message in a reply
Member
Posts: 110
Joined: 2009.07
Post: #4
Maybe I'm missing it, but I don't see the following anywhere:
Code:
glEnable(GL_ALPHA_TEST); // Critical for alpha-ing out the appropriate bits
glAlphaFunc(GL_NOTEQUAL, 0);

Curiously, this little pair seems to be missed out of pretty much every example code snippet I've ever found.

[Edit: as Jake notes below, while this can make your graphic's edges look nicer, it is usually omitted due to performance considerations. Rather brilliantly, it also fails to address the OP's primary issue: the black background. Madrayken now aware of his own ignorance and flagellating himself with birch twigs.]
Quote this message in a reply
Moderator
Posts: 3,579
Joined: 2003.06
Post: #5
Because alpha test and blend aren't the same thing, and further, alpha test is slower on iPhone than blend.
Quote this message in a reply
Member
Posts: 269
Joined: 2005.04
Post: #6
Code:
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); // Pre-multiplied alpha blending. Can be placed in you OGL initialization; doesn't have to be set every frame
glEnable(GL_BLEND); // Turn on blending
        
// Draw blended stuff here
        
glDisable(GL_BLEND); // Turn off blending

You want to avoid using alpha testing as Jake says. It's sloooow.
Quote this message in a reply
Member
Posts: 110
Joined: 2009.07
Post: #7
Noted. I did wonder why nobody seemed to be doing it. I'll alter my post to ensure nobody is misled.
Quote this message in a reply
Nibbie
Posts: 3
Joined: 2009.07
Post: #8
Cool. Thanks everyone! I got it to work. My ball is now circular. As long as we're on the topic of performance, which is faster, making a bunch of planes at the origin and using transforms to move them around, or making one mesh containing all of your planes, with transforms calculated out manually, as long as they are all the same texture?
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Fastest Possible Blending Function, OpenGL ES 2.0 Macmenace 12 16,752 Apr 16, 2010 11:44 AM
Last Post: Macmenace
  Point sprites and alpha blending issue OptimisticMonkey 4 4,759 Jun 18, 2009 03:25 PM
Last Post: ThemsAllTook
  OpenGL ES sprite alpha Holmes 27 15,540 Mar 16, 2009 01:06 PM
Last Post: Holmes