2011-10-11 21 views
5

के रूप में काम नहीं कर रहा है मैं ओपनजीएल में एक स्काईबॉक्स के अंदर रोलरकोस्टर बना रहा हूं, और इसके कार्यों या कंप्यूटर ग्राफिक्स पर बहुत अधिक पृष्ठभूमि के बिना यह बहुत मुश्किल साबित हो रहा है। मैंने कैटमुल-रोम स्पलीन इंटरपोलेशन का उपयोग करके रोलरकोस्टर खींचा, और प्रत्येक बिंदु को glVertex3f के साथ खींचा। अब मैं ट्रैक के चारों ओर कैमरे को स्थानांतरित करने के लिए प्रत्येक 50ms पर update() फ़ंक्शन को कॉल करना चाहता हूं। gluLookAt() अजीब परिणाम उत्पन्न कर रहा है, या तो स्क्रीन से ट्रैक को हटा रहा है, एक ब्लैक स्क्रीन का उत्पादन कर रहा है। मुझे लगता है कि मुझे मैट्रिक्स कार्यों में से कुछ को स्थानांतरित करने की आवश्यकता है, लेकिन मुझे यकीन नहीं है कि प्रत्येक को कहां रखना है।ओपनजीएल gluLookAt() इच्छित

int main(int argc, char** argc) 
{ 
    // ... load track, etc ... 

    // Init currpos, nextpos, iter, up 
    currpos = Vec3f(0, 0, 0); 
    nextpos = currpos; 
    iter = 0; 
    up = Vec3f(0, 1, 0); 

    deque<Vec3f> points; 
    Vec3f newpt; 

    // Loop through the points and interpolate 
    for (pointVectorIter pv = g_Track.points().begin(); pv != g_Track.points().end(); pv++) 
    { 
     Vec3f curr(*pv);   // Initialize the current point and a new point (to be drawn) 
     points.push_back(curr);  // Push the current point onto the stack 
     allpoints.push_back(curr); // Add current point to the total stack 

     if (points.size() == 4) // Check if there are 4 points in the stack, if so interpolate 
     { 
      for (float u = 0.0f; u < 1.0f; u += 0.01f) 
      { 
       newpt = interpolate(points[0], points[1], points[2], points[3], u); 
       glColor3f(1, 1, 1); 
       glVertex3f(newpt.x(), newpt.y(), newpt.z()); 

       allpoints.push_back(newpt); 
      } 

      points.pop_front(); 
     } 
    } 

    // glutInit, InitGL(), etc... 
} 

void InitGL(GLvoid) 
{ 
    glEnable(GL_DEPTH_TEST); 
    glDepthFunc(GL_LEQUAL); 
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    gluPerspective(100.0, (GLfloat)WINDOW_WIDTH/(GLfloat)WINDOW_HEIGHT, .0001, 999999); 
    glMatrixMode(GL_MODELVIEW); 
    glClearColor(0.0f, 0.0f, 0.0f, 0.5f); 
} 

void display (void) 
{ 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 
    gluLookAt(currpos.x(), currpos.y(), currpos.z(), nextpos.x(), nextpos.y(), nextpos.z(), up.x(), up.y(), up.z()); 

    glPushMatrix(); 
    glEnable(GL_TEXTURE_2D); // Enable texturing from now on 

    /* draw skybox, this was from previous assignment and renders correctly */ 

    glPopMatrix(); 

    // now draw rollercoaster ... 

    glPushMatrix(); 
    glBegin(GL_LINE_STRIP); 

    deque<Vec3f> points; 
    Vec3f newpt; 

    for each (Vec3f pt in allpoints) 
    { 
     glColor3f(1, 1, 1); 
     glVertex3f(pt.x(), pt.y(), pt.z()); 
    } 

    glutTimerFunc(50, update, 1); 
    glEnd(); 
    glPopMatrix(); 

    // Swap buffers, so one we just drew is displayed 
    glutSwapBuffers(); 
} 

void update(int a) 
{ 
    if (iter < allpoints.size()) 
    { 
     currpos = allpoints[iter]; 
     nextpos = allpoints[iter + 1]; 

     gaze = nextpos - currpos; 
     gaze.Normalize(); 

     Vec3f::Cross3(binorm, gaze, up); 
     binorm.Normalize(); 

     Vec3f::Cross3(up, binorm, gaze); 
     up.Normalize(); 

     glutPostRedisplay(); 
    } 

    iter++; 
} 

विचार यह है कि मैं एक वैश्विक Deque allpoints कि पट्टी का नियंत्रण अंक और अंतर्वेशित अंक शामिल रख रहा हूँ है: यहाँ मेरी कोड अब तक है। एक बार यह पूरा होने के बाद, मैं प्रत्येक 50ms update() पर कॉल करता हूं, और allpoints में प्रत्येक बिंदु के साथ कैमरे को ले जाता हूं। प्रोजेक्ट के पिछले संस्करण में, मैं देख सकता था कि रोलरकोस्टर सही ढंग से खींचा जा रहा था। यह gluLookAt() है जो काम नहीं करता है कि मैं इसे कैसे करना चाहता हूं। उपर्युक्त कोड के साथ, प्रोग्राम रोलरकोस्टर के एक हिस्से के साथ स्काईबॉक्स के एक तरफ देखे हुए कैमरे के साथ शुरू होता है, और फिर update() कहा जाता है, रोलरकोस्टर गायब हो जाता है लेकिन कैमरा नहीं चलता है। मैं ओपनजीएल मैट्रिक्स फ़ंक्शंस डाल रहा हूं, जहां मैं कभी-कभी update() पर एक रिक्त स्क्रीन का कारण बनता हूं, इस पर निर्भर करता हूं।

उत्तर

5

glPopMatrix के अभाव (जो पहले से ही देखा user971377) इसके अलावा, आप अपने ड्राइंग दिनचर्या है, जो निश्चित रूप से कोई भी परिवर्तन update विधि में modelview मैट्रिक्स पर किया था अधिलेखित कर देता है में glLoadIdentity फोन (gluLookAt का उपयोग)।

हमेशा ध्यान रखें: gluLookAt, glOrtho, gluPerspective, glTranslate, glRotate, और अन्य सभी मैट्रिक्स और परिवर्तन कार्यों हमेशा वर्तमान में चयनित मैट्रिक्स ढेर (glMatrixMode द्वारा परिवर्तित) के शीर्ष तत्व (glPush/PopMatrix द्वारा बदला) पर काम करते हैं। और वे हमेशा मौजूदा मैट्रिक्स, इसे बदलने की istead गुणा करते हैं। तो gluPerspective के लिए, आपको gluLookAt पर कॉल करने से पहले glLoadIdentity पर कॉल करना चाहिए। और पूरे कैमरे का परिवर्तन प्रतिपादन दिनचर्या, अद्यतन दिनचर्या के istead में किया जाना चाहिए।

इसके बजाय update में किसी भी जीएल परिवर्तनों करने का आप बल्कि चर जिस पर कैमरा निर्भर करता है बदल सकते हैं और display विधि में कैमरा (gluLookAt modelview मैट्रिक्स पर) स्थापित करना चाहिए। इन कार्यों के मानक उपयोग प्रदर्शित करने के लिए, अपने कोड होना चाहिए कुछ की तरह:

void display() 
{ 
    <general state setup (glClear, ...)> 

    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 
    glLookAt(camera);  //view transformation (camera) 

    //object 1 
    glPushMatrix();  //save modelview 
    glTranslate/glRotate/glScale;  //local model transformations 
    <draw object 1> 
    glPopMatrix(); 
    ... 
    //object n 
    glPushMatrix();  //save modelview 
    glTranslate/glRotate/glScale;  //local model transformations 
    <draw object n> 
    glPopMatrix(); 

    gluSwapBuffers(); 
} 

void update() 
{ 
    camera = ...; 
} 

}

+0

क्षमा करें, रोलर कोस्टर से पहले 'glPopMatrix() 'स्काईबॉक्स कोड के अंत में है (क्योंकि मैंने स्काईबॉक्स कोड शामिल नहीं किया है, इसलिए मैं इसे प्रश्न में भूल गया) - यह है कि इसे कहाँ जाना चाहिए, या रोलरकोस्टर ड्राइंग के बाद यह होना चाहिए? –

+0

@Logan जबकि नियंत्रण प्रवाह रनटाइम पर समान हो सकता है, 'glPopMatrix'' glpushMatrix' के समान दायरे में होना चाहिए, क्योंकि दोनों एकता का प्रतिनिधित्व करते हैं और हमेशा जोड़ी में आते हैं। –

+0

मेरा मतलब है, 'glPopMatrix() 'को स्काईबॉक्स कोड टिप्पणी के बाद होना चाहिए (आरसी को' glVertex3f' के साथ खींचा जाने से पहले) या लूप को 'glVertex3f' के साथ आरसी खींचने के बाद? –

0

gluLook हमेशा इसके परिणाम को वर्तमान मैट्रिक्स पर लागू नहीं करता है, जो आपके मामले में GL_MODEL_VIEW है। लेकिन जब आप अपने रोलर कोस्टर को प्रस्तुत करते हैं, तो आप उस मैट्रिक्स में पहचान लोड करते हैं, जो gluLookAt का उपयोग करके आपके द्वारा डाले गए मान को मिटा देता है।

इस मामले में, आपको मॉडल दृश्य को स्पर्श करने की आवश्यकता नहीं है। वास्तव में, GL_MODEL_VIEW मॉडल मैट्रिक्स को मैट्रिक्स द्वारा गुणा करके गुणा करता है। इस मामले में, आप glPushMatrix() के बाद glMulMatrix(myModelMatrix) और glPopMatrix() प्रस्तुत करने के बाद कर सकते हैं। इसके साथ, आप अपने दृश्य मैट्रिक्स को GL_MODEL_VIEW के अंदर रख सकते हैं और अभी भी प्रत्येक ऑब्जेक्ट

के लिए एक अलग मॉडल मैट्रिक्स का उपयोग कर सकते हैं, मैं यह भी सुझाव देता हूं कि आप फ्रेम के बाद केवल प्रक्षेपण मैट्रिक्स को बदल दें, न कि प्रत्येक फ्रेम।

0

यह एक लंबे समय के बाद से मैं ओपन छुआ हो गया है, लेकिन यहां पर कुछ बातों पर विचार करने के लिए कर रहे हैं:

    प्रत्येक कॉल के साथ
  • प्रदर्शित करने के लिए(), आप वर्तमान मैट्रिक्स तो पहचान लोड हो रहा है साथ skybox बना रहे रोलर कोस्टर खींचने के लिए मैट्रिक्स। शायद धक्का/पॉप के भीतर पहचान लोड करें ताकि आकाशबॉक्स स्थिर हो, लेकिन रोलर कोस्टर पर आपके प्रचलित ट्रान्सफॉर्मेशन लागू होते हैं।
  • क्या आपको gluPerspective और glMatrixMode को कॉल करने के लिए प्रत्येक कॉल के साथ कॉल करने की आवश्यकता है()?
  • दोबारा बिनोर्म से ऊपर और फिर बिनोर्म से ऊपर की गणना करने से आपको स्क्रीन के जेड अक्ष के चारों ओर कैमरे के घूर्णन के मामले में अप्रत्याशित परिणाम मिलेंगे।
  • gluLookAt पर कॉल अगली बार और currpos उलट है, कैमरा विपरीत दिशा में इंगित करता है।
  • (केवल राय) यह अभी भी पूरी तरह से स्थिर आकाशगंगा के साथ डरावना दिख सकता है। स्काईबॉक्स और रोलर कोस्टर ड्राइंग करते समय मिलान करने वाला कैमरा रोटेशन (लेकिन अनुवाद नहीं) बेहतर दिख सकता है।
+0

धन्यवाद, अपने सुझाव ठीक है (मुझे लगता है कि) काम कर रहा है रोलरकोस्टर ही अब कैमरे के साथ घूर्णन कर रहा है के रूप में। कैमरा स्वयं ही अभिनय कर रहा है, हालांकि यह ट्रैक का पालन नहीं करता है और अंततः नियंत्रण से बाहर निकलता है और आकाशबॉक्स के बाहर जाता है। मैंने अगलीपोज़ को घुमाया और चारों ओर घुमाया, तो शायद यह बिनोर्म/अप वेक्टर गणनाओं के कारण है? क्या आप जानते हैं कि इनकी गणना कैसे करें, क्योंकि मेरे कोड में जो कुछ है वह हमारे टीए द्वारा सुझाया गया था। –

+0

की गणना केवल कैमरा रोटियन को प्रभावित करनी चाहिए, जो इसे आकाशबॉक्स के बाहर अनुवाद करने की व्याख्या नहीं करती है। क्या आपके नियंत्रण बिंदु ओपनजीएल के समान xyz अभिविन्यास का उपयोग करते हैं? – SlightNihilism

+0

इस बीच, यदि आपके रोलर कोस्टर कभी भी चरणों के बीच बिल्कुल ऊपर या नीचे नहीं आते हैं तो आप निरंतर "ऊपर" रखने में सक्षम होना चाहिए। मैं अस्थायी रूप से रेल को भी ट्विक कर दूंगा ताकि मैं इस विधि का उपयोग तब तक कर सकूं जब तक कि मैं कैमरे की xyz स्थिति को डीबग/परीक्षण नहीं कर पाता। फिर मैं बाद में "ऊपर" की एक सुरक्षित गणना के बारे में चिंता करता हूँ। दुर्भाग्यवश, मेरे पास उस गणना के लिए हाथ की सिफारिश नहीं है। – SlightNihilism

3

अपने कोड glPushMatrix(); में देखा नहीं glPopMatrix();

बस एक विचार के साथ कहा जाता है, यह आप के साथ जारी करने के लिए कुछ हो सकता है।