Domanda

Sto lavorando su un'app che deve disegnare con OpengGL con una frequenza di aggiornamento almeno pari alla frequenza di aggiornamento del monitor.E devo eseguire il disegno in un thread separato in modo che il disegno non venga mai bloccato da intense azioni dell'interfaccia utente.

In realtà sto usando a NSOpenGLView in combinazione con CVDisplayLink e sono in grado di raggiungere 60-80FPS senza alcun problema.

Poiché ho bisogno anche di visualizzare alcuni controlli del cacao in questa vista, ho provato a creare una sottoclasse NSOpenGLView e renderlo a strati, seguendo LayerBackedOpenGLView Esempio della mela.

Il risultato non è soddisfacente e si ottengono molti artefatti.

Pertanto ho risolto il problema utilizzando un file separate NSWindow per ospitare i controlli Cocoa e aggiungendo questa finestra come finestra figlia della finestra principale contenente il file NSOpenGLView.Funziona bene e riesco a ottenere gli stessi FPS dell'implementazione iniziale.

Poiché considero questa soluzione un po' come uno sporco hack, sto cercando un modo alternativo e più pulito per ottenere ciò di cui ho bisogno.

Pochi giorni fa mi sono imbattuto NSOpenGLLayer e ho pensato che potesse essere usato come una valida soluzione al mio problema.

Quindi finalmente, dopo tutto questo preambolo, ecco la mia domanda:è possibile disegnare a NSOpenGLLayer da un thread separato utilizzando CVDisplayLink richiamare?.

Finora ho provato a implementarlo ma non sono in grado di attingere dal file CVDisplayLink richiamare.posso solo -setNeedsDisplay:TRUE sul NSOpenGLLayer dal CVDisplayLink richiamata e quindi eseguire il disegno -drawInOpenGLContext:pixelFormat:forLayerTime:displayTime: quando viene chiamato automaticamente da cacao.Ma suppongo che in questo modo attingo dal filo conduttore, no?

Dopo aver cercato su Google questo ho persino trovato Questo post in cui l'utente sostiene che sotto il Leone il disegno può avvenire solo all'interno -drawInOpenGLContext:pixelFormat:forLayerTime:displayTime:.

Al momento utilizzo Snow Leopard ma l'app dovrebbe funzionare perfettamente anche su Lion.

Mi sto perdendo qualcosa?

È stato utile?

Soluzione

Sì, è possibile, anche se non lo consiglio.Chiamata display sul livello dal tuo CVDisplayLink.Ciò causerà canDrawInContext:... da chiamare e se restituisce SI, drawInContext:... verrà chiamato e tutto questo su qualunque thread chiamato display.Per rendere visibile sullo schermo l'immagine renderizzata, è necessario chiamare [CATransaction flush].Questo metodo è stato suggerito sulla mailing list di Apple, sebbene non sia completamente esente da problemi (il metodo di visualizzazione di un'altra vista potrebbe essere chiamato anche sul thread in background e non tutte le viste supportano il rendering da un thread in background).

Il modo consigliato è rendere il livello asincrono ed eseguire il rendering del contesto OpenGL sul thread principale.Se non riesci a ottenere un buon framerate in questo modo, poiché il tuo thread principale è occupato altrove, ti consigliamo di spostare tutto il resto (praticamente tutta la logica dell'applicazione) su altri thread (ad es.utilizzando Grand Central Dispatch) e mantieni solo l'input dell'utente e il codice di disegno nel thread principale.Se la tua finestra è molto grande, potresti comunque non ottenere niente di meglio di 30 FPS (un fotogramma ogni due aggiornamenti dello schermo), ma ciò deriva dal fatto che la composizione di CALayer sembra un processo piuttosto costoso ed è stato ottimizzato per più o meno strati statici (es.livelli contenenti un'immagine) e non per i livelli che si aggiornano da soli a 60 FPS.

Per esempio.se stai scrivendo un gioco 3D, ti consigliamo di non mischiare affatto CALayers con contenuto OpenGL.Se hai bisogno di elementi dell'interfaccia utente Cocoa, mantienili separati dal contenuto OpenGL (ad es.dividere la finestra orizzontalmente in una parte che visualizza solo OpenGL e una parte che mostra solo i controlli) oppure disegna tu stesso tutti i controlli (il che è abbastanza comune per i giochi).

Ultimo ma non meno importante, l'approccio a due finestre non è così esotico come potresti pensare, è così che VLC (il lettore video) disegna i suoi controlli sull'immagine video (che è anche renderizzata da OpenGL su Mac).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top