NONSENSE! Sie müssen kein Multi-Texturing verwenden. Nur multiplizieren Sie Ihr Alpha.
Wenn Sie nach dem Laden Alpha in das Bild eingeben und bevor Sie die GL-Textur dafür erstellen, benötigen Sie nur eine Textureinheit für den Textur-Umgebungsmodus GL_ADD.
Wenn Sie auf iOS sind, dann kann Apple libs für Sie premultiply. Sehen Sie das Beispiel Texture2D-Klasse und suchen Sie nach dem kCGImageAlphaPremultipliedLast-Flag.
Wenn Sie keinen Image Loader verwenden, der Premultiply unterstützt, müssen Sie dies nach dem Laden des Images manuell tun. Pseudo-Code:
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;
}
Ich persönlich bin mit libpng und premultiplying manuell.
Wie auch immer, nach dem Premultiply binden Sie einfach die Byte-Daten als RGBA OpenGL-Textur. GlTexEnvi verwenden (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD); mit einer einzigen Textureinheit sollte alles sein, was Sie danach brauchen. Sie sollten genau (oder verdammt nah) bekommen, was Sie wollen. Möglicherweise müssen Sie glBlendFunc (GL_SRC_ALPHA, GL_ONE) verwenden; auch wenn du das Ding wirklich blank aussehen lassen willst.
Dies unterscheidet sich subtil von der Ozirus-Methode. Er reduziert niemals die RGB-Werte der Textur durch das Vormultiplizieren, so dass die RGB-Kanäle zu viel hinzugefügt werden und irgendwie ausgewaschen/übermäßig hell aussehen.
Ich nehme an, dass die Premultiply-Methode eher Overlay ähnelt, während die Ozirus-Methode Soft Light ist.
Weitere finden Sie unter:
http://en.wikipedia.org/wiki/Alpha_compositing
Suche nach "premultiplied alpha"
Ich glaube es nicht mit festen Pipeline möglich ist, werden Sie ein Fragment Shaders müssen, es zu erreichen. – ognian