Объединение нескольких трафаретов в GL - PullRequest
4 голосов
/ 12 марта 2012

Я хочу настроить несколько трафаретов в OpenGL и затем нарисовать их в нескольких комбинациях.

Например: У меня есть два прямоугольных трафарета, как это:

multiple regions

Тогда я хочу нарисовать:

  1. везде
  2. левый прямоугольник (синий + фиолетовый)
  3. Правый прямоугольник (фиолетовый + красный)
  4. средний прямоугольник (фиолетовый)
  5. вся цветная область (синий + фиолетовый + красный)

Я обнаружил, что можно объявить несколько трафаретов в разных битах буфера шаблонов, но я не знаю как. Как мне настроить glStencilOp и glStencilFunc, чтобы это работало?

Или я могу (должен) использовать для этого glScissor

1 Ответ

2 голосов
/ 12 марта 2012

В настоящее время я не знаю, возможно ли настроить буфер трафарета так, чтобы он мог выполнять все 5 вышеуказанных шагов, не внося никаких изменений в буфер трафарета между ними. Было бы легко, если бы glStencilOp предоставлял побитовое ИЛИ, но это не так, и просто используя увеличение или уменьшение, вы бы рисовали прямоугольники несколько раз.

Но если области всегда являются прямоугольниками, почему бы просто не использовать тест ножниц? Таким образом, первые 3 шага (или фактически 2 и 3) можно сделать, просто установив область прямоугольника с помощью glScissor и включив тест ножниц (glEnable(GL_SCISSOR_TEST)).

Для среднего (шаг 4) вы либо сами вычисляете фиолетовый прямоугольник пересечения и снова используете тест ножниц, либо тест трафарета:

glEnable(GL_STENCIL_TEST);
glStencilFunc(/*whatever*/);
glStencilOp(GL_INCR, GL_INCR, GL_INCR);    //increase the stencil value
//draw both rectangles

glStencilFunc(GL_EQUAL, 2, 0xFFFFFFFF);    //only draw where both rectangles are
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);    //don't change the stencil buffer
//draw things

Итак, сначала мы рисуем оба прямоугольника и увеличиваем значение трафарета везде, где они нарисованы. Затем мы рисуем наши вещи везде, где значение трафарета равно 2, что означает, что были нарисованы оба прямоугольника.

Для 5-го шага вы используете тот же буфер трафарета, но с

glStencilFunc(GL_LEQUAL, 1, 0xFFFFFFFF);

для второго прохода. Таким образом, вы рисуете что-то везде, где буфер трафарета равен как минимум 1, что означает, что был нарисован как минимум один прямоугольник.

Для более чем двух прямоугольников это может стать более сложным, и вам нужно немного поиграть, чтобы найти наиболее оптимальный путь.

...