2012-01-21 18 views
7

मेरी मौजूदा प्रोजेक्ट को अपग्रेड करने के लिए आधुनिक ओपनजीएल के बारे में खोज और पढ़ने के बाद, मैं थोड़ा उलझन में हूं, क्योंकि मेरा 3 डी फ्रेमवर्क ओपनजीएल 2.1 पर आधारित है।आधुनिक ओपनजीएल: वीबीओ, जीएलएम और मैट्रिक्स स्टैक्स

हां, जहां तक ​​मैं जानने के रूप में ...

  • हम कोने, सूचकांक, Normals, रंग, uvs से हमारे वर्टेक्स-बफर-वस्तुओं को उत्पन्न करने की जरूरत है, आदि

  • तो हम मैट्रिक्स परिवर्तन के लिए GLM उपयोग कर सकते हैं, और हम केवल बना सकते हैं या meshes में हेरफेर करने के VBO उपयोग करते हैं, अंत में हम इस तरह GLSL शिखर शेडर में सब कुछ पारित ...

    glm::mat4 MVP = projection * view * model; 
    glUniformMatrix4fv(glGetUniformLocation(shaderProgramID, "MVP"), 1, GL_FALSE, glm::value_ptr(MVP)); //or &MVP[0][0] 
    
    // uniform mat4 MVP; 
    // in vec3 Vertex; 
    // void main(void) 
    // { 
    // gl_Position = MVP * vec4(Vertex, 1.0); //instead of ftransform(); 
    // } 
    

प्रश्न: हम pushMatrix/popMatrix के बिना पदानुक्रमित परिवर्तन कैसे करते हैं? (या हो सकता है कि हम अपने वीबीओ का उपयोग करके पदानुक्रमित परिवर्तन करते हैं, क्या यह संभव है?)

यदि संभव नहीं है, तो GLM और C++ < स्टैक> लाइब्रेरी का उपयोग करके पुशमैट्रिक्स/पॉपमैट्रिक्स के समान परिणाम कैसे प्राप्त करें?

चलें कहते हैं कि मैं कुछ इस तरह की जरूरत है:

> Set identity 
> Translate to X, Y, Z 
> Draw Mesh 1 
> Rotate 0.5 by X axis 
> Draw Mesh 2 
> Scale down to 0.1 
> Draw Mesh 3 
+1

@ BЈовић: [ओपनजीएल गणित (जीएलएम)] (http://glm.g-truc.net/), मैट्रिक्स/वेक्टर गणित के लिए हेडर-केवल सी ++ लाइब्रेरी। – genpfault

उत्तर

5
  • हम कोने, सूचकांक, Normals, रंग, uvs से हमारे वर्टेक्स-बफर-वस्तुओं को उत्पन्न करने की जरूरत है, आदि

यह वास्तव में VBOs उपयोग करने के लिए आवश्यक नहीं है, क्लाइंट साइड वेरटेक्स Arrays भी काम करते हैं। हालांकि, वीबीओ का उपयोग करने की दृढ़ता से अनुशंसा की जाती है, क्योंकि यह ड्राइवर का जीवन आसान बनाता है और लंबे समय तक भी आपके डेटा को जोड़ना होता है। कोड ओवरहेड उपेक्षित है (यह बनावट डेटा बनाने और अपलोड करने जैसा ही है) और प्रदर्शन केवल बढ़ेगा।

  • तो हम मैट्रिक्स परिवर्तन के लिए GLM उपयोग कर सकते हैं, और हम केवल बना सकते हैं या meshes में हेरफेर करने के VBO उपयोग करते हैं, अंत में हम इस तरह GLSL शिखर शेडर में सब कुछ पारित ...

आप जीएलएम तक सीमित नहीं है। कोई भी मैट्रिक्स गणित पुस्तकालय करेगा। यदि आप कुछ ऐसा ढूंढ रहे हैं जिसे आप सी 99 में उपयोग कर सकते हैं, तो मेरे (अभी भी अपूर्ण) linmath.hhttps://github.com/datenwolf/linmath.h पर एक नज़र डालें जो static inline फ़ंक्शंस के साथ केवल एक हेडर फ़ाइल है।कोड डिप्लिकेशन के प्रदर्शन पर नकारात्मक प्रभाव पड़ने पर मुझे अभी तक बेंचमार्क नहीं करना है (कोड आकार एल 1 कैश दबाव बनाता है)।

प्रश्न: हम pushMatrix/popMatrix बिना श्रेणीबद्ध परिवर्तनों कर कैसे?

VBOs इस से कोई मतलब नहीं है (या शायद हम अपने VBOs का उपयोग करके श्रेणीबद्ध परिवर्तन करते हैं, यह संभव है?)। पुरानी शैली वाली ओपनजीएल मुसीबत के अधिकांश उपयोगकर्ताओं को उन मैट्रिक्स स्टैक फ़ंक्शन हैं जो ओपनजीएल को एक दृश्य ग्राफ की तरह दिखते हैं। लेकिन यह नहीं है।

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

worldtransform -> 
    pelvis -> 
     left upper leg -> left lower leg -> left foot 
     right upper leg -> right lower leg -> right foot 
    torso -> 
     neck -> head -> 
      left eye 
      right eye 
      facial deformation // this is a whole chapter of it's own 
     left upper arm -> left lower arm -> left hand 
     right upper arm -> right lower arm -> right hand 

हर आप इस तरह के एक पदानुक्रम में एक -> enounter की तरह एक चरित्र का कंकाल एनीमेशन की तरह deformables के लिए की जरूरत है आप मैट्रिक्स की एक प्रतिलिपि बनाने और है कि एक पर काम कर आगे बढ़ें। पेड़ के उच्च स्तर पर वापस गिरते समय आप उस मैट्रिक्स से फिर से काम करना शुरू कर देते हैं।

+1

"चेहरे की विकृति" // यह अपने स्वयं के => जबड़े ड्रॉप शामिल है उसका पूरा अध्याय है :) – mlvljr

4

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

[आपके संपादित प्रश्न पर]: आपको इसके लिए एक स्टैक की आवश्यकता नहीं है, और कोई पदानुक्रमित परिवर्तन नहीं है। बस एक एकल मैट्रिक्स है और अपना अनुवाद लागू करें, ड्रा करें, इसे अपने रोटेशन मैट्रिक्स के साथ गुणा करें, ड्रा करें, अपनी स्केलिंग गुणा करें, ड्रा करें।

+1

एर? यदि आपके पास प्रारंभिक मैट्रिक्स एम है, और अनुवाद टी, रोटेशन आर, और स्केल एस है, तो आपका पहला मैट्रिक्स एम = टी है, दूसरा एम * = आर = (टी * आर == अनुवाद पहले, रोटेशन दूसरा है), और तीसरा एम * = एस = (टी * आर * एस == सभी मैट्रिस है।) रोबोट बांह के लिए, आप अपने पेड़ को नीचे जाने के दौरान शीर्ष पर भी शुरू कर सकते हैं और ड्रॉ कॉल जारी कर सकते हैं। इससे कोई फर्क नहीं पड़ता कि "स्टैक" एक std :: स्टैक है या आपके रिकर्सिव दृश्य ट्रैवर्सल रूटीन का हिस्सा है। – Anteru

+0

यदि आप एम * = एस नहीं करते हैं, लेकिन बस एम * एस (प्रतिलिपि!) का उपयोग करें तो मूल मैट्रिक्स बदल नहीं है। आपका ढेर इस तरह दिखेगा: [एम], फिर आप टी को दबाते हैं (जिसके परिणामस्वरूप एक स्टैक [एम, एम * टी]) होता है, फिर आप पॉप ([एम]), फिर फिर से दबाएं आर ([एम, एम * आर])। मुझे आपकी समस्या नहीं है? – Anteru

+0

अपनी टिप्पणियों के अर्थ को संपादित करना बंद करें। मैंने कहा कि आप इसे एक स्टैक के माध्यम से कार्यान्वित कर सकते हैं, या आप अपने मैट्रिस को अपने रिकर्सिव ड्रॉ फ़ंक्शन के अंदर कॉपी कर सकते हैं (जो स्पष्ट रूप से एक स्टैक बनाता है।) [एम, ..] _ एक स्टैक_ है, अगर आप इसे चाहते हैं, तो बस इसका इस्तेमाल करें । लेकिन आप बिना किसी std :: स्टैक के आसानी से दूर हो सकते हैं। – Anteru

4

यदि आपका प्रतिपादन पहले से ही पदानुक्रमित रूप से उपयोग होता है, उदाहरण के लिए, फ़ंक्शन रिकर्सन तो आपके पास पहले से ही मैट्रिक्स स्टैक है!

void renderMesh(Matrix transform, Mesh mesh) 
{ 
    // here call glDrawElements/glDrawArrays and send transform matrix to MVP uniform 
    mesh->draw(transform); 

    // now render all the sub-meshes, then will be transformed relative to current mesh 
    for (int i=0; i<mesh->subMeshCount(); i++) 
    { 
     Matrix subMeshTransform = mesh->getSubMeshTransform(i); 
     Mesh subMesh = mesh->getSubMesh(); 

     renderMesh(subMeshTransform * transform, subMesh); 
    } 
} 

// somwhere in main function 
... 
Matrix projection = Matrix::perspective(...); 
Matrix view = camera->getViewMatrix(); 

Matrix transform = view * projectIon; 
renderMesh(transform, rootMesh); 
0

VAO और VBO प्रदर्शन के संबंध में मैं इससे सहमत नहीं है कि VBO तेजी से होता है, मैं इस लिंक

http://www.openglsuperbible.com/2013/12/09/vertex-array-performance/

आपको लगता है कि ऊपर दिए गए परिणामों से देख सकते हैं, कम से कम हमारे छोटा सा नमूना सेट के लिए देखने के लिए सुझाव देते हैं , सभी कार्यान्वयन पर वीएओ तेज है। इसका कारण यह है कि glbindVertexArray को glbindBuffer या glVertexAttribPointer से कॉल करते समय मान्य करने के लिए कम पैरामीटर हैं। यहां तक ​​कि जब केवल एक ही वर्टेक्स विशेषता होती है, तब भी वैश्विक वीएओ के स्पष्ट अपडेट की तुलना में वीएओ स्विच के साथ ओपनजीएल में आधे से ज्यादा कॉल होते हैं। स्पष्ट "कम एपीआई कॉल का अर्थ तेजी से निष्पादन" संबंध के अलावा, वीएओ एक ऐसा स्थान है जहां ओपनजीएल चालक अंतर्निहित जीपीयू प्रोग्राम करने के लिए आवश्यक जानकारी को रोक सकता है। GPU को भेजे गए राज्य परिवर्तनों की कुल राशि वही तरीका है।

+0

यह प्रश्न से संबंधित कैसे है? –

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