2012-01-01 7 views
6
Codice

Esempio:Puoi utilizzare più target con un singolo VBO?

1. glGenBuffers(1, &VboId); 
2. glBindBuffer(GL_ARRAY_BUFFER, VboId); 
3. glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW); 
4. glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0); 

Così abbiamo generare una maniglia generica VBO, e poi associarlo con "GL_ARRAY_BUFFER". Binding sembra avere 2 finalità:

  1. Dobbiamo legare il buffer prima di poter copiare i dati alla GPU tramite glBufferData
  2. Dobbiamo legare il buffer prima di poter aggiungere attributi ad esso tramite glVertexAttribPointer

E penso che quelle siano le uniche 2 volte necessarie per vincolare il VBO. La mia domanda è: esiste uno scenario in cui il target (GL_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER, GL_PIXEL_PACK_BUFFER o GL_PIXEL_UNPACK_BUFFER) sarà diverso sulle righe 2 e 3? O vorremmo ricollegarlo a un target diverso prima della riga 4?

È possibile associare più destinazioni buffer a un singolo VBO?

risposta

11

Non si associano i target a un oggetto buffer. Le destinazioni sono posizioni nel contesto OpenGL a cui è possibile associare oggetti (come oggetti buffer). Quindi si associano gli oggetti buffer agli obiettivi, non il contrario.

A buffer object (non esiste un VBO. Ci sono semplicemente oggetti buffer) è solo un array lineare non formattato di memoria di proprietà del driver OpenGL. È possibile utilizzarlo come origine per i dati di array di vertici, associando il buffer a GL_ARRAY_BUFFER e chiamando una delle funzioni gl*Pointer. Queste funzioni solo funzionano con il buffer attualmente associato a GL_ARRAY_BUFFER. È possibile utilizzarli come origine per i dati dell'indice legandoli a GL_ELEMENT_ARRAY_BUFFER e chiamando una delle funzioni glDrawElements.

Le funzioni utilizzate per modificare un contenuto degli oggetti buffer (glBufferData, glMapBuffer, glBufferSubData, ecc.) Specificano specificamente un obiettivo per il funzionamento delle operazioni. Quindi glBufferData(GL_ARRAY_BUFFER, ...) fa il suo contenuto con qualsiasi buffer attualmente legato a GL_ARRAY_BUFFER.

Quindi ci sono due tipi di funzioni che influenzano gli oggetti buffer: quelli che modificano il loro contenuto e quelli che usano in operazioni. Questi ultimi sono specifici di una fonte; glVertexAttribPointersempre utilizza il buffer attualmente associato a GL_ARRAY_BUFFER. Non puoi fargli usare un bersaglio diverso. Allo stesso modo, glReadPixels utilizza sempre il buffer associato a GL_PIXEL_PACK_BUFFER. E così via. Se una funzione fa roba con gli oggetti buffer ma non prende una destinazione come parametro, allora la sua documentazione ti dirà da quale target cerca il suo buffer.

Nota: Gli array di vertici sono un po 'strani. L'associazione tra un attributo vertice e un oggetto buffer viene effettuata chiamando glVertexAttribPointer. Che cosa fa questa funzione è impostare i dati appropriati per quell'attributo, usando l'oggetto buffer che è attualmente associato a GL_ARRAY_BUFFER. Per "attualmente associato", intendo legato al momento in cui questa funzione viene chiamata. Quindi, subito dopo aver chiamato questa funzione, puoi chiamare glBindBuffer(GL_ARRAY_BUFFER, 0) e cambierà niente su cosa succede quando vai a renderizzare. Renderà bene.

In questo modo, è possibile utilizzare diversi oggetti buffer per diversi attributi. Le informazioni verranno conservate fino a quando non le cambierai con un'altra chiamata glVertexAttribPointer per quel particolare attributo.

+0

Oooh! Grazie! Questo ha molto più senso ora. Era il mio modo di pensare all'indietro che mi stava buttando fuori. – mpen

+0

In realtà, per quanto riguarda il paragrafo 3, stai dicendo che "glBufferData" prende una destinazione per le loro operazioni su cui lavorare ... quindi stai dicendo che in sostanza si sta utilizzando 'GL_ARRAY_BUFFER' come buffer di lavoro temporaneo? Perché è necessario associare l'oggetto buffer alla destinazione e quindi specificare nuovamente la destinazione in "glBufferData", quindi? In sostanza ho provato a scambiare le righe 2 e 3 nella mia domanda, e il programma non funziona più. Sto cercando di capire perché dovresti specificare il bersaglio due volte, a meno che non stiano facendo qualcosa di diverso. – mpen

+1

Nevermind .. Penso che l'ho appena capito. Associamo l'oggetto buffer alla destinazione e quindi essenzialmente i dati vengono inviati a tale destinazione e quindi indirettamente all'oggetto buffer. Quindi entrambi sono necessari. Sto pensando a questo correttamente? I dati vengono legati all'oggetto buffer, quindi possiamo cancellare 'GL_ARRAY_BUFFER' immediatamente dopo aver chiamato glBufferData senza perdere nulla. Immagino che funzioni allo stesso modo dei puntatori degli attributi. – mpen

Problemi correlati