Blending only black...

Started by
14 comments, last by SilverLogic 19 years, 6 months ago
Ok, i just decided to add a little HUD to my game and now its making me mad, what blend function would you use to make ONLY the black part of an RGB image transparent? I cant loop through the pixels to assign an alpha value (im using sdl, so i dont think i can access the individual pixel data), and i dont want to use masking... http://www.logizone.com/images/trans_0.jpg Thats the result im getting by using glBlendFunc(GL_SRC_ALPHA, GL_ONE); i tryed a few other combinations but im not getting the result i want, please help!
---------------------------------------------think outside the quadLogic GamesI realized I stay on the pc too long when my wireless mouse died after replacing the batteries...twice
Advertisement
Did you try using glBlendFunc(GL_SRC_ALPHA,GL_SRC_ALPHA_MINUS_ONE)?

Not that I think it'll help, but it's worth a shot anyway.

Sorry, I honestly don't know how to help you besides to use a picture format that supports an alpha channel. What are you using atm?
Things change.
right now im just using 24-bit bitmaps
---------------------------------------------think outside the quadLogic GamesI realized I stay on the pc too long when my wireless mouse died after replacing the batteries...twice
Ok...then why don't you want to use masking, exactly? This sounds about like...you know, what you need. Exactly.
Things change.
Quote:Original post by SilverLogic
Ok, i just decided to add a little HUD to my game and now its making me mad, what blend function would you use to make ONLY the black part of an RGB image transparent?


well, correct me if i'm wrong, but how can you blend with no alpha values? why not just open up the bitmap in whatever paint program you use and assign all black pixels to be totally aplha'd out. load the image as RGBA then use your blend function. it should work fine. otherwise, if you have no alpha channel in your image i don't understand how openGL would blend out only the black.

-me
Because i want to assign all pure black pixels an alpha value of 1, which doesnt require the image to have an alpha channel
---------------------------------------------think outside the quadLogic GamesI realized I stay on the pc too long when my wireless mouse died after replacing the batteries...twice
i think it would be easiest here if you just rebuilt the image with the custom alpha map, if you only do it at load time it shouldnt be a problem.

here is a source snippet i put together for you, tell me if it works :)

// pixel data structure for easestruct pixel_t {	BYTE r,g,b,a;};// pixel functions (see below for implementation)pixel_t getPixel(BYTE *img, int size, int x, int y);void setPixel(BYTE *img, int size, int x, int y, pixel_t& px);// ***********************************************// creates an alpha channel, returns the new OpenGL texture idGLuint createAlphaChannel( GLuint glTextureName, int size ) {	// storage for readback an new image	BYTE *imageData = new BYTE[size * size * 4];	glBindTexture( GL_TEXTURE_2D, glTextureName );	glGetTexImage( GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData );	// create the new image with the alpha	for(int x=0; x<size; x++) {		for(int y=0; y<size; y++) {			pixel_t p = getPixel(imageData, size, x, y);			if( p.r == 0 && p.g == 0 && p.b == 0 ) {				p.a = 0; //set alpha to zero				setPixel(imageData, size, x, y, p);			}		}	}	GLuint newTexture = 0;	glGenTextures(1, &newTexture);	glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S, GL_REPEAT);	glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T, GL_REPEAT);	glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR);	glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);	// build the new image with the alpha map	gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA8, size, size, GL_RGBA, GL_UNSIGNED_BYTE, imageData);	delete [] imageData;	imageData = NULL;	return newTexture;}// ****************************************************// These functions may not work, but should be trivial // to fix.// ****************************************************// gets a pixel, only works with power of two imagepixel_t getPixel(BYTE *img, int size, int x, int y) {	pixel_t px;	px.r = img[x + (y * size) * 4 + 0];	px.g = img[x + (y * size) * 4 + 1];	px.b = img[x + (y * size) * 4 + 2];	px.a = img[x + (y * size) * 4 + 3]; //if the image is RGB, glGetTexImage will set A = 1	return px;}// sets a pixel, only works with power of two imagevoid setPixel(BYTE *img, int size, int x, int y, pixel_t& px) {	img[x + (y * size) * 4 + 0] = px.r;	img[x + (y * size) * 4 + 1] = px.g;	img[x + (y * size) * 4 + 2] = px.b;	img[x + (y * size) * 4 + 3] = px.a;}
"I am a donut! Ask not how many tris/batch, but rather how many batches/frame!" -- Matthias Wloka & Richard Huddy, (GDC, DirectX 9 Performance)

http://www.silvermace.com/ -- My personal website
No it doesnt work, first off, the image im using isnt a square image, and second, im using sdl, so i cant modify the pixel data like ordinary, so thats kinda useless to me, i said in my first post i couldnt modify the pixel data :/. thx for the attempt tho
---------------------------------------------think outside the quadLogic GamesI realized I stay on the pc too long when my wireless mouse died after replacing the batteries...twice
Hi
MMMMM as everyone said... hard to blend if no blend info.

a. Why don't you add alpha info and make your life easier?
b. I you dont want it, just blend using color/invsrccolor (as oposed to standar alpha/invsrcalpha). That way black color will be treated as transparent, but other colors will be blended at 50% opacity. If you want more opacity, render the same image again.

Its the only think that comes to my mind in this case. Sorry if not much help.

Luck!
Guimo


check out SDL_Surface

the "void *pixels;" is flagged read/write. Just make sure that it is RGBA after you load in the image (see SDL_ConvertSurface), and you can read each pixel to see if RGB = 000 => A=1 else A=0

This topic is closed to new replies.

Advertisement