我正在使用SDL2编写一个游戏,它在每一帧都显示一个磁贴地图,但是性能太慢了。我写了一个小程序来隔离这个问题。假设"temp.bmp“是一个16x16的图像。
#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 FPS (1000/60),这不会留下游戏逻辑的空间。另外,我在一台速度相当快的计算机上运行它。
我很确定我使用了错误的策略,但我不确定哪种策略是正确的。也许创建一个大的纹理并不经常更新它是可行的,但是我找不到任何关于如何复制一个纹理覆盖另一个纹理的文档。
那么,如何提高tilemap的性能呢?
发布于 2013-09-03 21:22:21
在this页面上,它提到SDL_RENDERER_PRESENTVSYNC标志表示您已同步到刷新率。尝尝这个
renderer = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED);发布于 2013-10-10 03:06:04
在我使用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);
}
}发布于 2013-10-09 17:28:12
可以首先使用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 tmhttps://stackoverflow.com/questions/18591758
复制相似问题