PDA

View Full Version : Transparency woes



architekt
01-13-2002, 06:31 PM
I'm trying to make black (0,0,0) be the transparent color (yes, i know it's all just alpha). In my code that loads bitmaps, it checks if the RGB of the pixel it just read in is all black. If so, it sets the alpha component of the texture data (a standard GLubyte *data) to 0. It it is a normal pixel, it sets it to 255. Later in my code when I go to draw it, i have the following:

GLfloat rgba[] = {.0f, .0f, .0f, 1.0f};
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
glEnable(GL_BLEND);

glPushMatrix();
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, rgba);
glBindTexture(GL_TEXTURE_2D, textureID);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);

<draw just a plain square using GL_QUADS>
glPopMatrix();

glDisable(GL_BLEND);


But I get some weird corrupted looking image. If I don't do any transparency setting (i.e. my texture data array only allocates memory for RGB and not RGBA info) then something weird happens. Now, all of a sudden none of the black pixels show up. This is good. BUT, the rest of the bitmap that is showing looks as if it's being alpha blended with the rest of the data on the screen. Can anyone tell me what I'm seriously screwing up??? Thanks for your help =)

rIO
01-14-2002, 12:16 AM
You are screwing up nothing, this is the way GL_SRC_ALPHA,GL_ONE handles transparency.

Use an alpha channel, instead of using black transparency (some famous tutorial lacks in alpha explaination).

rIO.sK

MrShoe
01-14-2002, 12:17 AM
Do this:
day you have the data for the bitmap in RGB form. All you have to do is scan through the data of the bitmap, check the color of each pixel, if it is black give it alpha 0, the fgollowing function should yield a RGBA texture from an RGB bitmap with black as transparant:
** sorry for no comments :-)

void LoadBMPAlpha(char *filename, Image *image){
FILE *file;
Image *token;
short int bpp;
short int planes;
long i;
long i2;
long size;
char temp;
char *data;

token = (Image *)malloc(sizeof(Image));
file = fopen(filename, "rb");
fseek(file, 18, SEEK_CUR);
i = fread(&image->SizeX, 4, 1, file);
i = fread(&image->SizeY, 4, 1, file);
size = image->SizeX * image->SizeY * 3;
i = fread(&bpp, 2, 1, file);
i = fread(&planes, 2, 1, file);
fseek(file, 24, SEEK_CUR);
token->data = (char *)malloc(size);
i = fread(token->data, size, 1, file);
for(i = 0; i < size; i+=3){
temp = token->data[i];
token->data[i] = token->data[i+2];
token->data[i+2] = temp;
}

size = image->SizeX * image->SizeY * 4;
image->data = (char *)malloc(size);
i2 = 0;
for(i = 0; i < size; i+=4){
image->data[i] = token->data[i2];
image->data[i+1] = token->data[i2+1];
image->data[i+2] = token->data[i2+2];
if(image->data[i] == 0 && image->data[i+1] == 0 && image->data[i+2] == 0){
image->data[i+3] = 0;
}
else{
image->data[i+3] = 255;
}
i2+=3;
}
fclose(file);
}

This is based a little bit on the NeHe Bitmap loading routine but it is modified to have black as transparant.
Dont forget when doing glTexImage2d or gluBuildMipmap2D to set to RGBA and to have 4 bytes per pixel.
Hope that helps, if you got additional problems ask me


[This message has been edited by MrShoe (edited 01-14-2002).]

architekt
01-14-2002, 04:46 AM
hmm, well see I did that (the equivalent of your source code)...and I'm able now to show the texture with the black regions as transparent....but the problem is that the colors are sort of washed out. I've got, as a test, a 64x64 black square, with a circle in the middle. The circle is a gradient from gray to white, and in the middle is a red small circle, so it looks kind of like a bull's eye. The red dot though appears orangish if I do something like make the background green, instead of the standard black. My concern is that once I start getting to the point where I've got lots of other images on the screen, I'm worried that the texture I'm trying to display will constantly be coming up in some slightly different color scheme than what the original bitmap intended.

architekt
01-14-2002, 01:59 PM
OK I solved my problem. But my new question is this: when I move the image around, you can slightly see it's pixels moving. It basically looks like it's shimmering I guess you could say. I noticed though that with GL_NEAREST specified, this is way more pronounced than with GL_LINEAR. Are there any tips to avoid this problem?

MrShoe
01-14-2002, 06:22 PM
Use mipmaps...
replace glTexImage2D (i think) with gluBuild2DMipmaps(GL_TEXTURE_2D, 4, image7->SizeX, image7->SizeY, GL_RGBA, GL_UNSIGNED_BYTE, image7->data);

notice the 4 bytes per pixel and GL_RGBA instead of GL_RGB

and for texture parameters use
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);