NONSENSE! Vous n'avez pas besoin d'utiliser la multi-texturation. Juste prémultiply votre alpha.
Si vous précultez alpha sur l'image après l'avoir chargé et avant de créer la texture GL, alors vous n'avez besoin que d'une unité de texture pour le mode d'environnement de texture GL_ADD.
Si vous êtes sur iOS alors les bibliothèques d'Apple peuvent premultiply pour vous. Voir l'exemple de la classe Texture2D et recherchez l'indicateur kCGImageAlphaPremultipliedLast.
Si vous n'utilisez pas un chargeur d'images prenant en charge prémultiplié, vous devez le faire manuellement après avoir chargé l'image. Code Pseudo:
uint8* LoadRGBAImage(const char* pImageFileName) {
Image* pImage = LoadImageData(pImageFileName);
if (pImage->eFormat != FORMAT_RGBA)
return NULL;
// allocate a buffer to store the pre-multiply result
// NOTE that in a real scenario you'll want to pad pDstData to a power-of-2
uint8* pDstData = (uint8*)malloc(pImage->rows * pImage->cols * 4);
uint8* pSrcData = pImage->pBitmapBytes;
uint32 bytesPerRow = pImage->cols * 4;
for (uint32 y = 0; y < pImage->rows; ++y) {
byte* pSrc = pSrcData + y * bytesPerRow;
byte* pDst = pDstData + y * bytesPerRow;
for (uint32 x = 0; x < pImage->cols; ++x) {
// modulate src rgb channels with alpha channel
// store result in dst rgb channels
uint8 srcAlpha = pSrc[3];
*pDst++ = Modulate(*pSrc++, srcAlpha);
*pDst++ = Modulate(*pSrc++, srcAlpha);
*pDst++ = Modulate(*pSrc++, srcAlpha);
// copy src alpha channel directly to dst alpha channel
*pDst++ = *pSrc++;
}
}
// don't forget to free() the pointer!
return pDstData;
}
uint8 Modulate(uint8 u, uint8 uControl) {
// fixed-point multiply the value u with uControl and return the result
return ((uint16)u * ((uint16)uControl + 1)) >> 8;
}
Personnellement, j'utilise libpng et manuellement prémultiplication. Quoi qu'il en soit, après la prémultiplication, il suffit de lier les données de l'octet comme une texture OpenGL RGBA. En utilisant glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD); avec une seule unité de texture devrait être tout ce dont vous avez besoin après cela. Vous devriez obtenir exactement (ou tout près) ce que vous voulez. Vous devrez peut-être utiliser glBlendFunc (GL_SRC_ALPHA, GL_ONE); aussi bien si vous voulez vraiment rendre la chose brillante btw.
Ceci est subtilement différent de la méthode Ozirus. Il ne "réduit" jamais les valeurs RVB de la texture en prémultipliant, donc les canaux RVB sont trop rajoutés et ont l'air un peu délavés/trop lumineux.Je suppose que la méthode premultiply est plus proche de Overlay alors que la méthode Ozirus est Soft Light.
Pour en savoir plus, voir:
http://en.wikipedia.org/wiki/Alpha_compositing
Chercher "prémultipliée alpha"
Je ne crois pas qu'il soit possible avec pipeline fixe, vous aurez besoin d'un fragment shader pour y parvenir. – ognian