tl; dr: forse solo bisogno di impostare s' contentMode
-UIViewContentModeRedraw
il GLKView
In primo luogo non credo che l'applicazione entra in realtà in secondo piano, penso che diventa solo inattiva. La distinzione tra i metodi delegati applicationWillResignActive
e applicationDidEnterBackground
. Supponendo che l'applicazione sia solo inattiva, usa quanto segue, nel caso in cui venga effettivamente messa in secondo piano, vedi sotto.
La documentazione Apple dice che è necessario "ridurre i framerate di OpenGL ES" quando viene chiamato il numero applicationWillResignActive
, non che le chiamate OpenGL ES non siano consentite, ciò accade solo dopo che l'applicazione viene messa in background.
Ciò significa che GLKit
's GLKView
/GLKViewController
può essere un po' troppo zelante in questo senso. Per risolvere il problema è necessario fare in modo che:
- Il
GLKView
's contentMode
è impostato su UIViewContentModeRedraw
- Il
GLKView
' s drawRect
metodo fa disegnare il telaio anche quando l'applicazione è inattiva, ma il telaio è modificato, ma non disegnare il frame (ovvero utilizzare chiamate OpenGL ES) quando l'applicazione è in background.
Tuttavia, la mia presunzione è che il metodo drawRect
non ha nemmeno ottenere chiamato quando l'applicazione è in background, quindi probabilmente non si hanno veramente a preoccuparsi per l'OpenGL ES chiama il metodo glkView:drawInRect
delegato.La ragione per cui questa funzione non viene chiamata nella tua situazione è che la vista non viene invalidata. La ragione per non essere invalidato è duplice:
- il ciclo telaio principale in
GLKViewController
che invalida la vista periodicamente viene messa in pausa dal struttura paused
.
- Il
GLKView
contentMode
è probabilmente il default 'UIViewContetModeScaleToFill'
Come il metodo GLKView
drawRect
è probabilmente nemmeno guardando la proprietà paused
, semplicemente cambiando il contentMode
potrebbe già essere sufficiente.
Vorrei proporre la seguente soluzione se l'applicazione effettivamente passa in secondo piano. Poiché non ti è permesso utilizzare le chiamate OpenGL ES mentre sei in esecuzione in background, la soluzione è piuttosto semplice:
Fai tutte le chiamate di OpenGL ES che devi fare per supportare ciò che vuoi prima di entrare in background.
Cioè, in applicationWillResignActive
effettuare le seguenti operazioni: ciclo
- Pausa il vostro gioco (fatta impostando
GLKViewController
's paused
)
- mettere in pausa il ciclo di rendering (fatto impostando
GLKViewController
' s paused
)
- Afferra il framebuffer corrente per lo stato di orientamento corrente
- Rendi lo stato di gioco corrente ancora una volta con un framebuffer e una finestra che corrispondono allo stato dell'orientamento ruotato e d afferrare che FrameBuffer
Inoltre è necessario GLKView
s' contentMode
da impostare a UIViewContentModeRedraw
modo che il metodo drawRect
è effettivamente chiamato il fotogramma della visualizzazione è stato modificato dal cambiamento di orientamento.
Infine nel drawRect
metodo GLKView
s' è necessario verificare se paused
è YES
o NO
nel caso NO
fare il rendering come normale, nel caso YES
prendere uno dei framebuffer salvati in applicationWillResignActive
e disegnare alla vista con regolari chiamate UIKit
.
Non sono sicuro di come questa soluzione di hacker si integri con GLKit
, potrebbe essere necessario qualche sottoclasse.
Ho appena testato un mio progetto nel simulatore, l'animazione si interrompe quando viene aperta la barra delle applicazioni, tuttavia quando ruoto l'ipad virtuale il fotogramma ** è ** ridisegnato con il nuovo rapporto aspetto. Ciò sembra accadere indipendentemente dalla modalità di contenuto, testando su iPad iOS 6.1. – wich
Il problema principale è che la scena viene ridisegnata solo alle nuove proporzioni (risultato).Gli oggetti sulla mia scena dipendono dal fotogramma della vista: ricalcolo le loro dimensioni e posizioni per riempire il maggior spazio possibile sullo schermo. Quindi durante l'animazione voglio ricalcoli regolari e non "dimensioni iniziali e posizioni" -> "dimensioni e posizioni finali" - qualche transizione animata da uno all'altro. E in caso di riutilizzo dello stesso framebuffer, vediamo lo stretching anziché il riposizionamento – kpower
A meno che non inizi ad hackerare con GLKit, non otterrai un'animazione l'una dall'altra, dato che il frameloop viene messo in pausa e tu non vuoi (non dovrebbe) avere il frameloop continua quando l'applicazione è inattiva, cioè ciò accade anche quando ricevi una chiamata in arrivo o simili sull'iPhone. L'unica cosa che puoi fare è semplicemente ridisegnare la scena in base ai nuovi limiti della vista, che funziona correttamente in GLKit. Personalmente non penso sia probabile che la rotazione del dispositivo cambierà le presentazioni anziché animarle. – wich