2

我有一个简单的 UI 小部件系统,并且我使用模板缓冲区充当剪辑器,这样小部件的子级就不能在小部件之外绘制。基本上,所有东西的模板值都在这个小部件的范围内,这个值是递增的。然后,在我制作剪刀后绘制的任何东西都必须在盒子内。

剪裁器构造函数如下所示:

// Stencil buffer and ClipperStack.size() start at 0
// Increment any pixel in the rect on my current recursion level 
glStencilFunc(GL_EQUAL, ClipperStack.size(), 0xFF);
glStencilOp(GL_KEEP, GL_INCR, GL_INCR);
ClipperStack.push_back(Rect);
// only draw to stencil buffer
glColorMask(0, 0, 0, 0);
glStencilMask(1);
glBegin(GL_QUADS);
    glVertex2f(Rect.Left, Rect.Top);
    glVertex2f(Rect.Left, Rect.Bottom);
    glVertex2f(Rect.Right, Rect.Bottom);
    glVertex2f(Rect.Right, Rect.Top);
glEnd();
// Stencil clipper drawn, 
glColorMask(1, 1, 1, 1);
glStencilMask(0);
// now only draw stuff that's that has the right clipper value
glStencilFunc(GL_EQUAL, ClipperStack.size(), 0xFF);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);

当裁剪器超出范围时,析构函数运行,如下所示:

// Decrement anything we previously incremented
glStencilFunc(GL_EQUAL, ClipperStack.size(), 0xFF);
glStencilOp(GL_KEEP, GL_DECR, GL_DECR);
// Get the old rect
sf::FloatRect Rect = clipperStack.back();
ClipperStack.pop_back();
// Only draw to stencil buffer
glColorMask(0, 0, 0, 0);
glStencilMask(1);
glBegin(GL_QUADS);
    glVertex2f(Rect.Left, Rect.Top);
    glVertex2f(Rect.Left, Rect.Bottom);
    glVertex2f(Rect.Right, Rect.Bottom);
    glVertex2f(Rect.Right, Rect.Top);
glEnd();
// now draw on regular color buffer again, 
// stencil buffer should be the same as before constructor call
glColorMask(1, 1, 1, 1);
glStencilMask(0);
glStencilFunc(GL_EQUAL, ClipperStack.size(), 0xFF);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);

但是,当我运行它时,只会绘制我的根小部件的直接子级。孩子们的孩子根本不画。我已经尝试了很多这样的变体,但我一直在做错事。我不知道我哪里错了。

4

1 回答 1

1

在构造函数和析构函数中,我认为您需要设置glStencilMask()模板缓冲区的每一位。例如,如果你有一个 8 位的模板缓冲区,你想使用glStencilMask(0xFF);

当然,如果您只有一个 1 位的模板缓冲区,您的代码将根本无法工作,因为您正在尝试增加每个级别的子小部件的模板值。

于 2011-03-10T08:27:35.890 回答