В настоящее время я не знаю, возможно ли настроить буфер трафарета так, чтобы он мог выполнять все 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, что означает, что был нарисован как минимум один прямоугольник.
Для более чем двух прямоугольников это может стать более сложным, и вам нужно немного поиграть, чтобы найти наиболее оптимальный путь.