Sign in to follow this  
SilverLogic

Blending only black...

Recommended Posts

SilverLogic    140
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!

Share this post


Link to post
Share on other sites
Boku San    428
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?

Share this post


Link to post
Share on other sites
Palidine    1315
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

Share this post


Link to post
Share on other sites
silvermace    634
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 ease
struct 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 id
GLuint 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 image
pixel_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 image
void 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;
}


Share this post


Link to post
Share on other sites
SilverLogic    140
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

Share this post


Link to post
Share on other sites
Guimo    463
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


Share this post


Link to post
Share on other sites
silvermace    634
Quote:
Original post by SilverLogic
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


did you even look at the code?
it gets the image data from theOpenGL Driver, ie. nothing to do with the source file or SDL.

it should work. also, its trivial to make it work with non power of two textures, just use your brain :)

PS. im assuming you missed the call to glGetTexImage in my snippet.

Share this post


Link to post
Share on other sites
SilverLogic    140
i did look at it, in fact i implemented it into my code, and i did fix the power of 2 part by making it width and height, but the way the pixel data is stored i cannot pass it to the function

thx guys, but i fixed my problem i gave in and used masks (didnt want to cuz im gonna be using alot of images and changing them frequently thats why i didnt want them)

Share this post


Link to post
Share on other sites
stroma    218
try this:

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0);

//{
// draw hud
//}

glDisable(GL_ALPHA);
glDisable(GL_BLEND);

Share this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
Quote:
Original post by SilverLogic
i did look at it, in fact i implemented it into my code, and i did fix the power of 2 part by making it width and height, but the way the pixel data is stored i cannot pass it to the function

thx guys, but i fixed my problem i gave in and used masks (didnt want to cuz im gonna be using alot of images and changing them frequently thats why i didnt want them)


sounds like he's just plain too lazy to figure it out.
glGetTexImage retunrns identical data format as glReadPixels, which i use to create TGA screenshot files, so its obviously not hard to read or write.

Share this post


Link to post
Share on other sites
SilverLogic    140
No, not lazy..limited, like i said already, i was using sdl which has a wierd format for storing pixels and i cant find a good resource on using it properly, from what i know its just bgr instead of rgb, but i cant figure out how to modify the data or anything, i know its surface->pixels but i get errors everytime i touch them, and if i use a type definition it goes haywire, dont worry bout it though, im dropping sdl and rewriting from the ground up, thx for the help

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this