Texture masking

Started by
3 comments, last by Trillian 14 years, 4 months ago
Hi all! I have a 128x128 alpha, 8bpp texture which is dynamically updated with values of 0 and 255 indicating if the corresponding tiles of my world are walkable. I have two other static textures: a ground texture and an obstacle texture. I want to display both textures by masking them in order for the ground texture to appear where the alpha texture is fully transparent and the obstacle texture to appear where the alpha texture is fully opaque. I've tried using the stencil buffer as a mask but I realized that it doesn't care about transparency, only polygons. How do I go doing this using the fixed-function pipeline? Alternative ways not involving an alpha texture are welcome. However, know that I cannot render each tile individually as it is too costly. Thanks a lot!
Advertisement
If your back-buffer has an alpha-channel, you should be able to render your alpha there first, and then blend with it. It is probably also possible with multi-texturing, Google has some answers, for example: http://www.codesampler.com/oglsrc/oglsrc_4.htm.

The following should work by drawing alpha to the destination first (pseudocode, untested):
glClear(black);glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);renderAlphaTexture();glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);glBlendFunc(GL_DST_ALPHA, GL_ONE);renderGround();glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ONE);renderObstacle();
Thanks for your input, Erik! I have managed to get it to work using the blending trick after a lot of trial and error.
If your framebuffer has an alpha channel (beware : unlike the common sense, the alpha channel is not created by default), and if you want to blend two textures exactly, Erik's solution is probably the way to go.

However, if your objects can overlap (3D world with objects occluding others, or event the same terrain self-occluding) perhaps you could play with the depth functions. Here is a slight modification of the above pseudo-code (also untested) :
glClear(black);glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);glDepthMask(GL_TRUE);glDepthFunc(GL_LESS);renderAlphaTexture();glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);glDepthMask(GL_FALSE);glDepthFunc(GL_EQUAL);glBlendFunc(GL_DST_ALPHA, GL_ONE);renderGround();glBlendFunc(GL_ONE_MINUS_DST_ALPHA, GL_ONE);renderObstacle();
Thanks for the alternative solution, vincoof. In my case, I'm doing a 2D game which doesn't use a depth buffer, so it was simpler for me to add an alpha channel to the backbuffer than to add a depth buffer. I'll try to remember your solution if I have to do it in a 3D game :).

This topic is closed to new replies.

Advertisement