SDL tilemap渲染速度很慢

时间:2019-02-14 10:50:06

标签: c++ sdl game-engine sdl-2 game-development

我使用SDL编写了一个模拟,该模拟显示了很大的图块图(大约240 * 240图块)。由于我对SDL库还很陌生,所以我无法真正分辨出渲染50,000个以上图块时相当慢的性能是否正常。每个图块始终可见,大约为4 * 4px。目前,它遍历2d数组的每一帧并渲染每个图块,这给了我约40fps的速度,太慢了,无法将任何游戏逻辑真正放在系统后面。

我试图找到一些替代系统,例如仅更新更新的图块,但人们总是评论这是一种不好的做法,并且应该在每一帧中都对渲染器进行清理,等等。

Here a picture of the map

因此,我基本上想问一问,是否还有比在每一帧渲染每个图块更多的性能系统。

编辑:因此,这是我使用的简单渲染方法

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/GDDactual 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

1 个答案:

答案 0 :(得分:1)

为多项目版本的SDL_RenderCopy()(类似于现有的SDL_RenderDrawLines() / SDL_RenderDrawPoints() / SDL_RenderDrawRects()函数)和/或{{3} } SDL_Renderer后端。

现在,您要尝试至少猛击 240 * 240 = 57000调用调用GPU的喉咙;您通常只能在任何给定的16毫秒内依靠1000-4000次绘画调用。

或者切换到OpenGL并自行进行批处理。