c++ - 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);
}
解决方案
如果我理解您的要求,您是否只想每次只更新地图上的一些块/图块?除非您将地图纹理分成几块,否则这是不可能的,这可能会产生比您节省的更多的开销。您不能只 SDL_RenderClear 纹理的一部分而没有一些潜在的不良副作用。
我要做的是将地图纹理分解为层(map_floors、map_walls 等)并缓存每个层。因此,不要每帧调用 GraphicsDrawer::drawMap(),而是只在图层发生变化的帧上调用它。因此,如果 NPC 移动,只需重新绘制上面有 NPC 的图层即可。您仍然会在每一帧调用 SDL_RenderCopy(),但不必每帧都重新生成每一层的纹理。
推荐阅读
- extjs - grid.reconfigure 是否删除列中存在的所有现有函数/事件处理程序并创建新表?
- mysql - SQL 选择计算
- laravel-5.4 - 如何在 laravel 中将批准的从 0 更新为 1
- selenium - 如何在控制台中为 selenium 生成输出
- java - 测试脚本中的 Thread.sleep 替代品
- java - WHERE 子句不适用于 SQLite
- navigation - 颤振通过路由导航到其他屏幕每隔一个屏幕更新一次
- android - 如何在本机后台服务中使用(角度)HTTP 客户端 - NativeScript
- java - 在 libgdx 游戏中将 GoogleMap 显示为片段
- python - 将循环中的数据框写入多个 Excel 文件