Самая эффективная архитектура для многоуровневого 2D-приложения с использованием OpenGL на iPhone?

Я работаю над приложением для iPhone OS, основным видом которого является двумерное представление OpenGL (это подкласс класса Apple EAGLView, в основном устанавливающий ортопроецируемую двумерную среду), с которым пользователь взаимодействует напрямую.

Иногда (не всегда) я хотел бы отобразить некоторые элементы управления поверх этого базового представления GL — представьте, что это Heads-Up Display. Обратите внимание, что базовый вид внизу может прокручиваться/анимироваться, в то время как элементы управления должны казаться фиксированными на экране выше.

Я хорошо разбираюсь в представлениях Cocoa в целом, и я неплохо разбираюсь в CoreGraphics, но я зеленый с Open GL, и операции EAGLView (и его связь с CALayers) довольно непрозрачны для меня. Я не уверен, как наиболее эффективно смешивать другие элементы (читай: лучшая производительность, минимум хлопот и т. д.). Я знаю, что в крайнем случае я могу создать и сохранить геометрию для всех других элементов управления, а также визуализировать их поверх моей базовой геометрии каждый раз, когда я рисую/переключаю местами, и, таким образом, просто сохраняю все, что видит пользователь, в одном представлении. Но я менее уверен в других методах, таких как наличие другого представления поверх (UIKit/CG или GL?) или каким-то образом создание других слоев в моем единственном представлении и т. д.

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

Спасибо.


person Ben Zotto    schedule 10.01.2010    source источник


Ответы (1)


Создайте свой анимированный вид как обычно. Рендерим его в рендер-цель. Что это значит? Что ж, обычно, когда вы «рисуете» полигоны на экране, вы на самом деле делаете это с нормальной поверхностью (основной поверхностью), которая в итоге оказывается той, которая в конечном итоге попадает на экран. Вместо рендеринга на поверхность экрана вы можете рендерить на любую старую поверхность.

Теперь ваш HUD. Будет ли это все время одинаковым или будет меняться? Изменятся ли только его части?

Если все это изменится, вам нужно будет сохранить всю геометрию и текстуры HUD в памяти и отобразить их на вашей «прокручиваемой» поверхности, как обычно. Вы можете применить этот окончательный составной рендеринг к экрану. Я бы не стал слишком беспокоиться о хлопотах и ​​производительности здесь — HUD вряд ли может быть таким же сложным, как фон. У вас будет максимум несколько квадов текстур?

Если весь hud статичен, вы можете визуализировать его на отдельной поверхности при запуске приложения, а затем каждый кадр визуализируется с этой поверхности на анимированную поверхность, которую вы рисуете в каждом кадре. Таким образом, вы можете выгрузить всю геометрию и текстуры HUD прямо на старте. Конечно, может случиться так, что поверхность занимает больше памяти — это зависит от того, какие ресурсы больше всего нужны вашему приложению.

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

Ваши два основных варианта зависят от динамики HUD. Если он движется, вам придется перерисовывать его на сцену в каждом кадре. Это отстой, но я с трудом могу себе представить, что геометрия сложна по сравнению со всем остальным. Если она статична, вы можете выполнить предварительный рендеринг и просто альфа-смешение одной поверхности с другой перед отправкой на экран.

Как я уже сказал, все зависит от того, какие ресурсы есть у вашего приложения.

person Pod    schedule 10.01.2010
comment
Спасибо за ответ, Под. Я предполагаю, что вы говорите, что не рисуйте элементы управления или что-то еще с CoreGraphics поверх вашего представления GL. Вот продолжение: когда я выполняю рендеринг на другую (не экранную) поверхность, как мне затем разместить ее поверх основной поверхности? - person Ben Zotto; 13.01.2010
comment
Я не использовал OGL в течение длительного времени, но у меня есть простой способ (если не «тот самый») — просто нарисовать четырехугольник размером с целевую поверхность и использовать предварительно отрендеренный материал в качестве текстуры. Это также будет масштабировать его для вас, если они разных размеров. Если они 1:1, то это в основном старомодный блит. Используйте альфа-смешивание и т. д., чтобы получить желаемые результаты при рисовании HUD (чтобы вы не делали белый экран только с HUD и т. д. :)) - person Pod; 13.01.2010
comment
Кроме того, при переносе одного предварительно отрендеренного четырехугольника на экран проще всего использовать «сквозной» VS. Я думаю, что в OGL есть функция, которая сделает это за вас, но если нет, просто создайте шейдер GLSL, а не просто пропускайте xyzw и uvst без их преобразования и используйте координаты (1,0,0,0),(0,0 ,0,0),(1,1,0,0) и т. д. для углов вашего четырехугольника. Возможно, вам придется поиграть с z, чтобы он отображался перед пикселями, уже на этой цели рендеринга. - person Pod; 13.01.2010