Трафаретный буфер OperGL работает не так, как я ожидаю - PullRequest
2 голосов
/ 10 марта 2011

У меня есть простая система виджетов пользовательского интерфейса, и я использую буфер трафарета, чтобы действовать как ограничитель, так что дочерние элементы виджета не могут быть нарисованы вне виджета. По сути, значение шаблона для всего, что находится внутри границ этого виджета, увеличивается. Тогда все, что нарисовано после того, как я сделаю машинку для стрижки, должно быть внутри коробки.

Конструктор машинки для стрижки выглядит так:

// 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);

Однако, когда я запускаю это, рисуются только прямые потомки моего корневого виджета. Дети детей вообще не нарисованы. Я попробовал несколько вариантов этого, и я продолжаю делать что-то не так. Я не знаю, где я иду не так с этим.

1 Ответ

1 голос
/ 10 марта 2011

Как в конструкторе, так и в деструкторе, я думаю, вам нужно установить glStencilMask() для установки каждого бита буфера трафарета.Например, если у вас есть 8-битный буфер трафарета, который вы хотите использовать glStencilMask(0xFF);

Конечно, если у вас есть только 1-битный буфер трафарета, ваш код вообще не будет работать, так как вы 'пытается увеличить значение трафарета для каждого уровня подвиджета.

...