2009-04-29 9 views
15

मुझे ओपनजीएल फ़ंक्शंस को कितनी बार glEnable() या glEnableClientState() और उनके संबंधित glDisable समकक्षों को कॉल करना चाहिए? क्या उन्हें एप्लिकेशन की शुरुआत में एक बार बुलाया जाना है, या क्या मुझे उन्हें अक्षम रखना चाहिए और केवल उन्हीं सुविधाओं को सक्षम करना चाहिए जिन्हें मुझे तुरंत ड्राइंग करने की ज़रूरत है? क्या कोई प्रदर्शन अंतर है?क्या मुझे हर बार ग्लेनेबल और glDisable कॉल करना चाहिए जब भी मैं कुछ खींचूं?

उत्तर

12

"यह निर्भर करता है"।

यदि आप संपूर्ण ऐप केवल सक्षम/अक्षम राज्यों के एक संयोजन का उपयोग करता है, तो हर तरह से इसे शुरुआत में सेट करें और जाएं।

अधिकांश वास्तविक दुनिया क्षुधा मिश्रण करने, ड्रा कॉल करने की ज़रूरत है, और फिर आप कुछ विशेष राज्य (रों) सक्षम करने के लिए glEnable() फोन करने के लिए मजबूर कर रहे हैं, तो उन्हें glDisable() फिर जब आप "मंच खाली करने के लिए काम हो गया "।

राज्य-वर्गीकरण, राज्य-ट्रैकिंग, और कई अनुकूलन योजनाएं इससे निकलती हैं, क्योंकि राज्य स्विचिंग कभी-कभी महंगा होती है।

15

यदि आपको लगता है कि आप अक्सर राज्य चर के मूल्य की जांच कर रहे हैं और बाद में glEnable/glDisable को कॉल कर रहे हैं तो आप विशेषता स्टैक (glPushAttrib/glPopAttrib) का उपयोग करके चीजों को थोड़ा सा साफ करने में सक्षम हो सकते हैं।

विशेषता स्टैक आपको अपने कोड के क्षेत्रों को अलग करने की अनुमति देता है और इस तरह कि एक वर्ग में विशेषता में परिवर्तन अन्य वर्गों में विशेषता स्थिति को प्रभावित नहीं करता है।

void drawObject1(){ 
    glPushAttrib(GL_ENABLE_BIT); 

    glEnable(GL_DEPTH_TEST); 
    glEnable(GL_LIGHTING);  

    /* Isolated Region 1 */ 

    glPopAttrib(); 
}   

void drawObject2(){ 
    glPushAttrib(GL_ENABLE_BIT); 

    glEnable(GL_FOG); 
    glEnable(GL_GL_POINT_SMOOTH);  

    /* Isolated Region 2 */ 

    glPopAttrib(); 
}  

void drawScene(){ 
    drawObject1(); 
    drawObject2(); 
} 

हालांकि GL_LIGHTING और GL_DEPTH_TEST drawObject1 में स्थापित कर रहे हैं उनके राज्य drawObject2 को संरक्षित नहीं किया गया है। GlPushAttrib की अनुपस्थिति में यह मामला नहीं होगा। साथ ही - ध्यान दें कि फ़ंक्शन कॉल के अंत में glDisable को कॉल करने की आवश्यकता नहीं है, glPopAttrib नौकरी करता है।

प्रदर्शन के रूप में, व्यक्तिगत फ़ंक्शन के कारण ओवरहेड glEnable/glDisable को न्यूनतम करता है। यदि आपको बहुत सारी स्थिति संभालने की आवश्यकता है तो आपको शायद अपने राज्य प्रबंधक बनाने की आवश्यकता होगी या glGetInteger को कई कॉल करने की आवश्यकता होगी ... और फिर तदनुसार कार्य करें। अतिरिक्त मशीनरी और नियंत्रण प्रवाह कोड को कम पारदर्शी, डीबग करने में कठोर, और बनाए रखने के लिए और अधिक कठिन बना सकता है। ये मुद्दे अन्य, अधिक उपयोगी, अनुकूलन को और अधिक कठिन बना सकते हैं।

एट्रिब्यूशन स्टैक अमूर्तता की परतों को बनाए रखने और अलगाव के क्षेत्रों को बनाने में सहायता कर सकता है।

glPushAttrib manpage

+0

.. और इसके ग्राहक समकक्ष glPush/PopClientAttrib –

+1

इन कार्यों को प्रोग्राम करने योग्य पाइपलाइन में बहिष्कृत किया गया है। – andrewrk

0

अंगूठे कि मैं सिखाया गया था का एक नियम ने कहा कि यह लगभग हमेशा सस्ता बस सक्षम/पर निष्क्रिय करने के लिए होगा न कि वर्तमान स्थिति की जाँच और केवल बदल रहा है अगर जरूरत है।

उस ने कहा, मार्क का जवाब कुछ ऐसा है जो निश्चित रूप से काम करना चाहिए।

8

सबसे पहले, आप किस ओपनजीएल संस्करण का उपयोग करते हैं? और ग्राफिक्स हार्डवेयर की कौन सी पीढ़ी आपके लक्षित समूह में है? इसे जानने से अधिक सही उत्तर देना आसान हो जाएगा। मेरा जवाब ओपनजीएल 2.1 मानता है।

ओपनजीएल एक राज्य मशीन है, जिसका अर्थ है कि जब भी कोई राज्य बदल जाता है, तब तक राज्य को "चालू" बना दिया जाता है जब तक कि प्रोग्रामर द्वारा एक नए ओपनजीएल एपीआई कॉल के साथ स्पष्ट रूप से परिवर्तित नहीं किया जाता है। इस नियम के अपवाद मौजूद हैं, जैसे क्लाइंट स्टेट एरे कॉल वर्तमान वर्टेक्स रंग को अपरिभाषित करते हैं। लेकिन वे अपवाद हैं जो नियम को परिभाषित करते हैं।

"आवेदन की शुरुआत में" बहुत अधिक समझ में नहीं आता है, क्योंकि एप्लिकेशन को अभी भी चल रहा है, जबकि आपके ओपनजीएल संदर्भ को नष्ट करने की आवश्यकता है। मुझे लगता है कि आप हर खिड़की के निर्माण के बाद ही मतलब है। यह राज्य के लिए काम करता है जिसे आपको बाद में बदलने की आवश्यकता नहीं है। उदाहरण: यदि आपके सभी ड्रा कॉल समान वर्टेक्स सरणी डेटा का उपयोग करते हैं, तो आपको बाद में glDisableClientState के साथ उन्हें अक्षम करने की आवश्यकता नहीं है।

पुराने फिक्स्ड-फ़ंक्शन पाइपलाइन से जुड़े बहुत से सक्षम/अक्षम राज्य हैं। इसके लिए आसान मोचन है: शेडर्स का प्रयोग करें! यदि आप पांच साल की उम्र में कार्ड की पीढ़ी को लक्षित करते हैं, तो शायद यह शेडर्स के साथ फिक्स्ड-फ़ंक्शन पाइपलाइन की नकल करता है। शेडर्स का उपयोग करके आप ट्रांसफॉर्म और रास्टरराइजेशन चरणों के दौरान क्या हो रहा है, इसके बारे में कम या ज्यादा नियंत्रण में हैं, और आप अपने स्वयं के "राज्य" वर्दी के साथ बना सकते हैं, जो बदलने/अपडेट करने के लिए बहुत सस्ते हैं।

यह जानकर कि ओपनजीएल एक राज्य मशीन है जैसा कि मैंने उपर्युक्त कहा है, इसे स्पष्ट करना चाहिए कि किसी को राज्य परिवर्तन को न्यूनतम रखने के लिए प्रयास करना चाहिए, जब तक यह संभव हो। हालांकि, संभवतः अन्य चीजें हैं जो प्रदर्शन/अक्षम राज्य कॉल से अधिक प्रदर्शन को प्रभावित करती हैं। यदि आप उनके बारे में जानना चाहते हैं, तो पढ़ें।


राज्य नहीं वर्ष निर्धारित समारोह राज्य कॉल और जो के साथ जुड़े की कीमत लागत में व्यापक रूप से भिन्न हो सकते हैं/अक्षम राज्य सक्षम सरल नहीं है। विशेष रूप से शेडर्स को जोड़ने, और बाध्यकारी नाम, (बनावट, प्रोग्राम, बफर ऑब्जेक्ट्स के "नाम) आमतौर पर काफी महंगा होते हैं। यही कारण है कि बनावट के अनुसार अपने मैश के ड्रा ऑर्डर को सॉर्ट करने के लिए बहुत सारे गेम और एप्लिकेशन इस्तेमाल किए जाते थे। इस तरह, उन्हें एक ही बनावट को दो बार बांधना नहीं था। आजकल, यह शेडर कार्यक्रमों पर भी लागू होता है। यदि आपको ऐसा करने की ज़रूरत नहीं है तो आप एक ही शेडर प्रोग्राम को दो बार बांधना नहीं चाहते हैं। साथ ही, किसी विशेष ओपनजीएल संस्करण में सभी सुविधाएं हार्डवेयर पर त्वरित नहीं होती हैं, भले ही उन कार्डों के विक्रेताओं का दावा है कि वे OpenGL अनुपालन कर रहे हैं। अनुपालन होने का मतलब है कि वे विनिर्देश का पालन करते हैं, न कि वे सभी featurs कुशलतापूर्वक चलाने के लिए। जीएल__ एआरबी __imaging से glHistogram और glMinMax जैसे कुछ कार्यों को इस संबंध में याद किया जाना चाहिए।


निष्कर्ष: जब तक कोई स्पष्ट कारण नहीं है, तो शेडर्स का उपयोग करें! यह आपको बहुत सी अनावश्यक राज्य कॉल से बचाता है क्योंकि आप इसके बजाय वर्दी का उपयोग कर सकते हैं। ओपनजीएल शेडर्स सिर्फ छह साल के लिए जानते हैं जो आप जानते हैं। इसके अलावा, सक्षम/अक्षम राज्य परिवर्तनों का ओवरहेड एक समस्या हो सकता है, लेकिन आमतौर पर ग्लूसेप्रोग्राम, ग्लोम्पाइलशैडर, ग्लिंकप्रप्रोग्राम, ग्लिंडबफर और ग्लिंडटेक्चर जैसे अन्य महंगे राज्य परिवर्तनों को अनुकूलित करने से लाभ प्राप्त करने के लिए बहुत कुछ है।

पीएस: ओपनजीएल 3.0 ने क्लाइंट स्टेट को सक्षम/अक्षम कॉल हटा दिया। वे स्पष्ट रूप से सक्षम हैं क्योंकि इस संस्करण में आकर्षित करने का एकमात्र तरीका ड्रॉ एरेज़ है। तत्काल मोड हटा दिया गया था। gl.. सूचक कॉल भी हटा दिए गए थे, क्योंकि वास्तव में केवल glvertexAttribPointer की आवश्यकता होती है।

संबंधित मुद्दे