0

关于文章OpenGL 剪辑中讨论的问题,出现了一个新问题。

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

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

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

现在,模板剪裁只需一个剪裁盒即可完美运行。但是,如果孩子或孙子与祖先相交,算法会失败,因为此处需要 2 个相关矩形的交集(如在轴对齐版本中)作为掩码,而不是孩子的完整矩形。

我已经想到了以下算法:

最上面的节点写入以计数器值 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 写入缓冲区。

有人可以帮我吗?

4

1 回答 1

2

glStencilFunc(GL_ALWAYS, ref, mask);说:

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

glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);具有以下效果:

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

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

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

在绘制用户可见的东西时,您可以使用glStencilFuncset to GL_GEQUAL并将传入的值与“1”、“2”、“3”或其他值进行比较。

如果您不想跟踪您的深度有多少层,假设您将一个剪辑区域绘制到模板中,您可以通过以下方式将其修改为下一个剪辑区域:

  1. GL_INCR用;绘制所有新几何图形 这将产生一个模板缓冲区,其中两个区域中的所有像素的值为“2”,而仅一个区域中的所有像素的值为“1”
  2. 绘制一个全屏多边形,仅使用模板基金GL_GREATER和参考值 0 传递,使用GL_DECR. 结果是“0”在从未绘制或只绘制一次的地方,“1”在任何地方绘制了两次。
于 2011-09-27T14:43:16.410 回答