OpenGL ES трафаретные операции - PullRequest
       52

OpenGL ES трафаретные операции

0 голосов
/ 27 сентября 2011

В связи с проблемой, обсуждаемой в статье Обрезка OpenGL , возникает новый вопрос.

Я реализую отсечение для двухмерного графа сцены на основе узла. Всякий раз, когда блоки отсечения выровнены по оси, я использую glScissor, как предложено в Отсечение OpenGL . Я успешно реализовал отсечение узлов из блоков, которые выровнены по оси.

Оказывается, что каждый узел должен пересекать свой прямоугольник отсечения с теми из его предков, которые используют отсечение. (Это необходимо в том случае, если братья и сестры перекрываются с обтравочной рамкой предка).

Механизм пересечения неосевых прямоугольников должен быть реализован с использованием буфера трафарета. Я начал реализовывать предложенное решение в OpenGL clipping , но у меня проблемы с детьми, у которых обрезки клипов пересекаются с их предшественниками.

В настоящее время трафаретная обрезка прекрасно работает только с одним отсечением. Но в случае дочернего элемента или внука, который пересекается с предком, алгоритм терпит неудачу, потому что пересечение 2 вовлеченных прямоугольников здесь необходимо (как в версии с выравниванием по оси) как маска, а не полный прямоугольник дочернего элемента.

Я придумал следующий алгоритм:

Самая верхняя запись узла начинается со значения счетчика 1 и рисует свой прямоугольник отсечения, заполненный 1, в буфере трафарета и отрисовывает его дочернее тестирование трафарета против 1. Каждый брат, у которого также включено отсечение, рисует свой ограничивающий прямоугольник добавление 1 в буфер трафарета, затем проверка на 2 и так далее. Теперь, когда прямоугольник отсечения братьев и сестер перекрывается с родительским, область, в которой они перекрываются, будет заполнена двумя секундами, что дает идеальное отсечение при тестировании против 2. Этот алгоритм может быть расширен до максимум 255 вложенных узлов отсечения.

А вот и мои вопросы:

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

Это мой код, который я использую для подготовки к визуализации в буфер трафарета:

glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_ALWAYS, ref, mask);
glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);

Я ищу установку, которая увеличит текущее значение буфера трафарета на значение ref вместо записи ref в буфер.

Может кто-нибудь мне помочь?

1 Ответ

2 голосов
/ 27 сентября 2011

glStencilFunc(GL_ALWAYS, ref, mask); говорит, что:

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

glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);, приводит к тому, что:

  • при сбое теста трафарета, новое значение заменяет старое (по первому аргументу)
  • , когда проверка глубины не проходит, но тест трафарета проходит, новое значение заменяет старое (по второму аргументу)
  • , когдаИспытание трафарета и глубины проходит успешно, новое значение заменяет старое (согласно третьему аргументу)

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

Вероятно, вы хотите изменить аргументы на glStencilOp, чтобы вы выполнялиGL_INCR на пикселях, которые проходят.Таким образом, в буфере трафарета вы получите «1» в любом месте, к которому прикоснулся один полигон, «2» в любом месте, где вы нарисовали два последовательных полигона, «3» в любом месте, где вы нарисовали 3, и т. Д.

При рисовании видимого пользователем материала вы можете использовать что-то вроде glStencilFunc, установленное на GL_GEQUAL, и сравнивать входящие значения с '1', '2', '3' или чем-либо другим.

Если выпредпочитаете не отслеживать, сколько уровней вы находитесь на глубине, предположив, что в трафарете нарисована одна область клипа, вы можете изменить ее на следующую область клипа следующим образом:

  1. рисуя всю новую геометрию с помощью GL_INCR;это приведет к созданию буфера трафарета, в котором все пиксели, которые были в обеих областях, имеют значение «2», а все пиксели, которые были только в одной области, имеют значение «1»
  2. , чтобы нарисовать полноэкранный многоугольник, передать только с трафаретным фондом GL_GREATER и ссылочным значением 0, с GL_DECR.Результатом является '0' везде, где никогда не был нарисован или был нарисован только один раз, '1' везде, где было нарисовано дважды.
...