RenderApp:渲染子应用
Bevy 的渲染在独立的子应用(SubApp)中运行,与主 ECS 世界隔离。这个子应用的标签是 RenderApp——一个实现了 AppLabel 的零大小结构体。
双世界架构
主应用(App)负责游戏逻辑、输入、UI 等;渲染子应用负责 GPU 资源管理、绘制命令提交。两者通过 ExtractSchedule 交换数据:每帧从主世界提取组件和资源的快照,复制到渲染世界。
主世界 (Main World) 渲染世界 (Render World)
┌──────────────────┐ Extract ┌──────────────────┐
│ 游戏逻辑系统 │ ─────────→ │ 渲染准备系统 │
│ Transform │ │ PrepareAssets │
│ Sprite │ │ Queue │
│ Camera │ │ Render │
└──────────────────┘ └──────────────────┘访问 RenderApp
在 Plugin::build 中通过 app.sub_app_mut(RenderApp) 获取渲染子应用的可变引用。拿到之后就可以往里面注册系统、插入资源、配置调度。
rust
struct RenderLogPlugin;
impl Plugin for RenderLogPlugin {
fn build(&self, app: &mut App) {
// sub_app_mut 返回 RenderApp 子应用的可变引用
let render_app = app.sub_app_mut(RenderApp);
// 在 Render 调度中注册一个系统,放在 RenderSystems::Render 阶段
render_app.add_systems(Render, log_render_phase.in_set(RenderSystems::Render));
}
}
fn log_render_phase() {
info!("Render 阶段正在执行");
}Listing 37-1:在插件中访问 RenderApp 并注册渲染系统
RenderApp 实现了 DerefMut<Target = SubApp>,所以你可以像操作普通 App 一样调用 add_systems、insert_resource 等方法。
何时需要访问 RenderApp
大多数游戏不需要直接操作 RenderApp。需要的场景包括:
- 自定义渲染系统或渲染阶段(往
RenderGraph调度与RenderSystems集合中插入系统) - 注册自定义的
ExtractComponent或ExtractResource - 往渲染管线中插入自定义的准备(prepare)或排队(queue)系统
- 配置 GPU 资源(Buffer、Texture、BindGroup)的生命周期
如果你只是想画东西,高层的 Sprite、Mesh3d、StandardMaterial 已经封装好了一切。