tl; dr: возможно, вам нужно только установить GLKView
contentMode
на UIViewContentModeRedraw
Во-первых, я не думаю, что ваше приложение действительно уходит в фон, я думаю, что оно просто становится неактивным. Различие между методами делегата applicationWillResignActive
и applicationDidEnterBackground
. Предполагая, что приложение неактивно, используйте следующее, если оно действительно переводится в фоновый режим, см. ниже.
В документации Apple говорится, что вы должны «дросселировать частоту кадров OpenGL ES», когда вызывается applicationWillResignActive
, а не то, что вызовы OpenGL ES не разрешены, это происходит только после того, как приложение переходит в фоновый режим.
Это означает, что GLKView
/GLKViewController
из GLKit
могут быть немного переусердствовали в этом отношении. Чтобы исправить это, вам нужно убедиться, что:
contentMode
GLKView
установлен на UIViewContentModeRedraw
- Метод
drawRect
класса GLKView
отрисовывает кадр, даже когда приложение неактивно, но кадр изменен, но не рисует кадр (то есть использует вызовы OpenGL ES), когда приложение находится в фоновом режиме.
Однако я предполагаю, что метод drawRect
даже не вызывается, когда приложение находится в фоновом режиме, поэтому вам, вероятно, не нужно беспокоиться о вызовах OpenGL ES в методе делегата glkView:drawInRect
. Однако причина того, что эта функция не вызывается в вашей ситуации, заключается в том, что представление не становится недействительным. Причина не признания недействительной двояка:
- Цикл основного кадра в
GLKViewController
, который периодически делает представление недействительным, приостанавливается свойством paused
.
GLKView
contentMode
, вероятно, является значением по умолчанию «UIViewContetModeScaleToFill».
Поскольку метод GLKView
drawRect
, вероятно, даже не смотрит на свойство paused
, простого изменения contentMode
может быть уже достаточно.
Я бы предложил следующее решение, если приложение действительно переходит в фоновый режим. Поскольку вам не разрешено использовать вызовы OpenGL ES во время работы в фоновом режиме, решение довольно простое:
Выполните все вызовы OpenGL ES, необходимые для поддержки того, что вы хотите, прежде чем войти в фоновый режим.
То есть в applicationWillResignActive
делаем следующее:
- Приостановить игровой цикл (сделано путем установки
paused
GLKViewController
)
- Приостановите цикл рендеринга (сделано путем установки
paused
GLKViewController
)
- Захватите текущий буфер кадра для текущего состояния ориентации
- Визуализируйте текущее состояние игры еще раз с буфером кадра и областью просмотра, которые соответствуют повернутому состоянию ориентации, и захватите этот буфер кадра.
Кроме того, вам нужно, чтобы contentMode
в GLKView
было установлено на UIViewContentModeRedraw
, чтобы метод drawRect
фактически вызывался после того, как рамка представления была изменена изменением ориентации.
Наконец, в методе drawRect
GLKView
вам нужно проверить, является ли paused
YES
или NO
в случае NO
сделать рендеринг как обычно, в случае YES
взять один из кадровых буферов, сохраненных в applicationWillResignActive
, и нарисовать его в представлении с помощью обычных вызовов UIKit
.
Я не уверен, насколько хорошо это хакерское решение будет интегрироваться с GLKit
, вам может понадобиться подкласс.
person
wich
schedule
13.03.2013