2013-09-03 73 views
5

Tôi đang sử dụng SDL2 để viết một trò chơi hiển thị sơ đồ trang ở mọi khung hình, nhưng hiệu suất quá chậm. Tôi đã viết một chương trình nhỏ để cô lập vấn đề. Hãy xem xét rằng "temp.bmp" là một hình ảnh 16x16.Sơ đồ trang web SDL2 - quá chậm

#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); 
    } 
} 

Chạy chương trình, tôi thấy mất khoảng 16ms để hiển thị khung. Đây là chính xác 60 FPS (1000/60), mà không có chỗ cho logic trò chơi. Ngoài ra, tôi đang chạy nó trong một máy tính khá nhanh.

Tôi khá chắc chắn rằng tôi đang sử dụng chiến lược sai, nhưng tôi không chắc điều gì là đúng. Có lẽ tạo ra một kết cấu lớn và cập nhật nó ít thường xuyên hơn sẽ là con đường để đi, nhưng tôi không thể tìm thấy bất kỳ tài liệu hướng dẫn về cách sao chép một kết cấu khác.

Vì vậy, làm cách nào để cải thiện hiệu suất sơ đồ trang web?

+1

bạn có thể thêm một mesure hiệu suất trước khi 'SDL_RenderPresent'to biết nếu bạn mất thời gian của bạn có trước đây. – dzada

+1

Tôi không biết SDL2, nhưng có thể hiển thị đang bị giới hạn bởi vsync? Bạn đã thử chạy ở chế độ toàn màn hình chưa? – user694733

+0

@dzada Phần lớn thời gian được dành cho SDL_RenderPresent. Khoảng 2 ms trước và sau 14 giây. –

Trả lời

1

Trên trang this nó đề cập rằng cờ SDL_RENDERER_PRESENTVSYNC có nghĩa là bạn được đồng bộ hóa với tỷ lệ làm mới. thử này

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

Bằng cách sử dụng SDL_GetRendererInfo, tôi nhận được rằng tôi đang sử dụng tăng tốc phần cứng (SDL_RENDERER_ACCELERATED được đặt và SDL_RENDERER_SOFTWARE không được đặt). Tôi cũng nhận được rằng tôi không bị chặn bởi VSYNC (SDL_RENDERER_PRESENTVSYNC không được thiết lập). –

+0

Ok xin lỗi tôi nghĩ rằng nó đã được thiết lập. – dzada

0

Bạn có thể trả cho một kết cấu lớn đầu tiên bằng cách sử dụng SDL_SetRenderTarget. Đó là kết cấu hơn sau đó được rút ra chỉ một lần cho mỗi khung hình.

I.e. một cái gì đó như:

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

Đồng bộ hóa dọc của nó được trình điều khiển đồ họa của bạn buộc (trình phụ trợ opengl). Nó được người dùng kiểm soát, và được dự định là không thể thay đổi bởi chính ứng dụng.

1

Trên hệ thống của tôi với vsync Tôi có rất nhiều thêm thời gian (~ 15ms) trước SDL_RenderPresent():

#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); 
    } 
}