5

मैं वर्तमान में जीएलटूल कक्षाओं का उपयोग कर रहा हूं जो सुपरबेल 5 वें संस्करण के साथ आते हैं। मैं GLTriangleBatch कक्षा में देख रहा हूँ और यह निम्नलिखित कोड है:ओपनजीएल वेरटेक्स बफर ऑब्जेक्ट, क्या मैं टक्कर का पता लगाने जैसे अन्य उपयोगों के लिए वर्टेक्स डेटा तक पहुंच सकता हूं?

// Create the master vertex array object 
glGenVertexArrays(1, &vertexArrayBufferObject); 
glBindVertexArray(vertexArrayBufferObject); 


// Create the buffer objects 
glGenBuffers(4, bufferObjects); 

#define VERTEX_DATA  0 
#define NORMAL_DATA  1 
#define TEXTURE_DATA 2 
#define INDEX_DATA  3 

// Copy data to video memory 
// Vertex data 
glBindBuffer(GL_ARRAY_BUFFER, bufferObjects[VERTEX_DATA]); 
glEnableVertexAttribArray(GLT_ATTRIBUTE_VERTEX); 
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*nNumVerts*3, pVerts, GL_STATIC_DRAW); 
glVertexAttribPointer(GLT_ATTRIBUTE_VERTEX, 3, GL_FLOAT, GL_FALSE, 0, 0); 

// Normal data 
glBindBuffer(GL_ARRAY_BUFFER, bufferObjects[NORMAL_DATA]); 
glEnableVertexAttribArray(GLT_ATTRIBUTE_NORMAL); 
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*nNumVerts*3, pNorms, GL_STATIC_DRAW); 
glVertexAttribPointer(GLT_ATTRIBUTE_NORMAL, 3, GL_FLOAT, GL_FALSE, 0, 0); 

// Texture coordinates 
glBindBuffer(GL_ARRAY_BUFFER, bufferObjects[TEXTURE_DATA]); 
glEnableVertexAttribArray(GLT_ATTRIBUTE_TEXTURE0); 
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*nNumVerts*2, pTexCoords, GL_STATIC_DRAW); 
glVertexAttribPointer(GLT_ATTRIBUTE_TEXTURE0, 2, GL_FLOAT, GL_FALSE, 0, 0); 

// Indexes 
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferObjects[INDEX_DATA]); 
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLushort)*nNumIndexes, pIndexes, GL_STATIC_DRAW); 

// Done 
glBindVertexArray(0); 

// Free older, larger arrays 
delete [] pIndexes; 
delete [] pVerts; 
delete [] pNorms; 
delete [] pTexCoords; 

// Reasign pointers so they are marked as unused 
pIndexes = NULL; 
pVerts = NULL; 
pNorms = NULL; 
pTexCoords = NULL; 

मैं क्या समझ कोड सरणियों गुजरता से कि संकेत pVerts, pNorms, pTexCoords, pIndexes और एक शीर्ष सरणी वस्तु में दुकानों उन्हें, जो अनिवार्य रूप से vertex बफर वस्तुओं की एक सरणी है। ये GPU पर स्मृति में संग्रहीत हैं। मूल पॉइंटर्स को हटा दिया जाता है।

मुझे वर्टेक्स पदों तक पहुंचने में दिलचस्पी है, जो सरणी पीवीर्ट में आयोजित की गई थीं।

अब मेरा प्रश्न टकराव का पता लगाने के आसपास घूमता है। मैं अपने GLTriangleBatch के सभी शीर्षकों की एक सरणी तक पहुंचने में सक्षम होना चाहता हूं। क्या मैं उन्हें बाद में vertexBufferObject के माध्यम से किसी प्रकार की गेटर विधि का उपयोग कर प्राप्त कर सकता हूं? क्या केवल पीवीर्ट्स पॉइंटर को चारों ओर रखना और इसके बजाय गेटटर विधि का उपयोग करना सबसे अच्छा होगा? मैं, प्रदर्शन के मामले में सोच रहा हूँ के रूप में मैं भविष्य में एक GJK टक्कर पता लगाने एल्गोरिथ्म लागू करने के लिए आशा है कि ...

उत्तर

7

बफर वस्तुओं, जब शिखर डेटा के लिए स्रोत के रूप में इस्तेमाल किया, प्रतिपादन के लाभ के लिए मौजूद हैं। पीछे की तरफ जाना (डेटा को वापस पढ़ना) आमतौर पर प्रदर्शन बिंदु से सलाह नहीं दी जाती है।

ग्लिफर डैटा देने के संकेत में तीन पहुंच पैटर्न हैं: ड्रॉ, रीड, और कॉपी; ये OpenGL को बताते हैं कि आप बफर ऑब्जेक्ट से सीधे डेटा प्राप्त करने/पुनर्प्राप्त करने का इरादा रखते हैं। संकेत यह नहीं मानते कि ओपनजीएल को कैसे पढ़ना/लिखना चाहिए। ये सिर्फ संकेत हैं; एपीआई किसी भी विशेष व्यवहार को लागू नहीं करता है, लेकिन उनका उल्लंघन करने से खराब प्रदर्शन हो सकता है।

ड्रैव का अर्थ है कि आप डेटा को बफर में डाल देंगे, लेकिन आप इससे नहीं पढ़ेंगे। पढ़ने का मतलब है कि आप बफर से डेटा पढ़ेंगे, लेकिन आप इसे नहीं लिखेंगे (आमतौर पर फीडबैक या पिक्सेल बफर बदलने के लिए)। और कॉपी का मतलब है कि आप न तो बफर को सीधे पढ़ेंगे और न ही लिखेंगे।

ध्यान दें कि "पढ़ने और लिखने" के लिए कोई संकेत नहीं है। बस "लिखना", "पढ़ा", और "न तो" है। इस बात पर विचार करें कि एक बफर को सीधे डेटा लिखना कितना अच्छा है और फिर उस बफर से पढ़ना शुरू करें।

फिर, संकेत सीधे उपयोगकर्ता को डेटा प्राप्त करने या पुनर्प्राप्त करने के लिए हैं। glBufferData, glBufferSubData, और विभिन्न मैपिंग फ़ंक्शन सभी लिखते हैं, जबकि glGetBufferSubData और मैपिंग फ़ंक्शंस सभी पढ़ते हैं।

किसी भी मामले में नहीं, आपको यह नहीं करना चाहिए। यदि आपको क्लाइंट पर इसका उपयोग करने की आवश्यकता है तो क्लाइंट मेमोरी में स्थिति डेटा की प्रतिलिपि रखें।

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

हालांकि, अगर आप ऐसा करने का आग्रह करते हैं, तो बफर ऑब्जेक्ट से डेटा पढ़ने के दो तरीके हैं। glGetBufferSubDataglBufferSubData के विपरीत है। और आप हमेशा लिखने के बजाय बफर को पढ़ने के लिए मानचित्र बना सकते हैं।

+1

धन्यवाद! वह प्रतिक्रिया बहुत उपयोगी थी! मैं बाद में कशेरुक डेटा तक पहुंचने के लिए पीवीर्ट पॉइंटर को रखूंगा। – kbirk

+0

@ user785259: केवल पॉइंटर रखना पर्याप्त नहीं है। आपको वास्तव में आवंटित स्मृति को अवश्य रखना चाहिए, यानी 'हटाएं [] 'या' मुक्त (...) 'नहीं। स्मृति जारी करने के बाद भी आपके पास सी में सूचक हो सकता है, जो तब अमान्य है। हो सकता है कि आप एक कचरा एकत्रित भाषा से आ रहे हैं, फिर एक पॉइंटर को छोड़कर वास्तव में स्मृति जारी करने का तात्पर्य है, और हां, यह सैवे अर्थपूर्ण है। लेकिन यह सी ++ है जिसके साथ आप काम कर रहे हैं और यह सब नाइटपिकिंग एक अपरिहार्य आवश्यकता है। – datenwolf