2012-02-19 12 views
13

में एक ही ऑब्जेक्ट को जल्दी से ड्रा करें इसलिए मैं एक गेम पर काम कर रहा हूं और मुझे एक ही ऑब्जेक्ट को आकर्षित करने की आवश्यकता है। वही आकार, एक ही आकार, एक ही रंग, बस अलग-अलग स्थान।ओपनजीएल

अभी मेरा सेटअप इस तरह है।

मैं कुछ वर्ग Renderer है जहां उद्देश्य यह है कि स्क्रीन पर आकर्षित करने के लिए static void addVertex(float x, float y, float z); जो एक std::vector में शीर्ष स्टोर करेगा कॉल कर सकते हैं चाहता हूँ। Renderer में static void draw(); ड्राइंग करते समय सभी को बुलाया जाता है, जहां सब कुछ एक वीबीओ में भर जाता है और स्क्रीन पर खींचा जाता है।

ड्रा इस तरह दिखता है:

void Renderer::draw() { 
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, _quadID); 
    glBufferSubDataARB(GL_QUADS, 0, _vertexBuffer.dataSize(), _vertexBuffer.toArray()); 

    glColorPointer(4, GL_FLOAT, 0, _colorBuffer.toArray()); 

    glEnableClientState(GL_VERTEX_ARRAY); 
    glEnableClientState(GL_COLOR_ARRAY); 
    glVertexPointer(3, GL_FLOAT, 0, _vertexBuffer.toArray()); 

    glDrawArrays(GL_QUADS, 0, (_vertexBuffer.size()/3)); 
    glDisableClientState(GL_VERTEX_ARRAY); 
    glDisableClientState(GL_COLOR_ARRAY); 

    glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); 

    _vertexBuffer.clear(); 
    _colorBuffer.clear(); 
} 

कहाँ _vertexBuffer और _colorBuffer एक वर्ग template <class T> Buffer को कमोबेश एक प्रबंधित मेरी प्रयोजनों के लिए std::vector<T> है के हैं।

इस सेटअप के साथ मैं धीमा होने से पहले स्क्रीन पर लगभग 300 चीजें प्राप्त कर सकता हूं। अभी सब कुछ एक GL_QUAD है। ध्यान रखें मैं ओपनजीएल के लिए थोड़ा नया हूं, अगर उपरोक्त शर्मनाक है तो मुझे खेद है।

बहुभुजों के लिए खाते में इसे कैसे सुधार सकता हूं?

उत्तर

21

~ आधुनिक हार्डवेयर पर, instancing जाने का रास्ता है।

विचार यह है कि आप अपने GPU को एक बार (एक ड्रॉ कॉल) पर ज्यामिति भेजते हैं, यह निर्दिष्ट करते हुए कि आप कितने उदाहरण आकर्षित करना चाहते हैं (primCount पैरामीटर)।

फिर कशेरुक शेडर में आप अंतर्निहित इनपुट चर gl_InstanceID का उपयोग कर सकते हैं यह जानने के लिए कि कौन सा उदाहरण प्रस्तुत किया जा रहा है और उसके बाद उचित परिवर्तन का उपयोग करें। इस दृष्टिकोण का तात्पर्य है कि आपको अपने सभी उदाहरणों के लिए वर्टेक्स शेडर में परिवर्तन होना चाहिए, उदाहरण के लिए Uniform Buffer Object में।

संपादित करें: glVertexAttribDivisor फ़ंक्शन इंस्टेंसिंग के साथ बहुत उपयोगी है; यह मूल रूप से प्रति प्रति-उदाहरण विशेषताओं के साथ कुछ प्रति-चरम विशेषताओं को एक साथ रखने की अनुमति देता है।

+0

धन्यवाद, मैं निश्चित रूप से इसे आजमाउंगा! जब मैं शोध कर रहा था तब मैंने इसके बारे में थोड़ा सा देखा। – SpaceFace

+0

[यह] (http://hacksoflife.blogspot.it/2013/04/there-must-be-50-ways-to-draw-your.html) भी उपयोगी हो सकता है। – sbabbi

+0

यह बहुत उपयोगी था, बहुत बहुत धन्यवाद! – SRG

1

ओपनजीएल में सुंदर चीज़ है, जिसे Display list कहा जाता है। नेहे उत्पादन में tutorial है जो सभी आवश्यक जानकारी और उदाहरण प्रदान करना चाहिए। लेकिन मूल रूप से:

GLuint displayList; // This should be class attribute 
displayList = glGenLists(1);  
glNewList(displayList,GL_COMPILE); 
Renderer::draw(); 
glEndList(); 

और वास्तविक ड्रॉ विधि बस में:

glCallList(displayList); 

मत भूलना precompiled प्रदर्शन सूची हर बार जब आप जोड़ने यथार्य करने के लिए/कुछ को हटा दें।

+2

प्रदर्शन सूची? Ooold :(, आधुनिक ओपनजीएल में बहिष्कृत। कभी-कभी उपयोगी – Kos

+0

@ कोस हे, मुझे नहीं पता था कि यह बहिष्कृत है: - /// क्या कोई विकल्प है? या ऐसा कुछ? – Vyktor

+1

उन्हें ओपनजीएल 3.x में कहीं हटा दिया गया है , लेकिन अगर आपको वास्तव में उनकी ज़रूरत है तो संगतता प्रोफाइल में अभी भी उपलब्ध हैं। फिर भी, वे शायद हार्डवेयर का उपयोग करने का सबसे अच्छा तरीका नहीं हैं, यानी इस मामले में आपको अभी भी प्रत्येक ऑब्जेक्ट के लिए एक ड्रॉ कॉल की आवश्यकता है। – Kos