OpenGL रेंडरिंग के लिए ट्यूटोरियल अलग-अलग तरीकों का उपयोग क्यों करते हैं?


43

http://www.sdltutorials.com/sdl-opengl-tutorial-basics

http://www.opengl-tutorial.org/beginners-tutorials/tutorial-2-the-first-triangle/

ये दोनों ट्यूटोरियल लगभग समान परिणाम प्राप्त करने के लिए पूरी तरह से अलग दृष्टिकोण का उपयोग करते हैं। पहले जैसी चीजों का उपयोग करता है glBegin(GL_QUADS)। दूसरा व्यक्ति vertexBufferObjectsGLEW पर आधारित सामान की तरह उपयोग करता है । लेकिन परिणाम एक ही है: आपको मूल आकार मिलते हैं।

ये अंतर क्यों मौजूद हैं?

पहला दृष्टिकोण समझने में बहुत आसान लगता है। जटिल दूसरे दृष्टिकोण का क्या फायदा है?


4
एक बिल्ली की त्वचा के लिए सिर्फ एक ही रास्ता नहीं है।
फिलिपिंस

4
@ फ़िलिप हां, लेकिन सही तरीके और गलत तरीके, पुराने तरीके और नए तरीके हैं (और जैसा कि नीचे दिए गए जवाब प्रदर्शित करते हैं, पुराने और नए तरीके सभी स्थितियों में संगत नहीं हो सकते हैं)
एंड्रयू हिल

3
हैं कोई सही तरीके और गलत तरीके, केवल बदतर तरीके और बेहतर तरीके (कई अलग अलग आयामों में)।
user253751

glBeginऔर glEndक्योंकि वे वर्तमान ग्राफिक्स आर्किटेक्चर के लिए बेहद अक्षम हैं
एलेक्स

जवाबों:


77

OpenGL के चार अलग-अलग प्रमुख संस्करण हैं, जो मोबाइल उपकरणों और एम्बेडेड सिस्टम (OpenGL | ES) के संस्करणों की गणना नहीं करते हैं और जावास्क्रिप्ट (WebGL) के माध्यम से वेब। जैसे Direct3D 11 में Direct3D 8 की तुलना में चीजों को करने का एक अलग तरीका है, वैसे ही OpenGL 3 में OpenGL 1 की तुलना में चीजों को करने का एक अलग तरीका है। बड़ा अंतर यह है कि OpenGL संस्करण पुराने संस्करणों में केवल एड-ऑन हैं (लेकिन नहीं पूरी तरह से)।

OpenGL के विभिन्न संस्करणों और संस्करणों के शीर्ष पर, मुख्य OpenGL ने प्रोफाइल की अवधारणा को भी जोड़ा। मुख्य रूप से संगतता प्रोफ़ाइल (जो पुराने संस्करणों से एपीआई के लिए समर्थन को सक्षम करता है) और कोर प्रोफ़ाइल (जो उन पुराने एपीआई को अक्षम करता है)। glBeginजब आप कोर प्रोफाइल का उपयोग करते हैं तो ऐसी चीजें काम नहीं करती हैं, लेकिन जब आप संगतता प्रोफ़ाइल का उपयोग करेंगे (जो कि डिफ़ॉल्ट है)।

एक और बड़ी जटिलता के रूप में, OpenGL के कुछ कार्यान्वयन (जैसे Apple, दूसरों के बीच में) केवल नए OpenGL फीचर को सक्षम करेंगे, जब आप कोर प्रोफाइल का उपयोग कर रहे होंगे। इसका मतलब यह है कि नए APIs का उपयोग करने के लिए आपको पुराने API का उपयोग बंद करना होगा

फिर आप ट्यूटोरियल के लिए कई बहुत भ्रामक परिदृश्यों को समाप्त करते हैं:

  1. ट्यूटोरियल पुराना है और केवल अपग्रेड किए गए एपीआई का उपयोग करता है।
  2. ट्यूटोरियल नया और अच्छी तरह से लिखा गया है और केवल कोर-संगत एपीआई का उपयोग करता है।
  3. ट्यूटोरियल नया है, लेकिन यह मानने की गलती करता है कि आप एक ड्राइवर के साथ काम कर रहे हैं जो सभी एपीआई को संगतता मोड में सक्षम बनाता है, और नए और पुराने दोनों एपीआई को स्वतंत्र रूप से मिलाता है।
  4. ट्यूटोरियल OpenGL की तरह के एक अलग संस्करण के लिए है OpenGL | ES जो किसी भी संस्करण में किसी भी पुराने APIs का समर्थन नहीं करता है।

जैसी चीजें हैं glBeginउन्हें कभी-कभी तत्काल मोड एपीआई कहा जाता है। यह भी सुपर भ्रामक है क्योंकि ओपनजीएल में एक बरकरार मोड जैसी कोई चीज नहीं है और "तत्काल मोड" में पहले से ही ग्राफिक्स में एक अलग परिभाषा थी। यह ज्यादा बेहतर है कि आप उन लोगों को ही देखें जो OpenGL 2.1 के बाद से अप्रचलित हैं।

OpenGL की 1.x API तुरंत पुराने दिनों में ग्राफिक्स पाइपलाइन को लंबवत प्रस्तुत करेगी। यह अच्छी तरह से काम करता है जब हार्डवेयर की गति जो लंबवत प्रस्तुत की गई थी, वह सीपीयू की गति के साथ लगभग बराबर थी, जो शीर्ष डेटा उत्पन्न करती थी। OpenGL वापस तो त्रिभुज रेखांकन बंद कर दिया और बहुत कुछ नहीं।

इन दिनों, GPU उन्नत वर्टेक्स और पिक्सेल ट्रांसफ़ॉर्मेशन करते समय बहुत अधिक गति से बड़े पैमाने पर चबाने के माध्यम से चबा सकता है और सीपीयू आसानी से दूर नहीं रख सकता है। उसके शीर्ष पर, CPU और GPU के बीच का इंटरफ़ेस इस गति अंतर के आसपास डिज़ाइन किया गया है, जिसका अर्थ है कि अब एक बार में GPU एक को वर्जन सबमिट करना संभव नहीं है।

सभी GL ड्राइवरों को glBeginआंतरिक रूप से एक वर्टेक्स बफर को आबंटित करके अनुकरण करना चाहिए , जो glVertexइस बफर के साथ जमा किए गए सिरों को लगाते हैं , और फिर जब कॉल किया glEndजाता है तो उस पूरे बफर को सिंगल ड्रा कॉल में सबमिट करते हैं । इन फ़ंक्शंस का ओवरहेड कहीं अधिक है यदि आपने अभी-अभी अपने आप को वर्टेक्स बफर अपडेट किया है, यही वजह है कि कुछ डॉक्यूमेंटेशन (बहुत गलती से!) वर्टेक्स बफ़र्स को "एक ऑप्टिमाइज़ेशन" के रूप में संदर्भित करते हैं (यह एक अनुकूलन नहीं है; यह वास्तव में एकमात्र तरीका है GPU से बात करें)।

कई अन्य एपीआई हैं जो पिछले कुछ वर्षों में ओपनजीएल में पदावनत या बाधित किए गए हैं। तथाकथित फिक्स्ड-फ़ंक्शन पाइपलाइन एक और ऐसा टुकड़ा है। कुछ प्रलेखन अभी भी इस पाइपलाइन का उपयोग कर सकते हैं या प्रोग्राम योग्य पाइपलाइन के साथ मिश्रण कर सकते हैं। फिक्स्ड-फंक्शन पाइपलाइन पुराने दिनों से आती है जब ग्राफिक्स 3 डी दृश्यों को प्रस्तुत करने के लिए उपयोग किए जाने वाले गणित के सभी हार्ड-कोडित होते हैं और ओपनजीएल एपीआई उस गणित के लिए कुछ कॉन्फ़िगरेशन मान सेट करने के लिए सीमित था। इन दिनों हार्डवेयर में बहुत कम हार्ड-कोडेड गणित होता है और (आपके सीपीयू की तरह) इसके बजाय उपयोगकर्ता-आपूर्ति वाले प्रोग्राम (अक्सर शेड्स कहा जाता है) चलाता है।

एक बार फिर से ड्राइवरों को पुराने एपीआई का अनुकरण करना चाहिए क्योंकि फिक्स्ड-फंक्शन फीचर्स अभी हार्डवेयर पर मौजूद नहीं हैं। इसका मतलब यह है कि ड्राइवर में संगतता शेडर्स का एक गुच्छा होता है, जो उस पुराने गणित को निर्धारित-फ़ंक्शन दिनों से निष्पादित करता है जो तब उपयोग किया जाता है जब आप अपने स्वयं के शेड्स की आपूर्ति नहीं करते हैं। पुराने OpenGL फ़ंक्शन जो उस पुराने फिक्स्ड-फ़ंक्शन स्टेट (पुराने OpenGL लाइटिंग API की तरह) को संशोधित करते हैं, वे वास्तव में ड्राइवर की संगतता शेड्स को इन मानों को खिलाने के लिए समान बफ़र जैसी आधुनिक OpenGL सुविधाओं का उपयोग कर रहे हैं।

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

बहुत सारे प्रलेखन की सिफारिश की जा सकती है कि आप पुराने एपीआई के साथ शुरू करते हैं बस उन्हें शुरू करने के लिए आसान होने के कारण। Direct3D ने शुरुआती लोगों के लिए इस समस्या को हल किया एक साथी पुस्तकालय ( डायरेक्टएक्स टूल किट ) जो सरल ड्राइंग एपीआई और पूर्व-लिखित शेड प्रदान करता है जो आपकी विशेषज्ञता बढ़ने पर कच्चे Direct3D 11 उपयोग के साथ स्वतंत्र रूप से मिलाया जा सकता है। व्यापक OpenGL समुदाय ज्यादातर शुरुआती के लिए संगतता प्रोफ़ाइल के साथ फंस गया है, दुर्भाग्य से, जो समस्याग्रस्त है क्योंकि फिर से ऐसे सिस्टम हैं जो आपको नए के साथ पुराने OpenGL API को मिश्रण करने की अनुमति नहीं देते हैं। सुविधाओं और लक्ष्य के उपयोग के मामलों और भाषाओं के अलग-अलग स्तरों के साथ नए ओपनजीएल पर सरल प्रतिपादन के लिए अनौपचारिक पुस्तकालय और उपकरण हैं ( मोनूगामे उदाहरण के लिए .NET उपयोगकर्ताओं के लिए), लेकिन आधिकारिक तौर पर कुछ भी समर्थन या व्यापक रूप से सहमत नहीं हुआ।

आपके द्वारा खोजा जा रहा दस्तावेज़ीकरण OpenGL के लिए भी नहीं हो सकता है, लेकिन अन्य समान API में से एक के लिए हो सकता है। OpenGL | ES 1.x में फिक्स्ड-फंक्शन रेंडरिंग थी, लेकिन वर्टेक्स सबमिशन के लिए OpenGL 1.x APIs नहीं थे। OpenGL | ES 2.x + और WebGL 1+ में कोई निश्चित-फ़ंक्शन सुविधाएँ नहीं हैं और उन API के लिए कोई पश्चगामी संगतता मोड नहीं है।

ये API मुख्य OpenGL के समान ही दिखते हैं; वे काफी संगत नहीं हैं, लेकिन OpenGL के लिए आधिकारिक एक्सटेंशन हैं कि कुछ (सभी नहीं) ड्राइवर ओपन के साथ संगत बनने के लिए समर्थन करते हैं। ES (जो WebGL पर आधारित है)। क्योंकि चीजें पहले पर्याप्त भ्रमित नहीं थीं।


4
+1 शानदार जवाब! यदि आप उन नए अनौपचारिक पुस्तकालयों और उपकरणों की एक जोड़ी का उल्लेख कर सकते हैं जो नए ओपनजीएल पर सरल प्रतिपादन के लिए महान होंगे :)
मेहरदाद

2
शानदार जवाब। मुझे दिन में वापस डायरेक्टएक्स के साथ एक ही परेशानी हुई है - ओपनजीएल की तुलना में बहुत सरल, लेकिन बनाए रखने के लिए / तत्काल मोड से छलांग तक छलांग बहुत बड़ी थी। सौभाग्य से, दस्तावेज़ ने बहुत मदद की (ओपनजीएल के विपरीत, कम से कम मेरे लिए), लेकिन "मैं भी कैसे प्रकाश करता हूं" की शुरुआत पागल थी: डी
लुअन

मैं opengl-tutorial.org का लेखक हूं, और मैं सीन से सहमत हूं। एपीआई मुख्य रूप से प्रदर्शन कारणों से इस तरह से विकसित हुआ।
केल्विन १६०२

विषय के बारे में बहुत अच्छी जानकारी ..
रेनमार

1
@ मेहरदाद: मुझे अपने सिर के ऊपर से कोई याद नहीं है; SDL2 या SFML जैसी लाइब्रेरी हैं जो सरलीकृत 2D रेंडरिंग, विभिन्न सीन ग्राफ लाइब्रेरी, C # के लिए मोनोअम, इत्यादि जोड़ते हैं, लेकिन मैं वास्तव में प्रत्यक्ष TK के समकक्ष किसी भी चीज़ के बारे में वास्तव में अवगत नहीं हूं जो अब मैं इसके बारे में सोचता हूं। "कई" कहने के बाद से पोस्ट को संपादित करेगा एक बड़ा मोटा झूठ हो सकता है। :)
सीन मिडिलिचच

9

प्राथमिक अंतर यह है कि रणनीतियां कितनी अद्यतित हैं। पहले ट्यूटोरियल में इस्तेमाल किया गया तत्काल मोड:

glBegin(GL_QUADS);
    glColor3f(1, 0, 0); glVertex3f(0, 0, 0);
    glColor3f(1, 1, 0); glVertex3f(100, 0, 0);
    glColor3f(1, 0, 1); glVertex3f(100, 100, 0);
    glColor3f(1, 1, 1); glVertex3f(0, 100, 0);
glEnd();

पुराना है और नए संस्करणों पर समर्थित नहीं है।

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


2

बस अन्य उत्कृष्ट उत्तरों के लिए कुछ और संदर्भ जोड़ना है।

पहले लिंक में वर्णित तत्काल मोड है, जैसा कि अन्य ने कहा है, ओपनजीएल (1.1) के शुरुआती संस्करणों से विरासत कोड। जब GPU त्रिभुज रेखापुंज की तुलना में थोड़ा अधिक था और प्रोग्राम योग्य पाइपलाइनों का विचार मौजूद नहीं था, तो इसका उपयोग वापस किया गया था। यदि आप उदाहरण के लिए GLQuake और Quake 2 जैसे कुछ शुरुआती हार्डवेयर-त्वरित गेम के स्रोत कोड को देखते हैं, तो आपको उपयोग में तत्काल मोड दिखाई देगा। सरल शब्दों में, सीपीयू स्क्रीन पर त्रिकोण ड्राइंग शुरू करने के लिए GPU पर एक समय में एक के लिए निर्देश भेजता है। रिकॉर्ड के लिए, GL_QUADS का GL_TRIANGLES के समान परिणाम है, सिवाय GPU के कि उन क्वाड्स को मक्खी पर ही त्रिकोण में बदलना होगा।

आधुनिक (3.2+) ओपनजीएल एक अलग दृष्टिकोण लेता है। यह त्वरित पहुँच के लिए GPU मेमोरी में शीर्ष डेटा को बफ़र करता है, और फिर आप glDrawArrays या glDrawElements का उपयोग करके या तो ड्राइंग निर्देश भेज सकते हैं। आपके पास प्रोग्राम करने योग्य पाइपलाइन (ग्लूसेप्रोग्राम) भी है जो आपको यह बताने की अनुमति देता है कि जीपीयू की स्थिति और रंगों को कैसे अनुकूलित किया जाए।

कुछ कारण हैं कि तत्काल मोड को हटा दिया गया था, मुख्य कारण प्रदर्शन था। जैसा कि शॉन ने अपने जवाब में कहा, आजकल GPU डेटा को तेजी से क्रंच कर सकता है, सीपीयू इसे अपलोड कर सकता है, इसलिए आप GPU प्रदर्शन को टोंटी मारेंगे। आपके द्वारा की गई OpenGL के लिए हर कॉल के लिए एक छोटा सा ओवरहेड शामिल है, यह मिनीस्कुल है लेकिन जब आप हर कॉल के दसियों हज़ारों को बना रहे होते हैं तो यह स्टैक होने लगता है। सीधे शब्दों में कहें, तो तत्काल मोड का उपयोग करके एक बनावट वाले मॉडल को खींचने के लिए, आपको प्रति फ्रेम कम से कम 2 कॉल प्रति वर्टेक्स (glTexCoord2f और glVertex3f) की आवश्यकता होती है। आधुनिक OpenGL के साथ आप डेटा को बफ़र करने के लिए प्रारंभ में कुछ कॉल का उपयोग करते हैं, फिर आप पूरे मॉडल को ड्रा कर सकते हैं, चाहे इसके कितने भी वर्टिकल हों, सिर्फ़ कुछ कॉल का उपयोग करके वर्टेक्स ऐरे ऑब्जेक्ट को बांधने के लिए, कुछ विशेषता बिंदुओं को सक्षम करें फिर glDrawElements या glDrawArrays पर एक कॉल।

कौन सी तकनीक सही है? ठीक है कि आप क्या करने की कोशिश कर रहे हैं पर निर्भर करता है। एक साधारण 2 डी गेम जिसमें किसी भी फैंसी पोस्ट-प्रोसेसिंग तकनीक या शेड की आवश्यकता नहीं होती है, बस तत्काल मोड का उपयोग करके ठीक काम करेगा और कोड लिखना संभवतः आसान होगा। हालांकि, एक अधिक आधुनिक 3D गेम वास्तव में संघर्ष करेगा, और यदि आप GLSL (shader भाषा) सीखने की योजना बना रहे हैं, तो निश्चित रूप से आधुनिक तकनीक सीखें।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.