私は単純な 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);
ただし、これを実行すると、ルート ウィジェットの直接の子のみが描画されます。子の子は全く描かれていません。私はこれのバリエーションをたくさん試しましたが、何か間違ったことをし続けています。これのどこが間違っているのかわかりません。