Jump to content
  • Advertisement
Sign in to follow this  
strivingJuno

OpenGL and selective texture blending

This topic is 2903 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

Hello world.

How can I avoid partially transparant textures being blended with the background of my scene? Consider a set of textures that compose a 2D-map. I want to (gradually) blend only the transitions from one texture to another and not the transitions from texture to background. Textures should be transparent only for textures, and opaque for the background...

Thanks for any reply.

Share this post


Link to post
Share on other sites
Advertisement
If you mean that you just want to transition from one texture to another, then draw the first texture with full opacity, and then render the other texture above it, although this only works if textures would be fully opaque without the transition.

I'm going by the assumption you aren't using multitexturing.

Share this post


Link to post
Share on other sites
No, I don't use multi-texturing.

Quote:
Original post by ashwathh
...although this only works if textures would be fully opaque without the transition


Exactly this is what I want to solve...

To depict my problem, have a look at the following sketch:
http://yfrog.com/edblendingsketchp

Share this post


Link to post
Share on other sites
Use the stencil buffer and render each surface two times. Here's some pseudo code to demonstrate the idea.


clearStencilBuffer();

set zbuffer check to: lesser than

for each surface do
{
// init stencil check
set stencil: render only if stencilvalue = 0

// render surface, first pass
render surface without blending and write stencilvalue = 1

// update stencil check
set stencil: render only if stencilvalue = 1

// render surface, second pass
render surface with blending
}

Share this post


Link to post
Share on other sites
Ashaman, thank you for your reply. I already played with stencil buffers, but had no success. I've implemented your suggestion, but failed again. The main issue was: if I enable depth test, there is nothing rendered. However, if I disable depth testing, the textures are shown correctly - but still: the transitions from texture to background are blended - this is not what I want...

Can you please have a look at my code? Hopefully you find just a bug...


// Prepare texture painting.
glEnable(GL_TEXTURE_2D);
// glEnable(GL_DEPTH_TEST);
// glDepthFunc(GL_LESS);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);

// Loop over images and draw.
for(int i=0; i<nImages; ++i)
{
drawTexture(i);
}

// glDisable(GL_DEPTH_TEST);
glDisable(GL_TEXTURE_2D);



In drawTexture(i), the following GL instructions are called.


// For each image, I do:
// Set-up stencil buffer pass. Don't update color or depth.
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glEnable(GL_STENCIL_TEST);

glStencilFunc(GL_ALWAYS, 0x1, 0x1);
glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);

// Draw texture.
drawTexture(image, pose);

// Switch off writing of stencil buffer.
// Switch on writing color (and depth).
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);

// Draw the area where more than one texture is available.
glStencilFunc(GL_EQUAL, 0x1, 0x1);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);

// In that region, alpha blending is enabled.
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

// Draw texture.
drawTexture(image, pose);

// Disable blending.
glDisable(GL_BLEND);
glDisable(GL_STENCIL_TEST);

Share this post


Link to post
Share on other sites
Quote:
Original post by strivingJuno
Ashaman, thank you for your reply. I already played with stencil buffers, but had no success. I've implemented your suggestion, but failed again. The main issue was: if I enable depth test, there is nothing rendered. However, if I disable depth testing, the textures are shown correctly - but still: the transitions from texture to background are blended - this is not what I want...

Ok, reset :-) I need more information. Take photoshop or gimp and try to archive your effect with different layers ! Are you rendering a 3d scene or 2d scene ? Are the textures applied to one surface or are there different surfaces ? Is there an example of your effect in any other game ?



Share this post


Link to post
Share on other sites
The context I'm working with is stitching. (You might know AutoStich). So the scene I try to draw is 2D. One of the easiest techniques to avoid seams between the images, is to blend from one image to the other.


I drew a few simplistic sketches in GIMP to depict my situation. Of course, when stitching images, we have images with common content in the overlapping area. I just used two colored squares to better visualize my OpenGL-problem. (Hope it's clear enough)

Starting point.
What I have, but what I don't want. Note that I draw the gradually transparent borders with the help of GLSL shaders.
What I want.

So the goal is to blend from one image to another, but not to blend from one image to the background...

[Edited by - strivingJuno on July 8, 2010 6:54:15 AM]

Share this post


Link to post
Share on other sites
Ok, then I would sugguest to turn the ztest off and just work with the stencil buffer. Hers's a modified and untested version of your code:


// For each image, I do:
// Set-up stencil buffer pass. Don't update color or depth.
// WRONG: you need to write the color
//glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
glEnable(GL_STENCIL_TEST);

// NOTE: render opaque part to background(stencil bit 1 = false) only !
glStencilFunc(GL_EQUAL, 0x0, 0x1);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);

// Draw texture.
drawTexture(image, pose);

// Switch off writing of stencil buffer.
// Switch on writing color (and depth).
// NOTE: no need to set the color mask
//glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);

// NOTE: blend ontop of already drawn surfaces only (stencil bit 1 = true)
// if opaque has already been drawn in the first pass, you will
// alpha blend the surface with itself which will not matter
glStencilFunc(GL_EQUAL, 0x1, 0x1);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);

// In that region, alpha blending is enabled.
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

// Draw texture.
drawTexture(image, pose);

// Disable blending.
glDisable(GL_BLEND);
glDisable(GL_STENCIL_TEST);





Good luck :)

Share this post


Link to post
Share on other sites
Awesome!!! That helped. Just had to comment out the glColorMask commands (I took these from a stencil-buffer tutorial...) Thanks a lot :)

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.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!