Add traits

This commit is contained in:
Florian RICHER 2025-06-07 20:25:45 +02:00
parent 5539381f46
commit 1a61aab218
Signed by: florian.richer
GPG key ID: C73D37CBED7BFC77
9 changed files with 663 additions and 94 deletions

View file

@ -1,16 +1,15 @@
use std::{collections::BTreeMap, error::Error, sync::Arc};
use std::{error::Error, sync::Arc};
use vulkano::{
buffer::{Buffer, BufferCreateInfo, BufferUsage, Subbuffer},
buffer::Subbuffer,
command_buffer::{AutoCommandBufferBuilder, PrimaryAutoCommandBuffer},
descriptor_set::{
DescriptorSet, WriteDescriptorSet,
allocator::StandardDescriptorSetAllocator,
layout::{DescriptorSetLayoutBinding, DescriptorSetLayoutCreateInfo, DescriptorType},
DescriptorSet, allocator::StandardDescriptorSetAllocator,
layout::DescriptorSetLayoutCreateInfo,
},
device::Device,
format::Format,
memory::allocator::{AllocationCreateInfo, MemoryTypeFilter, StandardMemoryAllocator},
memory::allocator::StandardMemoryAllocator,
pipeline::{
DynamicState, GraphicsPipeline, Pipeline, PipelineBindPoint, PipelineLayout,
PipelineShaderStageCreateInfo,
@ -27,11 +26,13 @@ use vulkano::{
},
layout::{PipelineDescriptorSetLayoutCreateInfo, PipelineLayoutCreateFlags},
},
shader::ShaderStages,
};
use crate::core::render::{
primitives::{AsBindableDescriptorSet, mvp::Mvp, transform::TransformRaw, vertex::Vertex3D},
primitives::{
AsBindableDescriptorSet, AsDrawable, AsIndexBuffer, AsRecordable, AsVertexBuffer, mvp::Mvp,
transform::TransformRaw, vertex::Vertex3D,
},
texture::Texture,
};
@ -80,6 +81,14 @@ pub struct Square {
pipeline: Arc<GraphicsPipeline>,
}
/// Structure pour encapsuler les données de rendu du Square
pub struct SquareRenderData<'a> {
pub square: &'a Square,
pub mvp_uniform: &'a Subbuffer<[Mvp]>,
pub transform_uniform: &'a Subbuffer<[TransformRaw]>,
pub texture: &'a Texture,
}
impl Square {
pub fn new(
device: &Arc<Device>,
@ -87,32 +96,9 @@ impl Square {
swapchain_format: Format,
depth_format: Format,
) -> Result<Self, Box<dyn Error>> {
let vertex_buffer = Buffer::from_iter(
memory_allocator.clone(),
BufferCreateInfo {
usage: BufferUsage::VERTEX_BUFFER,
..Default::default()
},
AllocationCreateInfo {
memory_type_filter: MemoryTypeFilter::PREFER_DEVICE
| MemoryTypeFilter::HOST_SEQUENTIAL_WRITE,
..Default::default()
},
Vec::from_iter(VERTICES),
)?;
let index_buffer = Buffer::from_iter(
memory_allocator.clone(),
BufferCreateInfo {
usage: BufferUsage::INDEX_BUFFER,
..Default::default()
},
AllocationCreateInfo {
memory_type_filter: MemoryTypeFilter::PREFER_DEVICE
| MemoryTypeFilter::HOST_SEQUENTIAL_WRITE,
..Default::default()
},
Vec::from_iter(INDICES),
)?;
let vertex_buffer = Vertex3D::create_vertex_buffer(memory_allocator, &VERTICES)?;
let index_buffer = u32::create_index_buffer(memory_allocator, &INDICES)?;
let vs = shaders::vs::load(device.clone())?
.entry_point("main")
@ -197,6 +183,13 @@ impl Square {
transform_uniform: &Subbuffer<[TransformRaw]>,
texture: &Texture,
) -> Result<(), Box<dyn Error>> {
let render_data = SquareRenderData {
square: self,
mvp_uniform,
transform_uniform,
texture,
};
let layouts = self.pipeline.layout().set_layouts();
let uniform_descriptor_set =
@ -205,25 +198,86 @@ impl Square {
let texture_descriptor_set =
Texture::as_descriptor_set(descriptor_set_allocator, &layouts[1], texture)?;
command_buffer.bind_pipeline_graphics(self.pipeline.clone())?;
command_buffer.bind_descriptor_sets(
PipelineBindPoint::Graphics,
self.pipeline.layout().clone(),
0,
vec![uniform_descriptor_set, texture_descriptor_set],
// Utiliser les nouveaux traits pour le rendu
Self::record_render_commands(
command_buffer,
&render_data,
&self.pipeline,
&[uniform_descriptor_set, texture_descriptor_set],
)?;
command_buffer
.bind_vertex_buffers(0, (self.vertex_buffer.clone(), transform_uniform.clone()))?;
command_buffer.bind_index_buffer(self.index_buffer.clone())?;
unsafe {
command_buffer.draw_indexed(
INDICES.len() as u32,
transform_uniform.len() as u32,
0,
0,
0,
)?;
Ok(())
}
}
// Implémentation des nouveaux traits pour Square
impl<'a> AsDrawable<SquareRenderData<'a>> for Square {
type VertexBuffer = Subbuffer<[Vertex3D]>;
type IndexBuffer = Subbuffer<[u32]>;
fn vertex_buffer(data: &SquareRenderData<'a>) -> &'a Self::VertexBuffer {
&data.square.vertex_buffer
}
fn index_buffer(data: &SquareRenderData<'a>) -> Option<&'a Self::IndexBuffer> {
Some(&data.square.index_buffer)
}
fn vertex_count(_data: &SquareRenderData<'a>) -> u32 {
VERTICES.len() as u32
}
fn index_count(_data: &SquareRenderData<'a>) -> u32 {
INDICES.len() as u32
}
fn instance_count(data: &SquareRenderData<'a>) -> u32 {
data.transform_uniform.len() as u32
}
}
impl<'a> AsRecordable<SquareRenderData<'a>> for Square {
fn record_render_commands(
builder: &mut AutoCommandBufferBuilder<PrimaryAutoCommandBuffer>,
data: &SquareRenderData<'a>,
pipeline: &Arc<GraphicsPipeline>,
descriptor_sets: &[Arc<DescriptorSet>],
) -> Result<(), Box<dyn Error>> {
// Bind pipeline
builder.bind_pipeline_graphics(pipeline.clone())?;
// Bind descriptor sets
builder.bind_descriptor_sets(
PipelineBindPoint::Graphics,
pipeline.layout().clone(),
0,
descriptor_sets.iter().cloned().collect::<Vec<_>>(),
)?;
// Bind buffers
builder.bind_vertex_buffers(
0,
(
Self::vertex_buffer(data).clone(),
data.transform_uniform.clone(),
),
)?;
if let Some(index_buffer) = Self::index_buffer(data) {
builder.bind_index_buffer(index_buffer.clone())?;
unsafe {
builder.draw_indexed(
Self::index_count(data),
Self::instance_count(data),
0,
0,
0,
)?;
}
} else {
unsafe {
builder.draw(Self::vertex_count(data), Self::instance_count(data), 0, 0)?;
}
}
Ok(())