Refactored and structured code to reduce load in state
This commit is contained in:
parent
f4484ba335
commit
31d4d53316
@ -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::<f32>().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,
|
||||
}
|
||||
|
||||
@ -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>,
|
||||
|
||||
@ -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<Shape, Geometry>,
|
||||
@ -58,3 +70,73 @@ impl GeometryManager {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_circle_vertices(segment_count: usize, radius: f32, color: [f32; 3]) -> (Vec<Vertex>, Vec<u16>) {
|
||||
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<Vertex>, Vec<u16>) {
|
||||
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)
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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<RenderInstance>,
|
||||
|
||||
@ -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;
|
||||
@ -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<f32>,
|
||||
pub rotation: cgmath::Quaternion<f32>,
|
||||
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::<InstanceRaw>() 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::<Self>() 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<Vertex>, Vec<u16>) {
|
||||
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<Vertex>, Vec<u16>) {
|
||||
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)
|
||||
}
|
||||
@ -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<f32>,
|
||||
pub rotation: cgmath::Quaternion<f32>,
|
||||
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::<InstanceRaw>() 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::<Self>() 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 {
|
||||
|
||||
@ -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>,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user