Советы по дизайну для OpenGL ES 2 / iOS GLKit

Я хотел бы создать приложение, используя новую структуру GLKit, и мне нужен совет по дизайну. Я хотел бы создать приложение, которое представит до пары тысяч «кирпичиков» (объекты с очень простой геометрией). У большинства будет идентичная текстура, но до пары сотен будут иметь уникальную текстуру. Я бы хотел, чтобы кирпичи появлялись каждые несколько секунд, перемещались на место и затем оставались на месте (в мировых координатах). Я хотел бы смоделировать камеру, положение и ориентация которой контролируются пользовательскими жестами.

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

  • Имеет ли смысл связывать объект в виде вида с каждой геометрией ручки, текстурой и т. Д.?
  • Должен ли каждый кирпич иметь собственный буфер вершин?
  • Должен ли каждый иметь свой собственный GLKBaseEffect?
  • Мне нужна помощь в организации того, какой объект и что должен делать во время настройки, а затем рендеринга.

Я надеюсь, что смогу придерживаться типичного шаблона MVC, когда мой GLKViewController будет отслеживать изменения состояния модели, управлять координатами глаз на основе жестов и т. Д.

Был бы очень признателен, если бы вы могли дать мне какой-нибудь совет или привести меня к хорошему примеру. Заранее спасибо!


person danh    schedule 29.10.2011    source источник


Ответы (1)


Что касается моделей, я считаю подходящим подход, аналогичный отношениям между UIImage и UIImageView. Таким образом, каждый тип кирпича имеет единственный буфер вершин, GLKBaseEffect, текстуру и все остальное. Тогда каждый кирпич может появляться несколько раз, так же как несколько UIImageViews могут использовать один и тот же UIImage. С точки зрения сохранения нескольких опорных кадров, на самом деле это действительно хорошая идея - построить иерархию, по существу эквивалентную UIView, каждая из которых содержит некоторое преобразование относительно родительского, а одна сортировка может отображать модель.

Из документации GLKit я думаю, что лучший способ сохранить нужный тип камеры (и действительно местоположения объектов) - это сохранить ее напрямую как GLKMatrix4 или GLKQuaternion, чтобы вы не выводили матрицу или кватернион (плюс местоположение ) из какого-либо другого описания камеры, а матрица или кватернион непосредственно являются хранилищем для камеры.

Оба этих класса имеют встроенные методы для применения поворотов, а GLKMatrix4 может напрямую обрабатывать переводы. Таким образом, вы можете напрямую сопоставить соответствующие жесты с этими функциями.

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

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

Если у вас есть какие-то кирпичи, которые движутся согласованно, более эффективно рисовать их как единый геометрический элемент. Если у вас есть кирпичи, которых точно не видно, даже не пытайтесь их рисовать. Начиная с iOS 5 доступен GL_EXT_occlusion_query_boolean, который позволяет передать некоторую геометрию в OpenGL и спросить, видна ли она. Вы можете использовать это в сценах в реальном времени, создав иерархическую структуру, описывающую ваши данные (которая у вас уже есть, если вы непосредственно следовали UIView аналогии), вычисляя или сохраняя некоторую ограничивающую геометрию для каждого вида и выполняя отрисовку, только если перекрытие Запрос предполагает, что по крайней мере часть ограничивающей геометрии будет видна. Следуя такой логике, вы часто можете отбросить большие участки своей геометрии задолго до того, как отправить их.

person Tommy    schedule 31.10.2011
comment
Спасибо за хороший совет. Я еще раз посмотрю на это с точки зрения аналогии с UIImageView, как вы предлагаете. Пока что я сделал несколько вариантов: 1) решил отделить материал GL от модели, 2) поскольку блоки могут иметь общую геометрию, поместил glGenBuffer и glBufferData на уровень класса. 3) то, что у меня работает до сих пор, - это единственный базовый эффект, принадлежащий контроллеру представления, но переданный как параметр рендеринга, поскольку vc выполняет итерацию кирпичей в сцене, вызывая каждый для рендеринга. При рендеринге кирпичи совмещают его локальное преобразование с эффектом, а затем вызывают glDrawArrays. - person danh; 02.11.2011