Рисование с OpenGL ES и GLKit
Платформа GLKit обеспечивает классы контроллера представления и представления, устраняющие код установки и обслуживания, который иначе требовался бы для рисования и анимации OpenGL содержание ES. GLKView
класс управляет OpenGL инфраструктура ES для обеспечения места для кода для прорисовки, и GLKViewController
класс обеспечивает цикл рендеринга для плавной анимации OpenGL содержание ES в представлении GLKit. Эти классы расширяют стандартные шаблоны разработки UIKit для рисования содержания представления и управления представлением представления. В результате можно фокусировать усилия прежде всего на OpenGL код рендеринга ES и разбудить приложение и работающий быстро. Платформа GLKit также обеспечивает другие функции для упрощения OpenGL ES 2.0 и 3,0 разработок.
Представление GLKit рисует OpenGL содержание ES по требованию
GLKView
класс обеспечивает OpenGL основанный на ES эквивалент стандарта UIView
рисование цикла. A UIView
экземпляр автоматически конфигурирует свой графический контекст так, чтобы Ваш drawRect:
потребность реализации только выполняет Кварц 2D команды рисования и a GLKView
экземпляр автоматически конфигурирует себя так, чтобы Ваш метод рисования должен был только выполнить OpenGL команды рисования ES. GLKView
класс обеспечивает эту функциональность путем поддержания объекта кадрового буфера, содержащего результаты OpenGL команды рисования ES, и затем автоматически представляющего их Базовой Анимации, как только возвращается метод рисования.
Как стандартное представление UIKit, представление GLKit представляет свое содержание по требованию. Когда Ваше представление сначала выведено на экран, оно вызывает Ваш метод рисования — Базовая Анимация кэширует представленный вывод и выводит на экран его каждый раз, когда показано Ваше представление. Когда Вы захотите изменить содержание своего представления, вызовите setNeedsDisplay
метод и представление снова вызывают Ваш метод рисования, кэшируют получающееся изображение и представляют его на экране. Когда данные раньше представляли изменения образа нечасто или только в ответ на пользовательское действие, этот подход полезен. Путем рендеринга нового содержания представления только, когда Вы должны, Вы сохраняете заряд батареи на устройстве и оставляете больше времени для устройства для выполнения других действий.
Создание и конфигурирование представления GLKit
Можно создать и сконфигурировать a GLKView
возразите или программно или использующий Интерфейсного Разработчика. Прежде чем можно будет использовать его для рисования, необходимо связать его с EAGLContext
объект (см. Конфигурирование OpenGL Контексты ES).
При создании представления программно, сначала создайте контекст и затем передайте его представлению
initWithFrame:context:
метод.После загрузки представления от раскадровки создайте контекст и установите ее как значение представления
context
свойство.
Представление GLKit автоматически создает и конфигурирует свой собственный OpenGL объект кадрового буфера ES и renderbuffers. Вы управляете атрибутами этих объектов с помощью drawable свойств представления, как проиллюстрировано в Перечислении 3-1. При изменении размера, масштабного коэффициента или drawable свойств представления GLKit, это автоматически удаляет и воссоздает надлежащие объекты кадрового буфера и renderbuffers в следующий раз, когда его содержание нарисовано.
Перечисление 3-1 , Конфигурирующее представление GLKit
- (void)viewDidLoad |
{ |
[super viewDidLoad]; |
// Create an OpenGL ES context and assign it to the view loaded from storyboard |
GLKView *view = (GLKView *)self.view; |
view.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; |
// Configure renderbuffers created by the view |
view.drawableColorFormat = GLKViewDrawableColorFormatRGBA8888; |
view.drawableDepthFormat = GLKViewDrawableDepthFormat24; |
view.drawableStencilFormat = GLKViewDrawableStencilFormat8; |
// Enable multisampling |
view.drawableMultisample = GLKViewDrawableMultisample4X; |
} |
Можно позволить мультивыбрать для a GLKView
экземпляр с помощью drawableMultisample
свойство. Мультивыборка является формой сглаживания, сглаживающего зубчатые края, улучшая качество изображения в большинстве 3D приложений за счет использования большего количества памяти и время обработки фрагмента — если Вы позволяете мультивыбрать, всегда тестируете производительность своего приложения, чтобы гарантировать, что это остается приемлемым.
Рисование с представлением GLKit
Рисунок 3-1 обрисовывает в общих чертах три шага для рисования OpenGL содержание ES: подготовка OpenGL инфраструктура ES, выпуск команд рисования и представление представленного содержания к Базовой Анимации для дисплея. GLKView
класс реализует первые и третьи шаги. Для второго шага Вы реализуете метод рисования как пример в Перечислении 3-2.
Метод рисования перечисления 3-2 В качестве примера для представления GLKit
- (void)drawRect:(CGRect)rect |
{ |
// Clear the framebuffer |
glClearColor(0.0f, 0.0f, 0.1f, 1.0f); |
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
// Draw using previously configured texture, shader, uniforms, and vertex array |
glBindTexture(GL_TEXTURE_2D, _planetTexture); |
glUseProgram(_diffuseShading); |
glUniformMatrix4fv(_uniformModelViewProjectionMatrix, 1, 0, _modelViewProjectionMatrix.m); |
glBindVertexArrayOES(_planetMesh); |
glDrawElements(GL_TRIANGLE_STRIP, 256, GL_UNSIGNED_SHORT); |
} |
GLKView
класс в состоянии обеспечить простой интерфейс для OpenGL получение ES, потому что это управляет стандартными компонентами OpenGL процесс рендеринга ES:
Прежде, чем вызвать Ваш метод рисования, представление:
Делает
EAGLContext
возразите текущему контекстуСоздает объект кадрового буфера и renderbuffers на основе его текущего размера, масштабного коэффициента и drawable свойств (в случае необходимости)
Связывает объект кадрового буфера как текущее место назначения для команд рисования
Устанавливает OpenGL область просмотра ES для соответствия размера кадрового буфера
После Ваших возвратов метода рисования, представления:
Решения, мультивыбирающие буферы (если мультивыборка включена),
Отбрасывания renderbuffers, чье содержание больше не необходимо
Подарки renderbuffer содержание к Базовой Анимации для кэширования и дисплея
Рендеринг Используя объект делегата
Многие OpenGL код рендеринга реализации приложений ES в пользовательском классе. Преимущество этого подхода состоит в том, что он позволяет Вам легко поддерживать многократные алгоритмы рендеринга путем определения различного класса средства рендеринга для каждого. Рендеринг алгоритмов, совместно использующих общую функциональность, может наследовать ее от суперкласса. Например, Вы могли бы использовать различные классы средства рендеринга для поддержки и OpenGL ES 2.0 и 3.0 (см. Конфигурирование OpenGL Контексты ES). Или Вы могли бы использовать их для настройки рендеринга для лучшего качества изображения на устройствах с более мощными аппаратными средствами.
GLKit хорошо подходит для этого подхода — можно заставить средство рендеринга возразить делегату стандарта GLKView
экземпляр. Вместо разделения на подклассы GLKView
и реализация drawRect:
метод, Ваш класс средства рендеринга принимает GLKViewDelegate
протокол и реализации glkView:drawInRect:
метод. Перечисление 3-3 демонстрирует выбор класса средства рендеринга на основе аппаратных функций во время запуска приложения.
Перечисление 3-3 Выбирая класс средства рендеринга на основе аппаратных функций
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions |
{ |
// Create a context so we can test for features |
EAGLContext *context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; |
[EAGLContext setCurrentContext:context]; |
// Choose a rendering class based on device features |
GLint maxTextureSize; |
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize); |
if (maxTextureSize > 2048) |
self.renderer = [[MyBigTextureRenderer alloc] initWithContext:context]; |
else |
self.renderer = [[MyRenderer alloc] initWithContext:context]; |
// Make the renderer the delegate for the view loaded from the main storyboard |
GLKView *view = (GLKView *)self.window.rootViewController.view; |
view.delegate = self.renderer; |
// Give the OpenGL ES context to the view so it can draw |
view.context = context; |
return YES; |
} |
Контроллер представления GLKit анимирует OpenGL содержание ES
По умолчанию, a GLKView
возразите представляет его содержание по требованию. Однако главное преимущество к рисованию с OpenGL , ES является его возможностью использовать аппаратные средства обработки графики для непрерывной анимации сложных сцен — приложения, такие как игры и моделирования редко, представляет статические изображения. Для этих случаев платформа GLKit обеспечивает класс контроллера представления, поддерживающий цикл анимации для GLKView
объект это управляет. Этот цикл следует шаблону разработки, распространенному в играх и моделированиях с двумя фазами: обновление и дисплей. Рисунок 3-2 показывает упрощенный пример цикла анимации.
Понимание цикла анимации
Для фазы обновления контроллер представления вызывает свое собственное update
метод (или его делегат glkViewControllerUpdate:
метод). В этом методе необходимо подготовиться к рисованию следующего кадра. Например, игра могла бы использовать этот метод для определения позиций проигрывателя и вражеских символов на основе входных событий, полученных начиная с последнего кадра, и аналитическая визуализация могла бы использовать этот метод для выполнения шага его моделирования. При необходимости в информации синхронизации для определения состояния приложения для следующего кадра, используйте одно из свойств синхронизации контроллера представления такой как timeSinceLastUpdate
свойство. На рисунке 3-2 фаза обновления постепенно увеличивается angle
переменная и использование это для вычисления матрицы преобразования.
Для фазы дисплея контроллер представления вызывает свое представление display
метод, поочередно вызывающий Ваш метод рисования. В Вашем методе рисования Вы представляете OpenGL команды рисования ES GPU для рендеринга содержания. Для оптимальной производительности Ваше приложение должно изменить OpenGL объекты ES в начале рендеринга нового кадра и представить команды рисования позже. На рисунке 3-2 фаза дисплея устанавливает универсальную переменную в программе программы построения теней к матрице, вычисленной в фазе обновления, и затем представляет команду рисования для рендеринга нового содержания.
Цикл анимации чередуется между этими двумя фазами на уровне, обозначенном контроллером представления framesPerSecond
свойство. Можно использовать preferredFramesPerSecond
свойство для установки уровня нужного кадра — для оптимизации производительности для текущих аппаратных средств дисплея контроллер представления автоматически выбирает оптимальную частоту кадров близко к предпочтительному значению.
Используя контроллер представления GLKit
Перечисление 3-4 демонстрирует типичную стратегию рендеринга анимированного OpenGL содержание ES, использующее a GLKViewController
подкласс и GLKView
экземпляр.
Перечисление 3-4 Используя контроллер представления и представления GLKit, чтобы нарисовать и анимировать OpenGL содержание ES
@implementation PlanetViewController // subclass of GLKViewController |
- (void)viewDidLoad |
{ |
[super viewDidLoad]; |
// Create an OpenGL ES context and assign it to the view loaded from storyboard |
GLKView *view = (GLKView *)self.view; |
view.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; |
// Set animation frame rate |
self.preferredFramesPerSecond = 60; |
// Not shown: load shaders, textures and vertex arrays, set up projection matrix |
[self setupGL]; |
} |
- (void)update |
{ |
_rotation += self.timeSinceLastUpdate * M_PI_2; // one quarter rotation per second |
// Set up transform matrices for the rotating planet |
GLKMatrix4 modelViewMatrix = GLKMatrix4MakeRotation(_rotation, 0.0f, 1.0f, 0.0f); |
_normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL); |
_modelViewProjectionMatrix = GLKMatrix4Multiply(_projectionMatrix, modelViewMatrix); |
} |
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect |
{ |
// Clear the framebuffer |
glClearColor(0.0f, 0.0f, 0.1f, 1.0f); |
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
// Set shader uniforms to values calculated in -update |
glUseProgram(_diffuseShading); |
glUniformMatrix4fv(_uniformModelViewProjectionMatrix, 1, 0, _modelViewProjectionMatrix.m); |
glUniformMatrix3fv(_uniformNormalMatrix, 1, 0, _normalMatrix.m); |
// Draw using previously configured texture and vertex array |
glBindTexture(GL_TEXTURE_2D, _planetTexture); |
glBindVertexArrayOES(_planetMesh); |
glDrawElements(GL_TRIANGLE_STRIP, 256, GL_UNSIGNED_SHORT, 0); |
} |
@end |
В этом примере, экземпляре PlanetViewController
класс (пользовательское GLKViewController
подкласс), загружается из раскадровки, вместе со стандартом GLKView
экземпляр и его drawable свойства. viewDidLoad
метод создает OpenGL контекст ES и обеспечивает его для представления, и также устанавливает частоту кадров для цикла анимации.
Контроллер представления является автоматически делегатом своего представления, таким образом, он реализует обоих обновление и фазы дисплея цикла анимации. В update
метод, это вычисляет, матрицы трансформации должны были вывести на экран вращающуюся планету. В glkView:drawInRect:
метод, это обеспечивает те матрицы для программы программы построения теней и представляет команды рисования для рендеринга геометрии планеты.
Используя GLKit для разработки средства рендеринга
Кроме того, чтобы просмотреть и просмотреть инфраструктуру контроллера, платформа GLKit обеспечивает несколько других функций для упрощения OpenGL разработка ES на iOS.
Обработка векторной и матричной математики
OpenGL ES 2.0 и позже не обеспечивает встроенные функции для создания или указания матриц трансформации. Вместо этого программируемые программы построения теней обеспечивают трансформацию вершины, и Вы указываете вводы программы построения теней с помощью универсальных универсальных переменных. Платформа GLKit включает всестороннюю библиотеку векторных и матричных типов и функций, оптимизированных для высокой производительности на аппаратных средствах iOS. (См. Ссылку Платформы GLKit.)
Миграция от конвейера стандартных функций OpenGL ES 1.1
OpenGL ES 2.0 и позже удаляет всю функциональность, связанную с конвейером графики стандартной функции OpenGL ES 1.1. GLKBaseEffect
класс обеспечивает аналог Objective C для трансформации, освещая и заштриховывая этапы конвейера OpenGL ES 1.1, и GLKSkyboxEffect
и GLKReflectionMapEffect
классы добавляют поддержку общих визуальных эффектов. См. справочную документацию для этих классов для подробных данных.
Загрузка данных текстуры
GLKTextureLoader
класс обеспечивает простой способ загрузить данные текстуры из любого формата изображения, поддерживаемого iOS в OpenGL контекст ES, синхронно или асинхронно. (См. Использование Платформа GLKit для Загрузки Данных Текстуры.)