use crate::mesh::InstanceRaw; use crate::render::DrawCall; use crate::world::World; use bytemuck::cast_slice; pub fn render_system(world: &World) -> Vec { let all_entities = world.entities.all_entities(); all_entities .iter() .filter_map(|&entity| { let transform = world.transforms.get(entity)?; let mesh_component = world.meshes.get(entity)?; let model_matrix = transform.to_matrix(); let (instance_buffer, num_instances) = if let Some(ref buffer) = mesh_component.instance_buffer { (Some(buffer.clone()), mesh_component.num_instances) } else { let dissolve_amount = world.dissolves.get(entity).map(|d| d.amount).unwrap_or(0.0); let instance_data = InstanceRaw { model: model_matrix.to_cols_array_2d(), dissolve_amount, _padding: [0.0; 3], }; let buffer = crate::render::with_device(|device| { let buffer = device.create_buffer(&wgpu::BufferDescriptor { label: Some("Instance Buffer"), size: std::mem::size_of::() as u64, usage: wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST, mapped_at_creation: false, }); crate::render::with_queue(|queue| { queue.write_buffer(&buffer, 0, cast_slice(&[instance_data])); }); buffer }); (Some(buffer), 1) }; Some(DrawCall { vertex_buffer: mesh_component.mesh.vertex_buffer.clone(), index_buffer: mesh_component.mesh.index_buffer.clone(), num_indices: mesh_component.mesh.num_indices, model: model_matrix, pipeline: mesh_component.pipeline, instance_buffer, num_instances, }) }) .collect() }