我使用SDL编写了一个模拟,该模拟显示了很大的图块图(大约240 * 240图块)。由于我对SDL库还很陌生,所以我无法真正分辨出渲染50,000个以上图块时相当慢的性能是否正常。每个图块始终可见,大约为4 * 4px。目前,它遍历2d数组的每一帧并渲染每个图块,这给了我约40fps的速度,太慢了,无法将任何游戏逻辑真正放在系统后面。
我试图找到一些替代系统,例如仅更新更新的图块,但人们总是评论这是一种不好的做法,并且应该在每一帧中都对渲染器进行清理,等等。
因此,我基本上想问一问,是否还有比在每一帧渲染每个图块更多的性能系统。
编辑:因此,这是我使用的简单渲染方法
void World::DirtyBiomeDraw(Graphics *graphics) {
if(_biomeTexture == NULL) {
_biomeTexture = graphics->loadImage("assets/biome_sprites.png");
printf("Biome texture loaded.\n");
}
for(int i = 0; i < globals::WORLD_WIDTH; i++) {
for(int l = 0; l < globals::WORLD_HEIGHT; l++) {
SDL_Rect srect;
srect.h = globals::SPRITE_SIZE;
srect.w = globals::SPRITE_SIZE;
if(sites[l][i].biome > 0) {
srect.y = 0;
srect.x = (globals::SPRITE_SIZE * sites[l][i].biome) - globals::SPRITE_SIZE;
}
else {
srect.y = globals::SPRITE_SIZE;
srect.x = globals::SPRITE_SIZE * fabs(sites[l][i].biome);
}
SDL_Rect drect = {i * globals::SPRITE_SIZE * globals::SPRITE_SCALE, l * globals::SPRITE_SIZE * globals::SPRITE_SCALE,
globals::SPRITE_SIZE * globals::SPRITE_SCALE, globals::SPRITE_SIZE * globals::SPRITE_SCALE};
graphics->blitOnRenderer(_biomeTexture, &srect, &drect);
}
}
}
因此,在这种情况下,每个图块都称为“站点”,这是因为它们还存储诸如湿度,温度等信息。
在生成过程中,每个站点都分配了一个生物群落,每个生物群落基本上都是一个ID,每个陆地生物群落的ID都大于0,每个水ID都等于或小于0。
这使我可以将ID排序的每个生物群落精灵放入“ biome_sprites.png”图像中。所有的陆地精灵基本上都在第一行中,而所有的水瓦片都在第二行中。这样,我就不必手动将精灵指定给生物群落,该方法本身可以通过将切片大小(基本上是宽度)乘以生物群落而实现。
在这里biome ID table from my SDD/GDD和actual spritesheet。
graphics类中的blitOnRenderer方法基本上只运行一个SDL_RenderCopy,将纹理拖到渲染器上。
void Graphics::blitOnRenderer(SDL_Texture *texture, SDL_Rect
*sourceRectangle, SDL_Rect *destinationRectangle) {
SDL_RenderCopy(this->_renderer, texture, sourceRectangle, destinationRectangle);
}
在游戏循环中,每帧都会调用RenderClear和RenderPresent。
我真的希望我能理解地解释这一点,问任何你想问的问题,我是向你们求助的人,所以我至少可以做的是合作:D
答案 0 :(得分:1)
为多项目版本的SDL_RenderCopy()
(类似于现有的SDL_RenderDrawLines()
/ SDL_RenderDrawPoints()
/ SDL_RenderDrawRects()
函数)和/或{{3} } SDL_Renderer后端。
现在,您要尝试至少猛击 240 * 240 = 57000调用调用GPU的喉咙;您通常只能在任何给定的16毫秒内依靠1000-4000次绘画调用。
或者切换到OpenGL并自行进行批处理。