2012-03-02 11 views
5

voglio un oggetto array vertice in OpenGL ES 2.0 per contenere due attributi diversi buffer, il secondo buffer vengono letti dalla memoria client (glBindBuffer(GL_ARRAY_BUFFER, 0)) ma si verifica un errore di runtime:OES_vertex_array_object e client stato

GLuint my_vao; 
GLuint my_buffer_attrib0; 
GLfloat attrib0_data[] = { 0, 0, 0, 0 }; 
GLfloat attrib1_data[] = { 1, 1, 1, 1 }; 

void init() 
{ 
    // setup vao 
    glGenVertexArraysOES(1, &my_vao); 
    glBindVertexArrayOES(my_vao); 

    // setup attrib0 as a vbo 
    glGenBuffers(1, &my_buffer_attrib0); 
    glBindBuffer(GL_ARRAY_BUFFER, my_buffer_attrib0); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(attrib0_data), attrib0_data, GL_STATIC_DRAW); 
    glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0); 

    glEnableVertexAttribArray(0); 
    glEnableVertexAttribArray(1); 

    // "end" vao 
    glBindVertexArrayOES(0); 

} 

void draw() 
{ 

    glBindVertexArrayOES(my_vao); 
    // (now I assume attrib0 is bound to my_buffer_attrib0, 
    // and attrib1 is not bound. but is this assumption true?) 

    // setup attrib1 
    glBindBuffer(GL_ARRAY_BUFFER, 0); 
    glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, attrib1_data); 

    // draw using attrib0 and attrib1 
    glDrawArrays(GL_POINTS, 0, 1); // runtime error: Thread1: EXC_BAD_ACCESS (code=2, address=0x0) 

} 

Quello che voglio raggiungere è quello di avvolgere il legame di due attributi come un buffer gamma vertex:

void draw_ok() 
{ 
    glBindVertexArrayOES(0); 

    // setup attrib0 
    glBindBuffer(GL_ARRAY_BUFFER, my_buffer_attrib0); 
    glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0); 

    // setup attrib1 
    glBindBuffer(GL_ARRAY_BUFFER, 0); 
    glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, attrib1_data); 

    glEnableVertexAttribArray(0); 
    glEnableVertexAttribArray(1); 

    // draw using attrib0 and attrib1 
    glDrawArrays(GL_POINTS, 0, 1); // ok 
} 

E 'possibile associare due buffer differenti in un oggetto array di vertice? OES_vertex_array_object è diverso dagli oggetti array di vertici OpenGL (semplici)? Si noti inoltre che ottengo questo errore in XCode con il simulatore iOS. Questi sono collegamenti correlati:

risposta

6

Beh, una citazione dalle specifiche di estensione lo spiega molto semplicemente:

Should a vertex array object be allowed to encapsulate client vertex arrays?

RESOLVED: No. The OpenGL ES working group agreed that compatibility with OpenGL and the ability to to guide developers to more performant drawing by enforcing VBO usage were more important than the possibility of hurting adoption of VAOs.

Così si può anzi si legano due diversi tamponi in un VAO, (o meglio, il tampone di legame non è disponibile memorizzato nel VAO, in ogni caso, solo i buffer di origine dei singoli attributi, impostati tramite glVertexAttribPointer) ma non è possibile utilizzare la memoria dello spazio client in un VAO, solo VBO. Questo è lo stesso per il desktop GL.

Quindi vorrei consigliarvi di memorizzare tutti i dati dei vertici in VBO. Se si desidera utilizzare la memoria del client perché i dati vengono aggiornati dinamicamente e si pensa che i VBO non ti compreranno nulla lì, è ancora l'approccio sbagliato. Basta usare un VBO con un uso dinamico (GL_DYNAMIC_DRAW o anche GL_STREAM_DRAW) e aggiornarlo usando glBuffer(Sub)Data o glMapBuffer (o la buona vecchia combinazione glBufferData(..., NULL); glMapBuffer(GL_WRITE_ONLY)).

+0

Hai la risposta accettata dal momento che non sei me e hai anche risposto se OES-VAO sono gli stessi del desktop-VAO :) grazie. – telephone

1

Rimuovere la riga seguente:

glBindBuffer(GL_ARRAY_BUFFER, 0);

dalla funzione draw(). Non hai associato alcun buffer prima e potrebbe rovinare lo stato del buffer.

+0

voglio il secondo attributo (attrib1) da leggere dalla memoria del cliente, in modo da GL_ARRAY_BUFFER deve essere non legato prima chiamando glVertexAttribPointer. Ma questo sembra rovinare le cose, e non sono sicuro del perché. Un esempio di ciò che voglio ottenere è lasciare che la geometria del negozio VAO, e quindi semplicemente impostare un altro attributo di quel VAO ai miei colori personalizzati, dopo aver vincolato il VAO. – telephone

+0

@telephone Non è possibile utilizzare la memoria del client con VAO, vedere la mia risposta. –

1

Dopo alcuni scavi (lettura), sono state trovate le risposte trovate in OES_vertex_array_object. Sembra che l'attenzione di OES_vertex_array_object sullo stato sul lato server e lo stato del client vengano utilizzati se e solo se l'oggetto zero è associato. Resta da rispondere se OES_vertex_array_object's sono gli stessi dei semplici OpenGL VAO. Si prega di commentare se si conosce la risposta a questo. Qui di seguito sono citazioni da OES_vertex_array_object:

 This extension introduces vertex array objects which encapsulate 
    vertex array states on the server side (vertex buffer objects). 



    * Should a vertex array object be allowed to encapsulate client 
    vertex arrays? 

    RESOLVED: No. The OpenGL ES working group agreed that compatibility 
    with OpenGL and the ability to to guide developers to more 
    performant drawing by enforcing VBO usage were more important than 
    the possibility of hurting adoption of VAOs. 



    An INVALID_OPERATION error is generated if 
    VertexAttribPointer is called while a non-zero vertex array object 
    is bound, zero is bound to the <ARRAY_BUFFER> buffer object binding 
    point and the pointer argument is not NULL [fn1]. 
     [fn1: This error makes it impossible to create a vertex array 
     object containing client array pointers, while still allowing 
     buffer objects to be unbound.] 



    And the presently attached vertex array object has the following 
    impacts on the draw commands: 

     While a non-zero vertex array object is bound, if any enabled 
     array's buffer binding is zero, when DrawArrays or 
     DrawElements is called, the result is undefined. 

Così EXC_BAD_ACCESS è stato il risultato indefinito!

+1

+1 per "Quindi EXC_BAD_ACCESS era il risultato non definito!". Ho inseguito un bug per * giorni *. Per qualche ragione lo stato del client GL_VERTEX_ARRAY è stato disabilitato da chissà chi dopo un po ', quindi riattivandolo dopo glDrawArray mi ha salvato: glEnableClientState (GL_VERTEX_ARRAY); Non ho mai pensato a EXC_BAD_ACCESS come risultato indefinito, ma come rilascio di memoria inaspettato, ma no, nessuna memoria è stata rilasciata qui. Grazie per il tuo suggerimento, è stato molto utile :) –

1

La funzionalità che desiderate ora è stato accettato dalla comunità come estensione di WebGL:

http://www.khronos.org/registry/webgl/extensions/OES_vertex_array_object/

+0

Questa risposta non sembra pertinente alla domanda. Il link indica che WebGL ora supporta OES_vertex_array_object. Bene, ma non affrontare la domanda. La risposta accettata spiega perché i VAO non possono essere utilizzati nel modo richiesto, e dà invece consigli su cosa fare. – ToolmakerSteve

Problemi correlati