What would be the appropriate blend function?

Started by
18 comments, last by Axesor 18 years ago
What would be the appropriate blend function to blend out only the color magenta?
.::WARNING!::. Axesor is a total newb or n00b! Beware his lack ofintellegence of OpenGL. Feel sorry for him and keep him in your thoughts.~Leader of the phsychoward
Advertisement
Before you upload the texture, loop over the pixels and make the FF00FF pixels transparent (0 alpha).

Then use glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA )
How would I set the alpha using this function to load bitmaps? :

void BmpImg::RESLoadImg(unsigned int idnumber, int num){	HBITMAP hBMP;										BITMAP	BMP;										glGenTextures(1, &g_bmp[num]);					hBMP=(HBITMAP)LoadImage(GetModuleHandle(NULL),MAKEINTRESOURCE(idnumber), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);		if (hBMP)										{												GetObject(hBMP,sizeof(BMP), &BMP);																				// Buffer For Object Information			glPixelStorei(GL_UNPACK_ALIGNMENT,4);				// Pixel Storage Mode (Word Alignment / 4 Bytes)			glBindTexture(GL_TEXTURE_2D, g_bmp[num]);		// Bind Our Texture		   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR);            glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_NEAREST);			// Generate Mipmapped Texture (3 Bytes, Width, Height And Data From The BMP)			gluBuild2DMipmaps(GL_TEXTURE_2D, 3, BMP.bmWidth, BMP.bmHeight, GL_BGR_EXT, GL_UNSIGNED_BYTE, BMP.bmBits);			DeleteObject(hBMP);									// Delete The Bitmap Object		}}


Thank you,
~Axesor
.::WARNING!::. Axesor is a total newb or n00b! Beware his lack ofintellegence of OpenGL. Feel sorry for him and keep him in your thoughts.~Leader of the phsychoward
If bmBitsPixel is three, as it looks like it is, then you would have to allocate a new block of memory with space for the alpha value.

I suggest using TGA and just making the color transparent using your image editor of choice.

Link
Likely another function is needed to convert the HBITMAP to a 32bit alpha bitmap. Since .BMP files cannot have alpha-channels you need to create a shadow bitmap that does. You may need to swap RGBA<->ARGB depending on what you want.

Here is some code and psuedo-code
unsigned char* Bmp24ToBmp32(BITMAP& BMP){//1)Allocate an RGBA bitmapunsigned char* alphabitmap = new char[BMP.bmWidth * BMP.bmHeight * 4];	if(NULL == alphabitmap)return NULL;//2)Calculate pitch (bytes per line)int alphapitch = BMP.bmWidth * 4;//3)Loop though all pixels of the original bitmap	for (i = 0;i < BMP.bmHeight;i++)	for (j = 0;j < BMP.bmWidth;j++)	{//4)Calculate proper byte offset into the bitmaps	int offRGBA = i *(alphapitch) + (j*4);	int offRGB = i * (BMP.bmWidthBytes) + (j*3);//4a) Get color at (i,j) from source bitmap	unsigned int pix = BMP.bmBits[offRGB]&0xFF;//B	pix |= BMP.bmBits[offRGB+1]<<8;//G	pix |= BMP.bmBits[offRGB+2]<<16;//R//4b) Get pointer to corresponding position in destination bitmap	unsigned int* curRGBA = static_cast<unsigned int *>(&alphabitmap[offRGBA]);//4c) Copy source pixel to dest	*curRGBA = pix;//5) Check if source color is magenta	if(pix == 0x00FF00FF)		curRGBA[3] = 0; //6) Set alpha to zero (this pixel will not be seen)	else		curRGBA[3] = 255; //7) Set alpha to 255 (this pixel will be seen fully)	}return alphabitmap;}void BmpImg::RESLoadImg(unsigned int idnumber, int num){	HBITMAP hBMP;	BITMAP	BMP;	glGenTextures(1, &g_bmp[num]);		hBMP=(HBITMAP)LoadImage(GetModuleHandle(NULL),MAKEINTRESOURCE(idnumber), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);		if (hBMP)		{												GetObject(hBMP,sizeof(BMP), &BMP);         unsigned char* ptrAlpha = Bmp24ToBmp32(BMP);         if(NULL == ptrAlpha)return;																// Buffer For Object Information			glPixelStorei(GL_UNPACK_ALIGNMENT,4);				// Pixel Storage Mode (Word Alignment / 4 Bytes)			glBindTexture(GL_TEXTURE_2D, g_bmp[num]);		// Bind Our Texture		   glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR);            glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_NEAREST);			// Generate Mipmapped Texture (4 Bytes, Width, Height And Data From The BMP)			gluBuild2DMipmaps(GL_TEXTURE_2D, 4, BMP.bmWidth, BMP.bmHeight, GL_BGRA_EXT, GL_UNSIGNED_BYTE, BMP.bmBits);         delete[] ptrAlpha;			DeleteObject(hBMP);									// Delete The Bitmap Object		}}


[Edited by - Jack Sotac on March 28, 2006 7:34:14 PM]
0xa0000000
Seems correct and mainly the way I am loading my bitmaps from a file.

Can you put that in code form? I don't seem how you transfer the resource bitmap.
.::WARNING!::. Axesor is a total newb or n00b! Beware his lack ofintellegence of OpenGL. Feel sorry for him and keep him in your thoughts.~Leader of the phsychoward
I cannot seem to get it working right.
.::WARNING!::. Axesor is a total newb or n00b! Beware his lack ofintellegence of OpenGL. Feel sorry for him and keep him in your thoughts.~Leader of the phsychoward
GLuint BitmapToTexture(char* filename, COLORREF key/*= RGB(255, 0, 255)*/, unsigned char alpha/*=255*/, unsigned char key_alpha/*=0*/){	GLuint texture = 0;							//the return value					long width = 0;	long height = 0;	unsigned long* data = BitmapToRGBA(filename, &width, &height, key, alpha, key_alpha);			//finally generate a texture	glGenTextures(1, &texture);	glBindTexture(GL_TEXTURE_2D, texture);	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA4, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR);	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR);	delete data;	return texture;}unsigned long int* BitmapToRGBA(char* filename, long int* width, long int* height, COLORREF key/*= RGB(255, 0, 255)*/, unsigned char alpha/*=255*/, unsigned char key_alpha/*=0*/){	BITMAP bmp;									//used only to get bmp dimensions	HDC hDC = CreateCompatibleDC(NULL);			//choose DC like the desktop	HBITMAP hBitmap = (HBITMAP)LoadImage(NULL,	//load the bitmap										 filename,										 IMAGE_BITMAP,										 0, 0, 										 LR_CREATEDIBSECTION|LR_DEFAULTSIZE|LR_LOADFROMFILE);	if(hBitmap == NULL)							//bitmap failed to load	{		return 0;	}	//get bitmap dimensions	GetObject(hBitmap, sizeof(BITMAP), &bmp);	//allocate memory for the bitmap	COLORREF *data = new COLORREF[bmp.bmWidth * bmp.bmHeight];	//put it into our device context for GetPixel calls	SelectObject(hDC, hBitmap);	for(int y = 0; y < bmp.bmHeight; y++)	{		for(int x = 0; x < bmp.bmWidth; x++)		{			data[x + (y*bmp.bmHeight)] = GetPixel(hDC, x, y);			if(key != data[x + (y*bmp.bmHeight)])			{				data[x + (y*bmp.bmHeight)] |= (alpha << 24);			}			else			{				data[x + (y*bmp.bmHeight)] |= (key_alpha << 24);			}		}	}	//if they care about the dimesions, give them back	if(width != NULL)	{		*width = bmp.bmWidth;	}	if(height != NULL)	{		*height = bmp.bmHeight;	}	return data;}
As your leader, I encourage you from time to time, and always in a respectful manner, to question my logic. If you're unconvinced that a particular plan of action I've decided is the wisest, tell me so, but allow me to convince you and I promise you right here and now, no subject will ever be taboo. Except, of course, the subject that was just under discussion. The price you pay for bringing up either my Chinese or American heritage as a negative is - I collect your f***ing head.
GLubyte *data = NULL;if( BMP.bmBitsPixel == 3 ){   data = AlphaPixelize( BMP.bmBits, BMP.bmWidth, BMP.bmHeight );} else return;gluBuild2DMipmaps(GL_TEXTURE_2D, 4, BMP.bmWidth, BMP.bmHeight, GL_ABGR_EXT, GL_UNSIGNED_BYTE, data);free( data );DeleteObject(hBMP);


I just realized that bmWidthBytes is 4, so you can probably loop over the bits without creating a new BITMAP or GLubyte[]

It doesn't know AlphaPixleize :(
.::WARNING!::. Axesor is a total newb or n00b! Beware his lack ofintellegence of OpenGL. Feel sorry for him and keep him in your thoughts.~Leader of the phsychoward

This topic is closed to new replies.

Advertisement