Jump to content
  • Advertisement
Sign in to follow this  
benang00

OpenGL Color key with OpenGL

This topic is 4079 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I'm trying to rewrite my 2D rendering engine from pure SDL to using textured quads with SDL and OpenGL. I've tried to fiddle with the code but stumbled on how to color key a sprite with a textured quad. FYI, I'm using BMP images (thus no alpha channel). And every sprites that need colorkeying can have its own color key / transparent pixel (eg. black, white, etc). So the question is pretty obvious, how do I implement color key to a textured quad? Thanks in advance.

Share this post


Link to post
Share on other sites
Advertisement
The most direct way would probably be to apply the color key to the image manually, turning it from an RGBA image into an RGBA image, before handing it over to OpenGL.

You can also do it during rendering if using fragment shaders.

Share this post


Link to post
Share on other sites
Well, I've tried that but it didn't work. FYI, I'm using SDL to load the image and then I generate the texture from the SDL surface that was created. Here's my texture loading function:


if ( (surface = SDL_LoadBMP("test.bmp")) )
{

// Check that the image's width is a power of 2
if ( (surface->w & (surface->w - 1)) != 0 )
{
printf("warning: test.bmp's width is not a power of 2\n");
}

// Also check if the height is a power of 2
if ( (surface->h & (surface->h - 1)) != 0 )
{
printf("warning: test.bmp's height is not a power of 2\n");
}

// Set the color key to black
SDL_SetColorKey(surface, SDL_SRCCOLORKEY, SDL_MapRGB(surface->format, 0, 0, 0));


// Have OpenGL generate a texture object handle for us
glGenTextures( 1, &texture );

// Bind the texture object
glBindTexture( GL_TEXTURE_2D, texture );

// Set the texture's stretching properties
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );

// Edit the texture object's image data using the information SDL_Surface gives us
glTexImage2D( GL_TEXTURE_2D, 0, 3, surface->w, surface->h, 0,
GL_BGR, GL_UNSIGNED_BYTE, surface->pixels );

return 0;
}
else
{
printf("SDL could not load test.bmp: %s\n", SDL_GetError());
return 1;
}

// Free the SDL_Surface only if it was successfully created
if ( surface ) {
SDL_FreeSurface( surface );
}

Share this post


Link to post
Share on other sites
u need an alpha channel with a texture, create the alpha channel in a paint program.

u need to use the following
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, surface->w, surface->h, 0, GL_BGRA, GL_UNSIGNED_BYTE, surface->pixels );

with glEnable( GL_ALPHA_TEST );
glAlphaFunc( GL_GREATER, 0.0 );

Share this post


Link to post
Share on other sites
Quote:
Original post by benang00
Well, I've tried that but it didn't work. FYI, I'm using SDL to load the image and then I generate the texture from the SDL surface that was created.

It doesn't work because "SDL_SetColorKey" doesn't actually change the image, it just tells SDL what the color key will be when you use SDL to blit it to the framebuffer, but that never happens.

You actually need to copy the RGB image into a new RGBA image, setting color keyed pixels as transparent. Then you send the RGBA image to OpenGL. You can do that manually, or you should be able to blit the image with color keying into an RGBA surface; that should work as long as the RGBA surface is transparent before you blit, although I haven't tested.

Share this post


Link to post
Share on other sites
Quote:
Original post by zedz
u need an alpha channel with a texture, create the alpha channel in a paint program.

u need to use the following
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, surface->w, surface->h, 0, GL_BGRA, GL_UNSIGNED_BYTE, surface->pixels );

with glEnable( GL_ALPHA_TEST );
glAlphaFunc( GL_GREATER, 0.0 );


Well, that means I've got to make non BMP (maybe a JPG or PNG) texture assets because AFAIK BMP images can't have alpha channel. Although I can do that by implementing SDL and SDL_image to load the image, I want to know how to load a BMP texture with color key.

Quote:
Original post by Nathan Baum
It doesn't work because "SDL_SetColorKey" doesn't actually change the image, it just tells SDL what the color key will be when you use SDL to blit it to the framebuffer, but that never happens.

You actually need to copy the RGB image into a new RGBA image, setting color keyed pixels as transparent. Then you send the RGBA image to OpenGL. You can do that manually, or you should be able to blit the image with color keying into an RGBA surface; that should work as long as the RGBA surface is transparent before you blit, although I haven't tested.


You're right. I've read the SDL documentation and it only ignores the color key when blitting. D'oh! :( I've also tried to blit a 24 bit RGB surface with color key to a new 32 bit RGBA with per pixel alpha channel of 0 (transparent) but the color key still didn't become transparent. Even it makes the color wrong. :D

Maybe the only thing I can do is changing the pixel data directly.

Share this post


Link to post
Share on other sites
BMP support 32 bit. Just set bits value in the header to 32.
jpg also supports 32 bit but I think libjpeg can't work with them.
png, yes for sure.

There is no such thing as color keying in GL. You need to emulate it like the others have shown.

Share this post


Link to post
Share on other sites
Quote:
Original post by V-man
BMP support 32 bit. Just set bits value in the header to 32.
jpg also supports 32 bit but I think libjpeg can't work with them.
png, yes for sure.

There is no such thing as color keying in GL. You need to emulate it like the others have shown.


Yeah I know that there's no color keying in openGL. But there's alpha blending. So I need to know how to convert from a color key pixel to a pixel with a transparent alpha channel (while the other colors become opaque). And then make a texture out of it. If not, I'll just try to change the assets and add alpha blending to them.

Share this post


Link to post
Share on other sites
its easier/better/more flexible if u do it in a paint program eg photoshop/gimp

u can do it yourself with something like

read in rgb texture data
create a rgba texture (empty)
loop through all pixels in the rgb texture
copy the rgb -> rgba
with the a see if the r==255 && g==255 & b==0 if so set a = 0 else a = 255;
ie all yellow pixels will be transparent

Share this post


Link to post
Share on other sites
you could also do this with "alpha testing" if you´re up to the challenge of providing an alpha channel to all your textures :)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!