NONSENSE! No tiene que usar multi texturas. Solo premultiply tu alfa.
Si premultiplica alfa en la imagen después de cargarla y antes de crear la textura GL para ella, solo necesita una unidad de textura para el modo env de textura GL_ADD.
Si está en iOS, las librerías de Apple pueden premultiplicarse para usted. Vea el ejemplo de la clase Texture2D y busque el indicador kCGImageAlphaPremultipliedLast.
Si no está utilizando un cargador de imágenes que admite premultiplicar, debe hacerlo manualmente después de cargar la imagen. Pseudocódigo:
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;
}
Personalmente, estoy usando libpng y premultiplicando manualmente.
De todos modos, después de ti premultiply, simplemente une los datos de bytes como una textura RGBA OpenGL. Usando glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD); con una sola unidad de textura debería ser todo lo que necesitas después de eso. Deberías obtener exactamente (o muy cerca) lo que quieres. Puede que tenga que usar glBlendFunc (GL_SRC_ALPHA, GL_ONE); también si realmente quieres que la cosa luzca brillante por cierto.
Esto es sutilmente diferente del método de Ozirus. Nunca está "reduciendo" los valores RGB de la textura mediante premultiplicación, por lo que los canales RGB se agregan demasiado y se ven como desvaídos/demasiado brillantes.
supongo que el método premultiplicar es más parecido a Overlay mientras que el método es Ozirus luz suave.
Para más información, véase:
http://en.wikipedia.org/wiki/Alpha_compositing
Búsqueda de "alfa premultiplicado"
no creo que es posible con la tubería fija, tendrá un fragment shader para lograrlo. – ognian