use crate::old_app::pipelines::triangle_pipeline::shaders::vs; use glam::{Mat3, Mat4, Vec3}; use std::error::Error; use std::sync::Arc; use std::time::Instant; use vulkano::buffer::{Buffer, BufferCreateInfo, BufferUsage, Subbuffer}; use vulkano::command_buffer::{AutoCommandBufferBuilder, PrimaryAutoCommandBuffer}; use vulkano::descriptor_set::{DescriptorSet, WriteDescriptorSet}; use vulkano::memory::allocator::{AllocationCreateInfo, MemoryTypeFilter}; use vulkano::pipeline::{GraphicsPipeline, Pipeline, PipelineBindPoint}; use crate::core::render::vertex::Vertex2D; use crate::old_app::pipelines::triangle_pipeline::create_triangle_pipeline; use super::vulkan_context::VulkanContext; use super::window_render_context::WindowRenderContext; const VERTICES: [Vertex2D; 12] = [ // Triangle en haut à gauche Vertex2D { position: [-0.5, -0.75], color: [1.0, 0.0, 0.0], }, Vertex2D { position: [-0.75, -0.25], color: [0.0, 1.0, 0.0], }, Vertex2D { position: [-0.25, -0.25], color: [0.0, 0.0, 1.0], }, // Triangle en bas à gauche Vertex2D { position: [-0.5, 0.25], color: [0.5, 0.5, 0.5], }, Vertex2D { position: [-0.75, 0.75], color: [0.2, 0.8, 0.2], }, Vertex2D { position: [-0.25, 0.75], color: [0.8, 0.2, 0.2], }, // Triangle en haut à droite Vertex2D { position: [0.5, -0.75], color: [1.0, 1.0, 0.0], }, Vertex2D { position: [0.25, -0.25], color: [0.0, 1.0, 1.0], }, Vertex2D { position: [0.75, -0.25], color: [1.0, 0.0, 1.0], }, // Triangle en bas à droite Vertex2D { position: [0.5, 0.25], color: [0.1, 0.5, 0.8], }, Vertex2D { position: [0.25, 0.75], color: [0.8, 0.6, 0.1], }, Vertex2D { position: [0.75, 0.75], color: [0.3, 0.4, 0.6], }, ]; pub struct Scene { pipeline: Arc, vertex_buffer: Subbuffer<[Vertex2D]>, rotation_start: Instant, } impl Scene { pub fn load( vulkan_context: &VulkanContext, window_render_context: &WindowRenderContext, ) -> Result> { let pipeline = create_triangle_pipeline(&vulkan_context.device, &window_render_context.swapchain)?; let vertex_buffer = Vertex2D::create_buffer(Vec::from_iter(VERTICES), &vulkan_context.memory_allocator)?; Ok(Scene { pipeline, vertex_buffer, rotation_start: Instant::now(), }) } pub fn render( &self, vulkan_context: &VulkanContext, window_render_context: &WindowRenderContext, builder: &mut AutoCommandBufferBuilder, ) -> Result<(), Box> { let vertex_count = self.vertex_buffer.len() as u32; let instance_count = vertex_count / 3; let uniform_buffer = self.get_uniform_buffer(vulkan_context, window_render_context); let layout = &self.pipeline.layout().set_layouts()[0]; let descriptor_set = DescriptorSet::new( vulkan_context.descriptor_set_allocator.clone(), layout.clone(), [WriteDescriptorSet::buffer(0, uniform_buffer)], [], ) .unwrap(); unsafe { builder .bind_pipeline_graphics(self.pipeline.clone())? .bind_descriptor_sets( PipelineBindPoint::Graphics, self.pipeline.layout().clone(), 0, descriptor_set, )? .bind_vertex_buffers(0, self.vertex_buffer.clone())? .draw(vertex_count, instance_count, 0, 0)?; } Ok(()) } fn get_uniform_buffer( &self, vulkan_context: &VulkanContext, window_render_context: &WindowRenderContext, ) -> Subbuffer { let swapchain = &window_render_context.swapchain; let elapsed = self.rotation_start.elapsed(); let rotation = elapsed.as_secs() as f64 + elapsed.subsec_nanos() as f64 / 1_000_000_000.0; let rotation = Mat3::from_rotation_y(rotation as f32); // NOTE: This teapot was meant for OpenGL where the origin is at the lower left // instead the origin is at the upper left in Vulkan, so we reverse the Y axis. let aspect_ratio = swapchain.image_extent()[0] as f32 / swapchain.image_extent()[1] as f32; let proj = Mat4::perspective_rh_gl(std::f32::consts::FRAC_PI_2, aspect_ratio, 0.01, 100.0); let view = Mat4::look_at_rh( Vec3::new(0.3, 0.3, 1.0), Vec3::new(0.0, 0.0, 0.0), Vec3::new(0.0, -1.0, 0.0), ); let scale = Mat4::from_scale(Vec3::splat(1.0)); let uniform_data = vs::MVPData { world: Mat4::from_mat3(rotation).to_cols_array_2d(), view: (view * scale).to_cols_array_2d(), projection: proj.to_cols_array_2d(), }; Buffer::from_data( vulkan_context.memory_allocator.clone(), BufferCreateInfo { usage: BufferUsage::UNIFORM_BUFFER, ..Default::default() }, AllocationCreateInfo { memory_type_filter: MemoryTypeFilter::PREFER_DEVICE | MemoryTypeFilter::HOST_SEQUENTIAL_WRITE, ..Default::default() }, uniform_data, ) .unwrap() } }