शब्दावली में से कुछ बंद है:
- A
Vertex Array
केवल एक सरणी (आमतौर पर float[]
) है जिसमें वर्टेक्स डेटा है। इसके लिए किसी चीज से बंधने की जरूरत नहीं है। एक Vertex Array Object
या वीएओ के साथ भ्रमित होने की नहीं , जो मैं बाद में जाऊंगा
- एक
Buffer Object
, आमतौर पर एक के रूप में भेजा Vertex Buffer Object
जब कोने भंडारण, या संक्षेप में VBO, क्या तुम सिर्फ एक कॉल कर रहे है Buffer
।
- वर्टेक्स ऐरे में कुछ भी सहेजा नहीं जाता है,
glVertexAttribPointer
ठीक वैसे ही काम करता है glVertexPointer
या glTexCoordPointer
काम करता है , नामांकित विशेषताओं के बजाय, आपको एक नंबर प्रदान करना है जो आपकी स्वयं की विशेषता को निर्दिष्ट करता है। आप इस मान से गुजरते हैं index
। glVertexAttribPointer
जब आप कॉल करते हैं glDrawArrays
या अगली बार आपके सभी कॉल कतारबद्ध हो जाते हैं glDrawElements
। यदि आपके पास एक VAO है, तो VAO आपकी सभी विशेषताओं के लिए सेटिंग्स संग्रहीत करेगा।
यहाँ मुख्य मुद्दा यह है कि आप VAOs के साथ वर्टेक्स विशेषताओं को भ्रमित कर रहे हैं। वर्टेक्स विशेषताएँ ड्राइंग के लिए वर्टीकल, टेक्सकोर्ड्स, नॉर्म्सल्स आदि को परिभाषित करने का नया तरीका हैं। VAO स्टोर राज्य। मैं सबसे पहले यह बताने जा रहा हूं कि ड्राइंग वर्टेक्स विशेषताओं के साथ कैसे काम करती है, फिर समझाएं कि कैसे आप वीएओ के साथ विधि कॉल की संख्या में कटौती कर सकते हैं:
- इससे पहले कि आप किसी shader में इसका उपयोग कर सकें, आपको एक विशेषता सक्षम करनी होगी। उदाहरण के लिए, यदि आप किसी शेडर को वर्टिकल भेजना चाहते हैं, तो आप सबसे पहले इसे पहली विशेषता के रूप में भेजने की संभावना रखते हैं। 0. इसलिए रेंडर करने से पहले आपको इसे सक्षम करना होगा
glEnableVertexAttribArray(0);
।
- अब जब एक विशेषता सक्षम हो गई है, तो आपको उस डेटा को परिभाषित करने की आवश्यकता है जो इसका उपयोग करने जा रहा है। ऐसा करने के लिए आपको अपने VBO को बांधने की आवश्यकता है -
glBindBuffer(GL_ARRAY_BUFFER, myBuffer);
।
- और अब हम विशेषता को परिभाषित कर सकते हैं -
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
। पैरामीटर के क्रम में: 0 वह विशेषता है जिसे आप परिभाषित कर रहे हैं, 3 प्रत्येक शीर्ष का आकार GL_FLOAT
है, प्रकार है, GL_FALSE
प्रत्येक शीर्ष को सामान्य नहीं करने का अर्थ है, अंतिम 2 शून्य का मतलब है कि कोई स्ट्राइड या कोने पर ऑफसेट नहीं है।
- इसके साथ कुछ ड्रा करें -
glDrawArrays(GL_TRIANGLES, 0, 6);
- आपके द्वारा आकर्षित की जाने वाली अगली चीज़ विशेषता 0 का उपयोग नहीं कर सकती है (वास्तविक रूप से यह होगा, लेकिन यह एक उदाहरण है), इसलिए हम इसे अक्षम कर सकते हैं -
glDisableVertexAttribArray(0);
लपेटें कि glUseProgram()
कॉल में और आपके पास एक रेंडरिंग सिस्टम है जो शेड्स के साथ ठीक से काम करता है। लेकिन मान लें कि आपके पास 5 अलग-अलग विशेषताएँ, कोने, टेक्सकोर्ड, मानदंड, रंग और लाइटमैप निर्देशांक हैं। सबसे पहले, आप glVertexAttribPointer
इनमें से प्रत्येक विशेषता के लिए एक कॉल कर रहे हैं, और आपको पहले से सभी विशेषताओं को सक्षम करना होगा। मान लीजिए कि आपने एट्रिब्यूट 0-4 को परिभाषित किया है क्योंकि मैंने उन्हें सूचीबद्ध किया है। आप उन सभी को इस तरह से सक्षम करेंगे:
for (int i = 0; i < 5; i++)
glEnableVertexAttribArray(i);
और फिर आप प्रत्येक विशेषता के लिए अलग VBOs बाध्य करने के लिए (जब तक आप उन सब को एक VBO और उपयोग ऑफसेट / कदम में स्टोर) के लिए होता है, तो आप 5 अलग अलग करने की जरूरत है glVertexAttribPointer
कॉल से, glVertexAttribPointer(0,...);
करने के लिए glVertexAttribPointer(4,...);
क्रमश: lightmap निर्देशांक के कोने के लिए।
उम्मीद है कि प्रणाली अकेले समझ में आता है। अब मैं इस प्रकार के प्रतिपादन करते समय विधि कॉल की संख्या में कटौती करने के लिए उनका उपयोग करने के तरीके के बारे में बताने के लिए VAO पर आगे बढ़ने जा रहा हूँ। ध्यान दें कि VAO का उपयोग करना आवश्यक नहीं है।
एक Vertex Array Object
या वीएओ का उपयोग सभी glVertexAttribPointer
कॉल की स्थिति और वीबीओ को संग्रहीत करने के लिए किया जाता है जो प्रत्येक glVertexAttribPointer
कॉल किए जाने पर लक्षित थे।
आप एक कॉल के साथ उत्पन्न करते हैं glGenVertexArrays
। एक VAO में आपको जो कुछ भी ज़रूरत है उसे स्टोर करने के लिए, इसके साथ बाँधें glBindVertexArray
, फिर एक पूर्ण ड्रॉ कॉल करें । सभी ड्रा बाइंड कॉल वीएओ द्वारा इंटरसेप्ट और स्टोर किए जाते हैं। आप के साथ VAO को रद्द कर सकते हैंglBindVertexArray(0);
अब जब आप ऑब्जेक्ट को आकर्षित करना चाहते हैं, तो आपको सभी VBO बाइंड या कॉल को फिर से कॉल करने की आवश्यकता नहीं है glVertexAttribPointer
, आपको बस VAO को glBindVertexArray
तब कॉल करने की आवश्यकता है glDrawArrays
या glDrawElements
आप ठीक उसी चीज़ को आरेखित करेंगे जैसे कि आप उन सभी विधि कॉल कर रहे थे। आप शायद VAO को भी बाद में अनबाइंड करना चाहते हैं।
एक बार जब आप VAO को अनबॉन्ड कर देते हैं, तो सभी राज्य आपके द्वारा VAO को बाध्य करने से पहले की स्थिति में वापस आ जाते हैं। मुझे यकीन नहीं है कि अगर कोई बदलाव किया जाता है जबकि VAO बाध्य है, लेकिन यह आसानी से एक परीक्षण कार्यक्रम के साथ पता लगाया जा सकता है। मुझे लगता है कि आप glBindVertexArray(0);
"डिफ़ॉल्ट" VAO के लिए बाध्यकारी के रूप में सोच सकते हैं ...
अद्यतन: किसी ने मेरे ध्यान में वास्तविक ड्रॉ कॉल की आवश्यकता को लाया। जैसा कि यह पता चला है, आपको वास्तव में VAO की स्थापना करते समय एक पूर्ण ड्रा कॉल करने की आवश्यकता नहीं है, बस सभी बाध्यकारी सामान। पता नहीं क्यों मुझे लगा कि यह पहले आवश्यक था, लेकिन यह अब तय हो गया है।