2013-09-03 13 views
5

मैं SDL2 उपयोग कर रहा हूँ एक खेल है कि हर फ्रेम पर एक tilemap प्रदर्शित करता है लिखने के लिए, लेकिन प्रदर्शन बहुत धीमी है। मैंने समस्या को अलग करने के लिए एक छोटा सा कार्यक्रम लिखा था। ध्यान दें कि "temp.bmp" एक 16x16 छवि है।SDL2 tilemap - बहुत धीमी गति से

#include <stdio.h> 

#include "SDL2/SDL.h" 
#include "SDL2/SDL_timer.h" 
#include "SDL2/SDL_image.h" 

int main() 
{ 
    SDL_Window* win; 
    SDL_Renderer* ren; 
    int x, y; 

    SDL_Init(SDL_INIT_VIDEO); 
    SDL_CreateWindowAndRenderer(800, 600, 0, &win, &ren); 
    SDL_Surface* sf = IMG_Load("temp.bmp"); 
    SDL_Texture* tx = SDL_CreateTextureFromSurface(ren, sf); 

    for(;;) { 
     Uint32 t = SDL_GetTicks(); 
     for(x=0; x<800; x+=16) { 
      for(y=0; y<600; y+=16) { 
       SDL_Rect src = { 0, 0, 16, 16 }; 
       SDL_Rect dst = { x, y, 16, 16 }; 
       SDL_RenderCopy(ren, tx, &src, &dst); 
      } 
     } 
     SDL_RenderPresent(ren); 
     printf("%ld ms\n", SDL_GetTicks() - t); 
    } 
} 

प्रोग्राम चलाना, मुझे लगता है कि फ्रेम को प्रस्तुत करने में लगभग 16ms लगते हैं। यह बिल्कुल 60 एफपीएस (1000/60) है, जो गेम तर्क के लिए कोई जगह नहीं छोड़ता है। इसके अलावा, मैं इसे एक सुंदर तेज़ कंप्यूटर में चला रहा हूं।

मैं बहुत यकीन है कि मैं गलत रणनीति का उपयोग कर रहा हूँ, लेकिन मुझे यकीन है कि सही एक हो क्या नहीं कर रहा हूँ। हो सकता है कि एक बड़ा बनावट बनाना और इसे कम करना अक्सर रास्ता तय करना होगा, लेकिन मुझे किसी अन्य पर एक बनावट की प्रतिलिपि बनाने के बारे में कोई दस्तावेज नहीं मिला।

तो, मैं कैसे tilemap प्रदर्शन में सुधार कर सकते हैं?

+1

आप 'SDL_RenderPresent'to से पहले एक प्रदर्शन मेसर जोड़ सकता है कि आप अपने समय से पहले की वहाँ ढीला है। – dzada

+1

मुझे एसडीएल 2 नहीं पता, लेकिन शायद प्रतिपादन बनाम बनाम सीमित हो रहा है? क्या आपने पूर्णस्क्रीन मोड में चलाने का प्रयास किया है? – user694733

+0

@dzada अधिकांश समय SDL_RenderPresent पर खर्च किया जाता है। लगभग 2 एमएस पहले, और 14 एमएस के बाद। –

उत्तर

1

this पृष्ठ पर यह उल्लेख है SDL_RENDERER_PRESENTVSYNC झंडा मतलब है कि आप दर को ताज़ा करने के सिंक किए गए हैं। इस

renderer = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED); 
+0

SDL_GetRendererInfo का उपयोग करके, मुझे लगता है कि मैं हार्डवेयर त्वरण का उपयोग कर रहा (SDL_RENDERER_ACCELERATED सेट किया गया है और SDL_RENDERER_SOFTWARE सेट नहीं है) मिलता है। मुझे यह भी लगता है कि मुझे वीएसवाईएनसी द्वारा अवरुद्ध नहीं किया जा रहा है (SDL_RENDERER_PRESENTVSYNC सेट नहीं है)। –

+0

ठीक है क्षमा करें मैंने सोचा कि यह सेट किया गया था। – dzada

0

आप SDL_SetRenderTarget का उपयोग करके पहले एक बड़ा बनावट के लिए प्रदान कर सकते हैं की कोशिश करो। तब से उस बनावट को प्रति फ्रेम केवल एक बार खींचा जा सकता है।

आईई। की तरह कुछ:

Uint32 fmt; 
SDL_QueryTexture(tx, &fmt, NULL, NULL, NULL); 
SDL_Texture* tm = SDL_CreateTexture(ren, fmt, SDL_TEXTUREACCESS_TARGET, 800, 600); 
SDL_SetRenderTarget(ren, tm); 
// Your draw loop here 
SDL_SetRenderTarget(ren, NULL); 
// Real draw loop only needs to RenderCopy tm 
0

यह ऊर्ध्वाधर सिंक आपके ग्राफिक्स ड्राइवर (ओपन बैकएंड) ने मजबूर है। यह उपयोगकर्ता नियंत्रित है, और इसका उद्देश्य स्वयं अनुप्रयोगों द्वारा अपरिवर्तनीय होना है।

1

vsync के साथ अपने सिस्टम पर मैं SDL_RenderPresent() से पहले अतिरिक्त समय (~ 15ms) के बहुत सारे है:

#include <stdio.h> 
#include <stdlib.h> 

#include <SDL2/SDL.h> 
#include <SDL2/SDL_timer.h> 

int main(int argc, char** argv) 
{ 
    SDL_Window* win; 
    SDL_Renderer* ren; 
    int x, y; 

    SDL_Init(SDL_INIT_VIDEO); 

    win = SDL_CreateWindow 
     ( 
     "Window", 
     SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 
     800, 600, 
     0 
     ); 

    ren = SDL_CreateRenderer 
     ( 
     win, 
     -1, 
     SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC 
     ); 

    for(;;) 
    { 
     Uint32 t = SDL_GetTicks(); 
     for(x=0; x<800; x+=16) 
     { 
      for(y=0; y<600; y+=16) 
      { 
       SDL_Rect dst = { x, y, 16, 16 }; 
       SDL_SetRenderDrawColor(ren, rand()%255, rand()%255, rand()%255, 255); 
       SDL_RenderFillRect(ren, &dst); 
      } 
     } 

     // adjust this up/down to figure out how much extra time you have 
     // stop when you start seeing frame times exceeding ~16ms 
     SDL_Delay(15); 

     SDL_RenderPresent(ren); 
     printf("%ld ms\n", SDL_GetTicks() - t); 
    } 
} 
संबंधित मुद्दे