2012-04-03 16 views
7

Ero sicuro che se si associa un buffer tramite glBindBuffer(), è possibile presumere che rimanga vincolato, fino a quando il target non viene rebound tramite un'altra chiamata a glBindBuffer(). Quindi sono rimasto molto sorpreso quando ho scoperto che chiamare glBindVertexArray() imposta il buffer legata al bersaglio GL_ELEMENT_ARRAY a 0.OpenGL 3: glBindVertexArray invalida GL_ELEMENT_ARRAY_BUFFER

Ecco il codice C minimo ++ di esempio:

GLuint buff; 
glGenBuffers(1, &buff); 
std::cout << "Buffer is " << buff << "\n"; 
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buff); 
GLuint vao; 
glGenVertexArrays(1, &vao); 

GLint bound_buff; 
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &bound_buff); 
std::cout << "Bound before glBindVertexArray: " << bound_buff << "\n"; 

glBindVertexArray(vao);  
    // ^- an implicit glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0); ? 

glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &bound_buff); 
std::cout << "Bound after glBindVertexArray: " << bound_buff << "\n"; 

ho eseguito questo codice subito dopo l'inizializzazione di un OpenGL 3.2 contesto di dispositivo e ottenere il seguente output:

Buffer is 1 
Bound before glBindVertexArray: 1 
Bound after glBindVertexArray: 0 

la GL_ARRAY_BUFFER invece è non modificati dalla chiamata. Ho controllato la specifica OpenGL 3.2 (2.10) per glBindVertexArray e non ho trovato alcun riferimento a quell'effetto collaterale inaspettato.

  1. Questo comportamento è conforme alla specifica?
  2. In tal caso, quali altri effetti collaterali ci si possono aspettare da una chiamata a glBindVertexArray?
  3. Qual è la logica alla base di questo?

L'ho provato su una scheda nvidia su una macchina Win XPx64 con il driver WHQL 296.10. Un test rapido su OS X Lion con una nvidia GT330M ha dato gli stessi risultati.

+0

Penso che l'associazione di un VAO vincoli implicitamente i buffer di elementi e di vertici. Ecco a cosa servono i VAO. Se si associa un VAO e si associa un indice e un buffer di vertici, tali buffer vengono quindi associati in modo implicito ogni volta che si associa il VAO in un secondo momento. Quindi legare il VAO sopra ha presumibilmente implicitamente impostato l'array di elementi e vertici a zero in quanto questi non sono stati inclusi da te nell'oggetto VAO. Aveva senso? :-) – Robinson

+0

Ma perché cambia solo GL_ELEMENT_ARRAY_BUFFER e non GL_ARRAY_BUFFER? – ComicSansMS

+0

Poiché il buffer di matrice è il buffer di vertici (almeno i vari glEnableVertexAttribArray e glVertexAttribPointer chiamano make con esso) e include un buffer di elementi come parte di quello stato. – Robinson

risposta

15

Vertex Array Objects incapsulare tutto lo stato * necessario per rendere i dati dei vertici. Pertanto, devono incapsulare i buffer associati agli attributi (tramite glVertexAttribPointer), GL_ELEMENT_ARRAY_BUFFER (necessari per le chiamate glDrawElement*) e così via.

Tuttavia, mi sento ancora un po 'perplesso dal fatto che non ho trovato alcuna menzione di questo effetto collaterale nei documenti.

La specifica spiega chiaramente questo, anche se richiede di capire come funziona la specifica per vedere come.

OpenGL è una raccolta di stati, il che significa che tutte le funzioni di OpenGL (ad eccezione di quelle che effettivamente rendono qualcosa) modificano lo stato di OpenGL. Quando chiami glVertexAttribPointer, questa funzione modifica concettualmente qualche parte dello stato OpenGL interno.

OpenGL objects sono definiti da quali parti di stato OpenGL incapsulano. Quindi, se una funzione modifica lo stato incapsulato da un oggetto, allora quella funzione modifica l'oggetto stesso. Legare un oggetto significa sostituire gli attuali pezzi di stato che incapsulano con lo stato corrente di quell'oggetto.

La specifica definisce i VAO in base allo stato che incapsulano. In pratica punta su una delle tabelle di stato OpenGL e dice "I VAO sono tutto questo". Il core versione 3.x di questa funzionalità modifica effettivamente le tabelle di stato per renderlo un po 'più chiaro (stesso comportamento, leggermente diversa spiegazione delle stesse):

OpenGL 3.3 specifica, sezione 2.10:

L'oggetto matrice vertice risultante è un nuovo vettore di stato, che comprende tutti i valori di stato elencati nelle tabelle 6.4 e 6.5.

Non ho intenzione di ristampare le tabelle 6.4 e 6.5; puoi cercarli da soli. Ma chiaramente includono GL_ELEMENT_ARRAY_BUFFER_BINDING e vari GL_VERTEX_ATTRIB_ARRAY_BUFFER_BIDNING (che sono oggetti buffer).

* Nota: i VAO non contengono lo stato impostato dalle funzioni glVertexAttrib. Questi possono influenzare il rendering se una matrice di attributi non è abilitata.

Problemi correlati