Imagination PowerVR SDK Blog

Alpha blending with textures alpha channel


#1

Hi,

i have a real problem with alpha blending of objects using the alpha channel of an pvrtc texture. in fact the alpha values of the textures are ok when i regard them in the pvrtc tex tool. i store the bytearray to file, before uploading the texture to gl.

after this the textures alpha values seems to be broken or sth like this.

i use

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

as blendfunction. glColor is set to 1.0, 1.0, 1.0, 1.0. object is shown completely white after blending. For testing i set down alpha value of glColor to 0.5 then this white object is blended somehow, but on complete different areas then the texture has alpha set.

This effect brought me to the point, that there must be something wrong in the way i send pvrtc texture to the gl pipeline.Â

Someone has a hint, what can be done wrong here?

With best regards!


#2

If a textured object shows up white it may be a sign that the texture is incomplete. If mipmapping is enabled for the texture (GL_TEXTURE_MIN_FILTER is one that contains MIPMAP) you need an entire mipmap chain from base level to 1x1. Could you post your code to load the texture?


#3

Of course i will do:

glGenTextures(1, &id);

glBindTexture(GL_TEXTURE_2D, id);

for(nMIPMapLevel = 0; nMIPMapLevel <= nTextureLevelsNeeded; nSizeX = PVRT_MAX(nSizeX/2, (unsigned int)1), nSizeY = PVRT_MAX(nSizeY/2, (unsigned int)1), nMIPMapLevel++)
 {
 if (format == GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG || format == GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG)
 {
 CompressedImageSize = ( PVRT_MAX(nSizeX, PVRTC2_MIN_TEXWIDTH) * PVRT_MAX(nSizeY, PVRTC2_MIN_TEXHEIGHT) * bitcount + 7) / 8;
 }
 else
 {// PVRTC4 case
 CompressedImageSize = ( PVRT_MAX(nSizeX, PVRTC4_MIN_TEXWIDTH) * PVRT_MAX(nSizeY, PVRTC4_MIN_TEXHEIGHT) * bitcount + 7) / 8;
 }
 Â
 glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );Â
Â
 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
 GL_REPEAT );
 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
 GL_REPEAT );
 glCompressedTexImage2D(GL_TEXTURE_2D, nMIPMapLevel, format, nSizeX, nSizeY, 0,
 CompressedImageSize, data);
}

[/CODE]

Best Regards

EDIT: All other textures are shown well with this code. Problems only occur with thouse which should be blended over textures alpha channel

Lichtens2009-06-09 07:44:09[CODE]

glGenTextures(1, &id);

glBindTexture(GL_TEXTURE_2D, id);

for(nMIPMapLevel = 0; nMIPMapLevel <= nTextureLevelsNeeded; nSizeX = PVRT_MAX(nSizeX/2, (unsigned int)1), nSizeY = PVRT_MAX(nSizeY/2, (unsigned int)1), nMIPMapLevel++)
 {
 if (format == GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG || format == GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG)
 {
 CompressedImageSize = ( PVRT_MAX(nSizeX, PVRTC2_MIN_TEXWIDTH) * PVRT_MAX(nSizeY, PVRTC2_MIN_TEXHEIGHT) * bitcount + 7) / 8;
 }
 else
 {// PVRTC4 case
 CompressedImageSize = ( PVRT_MAX(nSizeX, PVRTC4_MIN_TEXWIDTH) * PVRT_MAX(nSizeY, PVRTC4_MIN_TEXHEIGHT) * bitcount + 7) / 8;
 }
 Â
 glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );Â
Â
 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
 GL_REPEAT );
 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
 GL_REPEAT );
 glCompressedTexImage2D(GL_TEXTURE_2D, nMIPMapLevel, format, nSizeX, nSizeY, 0,
 CompressedImageSize, data);
}

[/CODE]

Best Regards

EDIT: All other textures are shown well with this code. Problems only occur with thouse which should be blended over textures alpha channel


Lichtens2009-06-09 07:44:09

#4

Nothing wrong with this code?Â

No new ideas?

I am still looking urgently for hints, pointing me to the solution of this problem!


#5

What code do you use for rendering? Can you make texturing work at all, or is this only related to alpha textures?


#6

As written before, it is only related to the alpha textures! All other textures, loaded with the same code above are rendered like excpected!

It is depthtest enabled without writing...Â

blending enabled, alphatest enabled, blendfunction is GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA

Alpha function is GL_GREATER, 0.01

Then rendered with an draw elements call!

Best regards,

Andi


#7

Can you send us a minimal example application that shows this behaviour?


#8

Wow.... i dont think this is possible that easy.... it is embedded in a really big project!Â

Textures are generated live, coming from internet. Same belongs to the geometry!


#9

I had some interesting findings to this problem today:

These objects are only white as long as we stand directly in front of it.... going away from them makes them shown as the picture which should be on them but with blackbackround on the parts of the texture which should be blended.... so also no blending...

Is this pointing to a problem with midmap generation?

Any new ideas with this information?


#10

Here is a debug logger output for the texture loading:

14:15:05 Message Handler: Texture UUID: bde22c20-5d1c-0914-975d-169f0284e9da
14:15:05 Message Handler: Texture Hash : 37349316
14:15:05 Message Handler: Texture Data Length : 5620
14:15:05 Message Handler: Total Texture Data Length = 5620
14:15:05 OpenGL Texture upload!
14:15:05 Loading PVRTC Texture!
14:15:05 Copied texture header... decoding!
14:15:05 ===> PVRTC Texture Header Size = 52
14:15:05 ===> PVRTC Texture Height = 128
14:15:05 ===> PVRTC Texture Width = 128
14:15:05 ===> PVRTC Texture MipMap Count = 7
14:15:05 ===> PVRTC Texture Pixel Format Flags = 0x0000830c
14:15:05 ===> PVRTC Texture Data Size = 5568
14:15:05 ===> PVRTC Texture Bit Count = 2
14:15:05 ===> PVRTC Texture Red Bit Mask = 0
14:15:05 ===> PVRTC Texture Green Bit Mask = 0
14:15:05 ===> PVRTC Texture Blue Bit Mask = 0
14:15:05 ===> PVRTC Texture Alpha Bit Mask = 1
14:15:05 PVRTC Header decompressed!
14:15:05 PVRTC Format Computed!
14:15:05 GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG
14:15:05 Texture Data Memory allocated!
14:15:05 PVRTC Texture Data copied!
14:15:05 Texture generated!
14:15:05 GL Error Code Hex = 0x00000000
14:15:05 Texture bound!
14:15:05 GL Error Code Hex = 0x00000000
14:15:05 ===> TextureID = 5
14:15:05 ===> PVRTC OpenGL Texture upload MipMap Level = 0
14:15:05 GL Error Code Hex = 0x00000000
14:15:05 ===> PVRTC OpenGL Texture upload MipMap Level = 1
14:15:05 GL Error Code Hex = 0x00000000
14:15:05 ===> PVRTC OpenGL Texture upload MipMap Level = 2
14:15:05 GL Error Code Hex = 0x00000000
14:15:05 ===> PVRTC OpenGL Texture upload MipMap Level = 3
14:15:05 GL Error Code Hex = 0x00000000
14:15:05 ===> PVRTC OpenGL Texture upload MipMap Level = 4
14:15:05 GL Error Code Hex = 0x00000000
14:15:05 ===> PVRTC OpenGL Texture upload MipMap Level = 5
14:15:05 GL Error Code Hex = 0x00000000
14:15:05 ===> PVRTC OpenGL Texture upload MipMap Level = 6
14:15:05 GL Error Code Hex = 0x00000000
14:15:05 ===> PVRTC OpenGL Texture upload MipMap Level = 7
14:15:05 GL Error Code Hex = 0x00000000
14:15:05 generated
14:15:05 iTextureLists->textureUploadReady

[/CODE]

Everything looks quite normal for me. maybe anyone here can see a mistake in there.Â

Can anyone tell me more about the header values:

PVRTC Texture Pixel Format Flags

PVRTC Texture Red Bit Mask
PVRTC Texture Green Bit Mask
PVRTC Texture Blue Bit Mask
PVRTC Texture Alpha Bit Mask

Is it correct, that R,G,B Bit Mask is set to 0 ?

What kind of information can i see in the format flags?

[CODE]

14:15:05 Message Handler: Texture UUID: bde22c20-5d1c-0914-975d-169f0284e9da
14:15:05 Message Handler: Texture Hash : 37349316
14:15:05 Message Handler: Texture Data Length : 5620
14:15:05 Message Handler: Total Texture Data Length = 5620
14:15:05 OpenGL Texture upload!
14:15:05 Loading PVRTC Texture!
14:15:05 Copied texture header... decoding!
14:15:05 ===> PVRTC Texture Header Size = 52
14:15:05 ===> PVRTC Texture Height = 128
14:15:05 ===> PVRTC Texture Width = 128
14:15:05 ===> PVRTC Texture MipMap Count = 7
14:15:05 ===> PVRTC Texture Pixel Format Flags = 0x0000830c
14:15:05 ===> PVRTC Texture Data Size = 5568
14:15:05 ===> PVRTC Texture Bit Count = 2
14:15:05 ===> PVRTC Texture Red Bit Mask = 0
14:15:05 ===> PVRTC Texture Green Bit Mask = 0
14:15:05 ===> PVRTC Texture Blue Bit Mask = 0
14:15:05 ===> PVRTC Texture Alpha Bit Mask = 1
14:15:05 PVRTC Header decompressed!
14:15:05 PVRTC Format Computed!
14:15:05 GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG
14:15:05 Texture Data Memory allocated!
14:15:05 PVRTC Texture Data copied!
14:15:05 Texture generated!
14:15:05 GL Error Code Hex = 0x00000000
14:15:05 Texture bound!
14:15:05 GL Error Code Hex = 0x00000000
14:15:05 ===> TextureID = 5
14:15:05 ===> PVRTC OpenGL Texture upload MipMap Level = 0
14:15:05 GL Error Code Hex = 0x00000000
14:15:05 ===> PVRTC OpenGL Texture upload MipMap Level = 1
14:15:05 GL Error Code Hex = 0x00000000
14:15:05 ===> PVRTC OpenGL Texture upload MipMap Level = 2
14:15:05 GL Error Code Hex = 0x00000000
14:15:05 ===> PVRTC OpenGL Texture upload MipMap Level = 3
14:15:05 GL Error Code Hex = 0x00000000
14:15:05 ===> PVRTC OpenGL Texture upload MipMap Level = 4
14:15:05 GL Error Code Hex = 0x00000000
14:15:05 ===> PVRTC OpenGL Texture upload MipMap Level = 5
14:15:05 GL Error Code Hex = 0x00000000
14:15:05 ===> PVRTC OpenGL Texture upload MipMap Level = 6
14:15:05 GL Error Code Hex = 0x00000000
14:15:05 ===> PVRTC OpenGL Texture upload MipMap Level = 7
14:15:05 GL Error Code Hex = 0x00000000
14:15:05 generated
14:15:05 iTextureLists->textureUploadReady

[/CODE]

Everything looks quite normal for me. maybe anyone here can see a mistake in there.Â

Can anyone tell me more about the header values:

PVRTC Texture Pixel Format Flags

PVRTC Texture Red Bit Mask
PVRTC Texture Green Bit Mask
PVRTC Texture Blue Bit Mask
PVRTC Texture Alpha Bit Mask

Is it correct, that R,G,B Bit Mask is set to 0 ?

What kind of information can i see in the format flags?


#11

For PVRTC, the bit mask flags don’t make a great deal of sense which is why they are left blank (I think they’re only really in the format because of an attempt to keep it like DDS which I’ve never really understood). It’s safe to ignore them entirely.





The alpha mask will be set to 0 if there is no alpha in the PVRTC file so that you can know whether to use GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG vs GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG or GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG vs GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG. You can also use the alpha bit of the dwpfFlags field for this purpose (this is how our own texture loading code does it).





It sounds like you are having trouble with MIP-maps. If you disable MIP-maps for these textures does your rendering improve?





PVRTC is tricky to load MIP-map chains for because of the minimum size requirement for MIP-levels and since OpenGL ES requires full MIP chains it’s very easy to have problems. I’d suggest you examine the loading code from our own SDK in PVRTools/OGLES/PVRTTextureAPI.cpp:





Code:

                    /* Calculate how many bytes this MIP level occupies */
                    if ((psPVRHeader->dwpfFlags & PVRTEX_PIXELTYPE)==OGL_PVRTC2)
                    {
                         CompressedImageSize = ( PVRT_MAX(nSizeX, PVRTC2_MIN_TEXWIDTH) * PVRT_MAX(nSizeY, PVRTC2_MIN_TEXHEIGHT) * psPVRHeader->dwBitCount) / 8;
                    }
                    else if ((psPVRHeader->dwpfFlags & PVRTEX_PIXELTYPE)==OGL_PVRTC4)
                    {
                         CompressedImageSize = ( PVRT_MAX(nSizeX, PVRTC4_MIN_TEXWIDTH) * PVRT_MAX(nSizeY, PVRTC4_MIN_TEXHEIGHT) * psPVRHeader->dwBitCount) / 8;
                    }
                    else
                    {// ETC
                         CompressedImageSize = ( PVRT_MAX(nSizeX, ETC_MIN_TEXWIDTH) * PVRT_MAX(nSizeY, ETC_MIN_TEXHEIGHT) * psPVRHeader->dwBitCount) / 8;
                    }

                    if(((signed int)nMIPMapLevel - (signed int)nLoadFromLevel) >= 0)
                    {
                         if(IsCompressedFormatSupported)
                         {
                              if(psPVRHeader->dwpfFlags&PVRTEX_CUBEMAP)
                              {
                                   /* Load compressed texture data at selected MIP level */
                                   glCompressedTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X+i, nMIPMapLevel-nLoadFromLevel, textureFormat, nSizeX, nSizeY, 0,
                                                       CompressedImageSize, theTextureToLoad);
                              }
                              else
                              {
                                   /* Load compressed texture data at selected MIP level */
                                   glCompressedTexImage2D(GL_TEXTURE_2D, nMIPMapLevel-nLoadFromLevel, textureFormat, nSizeX, nSizeY, 0,
                                                       CompressedImageSize, theTextureToLoad);

                              }
                         }



Where PVRTC4_MIN_TEXWIDTH is 8 and PVRTC2_MIN_TEXWIDTH is 16, for instance.