2012-03-02 9 views
5

मैं ओपन ES 2.0 में एक शीर्ष सरणी वस्तु अलग बफ़र्स से दो विशेषताओं रखना चाहते हैं, दूसरी बफर ग्राहक स्मृति (glBindBuffer(GL_ARRAY_BUFFER, 0)) से पढ़ा जा रहा लेकिन मैं एक रनटाइम त्रुटि मिलती है:OES_vertex_array_object और ग्राहक राज्य

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) 

} 

क्या मैं हासिल करना चाहते हैं एक शीर्ष सरणी बफर के रूप में दो विशेषताओं के बंधन रैप करने के लिए है:

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 
} 

यह एक शीर्ष सरणी वस्तु में दो अलग अलग बफ़र्स बाध्य करने के लिए संभव है? क्या OES_vertex_array_object अलग (सादे) ओपनजीएल वर्टेक्स सरणी ऑब्जेक्ट्स से अलग है? यह भी ध्यान रखें कि मुझे यह त्रुटि XCode में आईओएस सिम्युलेटर चलाने में मिलती है। ये संबंधित लिंक कर रहे हैं:

उत्तर

6

खैर, एक्सटेंशन विशेषताओं से एक उद्धरण यह काफी बस बताते हैं:

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.

तो आप वास्तव में एक VAO में बाँध दो अलग बफ़र्स, (अच्छी तरह से, बफर बाध्यकारी VAO में संगृहीत न हो, वैसे भी, केवल व्यक्तिगत गुणों के स्रोत बफर, glVertexAttribPointer के माध्यम से सेट) लेकिन आप वीएओ, केवल वीबीओ में क्लाइंट स्पेस मेमोरी का उपयोग नहीं कर सकते हैं। डेस्कटॉप जीएल के लिए यह वही है।

तो मैं आपको सलाह देता हूं कि आप अपने सभी वर्टेक्स डेटा को वीबीओ में स्टोर करें। यदि आप क्लाइंट मेमोरी का उपयोग करना चाहते हैं क्योंकि डेटा गतिशील रूप से अपडेट किया गया है और आपको लगता है कि वीबीओ आपको वहां कुछ भी नहीं खरीदेंगे, यह अभी भी गलत दृष्टिकोण है। बस एक गतिशील उपयोग (GL_DYNAMIC_DRAW या यहां तक ​​कि GL_STREAM_DRAW) के साथ एक वीबीओ का उपयोग करें और इसे glBuffer(Sub)Data या glMapBuffer (या पुराना पुराना glBufferData(..., NULL); glMapBuffer(GL_WRITE_ONLY) संयोजन) का उपयोग करके अपडेट करें।

+0

आपको स्वीकार्य उत्तर मिलता है क्योंकि आप मेरे नहीं हैं और उत्तर दिया गया है कि ओईएस-वीएओ डेस्कटॉप-वीएओ के समान हैं :) धन्यवाद। – telephone

1

निम्न पंक्ति निकालें:

glBindBuffer(GL_ARRAY_BUFFER, 0);

draw() समारोह से

। आपने पहले किसी भी बफर को बांध नहीं लिया था और यह बफर राज्य को गड़बड़ कर सकता है।

+0

मैं दूसरी विशेषता चाहते हैं (attrib1) ग्राहक स्मृति से पढ़ने के लिए है, तो GL_ARRAY_BUFFER से पहले अनबाउंड होना चाहिए glvertexAttribPointer कॉलिंग। लेकिन यह चीजों को गड़बड़ कर रहा है, और मुझे यकीन नहीं है कि क्यों। मैं जो हासिल करना चाहता हूं उसका एक उदाहरण वीएओ स्टोर ज्यामिति को देना है, और फिर वीएओ को बाध्य करने के बाद, बस अपने कस्टम रंगों में उस वीएओ की एक और विशेषता सेट करें। – telephone

+0

@telephone आप वीएओ के साथ क्लाइंट मेमोरी का उपयोग नहीं कर सकते हैं, मेरा जवाब देखें। –

1

कुछ खोदने (पढ़ने) के बाद, OES_vertex_array_object में उत्तर पाए गए। ऐसा लगता है कि सर्वर पक्ष पर राज्य पर OES_vertex_array_object का फ़ोकस, और क्लाइंट स्थिति का उपयोग तब किया जाता है जब शून्य ऑब्जेक्ट बाध्य हो। यह जवाब देना बाकी है कि OES_vertex_array_object's सादे OpenGL VAO के समान हैं। यदि आप इसका उत्तर जानते हैं तो कृपया टिप्पणी करें। नीचे 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. 

तो EXC_BAD_ACCESS अपरिभाषित परिणाम था!

+1

+1 "तो EXC_BAD_ACCESS अनिर्धारित परिणाम था!"। मैं * दिनों * के लिए एक बग का पीछा कर रहा हूँ। किसी कारण से क्लाइंट स्टेटस GL_VERTEX_ARRAY को अक्षम किया गया था, जो जानता है कि किसके बाद कुछ समय बाद, glDrawArray ने मुझे सहेजने के बाद इसे फिर से सक्षम किया: glEnableClientState (GL_VERTEX_ARRAY); मैंने EXC_BAD_ACCESS को कभी भी एक अनिर्धारित परिणाम के रूप में नहीं देखा है, लेकिन एक अप्रत्याशित स्मृति रिलीज के रूप में, लेकिन नहीं, यहां कोई स्मृति जारी नहीं की गई थी। आपके संकेत के लिए धन्यवाद, यह बहुत उपयोगी था :) –

1

आप इच्छा अब WebGL के लिए एक विस्तार के रूप में समुदाय द्वारा स्वीकार किया गया है कार्यक्षमता:

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

+0

यह उत्तर प्रश्न के लिए प्रासंगिक प्रतीत नहीं होता है। लिंक इंगित करता है कि WebGL अब OES_vertex_array_object का समर्थन करता है। अच्छा, लेकिन सवाल को संबोधित नहीं करते हैं। स्वीकार्य उत्तर बताता है कि क्यों वीएओ के बारे में पूछे जाने वाले तरीके से उपयोग नहीं किया जा सकता है, और सलाह देता है कि इसके बजाय क्या करना है। – ToolmakerSteve