Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm starting OpenGL with Apple's GLKit hand I'm having some trouble to get my sprites displayed properly. The Problem is that they all are surrounded with thin dark lines. The screen shot below shows two rectangles with a png image textures containing transparency (obviously).

enter image description here

The black shadows, surrounding them are definitely not part of the pngS. The green png is done without anti-aliasing the blue one has an anti-aliased border. The black border is also apparent if I draw only one sprite.

Te relevant part (hope so...) of code is:

//render the scene
-(void)render
{
    glClearColor(69./255., 115./255., 213./255., 1.);
    glClear(GL_COLOR_BUFFER_BIT);
    [shapes enumerateObjectsUsingBlock:^(AAAShape *shape, NSUInteger idx, BOOL *stop)   
     {
         [shape renderInScene:self];
     }];
}

//creating and storing the effect inside shape class
-(GLKBaseEffect *)effect
{
    if(!effect)
    {
        effect = [[GLKBaseEffect alloc] init];
    } 
    return effect;
}

//rendering the shape (including effect configuration)   
-(void)renderInScene:(AAAScene *)scene 
{
    //TODO: Storing vertices in Buffer
    self.effect.transform.projectionMatrix = scene.projectionMatrix; 
    self.effect.transform.modelviewMatrix = self.objectMatrix; 
    if(texture)
    {
        self.effect.texture2d0.enabled = GL_TRUE;
        self.effect.texture2d0.envMode = GLKTextureEnvModeReplace;
        self.effect.texture2d0.target = GLKTextureTarget2D;
        self.effect.texture2d0.name = texture.name;
    }
    [self.effect prepareToDraw];

    if(texture)
    {
        glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
        glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, 0, self.textureCoordinates);
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    }

    glEnableVertexAttribArray(GLKVertexAttribPosition);
    glVertexAttribPointer(GLKVertexAttribPosition, 2, GL_FLOAT, GL_FALSE, 0, self.vertices);
    glDrawArrays(GL_TRIANGLE_FAN, 0, self.vertexCount);
    glDisableVertexAttribArray(GLKVertexAttribPosition);

    if(texture)
    {
        glDisableVertexAttribArray(GLKVertexAttribTexCoord0);
        glDisable(GL_BLEND);
    }
}

Any ideas anyone? Thank you.

share|improve this question
    
Can you post the original PNGs, or links to them? –  Nathan Reed Dec 16 '11 at 22:30
    
I had the same idea, that it would be all about the texture images, but turned out that it was fixed by David's answer below. Thanks anyway. –  Kai Dec 16 '11 at 23:18

1 Answer 1

up vote 10 down vote accepted

This looks like a case of not drawing with a premultiplied alpha texture correctly. Here's a few helpful links on the subject:

If you search for "premultiplied alpha" and iOS you might find a direct solution to your problem. I suspect it will have something to do with the way you're setting up the glBlendFunc call. Here's my take at it:

In Shawn's XNA code he mentions that where before you would do:

RenderState.SourceBlend = Blend.SourceAlpha; 
RenderState.DestinationBlend = Blend.InverseSourceAlpha; 

You should do this instead:

RenderState.SourceBlend = Blend.One; 
RenderState.DestinationBlend = Blend.InverseSourceAlpha; 

I'm not too familiar with OpenGL, but my intuition tells me it should be something like replacing:

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

With:

glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);

Edit

Trevor mentioned that this conversion of textures into the pre-multiplied format is done automatically at build time by XCode, even if they were not originally in that format. Thanks for the tip.

share|improve this answer
    
Thank zoo very, very, very (did I say very?) much. I promise I'll also read/watch the recommended background info, but your hint really helped. I struggled with that one since yesterday, tried everything, read a lot. Same question posted 12 hours ago on stackoverflow had no answers. Actually it's glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);. –  Kai Dec 16 '11 at 23:01
    
There, fixed. I just did a quick Google on GL_SRC_ONE and got a few matches, so I figured it existed and wrote that. ;-) –  David Gouveia Dec 16 '11 at 23:06
1  
It's worth adding that the XCode build process auto-converts textures into a pre-multiplied format, while copying them into the app bundle. So even if you didn't create your textures as pre-multiplied textures, that's what they'll probably be by the time your program is loading them. (There used to be an undocumented way to disable this autoconversion. Not sure if it's still possible to disable under current versions of XCode) –  Trevor Powell Dec 16 '11 at 23:17
    
@Trevor Roger, I figured that was the case, just like the Content Pipeline in XNA 4.0. –  David Gouveia Dec 16 '11 at 23:19

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.