OpenGL ES 模板操作

发布于 2024-12-06 21:37:52 字数 1134 浏览 3 评论 0原文

参考OpenGL裁剪一文中讨论的问题,出现了一个新问题。

我正在实现基于节点的 2D 场景图的裁剪。每当剪切框轴对齐时,我都会使用 glScissor,就像 OpenGL 剪切 中建议的那样。我已经成功实现了轴对齐框的节点裁剪。

事实证明,每个节点都必须将其剪裁矩形与其使用剪裁的祖先的矩形相交。 (如果兄弟姐妹与祖先的剪切框重叠,这是必要的)。

必须使用模板缓冲区来实现非轴对齐矩形相交的机制。我开始在 OpenGL 裁剪 中实现建议的解决方案,但我遇到了剪辑矩形与祖先重叠的孩子的问题。

现在,只需一个剪贴盒即可完美地进行模板剪贴。 但是,如果子代或孙代与祖先相交,则算法会失败,因为这里需要两个相关矩形的交集(就像在轴对齐版本中一样)作为掩码,而不是子代的完整矩形。

我想出了以下算法:

最顶层的节点以计数器值 1 开始写入,并将其填充有 1 的剪切矩形绘制到模板缓冲区中,并根据 1 渲染其子模板测试。每个也打开剪切的同级节点都会进行绘制它的边界矩形是通过将 1 添加到模板缓冲区,然后针对 2 进行测试,依此类推。现在,当兄弟剪裁矩形与祖先剪裁矩形重叠时,它们重叠的区域将被 2 填充,在针对 2 进行测试时给出完美的剪裁。该算法可以扩展到最多 255 个嵌套剪裁节点。

我的问题是:

如何以一种方式执行对模板缓冲区的渲染,无论何时执行渲染,都将 1 添加到当前模板缓冲区值,而不是写入 1。

这是我用来准备渲染到模板缓冲区的代码:

glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_ALWAYS, ref, mask);
glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);

我正在寻找一种设置,可以将模板缓冲区当前值增加 ref 的值,而不是将 ref 写入缓冲区。

有人可以帮我吗?

In reference to the problem diskussed in article OpenGL clipping a new question arises.

I am implementing the clipping for a node based 2D scene graph. Whenever the clipping boxes are axis aligned I am using the glScissor like proposed in OpenGL clipping. I have sucessfully implemented node clipping of boxes that are axis aligned.

It turns out that each node has to intersect it's clipping rectangle with the ones of it's ancestors that use clipping. (That is necessary in case of siblings that are overlapping with the clipping box of an ancestor).

The mechanism of intersecting non axis aligned rectangles has to be implemented using the stencil buffer. I started implementing the proposed solution in OpenGL clipping but am having problems with chidrens having clip rects overlaping with theyr ancestors ones.

Right now stencil clipping works perfect with only one clipping box.
But in case of a child or grand child that intersects with an ancestor the algorith fails, because the intersection of the 2 involved rectangles would be needed here (like in the axis aligned version) as mask and not the full rectangle of the child.

I have thought out the following algorithm:

The topmost node writes starts with a counter value of 1 and draws it's clipping rectangle filled with 1s into the stencil buffer and renders it's children stencil-testing against 1. Each sibling that also has clipping turned on draws it's bounding rectangle by adding 1 to the stencil buffer and then testing against 2 and so on. Now when a siblings clipping rect overlaps with an ancestors one,the region where they overlap will be filled with 2s, giving perfect clipping when testing against 2. This algorithm can be extended to a maximum of 255 nested clipping nodes.

Here comes my questions:

How do I perform rendering to the stencil buffer in a way that instead of 1s being writing,1s are added to the current stencil buffer value, whenever rendering is performed.

This is my code I use to prepare for rendering to the stencil buffer:

glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_ALWAYS, ref, mask);
glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);

I am looking for a setup that will increase the stencil buffers current value by the value of ref instead of writing ref into the buffer.

Can someone help me out?

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

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

发布评论

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

评论(1

李白 2024-12-13 21:37:52

glStencilFunc(GL_ALWAYS, ref, mask); 表示:

  • 第一个参数表示模板比较测试总是成功,
  • 因此第二个和第三个参数被忽略,但原则上会设置一个常量来比较即将到来的值从模板缓冲区到哪些位用于比较

glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); 有效果是:

  • 当模板测试失败时,新值将替换旧值(根据第一个参数)
  • 替换旧值(根据第二个参数)。
  • ;当深度测试失败但模板测试通过时,新值将替换旧值(根据第二个参数);当模板和深度相同时,新值将 测试都通过,新值替换旧值(根据第三个参数)

因此,您正在进行设置,以便您尝试绘制的所有内容都将通过模板测试,并且在任何情况下,其值都将被复制到模板缓冲区中,无论它是否通过测试。

您可能想要做的是将参数更改为 glStencilOp,以便对通过的像素执行 GL_INCR。因此,在模板缓冲区中,您最终会在单个多边形接触的任何地方得到“1”,在绘制两个连续多边形的任何地方得到“2”,在绘制 3 个多边形的任何地方得到“3”,等等

。然后,您可以使用将 glStencilFunc 设置为 GL_GEQUAL 之类的内容,并将传入值与“1”、“2”、“3”或其他值进行比较。

如果您不想跟踪自己的深度,假设您在模板中绘制了一个剪辑区域,则可以通过以下方式将其修改为下一个剪辑区域:

  1. 使用 GL_INCR 绘制所有新几何图形;这将产生一个模板缓冲区,其中两个区域中的所有像素的值为“2”,而仅一个区域中的所有像素的值为“1”,
  2. 绘制一个全屏多边形,仅通过模板传递基金 GL_GREATER 和参考值 0,以及 GL_DECR。结果是“0”,凡是从未绘制过或只绘制了一次的地方,“1”,凡是绘制了两次的地方。

glStencilFunc(GL_ALWAYS, ref, mask); says that:

  • the first argument says that the stencil comparison test always succeeds
  • the second and third are hence ignored, but in principle would set a constant to compare the value coming from the stencil buffer to and which of the bits are used for comparison

glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); has the effect that:

  • when the stencil test fails, the new value replaces the old (per the first argument)
  • when the depth test fails but the stencil test passes, the new value replaces the old (per the second argument)
  • when the stencil and depth test both pass, the new value replaces the old (per the third argument)

So you're setting things up so that everything you try to draw will pass the stencil test, and in any case its value will be copied into the stencil buffer whether it passes the test or not.

Probably what you want to do is to change your arguments to glStencilOp so that you perform a GL_INCR on pixels that pass. So in your stencil buffer you'll end up with a '1' anywhere touched by a single polygon, a '2' anywhere that you drew two successive polygons, a '3' anywhere you drew 3, etc.

When drawing the user-visible stuff you can then use something like glStencilFunc set to GL_GEQUAL and to compare incoming values to '1', '2', '3' or whatever.

If you prefer not to keep track of how many levels deep you are, supposing you have one clip area drawn into the stencil, you can modify it to the next clip area by:

  1. drawing all new geometry with GL_INCR; this'll result in a stencil buffer where all pixels that were in both areas have a value of '2' and all pixels that were in only one area have a value of '1'
  2. draw a full screen polygon, to pass only with stencil fund GL_GREATER and reference value 0, with GL_DECR. Result is '0' everywhere that was never painted or was painted only once, '1' everywhere that was painted twice.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文