masking

Started by
2 comments, last by aaabbbzzz 21 years ago
I''ve read tute 20 on nehe and understand it, however It is going to be a pain to draw and load/store two images just to make one. How do I just "filter" out one color of all my bitmaps, for example BLACK? I like this idea: Eric Desrosiers pointed out that you can also check the value of each pixel in your bitmap while you load it. If you want the pixel transparent you can give it an alpha value of 0. For all the other colors you can give them an alpha value of 255. This method will also work but requires some extra coding But how do i do it? TIA!
Advertisement
OK:

Say you have your image loaded as 24bit RGB and you want to convert to 32bit RGBA with the black pixels having alpha of 0 and any other having alpha of 1 (0xff or 255):


  char input[width*height*3];char output[width*height*4];for(int y=0;y<height;y++)for(int x=0;x<width;x++){  output[(x+(y*width))*4+0] = input[(x+(y*width))*3+0];  output[(x+(y*width))*4+1] = input[(x+(y*width))*3+1];  output[(x+(y*width))*4+2] = input[(x+(y*width))*3+2];  if( input[(x+(y*width))*3+0] == 0 &&    input[(x+(y*width))*3+1] == 0 &&    input[(x+(y*width))*3+2] == 0)  {      output[(x+(y*width))*4+3] = 0x00;  }  else  {     output[(x+(y*width))*4+3] = 0xff;  }}  


Make sense?
Ok, thanks, I think it makes sense (and it does). However where does my input come from? I''m gussing some part of the loaded BMP file, right? So where in the below code should I place your submitted code fragment? Where does the input come from and where should the output go? And then how would I call the glTexImage2D() function (pointing to what data)? Many Thanks in advance!

AUX_RGBImageRec* loadBMP(char* fileName)
{
FILE* file = NULL;

if (!fileName) return NULL;

file = fopen(fileName, "r");

if (!file) return NULL;

fclose(file);
return auxDIBImageLoad(fileName);
}

bool loadGLTextures()
{
bool status = false;

AUX_RGBImageRec* textureImage[1];

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

if (textureImage[0] = loadBMP("tree.bmp"))
{
status = true;

glGenTextures(1, &texture[0]);

glBindTexture(GL_TEXTURE_2D, texture[0]);

glTexImage2D(GL_TEXTURE_2D, 0, 3, textureImage[0]->sizeX, textureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, textureImage[0]->data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_DECAL) ;

if (textureImage[0]->data) free(textureImage[0]->data);

free(textureImage[0]);
}

return status;
}
Here is a simple way to do what you need.


    unsigned char *Create32Map(AUX_RGBImageRec *ir, unsigned char r, unsigned char g, unsigned char b){ unsigned char *new_data; long tx,ty; unsigned long offset1=0,offset2=0; new_data = new unsigned char[ir->sizeX*ir->sizeY*4]; //*4 = r,g,b,a! for (ty=0;ty!=ir->sizeY;++ty) {  for (tx=0;tx!=ir->sizeX;++tx)  {   new_data[offset2] = ir->data[offset1];   new_data[offset2+1] = ir->data[offset1+1];   new_data[offset2+2] = ir->data[offset1+2];   if (ir->data[offset1]==r &&       ir->data[offset1+1]==g &&       ir->data[offset1+2]==b) //Check for our alpha mask     new_data[offset2+3]=0; //Make us invisible!   else     new_data[offset2+3]=255; //Make us visible!   offset1+=3;   offset2+=4;  } } return new_data;}//Now your function would go like this (a cut and paste with slight modification!AUX_RGBImageRec* loadBMP(char* fileName){FILE* file = NULL;if (!fileName) return NULL;file = fopen(fileName, "r");if (!file) return NULL;fclose(file);return auxDIBImageLoad(fileName);}bool loadGLTextures(){bool status = false;AUX_RGBImageRec* textureImage[1];memset(textureImage, 0, sizeof(void *)*1);if (textureImage[0] = loadBMP("tree.bmp")){status = true;glGenTextures(1, &texture[0]);glBindTexture(GL_TEXTURE_2D, texture[0]);//0,0,0 = black, violet = 255,0,255 which is what most people use!unsigned char *OurNewData = Create32Map(textureImage[0],0,0,0);glTexImage2D(GL_TEXTURE_2D, 0, 3, textureImage[0]->sizeX, textureImage[0]->sizeY, 0, GL_RGBA, GL_UNSIGNED_BYTE, OurNewData);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_DECAL) ;delete [] OurNewData; //Delete it now!if (textureImage[0]->data) free(textureImage[0]->data);free(textureImage[0]);}return status;}    


You can see I only modified a tiny bit (GL_RGB -> GL_RGBA, added the call to Create32Map, which returns a 32-bit array, after copying the 24-bit array over and making the correct alpha values). This gets passed instead of our other data now, and then at the bottom, we delete both sets of data.


--- Edit ---
Just wanted to make sure you knew that this wasn't tested, so use at your own risk . And, if there are syntactical errors, it wasn't me, it was my keyboard .

[edited by - Ready4Dis on April 3, 2003 5:54:03 PM]

This topic is closed to new replies.

Advertisement