首页 > 解决方案 > SDL 渲染到新纹理

问题描述

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

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

所以基本上,如果玩家移动,我将移动所有块(这两个,玩家移动和更新块位置,在单独的线程中处理)并在主线程中重新渲染地图纹理。

虽然,每帧绘制所有块确实效率不高,而且它滞后于窗口渲染,所以我想做的是创建另一个线程,这将创建一个可以在那里渲染块的空白纹理。

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

这是通过地图块并将它们绘制到新纹理的代码:

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


标签: c++sdl

解决方案


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

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


推荐阅读