PDA

View Full Version : Texture blending woes



Jon723
03-21-2007, 07:43 PM
Hello everyone. In my scene I am displaying a jpeg image on a quad (I am completely aware that jpeg do not support an alpha component natively). The quad with the applied texture are faded in until the alpha component is 1 but the rest of the scene is still visible through the texture. What I'm trying to accomplish is to have a solid texture with only the black components completely transparent. The following code is how I set up my texture and how i am rendering the texture. Any help would be greatly appreciated!

Jon


glGenTextures(1, &littlepic);
glBindTexture(GL_TEXTURE_2D, littlepic);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexEnvf(GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvf(GL_TEXTURE_2D, GL_COMBINE_ALPHA, GL_ADD);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, littleImg->getWidth(), littleImg->getHeight(), 0, GL_RGB, GL_UNSIGNED_BYTE, littleImg->getPixels());The rendering portion.

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);

glBindTexture(GL_TEXTURE_2D, littlepic);
glPushMatrix();
glTranslatef(1.0,1.0,1.0);

glBegin(GL_TRIANGLE_FAN);
glColor4f(1.0,1.0,1.0, logoAlpha2);
glTexCoord2f(0.0, 1.0); glVertex3f(150.0,220.0,0.0);
glTexCoord2f(0.0, 0.0); glVertex3f(150.0,370.0,0.0);
glTexCoord2f(1.0, 0.0); glVertex3f(650.0,370.0,0.0);
glTexCoord2f(1.0, 1.0); glVertex3f(650.0,220.0,0.0);
glEnd();
glPopMatrix();

if((seconds >= 29000.0001) &amp;&amp; (seconds <= 34000.0001))
{
logoAlpha2 += (t*1000.0)/5500.00;
}
else if(seconds >= 37000.0001)
{
logoAlpha2 -= (t*1000.0)/4000.00;
}

soconne
03-21-2007, 08:02 PM
You can't do it without an alpha channel. But you can ADD an alpha channel to the image data. Just read in the data, create a new array of bytes but with an extra channel and fill in the alpha values.

unsigned char *newData = new unsigned char[littleImg->getWidth() * littleImg->getHeight() * 4];

unsigned char *oldData = littleImg->getPixels();

for(int i = 0; i < littleImg->getWidth() * littleImg->getHeight(); i++) {

newData[i * 4 + 0] = oldData[i * 3 + 0];
newData[i * 4 + 1] = oldData[i * 3 + 1];
newData[i * 4 + 2] = oldData[i * 3 + 2];

if(newData[i * 4 + 0] == 0 && newData[i * 4 + 1] == 0 && newData[i * 4 = 2] == 0) {
newData[i * 4 + 3] = 0;
} else {
newData[i * 4 + 3] = 255;
}
}

Then just pass the newData array to glTexImage2D and change the format from GL_RGB to GL_RGBA. Hope that helps.

Jon723
03-21-2007, 08:59 PM
Well, I used the code to add a alpha channel to the data (I even tried using a PNG texture with an alpha channel to achieve the same effect) but the texture still shows up transparent. Black colors in the image are completely transparent which is what I'm looking for but non black colors (like solid blue and red) still have transparencies, even with an alpha value of 1.

Is there a way I can achieve the effect using multi-texturing such that non black colors are 100% opaque and black colors are transparent?

Komat
03-22-2007, 01:05 AM
You need to use different blending function. The glBlendFunc(GL_SRC_ALPHA, GL_ONE) you are using will add the texture multiplied by its alpha with current content of the framebuffer. You need to use glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA).

soconne
03-22-2007, 05:50 AM
You could also performing ALPHA TESTING instead of blending. Just do:

glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.4);