Вопрос

У меня есть какой -то код OpenGL, который ведет себя непоследовательно для разных оборудования.У меня есть код, который:

  1. Создает буфер рендеринга и привязывает текстуру к ее цветовому буферу (Текстура A).
  2. Устанавливает этот буфер рендеринга как активный, настраивает область просмотра и т. д.
  3. Активирует пиксельный шейдер (в данном случае размытие по Гауссу).
  4. Рисует четырехугольник на весь экран с текстурой A на нем.
  5. Отвязывает рендербуфер и т.д.

На моей машине разработки это работает нормально, и имеет предполагаемый эффект размытия текстуры «на месте», однако на других оборудовании это, похоже, не работает.

Я свел это к двум возможностям.

А) Предполагается, что приготовление рендеринга для себя не должно работать, и работает только на моей машине разработки из -за какой -то случайности.

Или

Б) Этот подход должен работать, но что-то еще идет не так.

Есть идеи?Честно говоря, мне было трудно найти конкретику по этому вопросу.

Это было полезно?

Решение

А) правильный ответ.Рендеринг в тот же буфер при чтении из него не определен.Это может сработать, а может и нет – именно это и происходит.

В случае OpenGL расширение Framebuffer_object есть раздел «4.4.3 Рендеринг, когда изображение привязанного объекта текстуры также прикреплено к кадровому буферу», в котором рассказывается, что происходит (в основном, неопределенное).В Direct3D9 среда выполнения отладки громко жалуется, если вы используете эту настройку (но она может работать в зависимости от оборудования/драйвера).Я думаю, что в D3D10 среда выполнения всегда отвязывает цель, которая используется в качестве места назначения.

Почему это неопределенно?Одна из причин, по которой графические процессоры такие быстрые, заключается в том, что они могут делать множество предположений.Например, они могут предположить, что устройствам, которые извлекают пиксели, не нужно взаимодействовать с модулями, которые записывают пиксели.Таким образом, поверхность может быть прочитана, через N циклов чтение завершено, через N циклов пиксельный шейдер завершает свое выполнение, затем он помещается в некоторые выходные буферы слияния на графическом процессоре и, наконец, в какой-то момент записывается в память.Вдобавок ко всему, графические процессоры растеризуются в «неопределённом» порядке (один графический процессор может растрировать по строкам, другой — в каком-то удобном для кэша порядке, третий — в совершенно другом порядке), поэтому вы не знаете, какие части поверхности будут записаны. сначала.

Итак, что вам нужно сделать, это создать несколько буферов.В случае размытия/свечения обычно достаточно двух — сначала визуализировать, затем прочитать и размыть во время записи во вторую.При необходимости повторите этот процесс в режиме пинг-понга.

Другие советы

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top