OpenGL shaders के लिए स्पष्ट बनाम स्वचालित विशेषता स्थान बाइंडिंग


83

OpenGL शेडर प्रोग्राम के लिए विशेषता स्थान सेट करते समय, आपको दो विकल्पों का सामना करना पड़ता है:

glBindAttribLocation लिंक करने से पहले स्पष्ट रूप से एक विशेषता स्थान को परिभाषित करने के लिए।

या

glGetAttribLocation () स्वचालित रूप से निर्दिष्ट विशेषता स्थान प्राप्त करने के लिए लिंक करने के बाद।

एक के ऊपर एक प्रयोग करने की उपयोगिता क्या है?

और कौन सा, यदि कोई है, व्यवहार में पसंद किया जाता है?


6
मैंने glBindAttribLocationअपने ग्राफिक्स इंजन का उपयोग करने में परेशान नहीं किया , जो कि लिनक्स पर अच्छी तरह से काम करता था। जब मैंने खिड़कियों पर पोर्ट किया, तो यह मेरे मानदंड को कोने के रूप में उपयोग कर रहा था - मुझे इसे स्पष्ट रूप से अपनी छाया में चर के आदेश के माध्यम glBindAttribLocationसे इसे काम करने के लिए बताना था ...
जेरेट

जवाबों:


93

मुझे स्पष्ट स्थान परिभाषा पसंद करने का एक अच्छा कारण पता है ।

इस बात पर विचार करें कि आप वर्टेक्स ऐरे ऑब्जेक्ट्स में अपना ज्यामिति डेटा रखते हैं किसी दिए गए ऑब्जेक्ट के लिए, आप इस तरह से एक वीएओ बनाते हैं, जो सूचकांक उदाहरण के लिए मेल खाते हैं:

  • सूचकांक 0 : स्थिति,
  • सूचकांक 1 : मानदंड,
  • सूचकांक 2 : टेक्सकोर्ड्स

अब विचार करें कि आप एक वस्तु को दो अलग-अलग शेड्स के साथ खींचना चाहते हैं । एक shader को इनपुट के रूप में स्थिति और सामान्य डेटा की आवश्यकता होती है , अन्य - स्थिति और बनावट के कोर्डर्स

यदि आप उन शेड्स को संकलित करते हैं, तो आप देखेंगे कि पहला शेडर विशेषता सूचकांक 0 पर स्थितियां और 1 पर मानदंडों की अपेक्षा करेगा। अन्य 1 पर स्थिति की उम्मीद करेंगे, लेकिन बनावट 1 पर।

उद्धरण https://www.opengl.org/wiki/Vertex_Shader :

स्वचालित असाइनमेंट

यदि पहले के दो तरीकों में से कोई भी विशेषता इंडेक्स में इनपुट असाइन नहीं करता है, तो प्रोग्राम के लिंक होने पर इंडेक्स स्वचालित रूप से OpenGL द्वारा असाइन किया जाता है। सौंपे गए सूचकांक पूरी तरह से मनमाना है और अलग-अलग कार्यक्रमों के लिए अलग-अलग हो सकते हैं जो जुड़े हुए हैं, भले ही वे एक ही वर्टेक्स शेडर कोड का उपयोग करते हों।

इसका मतलब है कि आप अपने VAO को दोनों शेड्स के साथ उपयोग नहीं कर पाएंगे। एक VAO प्रति होने के बजाय, कहें, ऑब्जेक्ट, आपको चाहिए - सबसे खराब स्थिति में - प्रति shader प्रति ऑब्जेक्ट का एक अलग VAO

अपने स्वयं के विशेषता नंबरिंग कन्वेंशन का उपयोग करने के लिए शेड्स को मजबूर glBindAttribLocationकरने से इस समस्या को आसानी से हल किया जा सकता है - आपको केवल इतना करना है कि विशेषताओं और उनके एस्टेब्लिशड आईडी के बीच एक सुसंगत संबंध बनाए रखें, और लिंक करते समय शेडर्स को उपयोग करने के लिए बाध्य करें।

(यदि आप अलग-अलग VAO का उपयोग नहीं करते हैं, तो यह वास्तव में एक बड़ा मुद्दा नहीं है, लेकिन फिर भी आपका कोड स्पष्ट हो सकता है।)


Btw:

OpenGL शेडर प्रोग्राम के लिए विशेषता स्थान सेट करते समय, आपको दो विकल्पों का सामना करना पड़ता है

OpenGL / GLSL 3.3 में तीसरा विकल्प है: सीधे shader कोड में स्थान निर्दिष्ट करें । यह इस तरह दिख रहा है:

layout(location=0) in vec4 position;

लेकिन यह GLSL ES shader भाषा में मौजूद नहीं है।


1
मैं बात नहीं देख रहा हूँ। VAO वास्तव में हल्के वजन वाले हैं और आप आमतौर पर प्रत्येक फ्रेम के लिए उन्हें फिर से बनाएंगे। आपके मामले में, आप बस प्रत्येक shader को कॉल करने से पहले अलग-अलग VAO बनाएंगे, है ना?
पियरेबर्ड

1
हां, आप ऐसा कर सकते हैं। यह भी काम करेगा, हम यहां केवल सम्मेलनों पर चर्चा कर रहे हैं। :)
कोस

4
तीसरा विकल्प वास्तव में GLES2.0 में उपलब्ध है, लेकिन प्रारूप थोड़ा अलग है: लेआउट (स्थान = 0) विशेषता vec4 स्थिति; ध्यान दें कि आपको अपनी GLSL फ़ाइल के शीर्ष पर भी इसकी आवश्यकता होगी: #extension GL_EXT_separate_shader_objects: सक्षम करें
Gavin Maclean

35
"VAO वास्तव में हल्के वजन वाले होते हैं और आप आमतौर पर प्रत्येक फ्रेम के लिए उन्हें फिर से बनाएंगे। आपके मामले में, आप प्रत्येक shader को कॉल करने से पहले बस अलग-अलग VAO बनाएंगे, है ना?" - नहीं, आप आमतौर पर ऐसा नहीं करेंगे, क्योंकि यह अंत में VAO के पूरे उद्देश्य को पूरी तरह से अमान्य कर देता है। फिर एक वीएओ का उपयोग क्यों करें?
क्रिश्चियन राऊ

2
सिर्फ एक नोट। आप अपने ज्यामिति डेटा को VAO में नहीं रखेंगे। यह एक VBO में होगा। VAO में डेटा स्टोरेज नहीं है।
औसत जो

20

यहां एक और जवाब यह है कि glGetAttribLocation कॉल करने वाले को डेटा लौटाता है, जिसका अर्थ है कि इसके लिए एक पाइपलाइन फ्लश की आवश्यकता है। यदि आप अपने प्रोग्राम को संकलित करने के बाद इसे सही कहते हैं, तो आप अनिवार्य रूप से अतुल्यकालिक संकलन को सिंक्रोनाइज़ करने के लिए मजबूर कर रहे हैं।



धन्यवाद, यह एक बहुत महत्वपूर्ण विचार है।
जिंग

1
यह मेरी समझ है कि ज्यादातर स्थितियों में आपको किसी भी तरह से कॉल करना होगा glGetUniformLocation; क्या यह विशेष रूप से विचार अभी भी प्रासंगिक है?
माइक वियर

@MikeWeir जीएल 4.3 के बाद से आप स्पष्ट वर्दी स्थान निर्धारित कर सकते हैं ।
रुस्लान

1
@Ruslan वे OpenGL ES का उपयोग कर रहे हैं।
माइक वियर

9

तीसरा विकल्प, यानी layout(location=0) in vec4 position;shader कोड, अब OpenGL ES 3.0 / GLSL 300 es में उपलब्ध है। केवल शीर्ष shader इनपुट चर के लिए हालांकि।


7
जैसा कि वे संकेत देते हैं, इंटेल कार्ड इस का समर्थन नहीं कर सकते हैं (पूरी तरह से 3.0+ कम्फर्टेंट होने के नाते अन्यथा, जैसा कि मुझे मिलता है), जो घृणित है :)
mlvljr
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.