La risposta più corretta è, dipende da come la programmate, ma questa è una buona cosa di cui preoccuparsi. Mentre le GPU sono diventate incredibilmente veloci, la larghezza di banda da e verso la GPU RAM non lo è e sarà il tuo collo di bottiglia più frustrante.
I suoi dati vengono inviati alla memoria GPU solo una volta e rimangono lì per sempre?
Speriamo di si. Per la velocità di rendering, vuoi che il maggior numero possibile di dati si trovi sulla GPU, invece di inviarlo nuovamente ad ogni frame. I VBO servono a questo preciso scopo. Ci sono VBO sia statici che dinamici, il primo è il migliore per i modelli statici e il secondo è il migliore per i modelli i cui vertici cambieranno ogni frame (diciamo, un sistema di particelle). Anche quando si tratta di VBO dinamici, tuttavia, non si desidera inviare nuovamente tutti i vertici ad ogni frame; solo quelli che stanno cambiando.
Nel caso del tuo edificio, i dati del vertice rimarranno semplicemente lì, e l'unica cosa che cambia sono le tue matrici (modello / mondo, proiezione e vista).
Nel caso di un sistema di particelle, ho creato un VBO dinamico abbastanza grande da contenere il numero massimo di particelle che esisterà per quel sistema. Ogni fotogramma a cui invio i dati per le particelle emesse da quel fotogramma, insieme a un paio di uniformi, e tutto qui. Quando disegno, posso specificare un punto iniziale e finale in quel VBO, quindi non devo cancellare i dati delle particelle. Posso solo dire di non disegnare quelli.
Quando il modello viene effettivamente reso ogni frame i processori GPU devono recuperare i suoi dati ogni volta dalla memoria GPU? Quello che voglio dire è - se avessi 2 modelli renderizzati più volte ciascuno - importerebbe se prima rendessi il primo più volte e poi il secondo più volte o se rendessi il primo solo una volta, il secondo solo una volta e continuato a interfogliarlo in quel modo?
L'atto di inviare più chiamate di pesca invece di una sola è un limite molto più grande. Controlla il rendering istanziato; potrebbe aiutarti molto e rendere inutile la risposta a questa domanda. Ho avuto alcuni problemi con i driver che non ho ancora risolto, ma se riesci a farlo funzionare, allora il problema è stato risolto.
Ovviamente le schede grafiche hanno una RAM limitata - quando non può contenere tutti i dati del modello necessari per il rendering di 1 frame, suppongo che continui a prenderne (parte) dalla RAM della CPU ogni frame, è corretto?
Non vuoi esaurire la RAM della GPU. Se lo fai, allora cambia le cose in modo da non farlo. Nello scenario molto ipotetico che finisci, probabilmente si bloccherà in qualche modo, ma non l'ho mai visto accadere, quindi onestamente non lo so.
Ho dimenticato di fare una distinzione: c'è l'invio dei dati alla GPU e c'è l'impostazione / associazione dei buffer come correnti. Quest'ultimo causa qualche flusso di dati?
Nessun flusso di dati significativo, no. Ci sono dei costi, ma questo è vero per ogni riga di codice che scrivi. Scopri quanto ti costa, di nuovo, a cosa serve la profilazione.
creazione di buffer con inizializzazione
La risposta di Raxvan suona bene, ma non è del tutto accurata. In OpenGL, la creazione del buffer non riserva spazio. Se vuoi riservare spazio senza passare alcun dato, puoi chiamare glBufferData e passare null. (Vedi la sezione note qui .)
aggiornamento dei dati del buffer
Immagino che intendi glBufferData, o altre funzioni del genere, giusto? Qui è dove si verifica il trasferimento reale dei dati. (A meno che non passi null, come ho appena detto nell'ultimo paragrafo.)
associando il buffer come attivo (è solo un modo per dire all'API che voglio che questo buffer sia renderizzato nella prossima chiamata di disegno e non fa nulla da solo?)
Sì, ma può fare un po 'di più. Ad esempio, se si associa un VAO (oggetto array di vertici), quindi si associa un VBO, quel VBO viene associato al VAO. Successivamente, se associ nuovamente quel VAO e chiami glDrawArrays, saprà quale VBO disegnare.
Nota che mentre molti tutorial ti faranno creare un VAO per ogni VBO, mi è stato detto che non è l'uso previsto. Presumibilmente dovresti creare un VAO e usarlo con ogni VBO che abbia gli stessi attributi. Non l'ho ancora provato, quindi non posso dire con certezza se è meglio o peggio.
Chiamata di disegno API
Quello che succede qui è piuttosto semplice (dal nostro punto di vista). Supponi di associare un VAO, quindi chiama glDrawArrays. Si specifica un punto di partenza e un conteggio, ed esegue lo shader di vertice per ogni vertice in quell'intervallo, che a sua volta passa i suoi output lungo la linea. L'intero processo è però un altro saggio a sé stante.