2012-10-17 29 views
6

मेरे पास एक एसडीएल/ओपनग्ल गेम है जो मैं मज़े के लिए काम कर रहा हूं। मुझे औसत पर एक सभ्य fps मिलते हैं, लेकिन आंदोलन वास्तव में चंचल है क्योंकि SDL_GL_SwapBuffers() यादृच्छिक रूप से प्रक्रिया करने के लिए एक पागल लंबी मात्रा ले जाएगा। बफर को लोड और लिखे गए बनावट के साथ कभी-कभी इसमें 100 मिलीमीटर लगेंगे! मैंने कोशिश की और पता लगाने के लिए मेरा बहुत सारे कोड काट दिया कि क्या यह कुछ गलत था लेकिन मुझे बहुत भाग्य नहीं मिला। जब मैं इस नंगे हड्डियों के कार्यक्रम को चलाता हूं तो यह कभी-कभी 70ms तक अवरुद्ध होगा।SDL_GL_SwapBuffers() अंततः धीमी गति से

मुख्य:

// Don't forget to link to opengl32, glu32, SDL_image.lib 

// includes 
#include <stdio.h> 

// SDL 
#include <cstdlib> 
#include <SDL/SDL.h> 

// Video 
#include "videoengine.h" 

int main(int argc, char *argv[]) 
{ 
    // begin SDL 
    if (SDL_Init(SDL_INIT_VIDEO) != 0) 
    { 
     printf("Unable to initialize SDL: %s\n", SDL_GetError()); 
    } 

    // begin video class 
    VideoEngine videoEngine; 

    // BEGIN MAIN LOOP 
    bool done = false; 
    while (!done) 
    { 
     int loopStart = SDL_GetTicks(); 

     printf("STARTING SWAP BUFFER : %d\n", SDL_GetTicks() - loopStart); 
     SDL_GL_SwapBuffers(); 


     int total = SDL_GetTicks() - loopStart; 
     if (total > 6) 
      printf("END LOOP : %d ------------------------------------------------------------>\n", total); 
     else 
      printf("END LOOP : %d\n", total); 

    } 
    // END MAIN LOOP 

    return 0; 
} 

मेरे "VideoEngine" निर्माता:

VideoEngine::VideoEngine() 
{ 
    UNIT = 16; 
    SCREEN_X = 320; 
    SCREEN_Y = 240; 
    SCALE = 1; 


    // Begin Initalization 

     SDL_Surface *screen; 

     SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); // [!] SDL_GL_SetAttributes must be done BEFORE SDL_SetVideoMode 

     screen = SDL_SetVideoMode(SCALE*SCREEN_X, SCALE*SCREEN_Y, 16, SDL_OPENGL); // Set screen to the window with opengl 
     if (!screen) // make sure the window was created 
     { 
      printf("Unable to set video mode: %s\n", SDL_GetError()); 
     } 

     // set opengl state 
     opengl_init(); 

    // End Initalization 

} 

void VideoEngine::opengl_init() 
{ 
    // Set the OpenGL state after creating the context with SDL_SetVideoMode 

     //glClearColor(0, 0, 0, 0);        // sets screen buffer to black 
     //glClearDepth(1.0f);          // Tells OpenGL what value to reset the depth buffer when it is cleared 
     glViewport(0, 0, SCALE*SCREEN_X, SCALE*SCREEN_Y);  // sets the viewport to the default resolution (SCREEN_X x SCREEN_Y) multiplied by SCALE. (x,y,w,h) 
     glMatrixMode(GL_PROJECTION);       // Applies subsequent matrix operations to the projection matrix stack. 
     glLoadIdentity();          // Replaces the current matrix with the identity matrix 
     glOrtho(0, SCALE*SCREEN_X, SCALE*SCREEN_Y, 0, -1, 1); //describes a transformation that produces a parallel projection 
     glMatrixMode(GL_MODELVIEW);       // Applies subsequent matrix operations to the projection matrix stack. 
     glEnable(GL_TEXTURE_2D);        // Need this to display a texture 
     glLoadIdentity();          // Replaces the current matrix with the identity matrix 
     glEnable(GL_BLEND);          // Enable blending for transparency 
     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);  // Specifies pixel arithmetic 
     //glDisable(GL_LIGHTING);        // Disable lighting 
     //glDisable(GL_DITHER);         // Disable dithering 
     //glDisable(GL_DEPTH_TEST);        // Disable depth testing 

     //Check for error 
     GLenum error = glGetError(); 
     if(error != GL_NO_ERROR) 
     { 
     printf("Error initializing OpenGL! %s\n", gluErrorString(error)); 
     } 

    return; 
} 

मैं संभवतः सोचने के लिए मैं एक हार्डवेयर मुद्दा है शुरू कर रहा हूँ? हालांकि मुझे इस खेल में कभी भी समस्या नहीं आई है।

+0

क्या आपके पास कोई बनाम सक्षम है? – Tim

+0

नहीं, मुझे यह पढ़ने के बाद ऐसा नहीं लगता-http: //stackoverflow.com/questions/589064/how-to-enable-vertical-sync-in-opengl मुझे लगता है कि क्या हो रहा है SwapBuffers () इसे संसाधित करने के लिए समय देने के बिना इसे लटका या लूप का कारण बन सकता है। मैं कुछ और पढ़ूंगा और देखूंगा कि मुझे इसका समर्थन करने के लिए कुछ नहीं मिला है। बफर स्वैप के बाद – Alden

+2

[टॉस] (http://www.msarnoff.org/sdb/) एक 'SDL_Delay (1)', देखें कि यह आपके फ्रेम समय के साथ क्या करता है। – genpfault

उत्तर

2

एसडीएल SwapIntervalEXT एक्सटेंशन का उपयोग करता है ताकि आप सुनिश्चित कर सकें कि बफर स्वैप जितना तेज़ हो सके (VSYNC अक्षम)। साथ ही, बफर स्वैप एक साधारण ऑपरेशन नहीं है, ओपनजीएल को glReadPixels() के मामले में बैक बफर की सामग्री को फ्रंट बफर में कॉपी करने की आवश्यकता है। WGL_SWAP_EXCHANGE_ARB का उपयोग करके WGL_ARB_pixel_format का उपयोग करके इस व्यवहार को नियंत्रित किया जा सकता है (आप चश्मे में इन सभी चीजों के बारे में पढ़ सकते हैं; अब मुझे यकीन नहीं है कि लिनक्स के लिए कोई विकल्प है या नहीं)।

और फिर उन सभी के शीर्ष पर, खिड़की प्रणाली है। इससे वास्तव में बहुत सारी परेशानी हो सकती है। इसके अलावा, अगर कुछ त्रुटियां उत्पन्न होती हैं ...

यदि आप एक छोटे मोबाइल जीपीयू पर चल रहे हैं तो यह व्यवहार शायद ठीक है।

SDL_GL_SwapBuffers() में केवल glxSwapBuffers()/wglSwapBuffers() पर कॉल है, इसलिए वहां कोई समय नहीं बिताया गया है।

+3

इसे "स्वैप" बफर का नाम दिया गया है क्योंकि कोई सायन कार्यान्वयन वास्तव में एक प्रतिलिपि नहीं करता है। –

+0

@BenVoigt खैर, स्पष्ट रूप से डब्लूजीएल करता है - ['WGL_SWAP_EXCHANGE_ARB' संबंधित दस्तावेज़] पढ़ें (http://oss.sgi.com/projects/ogl-sample/registry/ARB/wgl_pixel_format.txt) (मैं आपकी टिप्पणी नहीं लड़ रहा हूं हालांकि, सैनिटी के बारे में)। इसका कारण यह है कि स्वैप के बाद भी बफर की सामग्री को पढ़ने में सक्षम होना चाहिए (सुनिश्चित नहीं है कि कोई ऐसा क्यों करना चाहता था), और यह डिफ़ॉल्ट व्यवहार है। 'WGL_SWAP_EXCHANGE_ARB' को सक्षम करके आप स्वीकार करते हैं कि आप समझते हैं कि स्वैप के बाद, बफर स्वैप करते हैं और आप अब अपने डेटा तक नहीं पहुंच सकते हैं। –

+0

क्या आप वाकई बफर में वैध डेटा रखने का अनुरोध करने की आवश्यकता नहीं है? उस 'WGL_SWAP_METHOD_ARB' पैरामीटर में तीन विकल्प हैं, और यह स्पष्ट नहीं करता है कि डिफ़ॉल्ट क्या है। –

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