From 31d4d5331615d1d20db0036af52cffddf33db818 Mon Sep 17 00:00:00 2001 From: Verox001 Date: Thu, 8 May 2025 20:24:00 +0200 Subject: [PATCH] Refactored and structured code to reduce load in state --- simulator/src/main.rs | 6 +- solar_engine/src/device_manager.rs | 2 +- solar_engine/src/geometry_manager.rs | 84 +++++++++++++- solar_engine/src/globals.rs | 1 - solar_engine/src/instance_manager.rs | 3 +- solar_engine/src/lib.rs | 16 +-- solar_engine/src/render.rs | 167 --------------------------- solar_engine/src/renderer.rs | 75 +++++++++++- solar_engine/src/state.rs | 20 ++-- 9 files changed, 179 insertions(+), 195 deletions(-) delete mode 100644 solar_engine/src/render.rs diff --git a/simulator/src/main.rs b/simulator/src/main.rs index 9b3dd93..8ad7dd5 100644 --- a/simulator/src/main.rs +++ b/simulator/src/main.rs @@ -1,5 +1,5 @@ use cgmath::{Rotation3, Vector3}; -use solar_engine::{Application, Body, InputEvent, Key, Light, LightType, MouseButton, Simulator}; +use solar_engine::{Application, Body, InputEvent, Key, Light, MouseButton, RenderInstance, Shape, Simulator}; use std::sync::{Arc, RwLock}; use std::thread; @@ -74,7 +74,7 @@ pub async fn run() { .iter() .enumerate() .map(|(i, b)| { - solar_engine::RenderInstance { + RenderInstance { position: ((b.position / 1.496e11) - sun_pos).cast::().unwrap(), rotation: cgmath::Quaternion::from_angle_z(cgmath::Deg(0.0)), color: match i { @@ -83,7 +83,7 @@ pub async fn run() { _ => [0.5, 0.5, 0.5], }, scale: 0.05, - shape: solar_engine::Shape::Sphere, + shape: Shape::Sphere, always_lit: i == 0, // Sun is_transparent: false, } diff --git a/solar_engine/src/device_manager.rs b/solar_engine/src/device_manager.rs index ad602ea..f668931 100644 --- a/solar_engine/src/device_manager.rs +++ b/solar_engine/src/device_manager.rs @@ -1,5 +1,5 @@ use wgpu::{Device, Queue, Surface, SurfaceConfiguration}; -use crate::render::SampleCount; +use crate::state::SampleCount; pub struct DeviceManager<'a> { pub surface: Surface<'a>, diff --git a/solar_engine/src/geometry_manager.rs b/solar_engine/src/geometry_manager.rs index 8f90347..e515a6b 100644 --- a/solar_engine/src/geometry_manager.rs +++ b/solar_engine/src/geometry_manager.rs @@ -1,7 +1,19 @@ use std::collections::HashMap; use wgpu::{Device, Buffer}; -use crate::render::{create_circle_vertices, create_sphere_vertices, Geometry, Shape, Vertex}; use wgpu::util::DeviceExt; +use crate::renderer::Vertex; + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub enum Shape { + Circle, + Sphere, +} + +pub struct Geometry { + pub(crate) vertex_buffer: Buffer, + pub(crate) index_buffer: Buffer, + pub(crate) index_count: u32, +} pub struct GeometryManager { pub geometries: HashMap, @@ -58,3 +70,73 @@ impl GeometryManager { } } } + +pub fn create_circle_vertices(segment_count: usize, radius: f32, color: [f32; 3]) -> (Vec, Vec) { + let mut vertices = vec![Vertex { + position: [0.0, 0.0, 0.0], + color, + normal: [0.0, 0.0, 1.0], + }]; + let mut indices = vec![]; + + for i in 0..=segment_count { + let theta = (i as f32) / (segment_count as f32) * std::f32::consts::TAU; + let x = radius * theta.cos(); + let y = radius * theta.sin(); + vertices.push(Vertex { + position: [x, y, 0.0], + color, + normal: [0.0, 0.0, 1.0], + }); + } + + for i in 1..=segment_count { + indices.push(0); + indices.push(i as u16); + indices.push((i % segment_count + 1) as u16); + } + + (vertices, indices) +} + +pub fn create_sphere_vertices(stacks: usize, slices: usize, radius: f32, color: [f32; 3]) -> (Vec, Vec) { + let mut vertices = Vec::new(); + let mut indices = Vec::new(); + + for i in 0..=stacks { + let phi = std::f32::consts::PI * (i as f32) / (stacks as f32); + let y = phi.cos(); + let r = phi.sin(); + + for j in 0..=slices { + let theta = 2.0 * std::f32::consts::PI * (j as f32) / (slices as f32); + let x = r * theta.cos(); + let z = r * theta.sin(); + + let normal = [x, y, z]; + + vertices.push(Vertex { + position: [x * radius, y * radius, z * radius], + color, + normal, + }); + } + } + + for i in 0..stacks { + for j in 0..slices { + let first = i * (slices + 1) + j; + let second = first + slices + 1; + + indices.push(first as u16); + indices.push(second as u16); + indices.push((first + 1) as u16); + + indices.push(second as u16); + indices.push((second + 1) as u16); + indices.push((first + 1) as u16); + } + } + + (vertices, indices) +} diff --git a/solar_engine/src/globals.rs b/solar_engine/src/globals.rs index 7c4f90f..ecf66ca 100644 --- a/solar_engine/src/globals.rs +++ b/solar_engine/src/globals.rs @@ -1,5 +1,4 @@ use crate::camera::Camera; -use crate::render::Globals; use wgpu::{BindGroup, BindGroupLayout, Buffer, Device, Queue}; use bytemuck::{Pod, Zeroable}; use wgpu::util::DeviceExt; diff --git a/solar_engine/src/instance_manager.rs b/solar_engine/src/instance_manager.rs index 92fa685..2e5b850 100644 --- a/solar_engine/src/instance_manager.rs +++ b/solar_engine/src/instance_manager.rs @@ -1,7 +1,8 @@ -use crate::render::{InstanceRaw, RenderInstance, Shape}; use wgpu::{Buffer, Device, Queue}; use wgpu::util::DeviceExt; use std::mem::size_of; +use crate::geometry_manager::Shape; +use crate::renderer::{InstanceRaw, RenderInstance}; pub struct InstanceManager { instances: Vec, diff --git a/solar_engine/src/lib.rs b/solar_engine/src/lib.rs index e2909fa..ef2b46b 100644 --- a/solar_engine/src/lib.rs +++ b/solar_engine/src/lib.rs @@ -1,7 +1,6 @@ mod body; mod simulator; mod state; -mod render; mod application; mod input; mod camera; @@ -19,15 +18,16 @@ pub use simulator::distance_squared; pub use application::StateApplication as Application; -pub use render::RenderInstance; -pub use render::Shape; - pub use state::State; +pub use renderer::RenderInstance; + +pub use light::Light; +pub use light::LightType; + +pub use geometry_manager::Shape; + pub use input::Key; pub use input::map_winit_key; pub use input::InputEvent; -pub use input::MouseButton; - -pub use light::Light; -pub use light::LightType; \ No newline at end of file +pub use input::MouseButton; \ No newline at end of file diff --git a/solar_engine/src/render.rs b/solar_engine/src/render.rs deleted file mode 100644 index 9cadbe8..0000000 --- a/solar_engine/src/render.rs +++ /dev/null @@ -1,167 +0,0 @@ -#[repr(C)] -#[derive(Clone, Copy, Debug, bytemuck::Pod, bytemuck::Zeroable)] -pub struct Globals { - pub view_proj: [[f32; 4]; 4], - pub resolution: [f32; 2], - pub _padding: [f32; 2], -} - -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] -pub enum Shape { - Circle, - Sphere, -} - -pub struct Geometry { - pub(crate) vertex_buffer: wgpu::Buffer, - pub(crate) index_buffer: wgpu::Buffer, - pub(crate) index_count: u32, -} - -pub struct RenderInstance { - pub position: cgmath::Vector3, - pub rotation: cgmath::Quaternion, - pub color: [f32; 3], - pub scale: f32, - pub shape: Shape, - pub always_lit: bool, - pub is_transparent: bool -} - -impl RenderInstance { - pub fn to_raw(&self) -> InstanceRaw { - let model = cgmath::Matrix4::from_translation(self.position) - * cgmath::Matrix4::from(self.rotation) - * cgmath::Matrix4::from_scale(self.scale); - InstanceRaw { - model: model.into(), - color: self.color, - flags: (self.always_lit as u32) | ((self.is_transparent as u32) << 1) - } - } -} - -#[repr(C)] -#[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)] -pub struct InstanceRaw { - model: [[f32; 4]; 4], - color: [f32; 3], - flags: u32, -} - -impl InstanceRaw { - pub(crate) fn desc() -> wgpu::VertexBufferLayout<'static> { - wgpu::VertexBufferLayout { - array_stride: size_of::() as wgpu::BufferAddress, - step_mode: wgpu::VertexStepMode::Instance, - attributes: &[ - wgpu::VertexAttribute { offset: 0, shader_location: 5, format: wgpu::VertexFormat::Float32x4 }, - wgpu::VertexAttribute { offset: 16, shader_location: 6, format: wgpu::VertexFormat::Float32x4 }, - wgpu::VertexAttribute { offset: 32, shader_location: 7, format: wgpu::VertexFormat::Float32x4 }, - wgpu::VertexAttribute { offset: 48, shader_location: 8, format: wgpu::VertexFormat::Float32x4 }, - wgpu::VertexAttribute { offset: 64, shader_location: 9, format: wgpu::VertexFormat::Float32x3 }, - wgpu::VertexAttribute { offset: 76, shader_location: 10, format: wgpu::VertexFormat::Uint32 }, - ], - } - } -} - - -pub struct SampleCount(pub u32); - -impl SampleCount { - pub fn get(&self) -> u32 { - self.0 - } -} - -#[repr(C)] -#[derive(Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)] -pub struct Vertex { - pub(crate) position: [f32; 3], - pub(crate) color: [f32; 3], - pub(crate) normal: [f32; 3], -} - -impl Vertex { - const ATTRIBS: [wgpu::VertexAttribute; 3] = - wgpu::vertex_attr_array![0 => Float32x3, 1 => Float32x3, 2 => Float32x3]; - - pub(crate) fn desc() -> wgpu::VertexBufferLayout<'static> { - wgpu::VertexBufferLayout { - array_stride: size_of::() as wgpu::BufferAddress, - step_mode: wgpu::VertexStepMode::Vertex, - attributes: &Self::ATTRIBS, - } - } -} - -pub fn create_circle_vertices(segment_count: usize, radius: f32, color: [f32; 3]) -> (Vec, Vec) { - let mut vertices = vec![Vertex { - position: [0.0, 0.0, 0.0], - color, - normal: [0.0, 0.0, 1.0], - }]; - let mut indices = vec![]; - - for i in 0..=segment_count { - let theta = (i as f32) / (segment_count as f32) * std::f32::consts::TAU; - let x = radius * theta.cos(); - let y = radius * theta.sin(); - vertices.push(Vertex { - position: [x, y, 0.0], - color, - normal: [0.0, 0.0, 1.0], - }); - } - - for i in 1..=segment_count { - indices.push(0); - indices.push(i as u16); - indices.push((i % segment_count + 1) as u16); - } - - (vertices, indices) -} - -pub fn create_sphere_vertices(stacks: usize, slices: usize, radius: f32, color: [f32; 3]) -> (Vec, Vec) { - let mut vertices = Vec::new(); - let mut indices = Vec::new(); - - for i in 0..=stacks { - let phi = std::f32::consts::PI * (i as f32) / (stacks as f32); - let y = phi.cos(); - let r = phi.sin(); - - for j in 0..=slices { - let theta = 2.0 * std::f32::consts::PI * (j as f32) / (slices as f32); - let x = r * theta.cos(); - let z = r * theta.sin(); - - let normal = [x, y, z]; - - vertices.push(Vertex { - position: [x * radius, y * radius, z * radius], - color, - normal, - }); - } - } - - for i in 0..stacks { - for j in 0..slices { - let first = i * (slices + 1) + j; - let second = first + slices + 1; - - indices.push(first as u16); - indices.push(second as u16); - indices.push((first + 1) as u16); - - indices.push(second as u16); - indices.push((second + 1) as u16); - indices.push((first + 1) as u16); - } - } - - (vertices, indices) -} \ No newline at end of file diff --git a/solar_engine/src/renderer.rs b/solar_engine/src/renderer.rs index 793a733..39c3e0d 100644 --- a/solar_engine/src/renderer.rs +++ b/solar_engine/src/renderer.rs @@ -1,12 +1,79 @@ use crate::camera::Camera; -use crate::geometry_manager::GeometryManager; +use crate::geometry_manager::{GeometryManager, Shape}; use crate::globals::GlobalsManager; use crate::instance_manager::InstanceManager; use crate::light::LightManager; -use crate::render::{Geometry, InstanceRaw, Shape}; -use std::collections::HashMap; use wgpu::{Device, Queue, SurfaceTexture, TextureView}; +pub struct RenderInstance { + pub position: cgmath::Vector3, + pub rotation: cgmath::Quaternion, + pub color: [f32; 3], + pub scale: f32, + pub shape: Shape, + pub always_lit: bool, + pub is_transparent: bool +} + +impl RenderInstance { + pub fn to_raw(&self) -> InstanceRaw { + let model = cgmath::Matrix4::from_translation(self.position) + * cgmath::Matrix4::from(self.rotation) + * cgmath::Matrix4::from_scale(self.scale); + InstanceRaw { + model: model.into(), + color: self.color, + flags: (self.always_lit as u32) | ((self.is_transparent as u32) << 1) + } + } +} + +#[repr(C)] +#[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)] +pub struct InstanceRaw { + model: [[f32; 4]; 4], + color: [f32; 3], + flags: u32, +} + +impl InstanceRaw { + pub(crate) fn desc() -> wgpu::VertexBufferLayout<'static> { + wgpu::VertexBufferLayout { + array_stride: size_of::() as wgpu::BufferAddress, + step_mode: wgpu::VertexStepMode::Instance, + attributes: &[ + wgpu::VertexAttribute { offset: 0, shader_location: 5, format: wgpu::VertexFormat::Float32x4 }, + wgpu::VertexAttribute { offset: 16, shader_location: 6, format: wgpu::VertexFormat::Float32x4 }, + wgpu::VertexAttribute { offset: 32, shader_location: 7, format: wgpu::VertexFormat::Float32x4 }, + wgpu::VertexAttribute { offset: 48, shader_location: 8, format: wgpu::VertexFormat::Float32x4 }, + wgpu::VertexAttribute { offset: 64, shader_location: 9, format: wgpu::VertexFormat::Float32x3 }, + wgpu::VertexAttribute { offset: 76, shader_location: 10, format: wgpu::VertexFormat::Uint32 }, + ], + } + } +} + +#[repr(C)] +#[derive(Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)] +pub struct Vertex { + pub(crate) position: [f32; 3], + pub(crate) color: [f32; 3], + pub(crate) normal: [f32; 3], +} + +impl Vertex { + const ATTRIBS: [wgpu::VertexAttribute; 3] = + wgpu::vertex_attr_array![0 => Float32x3, 1 => Float32x3, 2 => Float32x3]; + + pub(crate) fn desc() -> wgpu::VertexBufferLayout<'static> { + wgpu::VertexBufferLayout { + array_stride: size_of::() as wgpu::BufferAddress, + step_mode: wgpu::VertexStepMode::Vertex, + attributes: &Self::ATTRIBS, + } + } +} + pub struct Renderer { pipeline: wgpu::RenderPipeline, depth_texture: TextureView, @@ -52,7 +119,7 @@ impl Renderer { vertex: wgpu::VertexState { module: &shader, entry_point: Some("vs_main"), - buffers: &[crate::render::Vertex::desc(), InstanceRaw::desc()], + buffers: &[Vertex::desc(), InstanceRaw::desc()], compilation_options: Default::default(), }, fragment: Some(wgpu::FragmentState { diff --git a/solar_engine/src/state.rs b/solar_engine/src/state.rs index ab79c74..f211525 100644 --- a/solar_engine/src/state.rs +++ b/solar_engine/src/state.rs @@ -1,21 +1,23 @@ -use std::cmp::max; -use std::collections::HashMap; use std::sync::{Arc}; -use cgmath::{perspective, Deg, Matrix4, Point3, Vector3}; use log::info; use pollster::FutureExt; -use wgpu::util::DeviceExt; -use wgpu::{Adapter, BindGroup, BindGroupLayout, Device, Instance, PresentMode, Queue, Surface, SurfaceCapabilities, SurfaceConfiguration, SurfaceError}; +use wgpu::{Adapter, Device, Instance, PresentMode, Queue, Surface, SurfaceCapabilities, SurfaceConfiguration, SurfaceError}; use winit::dpi::PhysicalSize; use winit::window::{Window}; use crate::camera::Camera; -use crate::device_manager::DeviceManager; use crate::geometry_manager::GeometryManager; use crate::globals::GlobalsManager; use crate::instance_manager::InstanceManager; -use crate::light::{ClusterBuffers, GpuLight, LightManager}; -use crate::render::{create_circle_vertices, create_sphere_vertices, Geometry, Globals, InstanceRaw, RenderInstance, SampleCount, Shape, Vertex}; -use crate::renderer::Renderer; +use crate::light::{LightManager}; +use crate::renderer::{RenderInstance, Renderer}; + +pub struct SampleCount(pub u32); + +impl SampleCount { + pub fn get(&self) -> u32 { + self.0 + } +} pub struct State<'a> { surface: Surface<'a>,