refactor(render): build game commands from snapshots
This commit is contained in:
@@ -25,8 +25,9 @@ use fparkan_assets::PreparedVisual;
|
|||||||
use fparkan_platform::WindowPort;
|
use fparkan_platform::WindowPort;
|
||||||
use fparkan_platform_winit::WinitWindow;
|
use fparkan_platform_winit::WinitWindow;
|
||||||
use fparkan_render::{
|
use fparkan_render::{
|
||||||
DrawCommand, DrawId, GpuMaterialId, GpuMeshId, IndexRange, RenderBackend, RenderCommand,
|
build_commands, CameraSnapshot, DrawId, GpuMaterialId, GpuMeshId, IndexRange, RenderBackend,
|
||||||
RenderCommandList, RenderPhase,
|
RenderCommand, RenderCommandList, RenderPhase, RenderProfile, RenderSnapshot,
|
||||||
|
RenderSnapshotDraw,
|
||||||
};
|
};
|
||||||
use fparkan_render_vulkan::VulkanPlanningBackend;
|
use fparkan_render_vulkan::VulkanPlanningBackend;
|
||||||
use fparkan_runtime::{
|
use fparkan_runtime::{
|
||||||
@@ -84,7 +85,8 @@ fn run(args: &[String]) -> Result<String, String> {
|
|||||||
last_tick = result.snapshot.tick.0;
|
last_tick = result.snapshot.tick.0;
|
||||||
last_hash = result.snapshot.hash.0;
|
last_hash = result.snapshot.hash.0;
|
||||||
let mission_assets = loaded_mission_assets(&engine);
|
let mission_assets = loaded_mission_assets(&engine);
|
||||||
let commands = render_snapshot_commands_with_assets(&result.snapshot, mission_assets);
|
let commands = render_snapshot_commands_with_assets(&result.snapshot, mission_assets)
|
||||||
|
.map_err(|err| format!("render snapshot: {err}"))?;
|
||||||
last_draw_count = commands
|
last_draw_count = commands
|
||||||
.commands
|
.commands
|
||||||
.iter()
|
.iter()
|
||||||
@@ -111,16 +113,23 @@ fn run(args: &[String]) -> Result<String, String> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
fn render_snapshot_commands(snapshot: &WorldSnapshot) -> RenderCommandList {
|
fn render_snapshot_commands(snapshot: &WorldSnapshot) -> Result<RenderCommandList, String> {
|
||||||
render_snapshot_commands_with_assets(snapshot, None)
|
render_snapshot_commands_with_assets(snapshot, None)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_snapshot_commands_with_assets(
|
fn render_snapshot_commands_with_assets(
|
||||||
snapshot: &WorldSnapshot,
|
snapshot: &WorldSnapshot,
|
||||||
mission_assets: Option<&MissionAssets>,
|
mission_assets: Option<&MissionAssets>,
|
||||||
) -> RenderCommandList {
|
) -> Result<RenderCommandList, String> {
|
||||||
let mut commands = Vec::with_capacity(snapshot.objects.len() + 2);
|
let render_snapshot = render_snapshot_with_assets(snapshot, mission_assets);
|
||||||
commands.push(RenderCommand::BeginFrame);
|
build_commands(&render_snapshot, RenderProfile::default()).map_err(|err| err.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render_snapshot_with_assets(
|
||||||
|
snapshot: &WorldSnapshot,
|
||||||
|
mission_assets: Option<&MissionAssets>,
|
||||||
|
) -> RenderSnapshot {
|
||||||
|
let mut draws = Vec::with_capacity(snapshot.objects.len());
|
||||||
for (index, handle) in snapshot.objects.iter().enumerate() {
|
for (index, handle) in snapshot.objects.iter().enumerate() {
|
||||||
let stable_order = u64::from(handle.slot);
|
let stable_order = u64::from(handle.slot);
|
||||||
let prepared = mission_assets.and_then(|assets| {
|
let prepared = mission_assets.and_then(|assets| {
|
||||||
@@ -146,19 +155,22 @@ fn render_snapshot_commands_with_assets(
|
|||||||
.0
|
.0
|
||||||
.wrapping_mul(1_000_003)
|
.wrapping_mul(1_000_003)
|
||||||
.wrapping_add(stable_order);
|
.wrapping_add(stable_order);
|
||||||
commands.push(RenderCommand::Draw(DrawCommand {
|
draws.push(RenderSnapshotDraw {
|
||||||
id: DrawId(draw_id),
|
id: DrawId(draw_id),
|
||||||
phase: RenderPhase::Opaque,
|
phase: RenderPhase::Opaque,
|
||||||
object_id: None,
|
object_id: None,
|
||||||
mesh,
|
mesh,
|
||||||
material,
|
material_slots: vec![material],
|
||||||
|
material_index: 0,
|
||||||
transform: identity_transform(index_to_f32(index)),
|
transform: identity_transform(index_to_f32(index)),
|
||||||
range: IndexRange { start: 0, count: 3 },
|
range: IndexRange { start: 0, count: 3 },
|
||||||
stable_order,
|
stable_order,
|
||||||
}));
|
});
|
||||||
|
}
|
||||||
|
RenderSnapshot {
|
||||||
|
camera: CameraSnapshot::default(),
|
||||||
|
draws,
|
||||||
}
|
}
|
||||||
commands.push(RenderCommand::EndFrame);
|
|
||||||
RenderCommandList { commands }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn identity_transform(x: f32) -> [f32; 16] {
|
fn identity_transform(x: f32) -> [f32; 16] {
|
||||||
@@ -305,12 +317,18 @@ mod tests {
|
|||||||
hash: StateHash([0; 32]),
|
hash: StateHash([0; 32]),
|
||||||
};
|
};
|
||||||
|
|
||||||
let commands = render_snapshot_commands(&snapshot);
|
let commands = render_snapshot_commands(&snapshot)?;
|
||||||
|
|
||||||
assert_eq!(commands.commands.len(), 4);
|
assert_eq!(commands.commands.len(), 4);
|
||||||
assert!(matches!(commands.commands[0], RenderCommand::BeginFrame));
|
assert!(matches!(
|
||||||
assert!(matches!(commands.commands[3], RenderCommand::EndFrame));
|
commands.commands[0],
|
||||||
let RenderCommand::Draw(first) = &commands.commands[1] else {
|
fparkan_render::RenderCommand::BeginFrame
|
||||||
|
));
|
||||||
|
assert!(matches!(
|
||||||
|
commands.commands[3],
|
||||||
|
fparkan_render::RenderCommand::EndFrame
|
||||||
|
));
|
||||||
|
let fparkan_render::RenderCommand::Draw(first) = &commands.commands[1] else {
|
||||||
return Err("expected draw".to_string());
|
return Err("expected draw".to_string());
|
||||||
};
|
};
|
||||||
assert_eq!(first.mesh, GpuMeshId(3));
|
assert_eq!(first.mesh, GpuMeshId(3));
|
||||||
|
|||||||
Reference in New Issue
Block a user