SDL渲染为新纹理

时间:2019-01-15 21:26:01

标签: c++ sdl

我正在使用SDL库制作2D游戏。

我试图一遍又一遍地绘制每一帧的地图,因为我正在根据玩家的移动来移动地图,以实现相机跟随玩家的错觉。

因此,基本上,如果玩家移动了,我将移动所有块(这两个,玩家移动和更新块的位置,在单独的线程中处理),然后在主线程中再次渲染地图纹理。 / p>

尽管,实际上每帧绘制所有块的效率并不高,并且滞后于窗口渲染,所以我要做的是制作另一个线程,这将创建一个空白纹理,可以在此处渲染块。

问题是: 没有渲染器,是否可以这样做?将所有块绘制为新纹理而没有实际卡住绘制窗口的主渲染器,并防止每帧遍历所有块?

这是遍历地图块并将其绘制到新纹理的代码:

SDL_Texture* GraphicsDrawer::drawMap() {
    map = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, WINDOW_WIDTH, WINDOW_HEIGHT);
    SDL_SetTextureBlendMode(map, SDL_BLENDMODE_BLEND); // set texture to be transparent
    SDL_SetRenderTarget(renderer, map);
    for (Block block : blocks) {
        std::cout << block.getTexture() << std::endl;
        SDL_RenderCopy(renderer, block.getTexture(), NULL, &block.getPosition());
        SDL_RenderPresent(renderer);
    }
    SDL_SetRenderTarget(renderer, NULL);
    return map;
}

这是将纹理绘制到窗口的代码:

void Game::render() {
    SDL_RenderClear(renderer);
    //map
    SDL_RenderCopy(renderer, map, NULL, NULL);
    //player
    SDL_RenderCopy(renderer, player->getAnimation(player->getFlipImageFlag()), NULL, &player->getPosition());

    SDL_SetRenderDrawColor(renderer, BG_R, BG_G, BG_B, BG_A);
    SDL_RenderPresent(renderer);
}


1 个答案:

答案 0 :(得分:0)

如果我了解您的要求,那么您每次只想更新地图上的某些街区/瓷砖吗?除非将地图纹理分成几部分,否则这是不可能的,这可能会产生比您节省的更多开销。您不能仅SDL_RenderClearClear清除部分纹理而没有一些潜在的不良副作用。

我要做的是将地图纹理分解为几层(map_floors,map_walls等)并缓存每一层。因此,与其在每一帧都调用GraphicsDrawer :: drawMap(),不如在层发生变化的帧上调用它。因此,如果NPC移动,则仅重绘具有NPC的图层。您仍然会每帧调用SDL_RenderCopy(),但是不必每帧都重新生成每一层的纹理。