OpenGL - 具有多个纹理的蒙版 [英] OpenGL - mask with multiple textures

查看:382
本文介绍了OpenGL - 具有多个纹理的蒙版的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经根据以下概念在OpenGL中实现了遮罩:




  • 遮罩由黑色和白色组成。

  • 前景纹理应该只在面具的白色部分可见。

  • 背景纹理应该仅在面具的黑色部分可见。 / li>


我可以通过使用glBlendFunc()使白色部分或黑色部分工作,但不能同时使用两个,因为前景层不仅混合到面具上,而且混合到背景层上。



有没有人知道如何以最好的方式完成这个?我一直在网上搜索并阅读关于片段着色器的内容。这是要走的方式吗?


b p $ p> glEnable(GL_BLEND);
//使用一个简单的blendfunc来绘制背景
glBlendFunc(GL_ONE,GL_ZERO);
//绘制整个背景而不掩蔽
drawQuad(backgroundTexture);
//接下来,我们想要一个blendfunc,它不会改变任何像素的颜色,
//而是用基于
//的值替换framebuffer alpha值。面具。换句话说,如果一个像素在掩码中为白色,
//那么相应的framebuffer像素的alpha将被设置为1.
glBlendFuncSeparate(GL_ZERO,GL_ONE,GL_SRC_COLOR,GL_ZERO);
//现在draw掩码(再次,这不会产生可见的结果,它只是
//改变framebuffer中的alpha值)
drawQuad(maskTexture);
//最后,我们想要一个blendfunc,使前景仅在
//高alpha字段中可见。
glBlendFunc(GL_DST_ALPHA,GL_ONE_MINUS_DST_ALPHA);
drawQuad(foregroundTexture);

这是相当棘手的,所以告诉我,如果有什么不清楚。



不要忘记请求Alpha缓冲区创建GL上下文时。否则,可能会得到没有Alpha缓冲区的上下文。



编辑:这里,我做了一个例证。



编辑:自撰写此答案后,我了解到有更好的方法:




  • 使用纹理环境

  • 如果您可以使用着色器,请使用片段着色器。



在这个答案中描述的方式工作,并不是特别差的性能比这两个更好的选择,但不那么优雅,不太灵活。


I have implemented masking in OpenGL according to the following concept:

  • The mask is composed of black and white colors.
  • A foreground texture should only be visible in the white parts of the mask.
  • A background texture should only be visible in the black parts of the mask.

I can make the white part or the black part work as supposed by using glBlendFunc(), but not the two at the same time, because the foreground layer not only blends onto the mask, but also onto the background layer.

Is there anyone who knows how to accomplish this in the best way? I have been searching the net and read something about fragment shaders. Is this the way to go?

解决方案

This should work:

glEnable(GL_BLEND);
// Use a simple blendfunc for drawing the background
glBlendFunc(GL_ONE, GL_ZERO);
// Draw entire background without masking
drawQuad(backgroundTexture);
// Next, we want a blendfunc that doesn't change the color of any pixels,
// but rather replaces the framebuffer alpha values with values based
// on the whiteness of the mask. In other words, if a pixel is white in the mask,
// then the corresponding framebuffer pixel's alpha will be set to 1.
glBlendFuncSeparate(GL_ZERO, GL_ONE, GL_SRC_COLOR, GL_ZERO);
// Now "draw" the mask (again, this doesn't produce a visible result, it just
// changes the alpha values in the framebuffer)
drawQuad(maskTexture);
// Finally, we want a blendfunc that makes the foreground visible only in
// areas with high alpha.
glBlendFunc(GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA);
drawQuad(foregroundTexture);

This is fairly tricky, so tell me if anything is unclear.

Don't forget to request an alpha buffer when creating the GL context. Otherwise it's possible to get a context without an alpha buffer.

Edit: Here, I made an illustration.

Edit: Since writing this answer, I've learned that there are better ways to do this:

  • If you're limited to OpenGL's fixed-function pipeline, use texture environments
  • If you can use shaders, use a fragment shader.

The way described in this answer works and is not particularly worse in performance than these 2 better options, but is less elegant and less flexible.

这篇关于OpenGL - 具有多个纹理的蒙版的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆