#ios #opengl-es #framebuffer
#iOS #opengl-es #фреймбуфер
Вопрос:
Возможно ли привязать несколько фреймбуферов и буферов визуализации в OpenGL ES? Я выполняю рендеринг в закадровый фреймбуфер / renderbuffer и предпочел бы просто использовать свой существующий код рендеринга.
Вот что я сейчас делаю:
// create/bind framebuffer and renderbuffer (for screen display)
// render all content
// create/bind framebuffer2 and renderbuffer2 (for off-screen rendering)
// render all content again (would like to skip this)
Вот что я хотел бы сделать:
// create/bind framebuffer and renderbuffer (for screen display)
// create/bind framebuffer2 and renderbuffer2 (for off-screen rendering)
// render all content (only once)
Возможно ли это?
Ответ №1:
Вы не можете одновременно отображать несколько фреймбуферов. Возможно, вы сможете использовать MRTS для рендеринга в несколько целевых объектов рендеринга (текстуры / буферы рендеринга), которые принадлежат одному и тому же FBO, выделяя несколько цветов в шейдере фрагмента, но не в несколько FBO, таких как закадровый FBO и буфер кадров по умолчанию. Но, если я правильно информирован, ES в любом случае на данный момент не поддерживает MRT.
Но в вашем случае вам все равно не нужно дважды отображать сцену. Если вам это все равно нужно в закадровом буфере рендеринга, почему бы вам просто не использовать текстуру вместо буфера рендеринга для хранения закадровых данных (это не должно иметь значения). Таким образом, вы можете просто отрендерить сцену один раз в закадровый буфер (текстуру), а затем отобразить эту текстуру в экранном фреймбуфере, нарисовав простой текстурированный квадрат с помощью простого сквозного фрагментного шейдера.
Хотя, в OpenGL ES это может иметь значение, если вы используете renderbuffer или текстуру для хранения закадровых данных, поскольку ES не имеет glGetTexImage
. Поэтому, если вам нужно скопировать закадровые данные в процессор, вы не обойдетесь glReadPixels
, и поэтому вам понадобится renderbuffer. Но в этом случае вам все равно не нужно дважды отображать сцену. Вам просто нужно ввести другой FBO с прикрепленной текстурой. Таким образом, вы визуализируете сцену один раз в текстуру, используя этот FBO, а затем визуализируете эту текстуру как в offsrceen FBO, так и в screen framebuffer. Это все равно может быть быстрее, чем отрисовка всей сцены дважды, хотя это может сказать вам только оценка.
Но если вам нужно скопировать данные в CPU для обработки, вы также можете просто скопировать их непосредственно из буфера кадров экрана, и вам не нужен закадровый FBO. И если вам нужны закадровые данные только для обработки на основе GPU, то текстура в любом случае лучше, чем буфер рендеринга. Поэтому может быть полезно подумать, действительно ли вам все равно нужен дополнительный закадровый буфер, если он содержит только те же данные, что и экранный фреймбуфер. Это может сделать всю проблему устаревшей.
Комментарии:
1. @MrDatabase Есть ли у вас FBO в версии 1.1 (если нет, весь вопрос в любом случае будет недействительным)? Если да, то это просто сработает. Вместо простого сквозного шейдера фрагментов вы просто визуализируете стандартный текстурированный квадрат, отключая все ненужное (например, освещение), чтобы ускорить процесс.
2. @MrDatabase И, кстати, вы не должны создавать FBO и renderbuffer заново каждый кадр. Создайте их в начале и просто привяжите их к каждому кадру.
3. @MrDatabase Что вы хотите сделать с закадровыми данными?
4. @MrDatabase — Да, это должно работать на iOS с 1.1, потому что FBO используются даже для вывода на экран в ОС. Я не думаю, что вам здесь что-то понадобится
glReadPixels()
, так как вы могли бы просто привязать целевую текстуру рендеринга в качестве входных данных для рендеринга на экране и перейти. Я сделал это сам, и это отлично сработало. Я думаю, вам это понадобится только в том случае, если вы хотите, чтобы визуализированная сцена использовалась для чего-то другого на стороне процессора (например, для сохранения на диск в виде изображения).5. @MrDatabase В этом случае вы не сможете обойти решение в третьем абзаце (обязательно сделайте текстуру с полным разрешением), но вы должны оценить, действительно ли это ускоряет рендеринг в два раза или даже удаляет дополнительный FBO и напрямую считывает с экрана в полном разрешении (хотяпоследнее может быть действительно худшей идеей с точки зрения производительности).