OpenGL裁剪
我已经阅读有关剪辑的文章几个小时了,但我似乎找不到解决我的问题的方法。
这是我的场景:
在 OpenGL ES 环境(IOS、Android)中,我有一个由可绘制对象组成的 2D 场景图,形成一棵树。
每个树节点都有自己的空间房间和自己的变换矩阵,并且每个节点将其坐标空间继承给其子节点。每个节点都有一个矩形边界框,但这些边界框不是轴对齐的。
此设置非常适合渲染 2D 场景图、迭代树、渲染每个对象及其子对象。
现在我的问题来了:我正在寻找一种在节点上启用剪辑的方法。启用剪切后,当节点的子节点离开父节点的边界框区域时,应该被剪切。
例如,我想要一个包含一组文本节点作为子节点的节点,该节点可以在其父边界框内上下滚动,并且在离开父边界框的区域时应被剪切。
由于边界框未轴对齐,因此我无法使用 glScissor,这将是最简单的方法。
我正在考虑使用模板缓冲区并在启用剪切时将填充的边界矩形绘制到其中,然后启用模板缓冲区。这可能有效,但会导致另一个问题:如果被剪切节点内的子节点再次被剪切,会发生什么? - 必须为孩子设置模板蒙版,擦除父母的模板蒙版。
我想到的另一个解决方案是在软件中进行剪辑。这是可能的,因为在每个节点内,可以在其自己的局部坐标空间中相对容易地完成裁剪。该解决方案的缺点是必须为每个实现的新节点类型实现裁剪。
这里有人能指出我正确的方向吗? 我正在寻找类似 glscissor 的功能,用于剪切非轴对齐的矩形区域。
I have been reading articles about clipping now for hours now but I dont seem to find a solution for my problem.
This is my scenario:
Within an OpenGL ES environment (IOS,Android) I am having a 2D scene graph consisting of drawable objects, forming a tree.
Each tree node has its own spatial room with it's own transformation matrix, and each node inherits its coordinate space to its children. Each node has a rectangular bounding box, but these bounding boxes are not axis aligned.
This setup works perfect to render a 2D scene graph, iterating through the tree, rendering each object and then it's children.
Now comes my problem: I am looking for a way enable clipping on a node. With clipping enabled, children of a node should be clipped when leaving the area of the parent's bounding box.
For example I wand to have a node containing a set of text nodes as children, which can be scrolled up and down withing it's parents bounding box, and should be clipped when leaving the area of the parent's bounding box.
Since bounding boxes are not axis aligned, I cannot use glScissor, which would be the easiest way.
I was thinking about using the stencil buffer and draw the filled bounding rectangle into it, when clipping is enabled and then enable the stencil buffer. This might workd but leads to another problem: What happens if a child inside a clipped node has clipping again ? - The stencil mask would have to be setup for the child, erasing the parents stencil mask.
Another solution I was thinking of, is to do the clipping in software. This would be possible, because within each node, clipping could be done relative easily in it's own local coordinate space. The backdraw of this solution would be that clipping has to be implemented for each new node type that is implemented.
Can anybody here point me into the right direction?
What I am looking for is something like the functionality of glscissor for clipping non axis aligned rectangular areas.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
剪刀盒是一个满足简单需求的简单工具。如果您有不太简单的需求,那么您将不得不使用不太简单的 OpenGL 机制进行裁剪:模板缓冲区。
假设您目前没有将模板缓冲区用于任何其他用途,则您可以访问 8 个模板位。通过为场景图中的每个级别指定比上一个级别更高的数字,您可以为每个级别分配自己的模板蒙版。当然,如果同一深度级别的两个兄弟姐妹重叠,或者只是太接近,那么就会遇到问题。
另一种替代方法是为每个节点分配一个从 1 到 255 的数字。使用 GL_EQUAL 的模板测试,您将能够防止上述重叠问题。但是,这意味着整个场景图中的节点数不能超过 255 个。根据您的特定需求,这可能是一个太大的限制。
当您通过任一方法用完位时,您当然可以清除模板(和深度。不要尝试仅清除其中一个)。但这可能成本较高,并且需要您清除深度,而您可能不想这样做。
另一种方法是仅对非轴对齐节点使用递增数量和 GL_EQUAL 测试。对于大多数节点,您使用剪刀盒,但如果存在一些旋转(无论是在该节点上还是继承的节点),则您可以使用模板遮罩,在处理图形时碰撞遮罩计数器。同样,您的节点数限制为 256 个,但至少这些仅适用于旋转节点。根据您的需求以及旋转节点的数量,这可能就足够了。
The scissor box is a simple tool for simple needs. If you have less simple needs, then you're going to have to use the less simple OpenGL mechanism for clipping: the stencil buffer.
Assuming that you aren't using the stencil buffer for anything else at present, you have access to 8 stencil bits. By giving each level in your scene graph a higher number than the last, you can assign each level its own stencil mask. Of course, if two siblings at the same depth level overlap, or simply are too close, then you've got a problem.
Another alternative is to assign each node a number from 1 to 255. Using a stencil test of GL_EQUAL, you will be able to prevent the overlap issue above. However, this means that you can have no more than 255 nodes in your entire scene graph. Depending on your particular needs, this may be too much of a restriction.
You can of course clear the stencil (and depth. Don't try to clear just one of them) when you run out of bits via either method. But that can be somewhat costly, and it requires that you clear the depth, which you may not want to do.
Another method is to use the increasing number and GL_EQUAL test only for non-axis-aligned nodes. You use the scissor box for most nodes, but if there is some rotation (whether on that node or inherited), then you use the stencil mask instead, bumping the mask counter as you process the graph. Again, you are limited to 256 nodes, but at least these are only for rotated nodes. Depending on your needs and how many rotated nodes there are, that may be sufficient.