使用 OpenGL 嵌套剪刀盒
我正在开发一个用 C 语言编写的基于 OpenGL 的 UI。我有一个控件层次结构 - 较大控件的可滚动区域内的小方形 2D 框。小盒子内部绘制了 3D 场景。 3D 场景必须在小 2D 框内进行剪切,而小 2D 框必须在较大区域内进行剪切。
glScissor()
显然是确保绘图发生在所需区域内的候选者。问题是我无法同时为大区域调用 glScissor()
,然后再次为较大剪切区域内的子区域调用 glScissor()
。
示例代码来演示我想要的内容:
void drawBigBox() {
glScissor( ... ); //set the bounds of the larger region
for each little box {
//these might be anywhere, but they should only be visible if inside the glScissor bounds
drawLittleBoxes();
}
}
void drawLittleBoxes() {
//draw only inside little box -- Whoops! This replaces the big box bounds!
//How can I meet this constraint while retaining the outer scissor region?
glScissor( ... );
draw3dScene();
}
是否有一种简单的方法可以实现我想要的功能?显然,我还可以计算小剪刀框和大剪刀框的交集,或者我可以更仔细地剪辑/投影我的 3D 场景,但这比 OpenGL 调用更复杂。也许还有另一种我不知道的方法可以做到这一点。
谢谢!
I am working on an OpenGL-based UI written in C. I have a hierarchy of controls -- small square 2D boxes inside a scrollable region of a bigger control. Inside the small boxes 3D scenes are drawn. The 3D scene must be scissored within the small 2D boxes and the small 2D boxes must be scissored within the larger region.
glScissor()
is an obvious candidate for making sure drawing takes places within the desired region. The problem is that I cannot simultaneously call glScissor()
for the large region and then call glScissor()
again for subregions inside the larger scissored region.
Example code to demonstrate what I want:
void drawBigBox() {
glScissor( ... ); //set the bounds of the larger region
for each little box {
//these might be anywhere, but they should only be visible if inside the glScissor bounds
drawLittleBoxes();
}
}
void drawLittleBoxes() {
//draw only inside little box -- Whoops! This replaces the big box bounds!
//How can I meet this constraint while retaining the outer scissor region?
glScissor( ... );
draw3dScene();
}
Is there a simple way of doing what I want? Obviously I can also calculate the intersection of the small and large scissor boxes, or I could more carefully clip/project my 3D scene, but that is more complicated than an OpenGL call. Perhaps there is another approach to doing this that I am unaware of.
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
为此,使用模板缓冲区可能更容易。您可以在向其写入四边形时使用 INCR 来增加模板缓冲区值,并且在绘制时将测试设置为 EQUAL 或 GEQUAL 以仅在模板缓冲区具有最高值的位置写入,因此它只会在受所有当前剪切区域。要在绘制层次结构时删除它们,请使用 DECR 再次删除它们。
这样你也可以有非矩形的剪切区域。
For this it is probably easier to use the stencil buffer. You can use INCR to increase the stencil buffer values when writing a quad to it, and when drawing you set the test to EQUAL or GEQUAL to only write where the stencil buffer has the highest value, thus it will only write in the region constrained by all current clipping regions. To remove them when drawing an hierarchy use DECR to remove them again.
This way you can also have non rectangular clipping regions.
您可以尝试依靠 glPush/PopAttribs 调用来保存和恢复剪刀状态。然而,它在 3.1 中被删除,并且属性堆栈可能没有您需要的那么大。所以你应该使用显式堆栈。
只需创建一些用于设置当前剪刀状态的对象即可。当您沿着调用堆栈向下移动时,每一层都会推送其剪刀状态,该状态使用实际的剪刀矩形堆栈。我有一个通用版本,它还推动变换矩阵、混合参数等。
该对象要么必须是全局 GUI 状态,要么与传递给每个函数的某个对象捆绑在一起。
You could try to rely on glPush/PopAttribs calls to save and restore the scissor state. However, that was removed in 3.1, and the stack for attributes may not be as large as you need. So you should use an explicit stack.
Just make some object that you use to set the current scissor state. Each layer as you go down the call stack pushes its scissor state, which uses an actual stack of scissor rectangles. I have a generalized version of this that also pushes transform matrices, blend parameters, and so forth.
The object either has to be global GUI state, or bundled with some object that you pass to each of the functions.
您可以使用
glGet()
和GL_SCISSOR_BOX
参数获取当前剪刀框的坐标(保存它们,或计算它们与另一个区域的交集)。You can get the coordinates of the current scissor box (either to save them, or to calculate their intersection with another region) using
glGet()
with theGL_SCISSOR_BOX
parameter.