PDA

View Full Version : alpha value in bitmap



t3jem
09-08-2005, 05:38 PM
Hi,

I'm trying to create a custom made cursor in one of my programs and I want the black pixels around the cursor to be transparent. I am using glut for my graphics system and I don't want to use the blending function "glBlendFunc(GL_SRC_ALPHA, GL_ONE)" because it doesn't quite get the effect i want.

What I am really looking for is a loading function that will add an alpha value to the loaded image depending on what color the pixel is. The folowing is the current code I am using to load my images.


void text(UINT textureArray[], LPSTR strFileName, int ID)
{
if(!strFileName) return;

AUX_RGBImageRec *pBitMap = auxDIBImageLoad(strFileName);

if(pBitMap == NULL) exit(0);

glGenTextures(1, &textureArray[ID]);
glBindTexture(GL_TEXTURE_2D, textureArray[ID]);
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, pBitMap->sizeX, pBitMap->sizeY, GL_RGB, GL_UNSIGNED_BYTE, pBitMap->data);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTE R,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTE R,GL_LINEAR);

if (pBitMap)
{
if (pBitMap->data)
{
free(pBitMap->data);
}
free(pBitMap);
}
}P.S. I don't use TGA files 1. because I can't make them and 2. because I have lost my loader to load TGA's

Hlz
09-08-2005, 05:48 PM
Well, you could calculate each texel's alpha based on a luminance (smooth) or based on whether it's greater than 0 (hard). It kinda depends on the cursor image and how you wnat it to look.

Hlz

09-09-2005, 06:40 AM
That is what I would like to do, but I'm not as good at C++ as I would like to be and I wouldnt know where to begin to look at each pixel of the image.

Hlz
09-09-2005, 08:05 AM
Try something like this.


GLuint genAlphaTex( const char* fileName )
{
AUX_RGBImageRec* image = auxDIBImageLoad(fileName);
if( !image )
return 0;

unsigned char* texels = new unsigned char[image->sizeX*image->sizeY*4];
unsigned char* outTexel = texels;
unsigned char* inTexel = image->data;
for( int y = 0; y < image->sizeY; y++ )
{
for( int x = 0; x < image->sizeX; x++, inTexel += 3, outTexel += 4 )
{
int r = inTexel[0];
int g = inTexel[1];
int b = inTexel[2];
int a = .3*r + .59*g + .11*b;
// int a = (r or g or b) ? 255 : 0;
outTexel[0] = r;
outTexel[1] = g;
outTexel[2] = b;
outTexel[3] = a;
}
}
GLuint texid;
glGenTextures(1, &amp;texid);
glBindTexture(GL_TEXTURE_2D, texid);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTE R,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTE R,GL_LINEAR);
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA,
image->sizeX, image->sizeY, 0, GL_RGBA, GL_UNSIGNED_BYTE, texels );
delete [] texels;
free(image->data);
free(image);
return texid;
}

t3jem
09-09-2005, 12:07 PM
thx alot, that worked like a charm, but I realized I still have to use blending functions and I can't find the right functions to use to make it so just the areas with 0 alpha value are transparent and the rest doesn't blend. I changed int a = .3*r + .59*g + .11*b; to if(r = 0 && b == 0....) then a = 0. and the rest of the cursor still gets blended and I can't see any of it on white. I'm using glBlendFunc(...); but I can't find what I should use in the parenthesis.

Hlz
09-09-2005, 12:32 PM
If you use glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPA), then you get an equation that amounts to texAlpha * texColor + (1 - texAlpha) * frameBufferColor (provided you set glColor3f(1,1,1) with modulate texenv mode). So if you want your cursor to be opaque where it's not black and transparent where it is black, you need if( r|g|b ) a = 255; else a = 0; That way with normalized alpha = 1 you get all texture; at alpha = 0 you get all framebuffer.

You may also want to enable the alpha test with glAlphaFunc(GL_GREATER,0). This can save on fill if the texture is mostly transparent. For a single small cursor image, it's not a big deal. but it's a handy optimization to keep in mind for alpha blending vacuous textures.

t3jem
09-09-2005, 03:53 PM
Great! thanks for all the help its working great now.