SDL tilemap рендеринг довольно медленный - PullRequest
0 голосов
/ 14 февраля 2019

Я использую SDL для написания симуляции, которая отображает довольно большую карту тайлов (около 240 * 240 плиток).Поскольку я довольно новичок в библиотеке SDL, я не могу сказать, является ли довольно медленная производительность при рендеринге более 50 000 плиток нормальной.Каждая плитка всегда видна, размером около 4 * 4 пикселей.В настоящее время выполняется итерация каждого кадра через 2d массив и рендеринг каждой отдельной плитки, что дает мне около 40 кадров в секунду, слишком медленно, чтобы фактически оставить какую-либо игровую логику за системой.

Я пытался найти некоторые альтернативные системы, например, обновлять только обновленные плитки, но люди всегда говорили, что это плохая практика, и что средство рендеринга должно очищаться каждый кадр и т. Д.

Вот изображение карты

Поэтому я в основном хотел спросить, существует ли какая-либо более эффективная система, чем рендеринг каждой отдельной плитки в каждом кадре.

Редактировать: Так вот простой метод рендеринга, который я использую

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

        }
    }
}

Так что в этом контексте каждая плитка называется "сайт", потому что они также хранят информацию, такую ​​как влажность, температура и тд.

Каждый сайт получил биом, назначенный во время процесса генерации, каждый биом в основном является идентификатором, каждый наземный биом имеет идентификатор выше 0 и каждый идентификатор воды равен 0 или ниже.

Это позволяет мне помещать каждый спрайт биома, упорядоченный по ID, в изображение "biome_sprites.png".Все наземные спрайты находятся в основном в первом ряду, в то время как все водяные плитки находятся во втором ряду.Таким образом, мне не нужно вручную назначать спрайт для биома, а метод может сделать это сам, умножив размер тайла (в основном ширину) на биом.

Вот таблица идентификатора биома из моегоSDD / GDD и фактическая таблица спрайтов .

Метод 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 голосов
/ 14 февраля 2019

Выберите разработчиков SDL2 для многоэлементной версии SDL_RenderCopy() (аналогично существующим функциям SDL_RenderDrawLines() / SDL_RenderDrawPoints() / SDL_RenderDrawRects()) и / или пакетных SDL_Renderer backends.

Прямо сейчас вы пытаетесь сбросить , по крайней мере, 240 * 240 = 57000 вызовов на ничью в горло графического процессора;обычно вы можете рассчитывать только на 1000-4000 вызовов в течение 16 миллисекунд.

В качестве альтернативы вы можете переключиться на OpenGL и выполнить пакетирование самостоятельно.

...