Конфигурирование OpenGL контексты ES

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

Эта глава детализирует, как создать и сконфигурировать контексты на iOS.

EAGL Является Реализация iOS OpenGL Контекст Рендеринга ES

Прежде чем Ваше приложение может вызвать любой OpenGL функции ES, это должно инициализировать EAGLContext объект. EAGLContext класс также обеспечивает, методы раньше интегрировали OpenGL содержание ES с Базовой Анимацией.

Текущим контекстом является Target для OpenGL вызовы функции ES

Каждый поток в приложении для iOS имеет текущий контекст; при вызове OpenGL функция ES это - контекст, состояние которого изменяется вызовом.

Для установки текущего контекста потока вызовите EAGLContext метод класса setCurrentContext: при выполнении на том потоке.

[EAGLContext setCurrentContext: myContext];

Вызовите EAGLContext метод класса currentContext получать текущий контекст потока.

OpenGL ES содержит сильную ссылку к EAGLContext объект, соответствующий текущему контексту. (При использовании подсчета ссылки на руководство OpenGL , ES сохраняет этот объект.), Когда Вы вызываете setCurrentContext: метод для изменения текущего контекста OpenGL ES больше не ссылается на предыдущий контекст. (При использовании подсчета ссылки на руководство OpenGL , ES выпускает EAGLContext объект.) Для предотвращения EAGLContext объекты от того, чтобы быть освобожденным если не текущий контекст, Ваше приложение должно сохранить сильные ссылки к (или сохранить), эти объекты.

Каждый контекст предназначается для определенной версии OpenGL ES

EAGLContext поддержка объектов только одна версия OpenGL ES. Например, код, записанный для OpenGL ES 1.1, не совместим с OpenGL ES 2.0 или 3,0 контекстами. Код, использующий базовые функции OpenGL ES 2.0, совместим с контекстом OpenGL ES 3.0, и код, разработанный для расширений OpenGL ES 2.0, может часто использоваться в контексте OpenGL ES 3.0 с незначительными изменениями. Много новых функций OpenGL ES 3.0 и увеличенных возможностей оборудования требуют контекста OpenGL ES 3.0.

Ваше приложение решает, какую версию OpenGL ES для поддержки, когда это создает и инициализирует EAGLContext объект. Если устройство не поддерживает запрашиваемую версию OpenGL ES, initWithAPI: возвраты метода nil. Ваше приложение должно протестировать, чтобы гарантировать, что контекст был инициализирован успешно перед использованием его.

Для поддержки многократных версий OpenGL ES как рендеринг опций в приложении необходимо сначала попытаться инициализировать контекст рендеринга новейшей версии, для которой Вы хотите предназначаться. Если возвращенный объект nil, инициализируйте контекст более старой версии вместо этого. Перечисление 2-1 демонстрирует, как сделать это.

Перечисление 2-1  , Поддерживающее многократные версии OpenGL ES в том же приложении

EAGLContext* CreateBestEAGLContext()
{
   EAGLContext *context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3];
   if (context == nil) {
      context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
   }
   return context;
}

Контекст API состояния свойства, который версия OpenGL ES поддержки контекста. Ваше приложение должно протестировать контекст API свойство и использование это для выбора корректного пути рендеринга. Общий образец для реализации этого поведения должен создать класс для каждого пути рендеринга. Ваше приложение тестирует контекст и создает средство рендеринга один раз на инициализации.

EAGL Sharegroup управляет OpenGL объекты ES для контекста

Несмотря на то, что контекст содержит OpenGL состояние ES, это непосредственно не управляет OpenGL объекты ES. Вместо этого OpenGL объекты ES создается и сохраняется EAGLSharegroup объект. Каждый контекст содержит EAGLSharegroup возразите, что это делегирует создание объекта к.

Когда два или больше контекста относятся к тому же sharegroup, как показано на рисунке 2-1, преимущество sharegroup становится очевидным. Когда многократные контексты подключены к общему sharegroup, OpenGL , объекты ES, создаваемые любым контекстом, доступны на всех контекстах; если Вы связываете с тем же идентификатором объекта на другом контексте, чем тот, создавший его, Вы ссылаетесь на тот же OpenGL объект ES. Ресурсы часто недостаточны на мобильных устройствах; создание многократных копий того же содержания на многократных контекстах расточительно. Совместное использование общих ресурсов лучше использует доступные графические ресурсы на устройстве.

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

Рисунок 2-1  Два контекста, совместно использующие OpenGL объекты ES
Core Animation-based renderbuffer

Sharegroups являются самыми полезными согласно двум определенным сценариям:

Для создания многократных контекстов, ссылающихся на тот же sharegroup первый контекст инициализируется путем вызова initWithAPI:; sharegroup автоматически создается для контекста. Вторые и более поздние контексты инициализируются для использования sharegroup первого контекста путем вызова initWithAPI:sharegroup: метод вместо этого. Перечисление 2-2 показывает, как это работало бы. Первый контекст создается с помощью функции, определяемой удобства в Перечислении 2-1. Второй контекст создается путем извлечения версии API и sharegroup от первого контекста.

Перечисление 2-2  , Создающее два контекста с общим sharegroup

EAGLContext* firstContext = CreateBestEAGLContext();
EAGLContext* secondContext = [[EAGLContext alloc] initWithAPI:[firstContext API] sharegroup: [firstContext sharegroup]];

 Когда sharegroup совместно используется многократными контекстами, это - ответственность Вашего приложения управлять изменения состояния к OpenGL объекты ES. Вот правила:

Вот шаги, которые Ваше приложение должно выполнить для обновления OpenGL объект ES:

  1. Вызвать glFlush на каждом контексте, который может использовать объект.

  2. На контексте, хотящем изменить объект, вызовите один или несколько OpenGL функции ES для изменения объекта.

  3. Вызвать glFlush на контексте, получившем изменяющие состояние команды.

  4. На любом контексте снова переплетите идентификатор объекта.