tags:

views:

293

answers:

2

I have a billboard quad with a texture mapped onto it.

This is basically some text with transparency.

The billboard floats forwards and backwards from the camera's perspective.

As the billboard moves away (and appears smaller) there is an flickering effect around the edges of the text where there is a stroke border on the actual texture.

I think this is because interpolation is needed as the image which is normally X pixels wide is now shown as only a % of X and some pixels need to be merged together. I guess it's doing nearest neighbour or something? Can anyone point me in the right direction for opengl settings to control this, I'm guessing there is some way of preventing this effect from happening by adjusting the method for how the texture is handled ?

I think its got something to do with:

GL_NEAREST_MIPMAP_NEAREST

but when i try setting this for the MIN filter and enabling mip mapping my texture becomes very blocky and blurred...

i've also tried:

GL_LINEAR_MIPMAP_LINEAR

which is apparently triliear filtering for the MIN filter but my image is very blurry when displayed. (looks like it is a very low res texture) any ideas what I'm doing wrong?

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); // trilinear

    glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);

More code:

        // Allocated memory needed for the bitmap context
    spriteData = (GLubyte *) calloc(width * height * 4, sizeof(GLubyte));
    // Uses the bitmap creation function provided by the Core Graphics framework. 
    spriteContext = CGBitmapContextCreate(spriteData, width, height, 8, width * 4, CGImageGetColorSpace(spriteImage), kCGImageAlphaPremultipliedLast);
    // After you create the context, you can draw the sprite image to the context.
    CGContextDrawImage(spriteContext, CGRectMake(0.0, 0.0, (CGFloat)width, (CGFloat)height), spriteImage);
    // You don't need the context at this point, so you need to release it to avoid memory leaks.
    CGContextRelease(spriteContext);

    // Use OpenGL ES to generate a name for the texture.
    glGenTextures(1, &spriteTexture[textureCount-1]); 

    // Bind the texture name. 
    glBindTexture(GL_TEXTURE_2D, spriteTexture[textureCount-1]);


    glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);


    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);



    // Specify a 2D texture image, providing the a pointer to the image data in memory
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, spriteData);
    // Release the image data
    free(spriteData);

The texture is 512 x 512.

Example of the blurryness when the MIN filter is used: Blurry billboard

When just using GL_NEAREST for the min filter sharper but nasty bilinear and the flickering as mentioned above when animated as shrinking: GL_NEAREST

+1  A: 

If you were using glu, I would suggest that you try using gluBuild2DMipmaps to create the mipmaps and see how others do this.

To avoid using glu functions, I sometimes look at Mesa's OpenGL implementation to get some ideas (I generally try to keep a lot of code in my own project.. and I share a lot of it between OpenGL, D3D, and other platforms). You can try looking at the source for the Mesa implementation (MesaLib) of gluBuild2DMipmaps to see how you could get a similar effect. It appears in MesaLib's mipmap.c, and you'll probably end up jumping to the implementation of bitmapBuild2DMipmaps.

I can't guarantee that this will lead to good results, but it's an avenue to explore. For general debugging of what's happening, another thing you could try is to output your mipmap textures to files for external viewing. All this is of course after you've exhausted your options of randomly toggling flags and googling other peoples' code to see if you missed any state functions.

guesser
+1  A: 

Mipmapping is controlled by the ratio of texels to pixels for the fragments being drawn (hopefully my terminology is correct there). How large are you drawing it on screen?

If you're drawing it at (say) 128x128, you'll get mipmap level 2, hence the blur.

Textures should be created at the size they'll be shown at on screen, or as close as possible to, rather than producing too many pixels and letting the GPU pick an inappropriate mipmap level...

brone