PDA

View Full Version : multiple layers / transparency..



method5
03-31-2002, 07:10 AM
is there a way to set a color of a bitmap to become transparent??! to be used with multiple layers in a game.. i didnt see a tutorial on this at nehe..

method5
03-31-2002, 07:47 AM
found the tutorial at nehe.. must of missed it.. followed it and now have..

if (tilet[3].mask == 1) {
glEnable(GL_BLEND);
glBlendFunc(GL_DST_COLOR,GL_ZERO);
}
glBindTexture(GL_TEXTURE_2D, tiles[3]);
glBegin(GL_QUADS);
glTexCoord2f(0.0f,1.0f); glVertex2f(testx, testy);
glTexCoord2f(0.0f,0.0f); glVertex2f(testx,testy+32);
glTexCoord2f(1.0f,0.0f); glVertex2f(testx+32,testy+32);
glTexCoord2f(1.0f,1.0f); glVertex2f(testx+32, testy);
glEnd();
if (tilet[3].mask == 1) {
glBlendFunc(GL_ONE, GL_ONE);
glBindTexture(GL_TEXTURE_2D, tiles[4]);
glBegin(GL_QUADS);
glTexCoord2f(0.0f,1.0f); glVertex2f(testx, testy);
glTexCoord2f(0.0f,0.0f); glVertex2f(testx,testy+32);
glTexCoord2f(1.0f,0.0f); glVertex2f(testx+32,testy+32);
glTexCoord2f(1.0f,1.0f); glVertex2f(testx+32, testy);
glEnd();
}

it semi works... the image comes out.. but the part that is supposed to be erased by the mask is just made translucent.. (you can see through it),,but it should be invisable..

Jambolo
03-31-2002, 10:25 AM
Perhaps it would be easier to scan the bitmap when it is loaded and give it an alpha channel.

method5
03-31-2002, 11:26 AM
how it that done?

method5
03-31-2002, 01:39 PM
*bump*

anyone?

MrShoe
03-31-2002, 04:31 PM
Here is my code for doing this, here black is treated as transparent colour and turns all the black pixels in the texture to transparent:

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;

// This is the temp texure
token = (Image *)malloc(sizeof(Image));
// Open the file and see to the 18th byte
file = fopen(filename, "rb");
fseek(file, 18, SEEK_CUR);
// Read and compute the size of the texture
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);
// Read in the pixel info and convert to RGB
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;
}

// Convert RGB texture to RGBA texture, if RGB = 0 then A = 0, else 1
// Black is the transparent colour
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);
}

A little inefficient in terms of memory as i create a temporary texture holding unit, but hey, its fast and easy...

Oh yeh, dont forget that its 4 bpp so its:
gluBuild2DMipmaps(GL_TEXTURE_2D, 4, image->SizeX, image->SizeY, GL_RGBA, GL_UNSIGNED_BYTE, image->data);


[This message has been edited by MrShoe (edited 03-31-2002).]

method5
03-31-2002, 05:10 PM
hrmm.. tried adding it to my loading routine.. didnt work too well, heh.. maybe you could help..




int load_gl_textures()
{
char temp[64];

AUX_RGBImageRec *tilesimage[251];

memset(tilesimage,0,sizeof(void *)*1);

glGenTextures(251, tiles);

for (int t = 0; t < 5; t++)
{
sprintf(temp,"tile%03u.bmp",t);

tilesimage[t] = loadbmp(temp);

if (tilet[t].mask == 1) {
long size;
long i;
long i2;
size = tilesimage[t]->sizeX * tilesimage[t]->sizeY * 4;
i2 = 0;
for(i = 0; i < size; i+=4){
tilesimage[t]->data[i] = tilesimage[t]->data[i2];
tilesimage[t]->data[i+1] = tilesimage[t]->data[i2+1];
tilesimage[t]->data[i+2] = tilesimage[t]->data[i2+2];
if(tilesimage[t]->data[i] == 0 &amp;&amp; tilesimage[t]->data[i+1] == 0 &amp;&amp; tilesimage[t]->data[i+2] == 0){
tilesimage[t]->data[i+3] = 0;
} else{
tilesimage[t]->data[i+3] = 255;
}
i2+=3;
}
}

glBindTexture(GL_TEXTURE_2D, tiles[t]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTE R,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTE R,GL_NEAREST);
if (tilet[t].mask == 1) {
gluBuild2DMipmaps(GL_TEXTURE_2D, 4, tilesimage[t]->sizeX,
tilesimage[t]->sizeY, GL_RGBA,
GL_UNSIGNED_BYTE, tilesimage[t]->data);
} else {
glTexImage2D(GL_TEXTURE_2D, 0, 3, tilesimage[t]->sizeX,
tilesimage[t]->sizeY, 0, GL_RGB,
GL_UNSIGNED_BYTE, tilesimage[t]->data);
}

if (tilesimage[t])
{
if (tilesimage[t]->data)
{
free(tilesimage[t]->data);
}

free(tilesimage[t]);
}
}

return(1);
}

i dont get compiler errors, i get the great windows error box :-)


it runs when i comment out




if (tilet[t].mask == 1) {
long size;
long i;
long i2;
size = tilesimage[t]->sizeX * tilesimage[t]->sizeY * 4;
i2 = 0;
for(i = 0; i < size; i+=4){
tilesimage[t]->data[i] = tilesimage[t]->data[i2];
tilesimage[t]->data[i+1] = tilesimage[t]->data[i2+1];
tilesimage[t]->data[i+2] = tilesimage[t]->data[i2+2];
if(tilesimage[t]->data[i] == 0 &amp;&amp; tilesimage[t]->data[i+1] == 0 &amp;&amp; tilesimage[t]->data[i+2] == 0){
tilesimage[t]->data[i+3] = 0;
} else{
tilesimage[t]->data[i+3] = 255;
}
i2+=3;
}
}



anyone? or anyone have a routine that they think would work in my situation?

method5
03-31-2002, 05:49 PM
here is my original routine before i added anything




int load_gl_textures()
{
char temp[64];

AUX_RGBImageRec *tilesimage[251];

memset(tilesimage,0,sizeof(void *)*1);

glGenTextures(251, tiles);

for (int t = 0; t < 5; t++)
{
sprintf(temp,"tile%03u.bmp",t);

tilesimage[t] = loadbmp(temp);


glBindTexture(GL_TEXTURE_2D, tiles[t]);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTE R,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTE R,GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, 3, tilesimage[t]->sizeX,
tilesimage[t]->sizeY, 0, GL_RGB,
GL_UNSIGNED_BYTE, tilesimage[t]->data);

if (tilesimage[t])
{
if (tilesimage[t]->data)
{
free(tilesimage[t]->data);
}

free(tilesimage[t]);
}
}

return(1);
}




can someone PLEASE add something to turn image into RGBA then turn color 0 255 0 (bright green) into transparent..

MrShoe
03-31-2002, 08:49 PM
I see you using GLAUX... dont...
Here is the FULL code for loading the texture:

// Structure for holding bitmap info
struct Image{
long SizeX;
long SizeY;
char *data;
};
typedef struct Image Image;

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;

// This is the temp texure
token = (Image *)malloc(sizeof(Image));
// Open the file and see to the 18th byte
file = fopen(filename, "rb");
fseek(file, 18, SEEK_CUR);
// Read and compute the size of the texture
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);
// Read in the pixel info and convert to RGB
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;
}

// Convert RGB texture to RGBA texture, if RGB = 0 then A = 0, else 1
// Black is the transparent colour
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);
}

void LoadTextures(void){
Image *image1;

image1= (Image *)malloc(sizeof(Image));
LoadBMPAlpha("texturename.bmp", image1;
glGenTextures(1, &texture[0]);
glBindTexture(GL_TEXTURE_2D, texture[0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
gluBuild2DMipmaps(GL_TEXTURE_2D, 4, image1->SizeX, image1->SizeY, GL_RGBA, GL_UNSIGNED_BYTE, image1->data);
}


just call LoadTextures from you Init function. When actually drawing the polygon with teh texture make sure blending, use the func glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

method5
04-01-2002, 07:55 AM
thanks! it works great.. but i get a warning and wondered if you knew how to get rid of it...


on this line..

image->data[i+3] = 255;

C:\Program Files\Microsoft Visual Studio\MyProjects\testopengl\test.cpp(504) : warning C4309: '=' : truncation of constant value

gumby
04-01-2002, 09:28 AM
Probably should use unsigned char for data.

MrShoe
04-01-2002, 07:43 PM
Its probably a compiler thing, i dont get that and I use DevC++, dont worry about it. Cool that it worked right.