diff --git a/src/core/render/primitives/command.rs b/src/core/render/primitives/command.rs index f7a20e4..a71b9d2 100644 --- a/src/core/render/primitives/command.rs +++ b/src/core/render/primitives/command.rs @@ -1,26 +1,61 @@ use std::{error::Error, sync::Arc}; use vulkano::{ - buffer::Subbuffer, - command_buffer::{ - AutoCommandBufferBuilder, PrimaryAutoCommandBuffer, RenderPassBeginInfo, SubpassBeginInfo, - SubpassEndInfo, - }, + buffer::{IndexBuffer, Subbuffer}, + command_buffer::{AutoCommandBufferBuilder, PrimaryAutoCommandBuffer}, descriptor_set::allocator::StandardDescriptorSetAllocator, pipeline::GraphicsPipeline, - render_pass::{Framebuffer, RenderPass}, }; -pub trait AsRecordable { - fn record_render_commands( +pub trait AsRecordable +where + MI: Into + Clone, +{ + fn record_bind_commands( builder: &mut AutoCommandBufferBuilder, descriptor_set_allocator: &Arc, pipeline: &Arc, - data: &T, + mesh: &impl AsRenderableMesh, + instances: &impl AsRenderableMeshInstance, + extra_data: &T, ) -> Result<(), Box>; + + fn record_draw_commands( + builder: &mut AutoCommandBufferBuilder, + mesh: &impl AsRenderableMesh, + instances: &impl AsRenderableMeshInstance, + ) -> Result<(), Box> { + match mesh.index_buffer() { + Some(index_buffer) => { + builder.bind_index_buffer(index_buffer.clone())?; + unsafe { + builder.draw_indexed( + mesh.index_count(), + instances.instance_count(), + mesh.first_index(), + mesh.vertex_offset(), + instances.first_instance(), + )?; + } + } + None => unsafe { + builder.draw( + mesh.vertex_count(), + instances.instance_count(), + mesh.first_vertex(), + instances.first_instance(), + )?; + }, + } + + Ok(()) + } } -pub trait AsRenderableMesh { +pub trait AsRenderableMesh +where + I: Into + Clone, +{ fn vertex_buffer(&self) -> &Subbuffer<[V]>; fn vertex_count(&self) -> u32; @@ -33,7 +68,7 @@ pub trait AsRenderableMesh { 0 } - fn index_buffer(&self) -> Option<&Subbuffer<[I]>> { + fn index_buffer(&self) -> Option<&I> { None } @@ -44,41 +79,14 @@ pub trait AsRenderableMesh { fn first_index(&self) -> u32 { 0 } +} - fn index_offset(&self) -> i32 { +pub trait AsRenderableMeshInstance { + fn instance_buffer(&self) -> &Subbuffer<[T]>; + + fn instance_count(&self) -> u32; + + fn first_instance(&self) -> u32 { 0 } } - -pub trait AsRenderPassRecordable { - fn begin_render_pass( - builder: &mut AutoCommandBufferBuilder, - _render_pass: &Arc, - framebuffer: &Arc, - clear_values: Vec>, - ) -> Result<(), Box> { - builder.begin_render_pass( - RenderPassBeginInfo { - clear_values, - ..RenderPassBeginInfo::framebuffer(framebuffer.clone()) - }, - SubpassBeginInfo { - contents: vulkano::command_buffer::SubpassContents::Inline, - ..Default::default() - }, - )?; - Ok(()) - } - - fn end_render_pass( - builder: &mut AutoCommandBufferBuilder, - ) -> Result<(), Box> { - builder.end_render_pass(SubpassEndInfo::default())?; - Ok(()) - } - - fn record_render_pass_commands( - builder: &mut AutoCommandBufferBuilder, - data: &T, - ) -> Result<(), Box>; -} diff --git a/src/core/render/primitives/mod.rs b/src/core/render/primitives/mod.rs index 3303d41..427b633 100644 --- a/src/core/render/primitives/mod.rs +++ b/src/core/render/primitives/mod.rs @@ -19,7 +19,7 @@ pub mod vertex; pub mod resource; pub use buffer::{AsBindableBuffer, AsIndexBuffer, AsUniformBuffer, AsVertexBuffer}; -pub use command::{AsRecordable, AsRenderableMesh}; +pub use command::{AsRecordable, AsRenderableMesh, AsRenderableMeshInstance}; pub trait AsBindableDescriptorSet { fn as_descriptor_set_layout_bindings() -> BTreeMap; diff --git a/src/core/render/primitives/transform.rs b/src/core/render/primitives/transform.rs index d7c1249..27f24f4 100644 --- a/src/core/render/primitives/transform.rs +++ b/src/core/render/primitives/transform.rs @@ -10,6 +10,8 @@ use vulkano::{ use crate::core::render::primitives::{AsBindableBuffer, AsVertexBuffer}; +use super::command::AsRenderableMeshInstance; + #[derive(Debug, Clone)] pub struct Transform { pub position: Vec3, @@ -161,3 +163,13 @@ impl AsBindableBuffer for TransformRaw { } impl AsVertexBuffer for TransformRaw {} + +impl AsRenderableMeshInstance for Subbuffer<[TransformRaw]> { + fn instance_buffer(&self) -> &Subbuffer<[TransformRaw]> { + self + } + + fn instance_count(&self) -> u32 { + self.len() as u32 + } +} diff --git a/src/game/assets/meshs/square.rs b/src/game/assets/meshs/square.rs index d1dc524..1a67013 100644 --- a/src/game/assets/meshs/square.rs +++ b/src/game/assets/meshs/square.rs @@ -44,7 +44,7 @@ impl Square { } } -impl AsRenderableMesh for Square { +impl AsRenderableMesh> for Square { fn vertex_buffer(&self) -> &Subbuffer<[Vertex3D]> { &self.vertex_buffer } diff --git a/src/game/assets/pipelines/simple.rs b/src/game/assets/pipelines/simple.rs index b46c993..f26bcda 100644 --- a/src/game/assets/pipelines/simple.rs +++ b/src/game/assets/pipelines/simple.rs @@ -28,20 +28,15 @@ use vulkano::{ use crate::core::render::{ primitives::{ - AsBindableDescriptorSet, AsRecordable, AsRenderableMesh, mvp::Mvp, transform::TransformRaw, - vertex::Vertex3D, + AsBindableDescriptorSet, AsRecordable, AsRenderableMesh, AsRenderableMeshInstance, + mvp::Mvp, transform::TransformRaw, vertex::Vertex3D, }, texture::Texture, }; -pub struct SimplePipelineRenderData<'a, T> -where - T: AsRenderableMesh, -{ - pub mesh: &'a T, +pub struct SimplePipelineRenderData<'a> { pub mvp_uniform: &'a Subbuffer<[Mvp]>, pub texture: &'a Texture, - pub instances: &'a Subbuffer<[TransformRaw]>, } pub struct SimplePipeline { @@ -130,14 +125,16 @@ impl SimplePipeline { } } -impl<'a, T: AsRenderableMesh> AsRecordable> +impl<'a> AsRecordable, Vertex3D, Subbuffer<[u32]>, TransformRaw> for SimplePipeline { - fn record_render_commands( + fn record_bind_commands( builder: &mut AutoCommandBufferBuilder, descriptor_set_allocator: &Arc, pipeline: &Arc, - data: &SimplePipelineRenderData<'a, T>, + mesh: &impl AsRenderableMesh>, + instances: &impl AsRenderableMeshInstance, + data: &SimplePipelineRenderData<'a>, ) -> Result<(), Box> { let layouts = pipeline.layout().set_layouts(); @@ -158,32 +155,12 @@ impl<'a, T: AsRenderableMesh> AsRecordable { - builder.bind_index_buffer(index_buffer.clone())?; - unsafe { - builder.draw_indexed( - data.mesh.index_count(), - data.instances.len() as u32, - data.mesh.first_index(), - data.mesh.vertex_offset(), - 0, - )?; - } - } - None => unsafe { - builder.draw( - data.mesh.vertex_count(), - data.instances.len() as u32, - data.mesh.first_vertex(), - 0, - )?; - }, - } - Ok(()) } } diff --git a/src/game/scenes/main_scene.rs b/src/game/scenes/main_scene.rs index eb3b6bf..5f1388c 100644 --- a/src/game/scenes/main_scene.rs +++ b/src/game/scenes/main_scene.rs @@ -206,17 +206,18 @@ impl Scene for MainScene { let transform_uniform = Transform::create_buffer(&app_context.memory_allocator, &state.instances)?; - SimplePipeline::record_render_commands( + SimplePipeline::record_bind_commands( &mut builder, &app_context.descriptor_set_allocator, state.simple_pipeline.pipeline(), + &state.square, + &transform_uniform, &SimplePipelineRenderData { - mesh: &state.square, mvp_uniform: &camera_uniform, texture: &state.texture, - instances: &transform_uniform, }, )?; + SimplePipeline::record_draw_commands(&mut builder, &state.square, &transform_uniform)?; RenderPassManager::end_rendering(&mut builder)?;