在适用于 iOS 应用程序的 OpenGL ES 2.0 中使用遮罩

发布于 2024-12-10 01:13:01 字数 331 浏览 0 评论 0原文

我有一个应用程序,我希望用户在屏幕的某个特定区域进行绘制。为此,我使用了一张蒙版图片,该图片在可绘制区域为黑色,在不可绘制区域为透明。因此,用户只能在遮罩内部和遮罩黑色区域内部的屏幕区域上进行绘制。

我尝试通过模板缓冲区来实现它,并修改了 GLPaint 示例项目中的一些代码: http://pastebin.com/94MBr1Su< /a>

但是我仍然不明白模板缓冲区的使用。任何人都可以帮我解决我的问题的模板缓冲区的代码示例吗?另外,有没有办法在没有模板缓冲区的情况下实现这一点?

I have an app where I want user to draw in one certain area of the screen. For this purpose I use a picture of mask which is black in drawable area and transparent in non-drawable area. So user can draw only on the area of the screen inside the mask and inside the black area of the mask.

I've tried to implement it via stencil buffer and modified some code from GLPaint sample project: http://pastebin.com/94MBr1Su

However I still don't get the idea of stencil buffers usage. Can anyone please help me with code examples of stencil buffers for my issue? Also, is there any way to implement this without stencil buffers?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

攀登最高峰 2024-12-17 01:13:01

因为您的蒙版是纹理,所以模板缓冲区不是一个好主意。

  • 在遮罩渲染期间,必须使用“discard;”对于片段着色器中的透明像素,
  • 请说欢迎遇到抗锯齿问题。

出于您的好奇心,这里有一些使用模板缓冲区配置蒙版的代码:

const bool invert_mask = false; // allow to draw inside or outside mask
unsigned mask_id = 1; // you can use this code multiple time without clearing stencil, just increment mask_id

glEnable(GL_STENCIL_TEST);
// write on stencil_mask
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
glStencilFunc(GL_ALWAYS, mask_id, 0);

// remove depth test and color writing
glDepthMask(GL_FALSE);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);


// TODO: draw geometry of mask here. (if you use a texture, dont forget to use discard in the shader 


// enabled depth & color writing
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glDepthMask(GL_TRUE);

// no stencil write
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
// test stencil value
glStencilFunc(invert_mask ? GL_NOTEQUAL : GL_EQUAL, mask_id, 0xff);


// TODO: draw  "clipped" geometry here


// finally, remove stencil test
glDisable(GL_STENCIL_TEST);

最简单的方法是根本不使用模板。创建一个灰度屏幕大小的纹理,在里面写下你的蒙版。然后将其绑定到片段着色器中:

uniform LOW_P sampler2D u_diffuse_sampler;
uniform LOW_P sampler2D u_mask_sampler;
varying mediump vec2 v_texcoord;

void main(void) {
    gl_FragColor = texture2D(u_diffuse_sampler, v_texcoord) * texture2D(u_mask_sampler, v_texcoord).r;
}

Because your mask is a texture, stencil buffer is not a good idea.

  • during mask rendering, you must use "discard;" for transparent pixels in your fragment shader
  • say welcome to antialiasing problems

For your curiosity, here some code to configure a mask with stencil buffer:

const bool invert_mask = false; // allow to draw inside or outside mask
unsigned mask_id = 1; // you can use this code multiple time without clearing stencil, just increment mask_id

glEnable(GL_STENCIL_TEST);
// write on stencil_mask
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
glStencilFunc(GL_ALWAYS, mask_id, 0);

// remove depth test and color writing
glDepthMask(GL_FALSE);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);


// TODO: draw geometry of mask here. (if you use a texture, dont forget to use discard in the shader 


// enabled depth & color writing
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glDepthMask(GL_TRUE);

// no stencil write
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
// test stencil value
glStencilFunc(invert_mask ? GL_NOTEQUAL : GL_EQUAL, mask_id, 0xff);


// TODO: draw  "clipped" geometry here


// finally, remove stencil test
glDisable(GL_STENCIL_TEST);

The simplest way is to NOT USE STENCIL AT ALL. Create a grayscale screen-size texture, write your mask inside. Then bind it in your fragment shader:

uniform LOW_P sampler2D u_diffuse_sampler;
uniform LOW_P sampler2D u_mask_sampler;
varying mediump vec2 v_texcoord;

void main(void) {
    gl_FragColor = texture2D(u_diffuse_sampler, v_texcoord) * texture2D(u_mask_sampler, v_texcoord).r;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文