GlDrawArrays और GlDrawElements में अंतर


12

OpenGL ES पर अपने दिमाग को ताज़ा करते हुए, मैं भर में आया glDrawArraysऔर glDrawElements

मैं समझता हूं कि उनका उपयोग कैसे किया जाता है और यह समझने का तरीका है कि वे अलग-अलग क्यों हैं।

क्या मुझे समझ में नहीं हैं, मैं कैसे को देखने के लिए असफल कि है glDrawElementsकॉल आकर्षित बचा सकता है ( ड्रा कॉल से बचा एक वर्णन है कि, किताबें मैंने पढ़ा है की सबसे अधिक से उल्लेख किया गया है और इसलिए मेरे यहाँ यह उल्लेख है)।

एक सरल परिदृश्य की कल्पना करें जिसमें मैंने 2 त्रिकोणों का उपयोग करके एक वर्ग खींचने की कोशिश की।

उपयोग glDrawArraysकरते समय glDrawElementsमुझे 6 छोरों का एक सेट होना चाहिए , मुझे एक सूचकांक सरणी के अलावा केवल 4 की आवश्यकता होगी जिसमें 6 तत्व हैं।

उपरोक्त को देखते हुए, यहाँ वह है जो मुझे समझ में नहीं आता है:

  1. glDrawElementsड्रा कॉल को कैसे बचाया जा सकता है , अगर इसे अभी भी मेरे वर्टेक्स ऐरे में इंडेक्स सरणी (6 इंडेक्स, एक वर्ग के मामले में) का उपयोग करने की आवश्यकता है जिसमें 4 तत्व (6 बार) थे? दूसरे शब्दों में, क्या इसका मतलब यह है glDrawElementsकि अभी भी कुल 6 ड्रॉ कॉल करने की आवश्यकता होगी glDrawArrays?
  2. glDrawElementsअंतरिक्ष को बचाने का उपयोग कैसे किया जाएगा , अगर किसी को अभी भी 2 सरणियों की आवश्यकता होगी, अर्थात् एक कोने के लिए और एक सूचकांकों के लिए?
  3. 2 त्रिकोणों से एक वर्ग खींचने के मामले में, सादगी के लिए, कितने ड्रॉ कॉल करता है glDrawElements(4 वस्तुएं वर्टेक्स एरे में और 6 आइटम इंडेक्स एरे में) और glDrawArrays(6 आइटम केवल वर्टेक्स ऐरे में) व्यक्तिगत रूप से जरूरत है?

धन्यवाद।

जवाबों:


16

प्रत्येक ग्लैड्र * एक ड्रॉ कॉल है।

1 glDrawArrays 1 ड्रॉ कॉल है।
1 glDrawElements 1 ड्रॉ कॉल है।

इससे कोई फर्क नहीं पड़ता (अब तक ड्रॉ कॉल काउंट का संबंध है) आप कितने वर्टिकल या इंडेक्स का उपयोग करते हैं, 1 ग्लड्रॉव * 1 ड्रॉ कॉल है।

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

आइए थोड़ा और अधिक जटिल मामला लें, लेकिन एक जो अधिक वास्तविक दुनिया के परिदृश्य का प्रतिनिधि है। कल्पना करें कि आपके पास कई त्रिभुज स्ट्रिप्स और प्रशंसकों से बना एक मॉडल है:

glDrawArrays (GL_TRIANGLE_FAN, .....);
glDrawArrays (GL_TRIANGLE_STRIP, .....);
glDrawArrays (GL_TRIANGLE_STRIP, .....);
glDrawArrays (GL_TRIANGLE_FAN, .....);
glDrawArrays (GL_TRIANGLE_STRIP, .....);
glDrawArrays (GL_TRIANGLE_FAN, .....);

इस उदाहरण में, glDrawArrays का उपयोग करने से आपको मॉडल के लिए कुल 6 ड्रॉ कॉल मिलते हैं। हालांकि, दोनों स्ट्रिप्स और प्रशंसकों को आसानी से अनुक्रमित त्रिकोण में परिवर्तित किया जा सकता है, इसलिए सूचकांक जोड़ें और यह हो जाता है:

glDrawElements (GL_TRIANGLES, .....);

वह पूरे मॉडल के लिए एक ड्रॉ कॉल है।


GlDrawArrays पर glDrawElements के फायदे सिर्फ मेमोरी सेविंग से ज्यादा हैं, जो इसे मापने का भोला तरीका है। नहीं है संभावित क्योंकि एक सूचकांक आम तौर पर एक शिखर (ताकि भले ही आप संतुलन पर सूचकांक के बहुत सारे है वे छोटे हो जाएगा) से छोटी है, स्मृति की बचत जहां कोने पुन: उपयोग किया जा सकता है के लिए है, लेकिन अन्य लाभ शामिल हैं:

  • कम की गई कॉल की गिनती। प्रत्येक आह्वान में कुछ ओवरहेड को राज्य से मान्य करने, चीजों को स्थापित करने, आदि के बारे में बताया जाता है, और इस ओवरहेड का अधिकांश भाग सीपीयू की तरफ होता है। ड्रॉ कॉल की संख्या को कम करके हम इस ओवरहेड से बहुत अधिक बचते हैं।

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


तो अपने विशिष्ट सवालों के जवाब देने के लिए:

  1. कैसे glDrawElements ड्रा कॉल को बचा सकता है ...? आपके द्वारा उपयोग किए जाने वाले उदाहरण में, यह नहीं है। प्रत्येक में एक ड्रॉ कॉल है। जैसा कि मैं ऊपर चर्चा करता हूं, यह उदाहरण दोनों की तुलना करने के लिए बहुत बुरा है।

  2. GlDrawElements का उपयोग करके अंतरिक्ष को कैसे बचाया जाएगा ...? क्योंकि सूचकांक लंबों की तुलना में छोटे होते हैं। एक 16-बिट इंडेक्स दो बाइट्स है, एक स्थिति / रंग / टेक्सकोर्ड शीर्ष 24 बाइट्स है। 6 कोने 144 बाइट्स हैं, 4 कोने प्लस 6 सूचकांक 108 बाइट्स हैं।

  3. 2 त्रिकोणों से एक वर्ग खींचने के मामले में ...? एक और एक। एक glDraw * कॉल वन ड्रॉ कॉल है, इस माप के लिए उपयोग किए जाने वाले वर्टिस या सूचकांकों की संख्या अप्रासंगिक है। लेकिन मुझे फिर से जोर देना चाहिए, दोनों की तुलना करने के लिए यह बहुत बुरा उदाहरण है।


अंत में, और बस मामलों को थोड़ा जटिल करने के लिए, जबकि त्रिकोण के साथ glDrawElements डेस्कटॉप जीपीयू पर इष्टतम पथ है, मोबाइल पर यह बहुत अलग हो सकता है। कुछ मोबाइल GPU GL_TRIANGLE_STRIP के साथ glDrawArrays पसंद कर सकते हैं (आप इस मामले में आदिमों को छिपाने के लिए पतले त्रिकोण जोड़ सकते हैं), और मैंने आदिम पुनरारंभ या बहु-ड्रा जैसे अधिक उन्नत विषयों पर भी नहीं छुआ है।


आपकी प्रतिक्रिया के लिए हार्दिक धन्यवाद; आपने जो कुछ साझा किया है उसे पढ़कर मुझे थोड़ा समय लग रहा है। बस आपको बताना चाहता हूं कि मैंने आपकी प्रतिक्रिया स्वीकार कर ली है। एक बार फिर धन्यवाद।
उन्हेलिग

6 DrawTriangleFans और DrawTriangleStrips 1 सिंगल ड्राट्रायंगल कॉल में कनवर्ट करने के अपने उदाहरण में। क्या यह वास्तव में कुछ प्रदर्शन में सुधार करता है? मेरी समझ में 100 त्रिकोणों से मिलकर एक त्रिभुज पट्टी खींचना व्यक्तिगत रूप से 100 त्रिकोण खींचने की तुलना में बहुत अधिक कुशल है, और लाभ आसानी से 1 के बजाय 6 फ़ंक्शन कॉल का उपयोग करने से होने वाले किसी भी दंड को ऑफसेट करेगा
शमूएल ली

@SamuelLi 6-to-1 एक बहुत बड़ा सुधार नहीं होगा, यह केवल सिद्धांत को दर्शाने के लिए है। इसके अलावा, और जैसा कि मैंने संकेत दिया, स्ट्रिप्स आमतौर पर 1998 के बाद के डेस्कटॉप हार्डवेयर पर अनुक्रमित सूचियों पर एक प्रदर्शन जीत नहीं है। स्ट्रिप्स का उपयोग करने की सलाह देने वाले किसी भी दस्तावेज़ पर तारीख की जांच करें।
मैक्सिमस मिनिमस

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