首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在OpenGL中绘制剪裁UI元素的最佳方法

在OpenGL中绘制剪裁UI元素的最佳方法
EN

Stack Overflow用户
提问于 2012-12-06 11:21:48
回答 3查看 3.4K关注 0票数 7

我有一个复杂的UI-系统,它允许很多东西也可以用WPF完成,但支持多个平台( iOS,Android,Windows,. )。它尚未完成,现在我面临以下问题:

我的设计师想要旋转的物体!旋转对象比简单的轴对齐对象要复杂得多,这就是我不能使用glScissor的原因。一张可能有助于理解问题的小图形:

您可以看到,我需要将对象"Subcontainer“按”父容器“的界限剪辑。据我所知,几乎没有选择:

  • 使用模具缓冲区,在这种情况下,我遇到了一个问题,因为我有一些不可见的对象,而且还必须影响模具缓冲区,因为它们可能掩盖子对象。此外,我必须绘制每个对象两次,因为我需要减少模具缓冲区时,回到层次结构。
  • 切割用于绘制ui对象的平面(三角剖分;或任何其他UI模型),这似乎是很有代价的,因为它们可能会在不同的点被裁剪(想象一下旋转容器中的容器中的容器在旋转的容器中.)而且,很难正确裁剪它们,这可能是性能问题的根源之一。

然而,两者似乎导致了许多不同的问题,可能是性能泄漏的一个来源。还有其他方法来存档我想要的东西吗?还是有任何方法来改进上述两种方法?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-03-05 00:11:42

最后,我使用了模板缓冲区,这会产生比深度方法更多的绘图调用,但更容易实现。

在我画之前,我写了以下代码:

代码语言:javascript
复制
if (_Mask)
{
    if (Stage.StencilMaskDepth++ == 0)
        GL.Enable(EnableFlags.STENCIL_TEST);

    GL.ColorMask(false, false, false, false);
    GL.DepthMask(false);
    GL.StencilFunc(StencilFunction.ALWAYS, Stage.StencilMaskDepth, Stage.StencilMaskDepth);
    GL.StencilOp(StencilOp.INCR, StencilOp.INCR, StencilOp.INCR);

    // Draw rectangle
    DrawColor(Colors.Black);

    GL.ColorMask(true, true, true, true);
    GL.DepthMask(true);
    GL.StencilFunc(StencilFunction.EQUAL, Stage.StencilMaskDepth, Stage.StencilMaskDepth);
    GL.StencilOp(StencilOp.KEEP, StencilOp.KEEP, StencilOp.KEEP);
}

在绘制了所有的childs之后,这个代码被称为:

代码语言:javascript
复制
if (_Mask)
{
    GL.ColorMask(false, false, false, false);
    GL.DepthMask(false);
    GL.StencilFunc(StencilFunction.ALWAYS, Stage.StencilMaskDepth, Stage.StencilMaskDepth);
    GL.StencilOp(StencilOp.DECR, StencilOp.DECR, StencilOp.DECR);
    // Draw rectangle
    DrawColor(Colors.Black);

    GL.ColorMask(true, true, true, true);
    GL.DepthMask(true);

    if (--Stage.StencilMaskDepth == 0)
        GL.Disable(EnableFlags.STENCIL_TEST);
}

也许我会在几个月内测试其他一些方法,但目前这是最容易实现的。

票数 5
EN

Stack Overflow用户

发布于 2012-12-06 11:46:47

这只是一个想法,但是如何使用深度缓冲区进行掩蔽呢?

  1. 启用深度缓冲区并设置glDepthFunc(GL_LEQUAL);
  2. 在Z=0处呈现容器A及其框架
  3. 将容器呈现为Z=1的内部区域/背景(其中将有其他嵌套容器)
  4. 现在你有一个“深度模板”,容器框架在深度0,容器内部在深度1。这意味着你呈现在中间的任何东西都在内部,但是低于帧(并被它剪裁)。
  5. 现在使用下一个容器B,将它的帧呈现为Z= 0.5 (它将由GPU上的父容器A裁剪)
  6. 在Z= 0.75处渲染容器B内部区域
  7. 现在,您想在容器B中呈现的任何内容都必须以Z= 0.75的速度呈现。它将覆盖容器的内部区域,但将被两个容器A和B帧剪裁。
票数 3
EN

Stack Overflow用户

发布于 2012-12-06 12:53:45

也许你可以试着渲染纹理。创建父纹理。然后将所有的孩子渲染到这个纹理中。然后将父纹理呈现到屏幕上,按需要变形和替换。此解决方案可能存在问题,也可能没有问题,这取决于您想要实现什么。特别是,如果您对容器进行缩放,或者有一个非常复杂的树,由许多嵌套的容器组成,那么您可能会出现性能问题。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13742556

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档