Add instances support

This commit is contained in:
Florian RICHER 2025-05-29 17:13:01 +02:00
parent f8b81f3269
commit 77c717f90b
Signed by: florian.richer
GPG key ID: C73D37CBED7BFC77
7 changed files with 158 additions and 31 deletions

View file

@ -30,26 +30,26 @@ use vulkano::{
};
use crate::core::render::{
primitives::{mvp::MVP, vertex::Vertex2D},
primitives::{mvp::MVP, transform::TransformRaw, vertex::Vertex3D},
texture::Texture,
};
const VERTICES: [Vertex2D; 4] = [
Vertex2D {
position: [0.0, 0.0],
const VERTICES: [Vertex3D; 4] = [
Vertex3D {
position: [-0.5, -0.5, 0.0],
uv: [0.0, 0.0],
},
Vertex2D {
position: [0.0, 5.0],
uv: [0.0, 0.5],
Vertex3D {
position: [-0.5, 0.5, 0.0],
uv: [0.0, 1.0],
},
Vertex2D {
position: [10.0, 0.0],
Vertex3D {
position: [0.5, -0.5, 0.0],
uv: [1.0, 0.0],
},
Vertex2D {
position: [10.0, 5.0],
uv: [1.0, 0.5],
Vertex3D {
position: [0.5, 0.5, 0.0],
uv: [1.0, 1.0],
},
];
@ -74,7 +74,7 @@ pub mod shaders {
}
pub struct Square {
vertex_buffer: Subbuffer<[Vertex2D]>,
vertex_buffer: Subbuffer<[Vertex3D]>,
index_buffer: Subbuffer<[u32]>,
pipeline: Arc<GraphicsPipeline>,
}
@ -120,7 +120,8 @@ impl Square {
.entry_point("main")
.ok_or("Failed find main entry point of fragment shader".to_string())?;
let vertex_input_state = Vertex2D::per_vertex().definition(&vs)?;
let vertex_input_state =
[Vertex3D::per_vertex(), TransformRaw::per_instance()].definition(&vs)?;
let stages = [
PipelineShaderStageCreateInfo::new(vs),
@ -207,6 +208,7 @@ impl Square {
command_buffer: &mut AutoCommandBufferBuilder<PrimaryAutoCommandBuffer>,
descriptor_set_allocator: &Arc<StandardDescriptorSetAllocator>,
mvp_uniform: &Subbuffer<[MVP]>,
transform_uniform: &Subbuffer<[TransformRaw]>,
texture: &Texture,
) -> Result<(), Box<dyn Error>> {
let layouts = self.pipeline.layout().set_layouts();
@ -235,11 +237,18 @@ impl Square {
0,
vec![uniform_descriptor_set, texture_descriptor_set],
)?;
command_buffer.bind_vertex_buffers(0, self.vertex_buffer.clone())?;
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, 1, 0, 0, 0)?;
command_buffer.draw_indexed(
INDICES.len() as u32,
transform_uniform.len() as u32,
0,
0,
0,
)?;
}
Ok(())

View file

@ -1,11 +1,14 @@
use std::{error::Error, sync::Arc};
use crate::core::render::primitives::camera::Camera3D;
use crate::core::render::primitives::transform::Transform;
use crate::core::render::texture::Texture;
use crate::core::scene::Scene;
use crate::core::scene::SceneContext;
use egui_winit_vulkano::{Gui, egui};
use glam::Mat4;
use glam::EulerRot;
use glam::Quat;
use glam::Vec3;
use vulkano::{
command_buffer::{
AutoCommandBufferBuilder, CommandBufferUsage, PrimaryCommandBufferAbstract,
@ -21,6 +24,7 @@ use super::assets::square::Square;
pub struct MainSceneState {
square: Square,
instances: Vec<Transform>,
camera: Camera3D,
texture: Texture,
speed: f32,
@ -43,6 +47,27 @@ impl Scene for MainScene {
scene_context.swapchain_format,
)?;
let num_instances = 100;
let instance_size = 10.0;
let instance_spacing = 10.0;
let num_instances_per_row = (num_instances as f32 / instance_spacing as f32).ceil() as u32;
let instances: Vec<Transform> = (0..num_instances)
.map(|i| Transform {
position: Vec3::new(
(i % num_instances_per_row) as f32 * (instance_spacing + instance_size),
0.0,
(i / num_instances_per_row) as f32 * (instance_spacing + instance_size),
),
rotation: Quat::from_euler(
EulerRot::XYZ,
0.0,
rand::random_range(0.0..=360.0),
0.0,
),
scale: Vec3::new(instance_size, instance_size, instance_size),
})
.collect();
let camera = Camera3D::new(
scene_context.aspect_ratio,
std::f32::consts::FRAC_PI_2,
@ -69,6 +94,7 @@ impl Scene for MainScene {
self.state = Some(MainSceneState {
square,
instances,
camera,
texture,
speed: 50.0,
@ -129,12 +155,16 @@ impl Scene for MainScene {
.camera
.create_buffer(&scene_context.memory_allocator)?;
let transform_uniform =
Transform::create_buffer(&scene_context.memory_allocator, &state.instances)?;
state
.square
.render(
&mut builder,
&scene_context.descriptor_set_allocator,
&camera_uniform,
&transform_uniform,
&state.texture,
)
.unwrap();