शब्दावली में से कुछ एक सा बंद है:
- एक
Vertex Array
सिर्फ एक सरणी है (आम तौर पर एक float[]
) कि शिखर डेटा होता है। इसे किसी भी चीज़ से बंधने की आवश्यकता नहीं है। एक Vertex Array Object
या VAO, जो मैं बाद में
- एक
Buffer Object
, जब कोने भंडारण, या संक्षेप में VBO सामान्यतः एक Vertex Buffer Object
रूप में जाना जाता पर चर्चा करेंगे के साथ भ्रमित होने की नहीं, क्या तुम सिर्फ एक Buffer
कॉल कर रहे है।
- कुछ भी कशेरुक सरणी पर वापस सहेजा नहीं जाता है,
glVertexAttribPointer
glVertexPointer
या glTexCoordPointer
काम की तरह काम करता है, सिर्फ नामित विशेषताओं के बजाय, आपको एक ऐसी संख्या प्रदान करने के लिए मिलता है जो आपकी अपनी विशेषता निर्दिष्ट करता है। आप इस मान को index
के रूप में पास करते हैं। अगली बार जब आप glDrawArrays
या glDrawElements
पर कॉल करते हैं तो आपके सभी glVertexAttribPointer
कॉल कतारबद्ध हो जाते हैं। यदि आपके पास वीएओ बाध्य है, तो वीएओ आपके सभी विशेषताओं के लिए सेटिंग स्टोर करेगा।
मुख्य मुद्दा यह है कि आप वीएओ के साथ वर्टेक्स विशेषताओं को भ्रमित कर रहे हैं। Vertex विशेषताओं ड्राइंग के लिए चरम, texcoords, normals, आदि को परिभाषित करने का एक नया तरीका है। वीएओ स्टोर राज्य। मैं पहली बार कैसे ड्राइंग शिखर विशेषताओं के साथ काम करता है समझाने के लिए जा रहा हूँ, तो यह बताएं कि आप की विधि VAOs साथ कॉल संख्या में कटौती कर सकते हैं:
- से पहले आपको किसी शेडर में उपयोग कर सकते हैं एक विशेषता सक्षम करना होगा।उदाहरण के लिए, यदि आप किसी शेडर पर शीर्ष पर भेजना चाहते हैं, तो आप इसे पहले विशेषता के रूप में भेजने की संभावना रखते हैं, 0. इसलिए प्रस्तुत करने से पहले, आपको
glEnableVertexAttribArray(0);
के साथ इसे सक्षम करने की आवश्यकता है।
- अब एक विशेषता सक्षम है, आपको उस डेटा को परिभाषित करने की आवश्यकता है जिसका उपयोग करने जा रहा है। ऐसा करने के लिए आपको अपने वीबीओ -
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,...);
क्रमशः लाइटमैप निर्देशांक के लिए शिखर के लिए।
उम्मीद है कि अकेले सिस्टम समझ में आता है। अब मैं इस प्रकार के प्रतिपादन करते समय विधि कॉल की संख्या को कम करने के लिए उनका उपयोग करने के तरीके को समझाने के लिए वीएओ पर जाने जा रहा हूं। ध्यान दें कि वीएओ का उपयोग करना जरूरी नहीं है।
ए Vertex Array Object
या वीएओ का उपयोग glVertexAttribPointer
कॉल और वीबीओ की स्थिति को संग्रहीत करने के लिए किया जाता है, जब glVertexAttribPointer
कॉलों में से प्रत्येक को लक्षित किया गया था।
आप glGenVertexArrays
पर कॉल के साथ एक उत्पन्न करते हैं। वीएओ में आपको जो कुछ भी चाहिए उसे स्टोर करने के लिए, इसे glBindVertexArray
से बांधें, फिर पूर्ण ड्रा कॉल
करें। सभी
ड्रा
बाइंड कॉल वीएओ द्वारा अवरुद्ध और संग्रहित हो जाते हैं। आप glBindVertexArray(0);
साथ VAO निकल सकते हैं अब जब आप वस्तु आकर्षित करने के लिए चाहते हैं, तो आप फिर से कॉल करने के लिए सभी VBO glVertexAttribPointer
कॉल बांधता है या की जरूरत नहीं है, तो आप सिर्फ glBindVertexArray
साथ VAO बाध्य करने के लिए की जरूरत है तो glDrawArrays
फोन या glDrawElements
और आप वही चीज़ तैयार करेंगे जैसे कि आप उन सभी विधि कॉल कर रहे थे। आप शायद बाद में वीएओ को भी अनइंड करना चाहते हैं।
एक बार जब आप वीएओ को छोड़ देते हैं, तो सभी राज्य वीएओ को बाध्य करने से पहले यह कैसे लौटते हैं। मुझे यकीन नहीं है कि वीएओ बाध्य होने पर आपके द्वारा किए गए कोई भी बदलाव किए जाते हैं, लेकिन इसे आसानी से परीक्षण कार्यक्रम के साथ लगाया जा सकता है। मुझे लगता है कि आप "डिफ़ॉल्ट" VAO के लिए बाध्य के रूप में glBindVertexArray(0);
के बारे में सोच सकते हैं ...
अद्यतन: किसी ने मेरे ध्यान में वास्तविक ड्रॉ कॉल के लिए की जरूरत ले आया।जैसे-जैसे यह निकलता है, वीएओ की स्थापना करते समय आपको वास्तव में एक पूर्ण ड्रॉ कॉल करने की आवश्यकता नहीं होती है, बस सभी बाध्यकारी सामान। पता नहीं क्यों मैंने सोचा कि यह पहले जरूरी था, लेकिन अब यह तय हो गया है।
"एक वेरटेक्स बफर ऑब्जेक्ट, या वीबीओ (कभी-कभी केवल एक बफर ऑब्जेक्ट के रूप में जाना जाता है)" इसे "कभी-कभी" कहा जाता है क्योंकि वास्तव में इसे कहा जाता है। यह सिर्फ एक बफर ऑब्जेक्ट है, किसी भी अन्य बफर ऑब्जेक्ट से अलग नहीं है जिसे आप वर्दी ब्लॉक, पिक्सेल ट्रांसफर, फीडबैक बदलने या किसी अन्य उपयोग के लिए उपयोग कर सकते हैं। ओपनजीएल स्पेक * कभी * किसी भी "वर्टेक्स बफर ऑब्जेक्ट" के रूप में संदर्भित नहीं करता है; यहां तक कि [मूल विस्तार spec] (http://www.opengl.org/registry/specs/ARB/vertex_buffer_object.txt) इसे कभी भी कॉल नहीं करता है। –
उचित नामकरण से मेल खाने के लिए संपादित, धन्यवाद। –
उत्कृष्ट जवाब। इसे लिखने के लिए समय निकालने के लिए धन्यवाद! कुछ जोड़े प्रश्नों का पालन करते हैं: (1) आपने कहा "प्रस्तुत करने से पहले, और विशेषता को परिभाषित करने से पहले, आपको इसे glEnableVertexAttribArray (0)" के साथ सक्षम करने की आवश्यकता है - क्या आपको यकीन है कि इसे कॉल से पहले सक्षम होना आवश्यक है। glVertexAttribPointer'? मेरे परीक्षणों में, आदेश कोई फर्क नहीं पड़ता है। (2) यदि मैं आपको सही ढंग से समझता हूं, तो Vertex विशेषताएँ वैश्विक हैं, और केवल उनकी सक्षम/अक्षम स्थिति वर्तमान में बाध्य वीएओ में सहेजी गई है? – mpen