2012-09-27 30 views
11

समस्या

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

यह समस्या अपने साथी के कंप्यूटर, एक ही कोड पर नहीं होती है।

मैं विंडोज 7 कंप्यूटर पर विजुअल स्टूडियो 2012 सी ++ एक्सप्रेस के साथ काम कर रहा हूं। मैं एक अनुभवी प्रोग्रामर नहीं हूं।

कोड

// OpenGLHandin1.cpp : Defines the entry point for the console application. 
// 

#include "stdafx.h" 
#include <GL/glut.h> 

void initView(int argc, char * argv[]){ 
    //init here 
    glutInit(&argc, argv); 
    //Simple buffer 
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA); 
    glutInitWindowPosition(100,100); 
    glutInitWindowSize(800,400); 
    glutCreateWindow("Handin 2"); 
} 
void draw(){ 

    glClearColor(0,0,0,1); 
    glClear(GL_COLOR_BUFFER_BIT); 
    //Background color 

    glPushMatrix(); 
    glLoadIdentity(); 
    glTranslatef(0.6, 0, 0); 

    glColor3f(0.8,0,0); 
    glutWireCube(1.1); //Draw the cube 
    glPopMatrix(); 

    glPushMatrix(); 
    glLoadIdentity(); 
    glTranslatef(-0.5, 0, -0.2); 

    glColor3f(0,0.8,0); 
    glutWireCube(1.1); //Draw the cube 
    glPopMatrix(); 

    glPushMatrix(); 
    glLoadIdentity(); 
    glTranslatef(0, 1.2, 0); 
    glRotatef(90, 1, 0, 0); 

    glColor3f(1,1,1); 
    glutWireSphere(0.6, 20, 20); //Draw the sphere 
    glPopMatrix(); 

    //draw here 
    //glutSwapBuffers(); 
    glutPostRedisplay(); 
    glFlush(); 

} 
void reshape (int w, int h){ 
    glViewport(0,0,w ,h); 
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    gluPerspective(45, (float)w/(float)h, 1.5, 10); 
    gluLookAt(1.5, 2.5, 4, 
       0, 0.6, 0, 
       0, 1, 0); //Orient the camera 
    glRotatef(5, 0, 0, 1); 
    glMatrixMode(GL_MODELVIEW); 
} 
int main(int argc, char * argv[]) 
{ 
    initView(argc,argv); 
    glutDisplayFunc(draw); 
    glutReshapeFunc(reshape); 
    glutMainLoop(); 
} 
+1

बस एक अनुमान है, लेकिन शायद आपके 'ड्रा' फ़ंक्शन –

+1

में 'नींद (1) 'जोड़ने का प्रयास करें जो वास्तव में काम करता है! क्या आप इस काम के लिए तकनीकी कारण जानते हैं और मुझे अपने साथी छात्रों की आवश्यकता क्यों है? – aPerfectMisterMan

उत्तर

10

समाधान:

ऐसा लगता है कि समारोह प्रस्तुत करना में Sleep(1) का उपयोग कर सरल उपाय काम किया। आप यह भी पूछा है कि क्यों - मुझे यकीन है कि मैं इस को ठीक से हल करने में सक्षम हो जाएगा नहीं कर रहा हूँ, लेकिन यहाँ मेरी सर्वश्रेष्ठ अनुमान दिया है:

क्यों यह और भी काम करता है?

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

अब, यदि आप लंबवत सिंक को अक्षम करते हैं, तो प्रोग्राम जितना संभव हो उतना फ्रेम प्रस्तुत करने का प्रयास करेगा, प्रभावी रूप से अन्य सभी प्रक्रियाओं को छेड़छाड़ कर देगा। मैंने आपको नींद का उपयोग करने का सुझाव दिया है, क्योंकि यह इस विशेष मुद्दे को प्रकट करता है। यह वास्तव में अगर यह 1 या 3 एमएस, क्या यह वास्तव में करता कहना है कोई प्रभाव नहीं पड़ेगा "हे, सीपीयू, मैं नहीं विशेष रूप से अभी कुछ भी कर रहा हूँ, तो आप अन्य बातों के कर सकते हैं"।

लेकिन क्या यह मेरे कार्यक्रम को धीमा नहीं कर रहा है?

नींद का उपयोग करना एक आम तकनीक है। आपको लगता है कि के साथ संबंध 1 एमएस हर फ्रेम कर रहे हैं खो, आप भी Sleep(0) डाल, के रूप में यह बिल्कुल वैसा ही कार्य करना चाहिए कोशिश कर सकते हैं - सीपीयू के लिए खाली समय दे रही है। यदि आप वास्तव में मेरा अनुमान सही था तो आप लंबवत सिंक को सक्षम करने और सत्यापित करने का भी प्रयास कर सकते हैं।

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

नींद के बारे में अतिरिक्त टिप्पणी (0)

के बाद नींद अंतराल बीत चुका है, धागा चलाने के लिए तैयार है। यदि आप 0 मिलीसेकंड निर्दिष्ट करते हैं, तो थ्रेड शेष समय के टुकड़े को छोड़ देगा लेकिन तैयार रहेंगे। ध्यान दें कि एक तैयार धागा तुरंत चलाने के लिए गारंटी नहीं है। नतीजतन, नींद अंतराल समाप्त होने के कुछ समय बाद धागा नहीं चल सकता है। - यह here से है।

यह भी ध्यान दें कि लिनक्स सिस्टम व्यवहार पर थोड़ा अलग हो सकता है; लेकिन मैं एक लिनक्स विशेषज्ञ नहीं हूँ; शायद एक यात्री द्वारा स्पष्ट किया जा सकता है।

+1

+1 अच्छा स्पष्टीकरण। नींद (0) _yields_ थ्रेड निष्पादन, आंशिक रूप से 'सहकारी' थ्रेड शेड्यूलिंग (a.o.t. _preemptive_ थ्रेड शेड्यूलिंग) के लिए बना रहा है। लिनक्स के बारे में – sehe

+2

। POSIX पर CPU समय को छोड़ने के लिए फ़ंक्शन 'sched_yield' है। इसमें कोई पैरामीटर नहीं होता है और विंडोज़ पर 'स्लीप (0)' को कॉल करने के समान प्रभाव पड़ता है। – datenwolf