2015-01-14 7 views
6

मेरे पास निम्न कार्य कोड है, हालांकि मुझे विश्वास नहीं है कि मैं एक सुरक्षित तरीके से glDeleteBuffers को कॉल कर रहा हूं। व्यवहार में यह काम कर रहा है (अब कम से कम) लेकिन जो मैं पढ़ रहा हूं उससे मुझे नहीं लगता कि इसे काम करना चाहिए।मुझे glDeleteBuffers() कब कॉल करना चाहिए?

GLuint vao_id; 
glGenVertexArrays(1, &vao_id); 
glBindVertexArray(vao_id); 

GLuint VBO; 
glGenBuffers(1, &VBO); 
glBindBuffer(GL_ARRAY_BUFFER, VBO); 
glBufferData(GL_ARRAY_BUFFER, size, data, GL_STATIC_DRAW); 

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0); 
glEnableVertexAttribArray(0); 

    //Alternate position <<---- 

//Unbind the VAO 
glBindVertexArray(0); 

//Current position <<---- 
glDeleteBuffers(1, &VBO); 

मैं वर्तमान में वीएओ को अनबाइंड करने के बाद सीधे glDeleteBuffers को कॉल कर रहा हूं। मैंने विशेषता पॉइंटर सेट करने के तुरंत बाद चिह्नित वैकल्पिक स्थिति में इसे कॉल करने का प्रयास किया है। हालांकि यह एक दुर्घटना का कारण बन गया - मेरा अनुमान यह था क्योंकि जब मैंने ड्रॉ कॉल किया था तो वहां कोई डेटा नहीं खींचा गया था क्योंकि मैंने इसे हटा दिया था।

जो चीज मुझे भ्रमित करती है वह यह है कि यह मेरे पास वर्तमान में काम करता है। मुझे चिंता है कि ए) मुझे समझ में नहीं आता कि बफर हटाए जाने पर क्या होता है और बी) कि यह केवल मौके से काम करता है और अप्रत्याशित रूप से तोड़ सकता है।

जहां तक ​​मैं समझता हूं कि glDeleteBuffers डेटा को हटा देता है इसलिए आकर्षित करने के लिए कोई डेटा नहीं होना चाहिए - लेकिन वहां है। तो मेरा दूसरा विचार यह था कि जब मैं वीएओ को दोबारा बांधता हूं तो डेटा बहाल हो जाता है, हालांकि इससे मुझे ज्यादा समझ नहीं आती है क्योंकि मैं यह नहीं कह सकता कि डेटा कहां से बहाल किया जाएगा।

क्या कोई मुझे बता सकता है कि क्या मैं glDeleteBuffer का सही उपयोग कर रहा हूं? और यदि नहीं, जहां इसे कहा जाना चाहिए (मुझे अनुमान है कि डेटा के लिए संभवतः प्रोग्राम के अंत में, और अधिक खींचना नहीं है)।

उत्तर

11

जो आप देख रहे हैं वह अच्छी तरह से परिभाषित व्यवहार है। इस से संबंधित spec के प्रमुख भाग निम्नलिखित हैं (जोर जोड़ा)।

ओपन 4.5 कल्पना में "हटाए गए वस्तुओं की 5.1.2 स्वत: बंधन खोलने"

से अनुभाग:

जब एक बफर, बनावट, या renderbuffer वस्तु हटाने के बाद, किसी भी बाँध अंक यह है से अबाध है वर्तमान संदर्भ, और को वर्तमान संदर्भ के लिए संलग्न कंटेनर ऑब्जेक्ट्स के किसी भी अनुलग्नक से अलग किया गया है, जैसा कि DeleteBuffers, DeleteTextures, और DeleteRenderbuffers के लिए वर्णित है।

और "5.1.3 हटाए गए ऑब्जेक्ट और ऑब्जेक्ट नाम जन्मों":

जब एक बफर, बनावट, नमूना, renderbuffer, क्वेरी, या सिंक वस्तु हटा दी जाती है, इसके नाम तुरंत अमान्य हो जाता है (उदाहरण के लिए अप्रयुक्त चिह्नित किया गया है), लेकिन अंतर्निहित ऑब्जेक्ट तब तक नहीं हटाया जाएगा जब तक यह उपयोग में नहीं आता है।

एक बफर, बनावट, नमूना, या renderbuffer वस्तु उपयोग में है जब निम्नलिखित शर्तें के किसी भी संतुष्ट हैं:

वस्तु किसी भी कंटेनर वस्तु

से जुड़ा हुआ है ...

वीएओ को इस मामले में वीबीओ के लिए "कंटेनर ऑब्जेक्ट" माना जाता है। इसलिए जब तक वीओओ को वीएओ में संदर्भित किया जाता है, और वीएओ स्वयं हटा नहीं जाता है, तो वीबीओ जिंदा रहता है। यही कारण है कि अंत में glDeleteBuffers() के साथ कोड का आपका संस्करण।

हालांकि, VAO वर्तमान में ही है, और आप VBO हटाते हैं, तो यह VAO से स्वचालित रूप से अबाध है।इसलिए, इसे अब वीएओ द्वारा संदर्भित नहीं किया गया है, और तुरंत हटा दिया गया है। यह उस मामले पर लागू होता है जहां आप को glVertexAttribPointer() के तुरंत बाद कॉल करते हैं।

किसी भी मामले में आईडी (उर्फ नाम) तुरंत अमान्य हो जाता है। तो आप इसे फिर से बांधने में सक्षम नहीं होंगे, और उदाहरण के लिए डेटा संशोधित करें।

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

इस कारण से, मैं व्यक्तिगत रूप से उन वस्तुओं के लिए glDelete*() पर कॉल नहीं करना चाहूंगा जिन्हें आप उपयोग करना चाहते हैं। लेकिन अन्य लोग जितनी जल्दी हो सके glDelete*() पर कॉल करना पसंद करते हैं।

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