Added circles and geometries
This commit is contained in:
parent
7eacf0d0a5
commit
e709e2dd3f
@ -1,4 +1,5 @@
|
|||||||
use std::cmp::max;
|
use std::cmp::max;
|
||||||
|
use std::collections::HashMap;
|
||||||
use std::sync::{Arc, RwLock};
|
use std::sync::{Arc, RwLock};
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
@ -21,11 +22,24 @@ pub async fn run() {
|
|||||||
let _ = event_loop.run_app(&mut window_state);
|
let _ = event_loop.run_app(&mut window_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||||
|
enum Shape {
|
||||||
|
Polygon,
|
||||||
|
Circle,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Geometry {
|
||||||
|
vertex_buffer: wgpu::Buffer,
|
||||||
|
index_buffer: wgpu::Buffer,
|
||||||
|
index_count: u32,
|
||||||
|
}
|
||||||
|
|
||||||
struct RenderInstance {
|
struct RenderInstance {
|
||||||
position: cgmath::Vector3<f32>,
|
position: cgmath::Vector3<f32>,
|
||||||
rotation: cgmath::Quaternion<f32>,
|
rotation: cgmath::Quaternion<f32>,
|
||||||
color: [f32; 3],
|
color: [f32; 3],
|
||||||
scale: f32
|
scale: f32,
|
||||||
|
shape: Shape,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RenderInstance {
|
impl RenderInstance {
|
||||||
@ -83,20 +97,6 @@ impl Vertex {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const VERTICES: &[Vertex] = &[
|
|
||||||
Vertex { position: [-0.0868241, 0.49240386, 0.0], color: [0.5, 0.0, 0.5] },
|
|
||||||
Vertex { position: [-0.49513406, 0.06958647, 0.0], color: [0.5, 0.0, 0.5] },
|
|
||||||
Vertex { position: [-0.21918549, -0.44939706, 0.0], color: [0.5, 0.0, 0.5] },
|
|
||||||
Vertex { position: [0.35966998, -0.3473291, 0.0], color: [0.5, 0.0, 0.5] },
|
|
||||||
Vertex { position: [0.44147372, 0.2347359, 0.0], color: [0.5, 0.0, 0.5] },
|
|
||||||
];
|
|
||||||
|
|
||||||
const INDICES: &[u16] = &[
|
|
||||||
0, 1, 4,
|
|
||||||
1, 2, 4,
|
|
||||||
2, 3, 4,
|
|
||||||
];
|
|
||||||
|
|
||||||
struct StateApplication<'a> {
|
struct StateApplication<'a> {
|
||||||
state: Option<State<'a>>,
|
state: Option<State<'a>>,
|
||||||
}
|
}
|
||||||
@ -148,6 +148,26 @@ impl<'a> ApplicationHandler for StateApplication<'a>{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 }];
|
||||||
|
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 });
|
||||||
|
}
|
||||||
|
|
||||||
|
for i in 1..=segment_count {
|
||||||
|
indices.push(0);
|
||||||
|
indices.push(i as u16);
|
||||||
|
indices.push((i % segment_count + 1) as u16);
|
||||||
|
}
|
||||||
|
|
||||||
|
(vertices, indices)
|
||||||
|
}
|
||||||
|
|
||||||
struct State<'a> {
|
struct State<'a> {
|
||||||
surface: Surface<'a>,
|
surface: Surface<'a>,
|
||||||
device: Device,
|
device: Device,
|
||||||
@ -156,16 +176,13 @@ struct State<'a> {
|
|||||||
|
|
||||||
size: PhysicalSize<u32>,
|
size: PhysicalSize<u32>,
|
||||||
window: Arc<Window>,
|
window: Arc<Window>,
|
||||||
|
|
||||||
render_pipeline: wgpu::RenderPipeline,
|
render_pipeline: wgpu::RenderPipeline,
|
||||||
vertex_buffer: wgpu::Buffer,
|
|
||||||
index_buffer: wgpu::Buffer,
|
|
||||||
|
|
||||||
instances: Vec<RenderInstance>,
|
instances: Vec<RenderInstance>,
|
||||||
instance_buffer: wgpu::Buffer,
|
instance_buffer: wgpu::Buffer,
|
||||||
|
|
||||||
num_vertices: u32,
|
geometries: HashMap<Shape, Geometry>,
|
||||||
num_indices: u32,
|
|
||||||
|
|
||||||
simulator: Arc<RwLock<Simulator>>,
|
simulator: Arc<RwLock<Simulator>>,
|
||||||
}
|
}
|
||||||
@ -183,11 +200,51 @@ impl<'a> State<'a> {
|
|||||||
surface.configure(&device, &config);
|
surface.configure(&device, &config);
|
||||||
|
|
||||||
let render_pipeline = Self::create_render_pipeline(&device, &config);
|
let render_pipeline = Self::create_render_pipeline(&device, &config);
|
||||||
let vertex_buffer = Self::create_vertex_buffer(&device);
|
|
||||||
let index_buffer = Self::create_index_buffer(&device);
|
|
||||||
|
|
||||||
let num_vertices = VERTICES.len() as u32;
|
let mut geometries = HashMap::new();
|
||||||
let num_indices = INDICES.len() as u32;
|
let polygon_vertices = vec![
|
||||||
|
Vertex { position: [-0.0868241, 0.49240386, 0.0], color: [0.5, 0.0, 0.5] },
|
||||||
|
Vertex { position: [-0.49513406, 0.06958647, 0.0], color: [0.5, 0.0, 0.5] },
|
||||||
|
Vertex { position: [-0.21918549, -0.44939706, 0.0], color: [0.5, 0.0, 0.5] },
|
||||||
|
Vertex { position: [0.35966998, -0.3473291, 0.0], color: [0.5, 0.0, 0.5] },
|
||||||
|
Vertex { position: [0.44147372, 0.2347359, 0.0], color: [0.5, 0.0, 0.5] },
|
||||||
|
];
|
||||||
|
let polygon_indices = vec![0, 1, 4, 1, 2, 4, 2, 3, 4];
|
||||||
|
|
||||||
|
let polygon_vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||||
|
label: Some("Polygon Vertex Buffer"),
|
||||||
|
contents: bytemuck::cast_slice(&polygon_vertices),
|
||||||
|
usage: wgpu::BufferUsages::VERTEX,
|
||||||
|
});
|
||||||
|
|
||||||
|
let polygon_index_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||||
|
label: Some("Polygon Index Buffer"),
|
||||||
|
contents: bytemuck::cast_slice(&polygon_indices),
|
||||||
|
usage: wgpu::BufferUsages::INDEX,
|
||||||
|
});
|
||||||
|
|
||||||
|
geometries.insert(Shape::Polygon, Geometry {
|
||||||
|
vertex_buffer: polygon_vertex_buffer,
|
||||||
|
index_buffer: polygon_index_buffer,
|
||||||
|
index_count: polygon_indices.len() as u32,
|
||||||
|
});
|
||||||
|
|
||||||
|
let (circle_vertices, circle_indices) = create_circle_vertices(32, 0.5, [0.5, 0.5, 0.5]);
|
||||||
|
let circle_vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||||
|
label: Some("Circle Vertex Buffer"),
|
||||||
|
contents: bytemuck::cast_slice(&circle_vertices),
|
||||||
|
usage: wgpu::BufferUsages::VERTEX,
|
||||||
|
});
|
||||||
|
let circle_index_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||||
|
label: Some("Circle Index Buffer"),
|
||||||
|
contents: bytemuck::cast_slice(&circle_indices),
|
||||||
|
usage: wgpu::BufferUsages::INDEX,
|
||||||
|
});
|
||||||
|
geometries.insert(Shape::Circle, Geometry {
|
||||||
|
vertex_buffer: circle_vertex_buffer,
|
||||||
|
index_buffer: circle_index_buffer,
|
||||||
|
index_count: circle_indices.len() as u32,
|
||||||
|
});
|
||||||
|
|
||||||
let mut sim = Simulator::new(60.0 * 60.0 * 24.0);
|
let mut sim = Simulator::new(60.0 * 60.0 * 24.0);
|
||||||
sim.add_body(Body {
|
sim.add_body(Body {
|
||||||
@ -231,6 +288,7 @@ impl<'a> State<'a> {
|
|||||||
_ => [0.5, 0.5, 0.5],
|
_ => [0.5, 0.5, 0.5],
|
||||||
},
|
},
|
||||||
scale: 0.1,
|
scale: 0.1,
|
||||||
|
shape: Shape::Circle
|
||||||
}).collect::<Vec<_>>()
|
}).collect::<Vec<_>>()
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -248,16 +306,12 @@ impl<'a> State<'a> {
|
|||||||
config,
|
config,
|
||||||
size,
|
size,
|
||||||
window: window_arc,
|
window: window_arc,
|
||||||
|
|
||||||
render_pipeline,
|
render_pipeline,
|
||||||
vertex_buffer,
|
geometries,
|
||||||
index_buffer,
|
|
||||||
|
|
||||||
instances,
|
instances,
|
||||||
instance_buffer,
|
instance_buffer,
|
||||||
|
|
||||||
num_vertices,
|
|
||||||
num_indices,
|
|
||||||
|
|
||||||
simulator,
|
simulator,
|
||||||
}
|
}
|
||||||
@ -279,6 +333,7 @@ impl<'a> State<'a> {
|
|||||||
_ => [0.5, 0.5, 0.5],
|
_ => [0.5, 0.5, 0.5],
|
||||||
},
|
},
|
||||||
scale: 0.5,
|
scale: 0.5,
|
||||||
|
shape: Shape::Circle
|
||||||
}).collect()
|
}).collect()
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -287,26 +342,6 @@ impl<'a> State<'a> {
|
|||||||
self.instances = updated_instances;
|
self.instances = updated_instances;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_index_buffer(device: &Device) -> wgpu::Buffer {
|
|
||||||
device.create_buffer_init(
|
|
||||||
&wgpu::util::BufferInitDescriptor {
|
|
||||||
label: Some("Index Buffer"),
|
|
||||||
contents: bytemuck::cast_slice(INDICES),
|
|
||||||
usage: wgpu::BufferUsages::INDEX,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn create_vertex_buffer(device: &Device) -> wgpu::Buffer {
|
|
||||||
device.create_buffer_init(
|
|
||||||
&wgpu::util::BufferInitDescriptor {
|
|
||||||
label: Some("Vertex Buffer"),
|
|
||||||
contents: bytemuck::cast_slice(VERTICES),
|
|
||||||
usage: wgpu::BufferUsages::VERTEX,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn create_render_pipeline(device: &Device, config: &wgpu::SurfaceConfiguration) -> wgpu::RenderPipeline {
|
fn create_render_pipeline(device: &Device, config: &wgpu::SurfaceConfiguration) -> wgpu::RenderPipeline {
|
||||||
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
|
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
|
||||||
label: Some("Shader"),
|
label: Some("Shader"),
|
||||||
@ -449,11 +484,25 @@ impl<'a> State<'a> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
render_pass.set_pipeline(&self.render_pipeline);
|
render_pass.set_pipeline(&self.render_pipeline);
|
||||||
render_pass.set_vertex_buffer(0, self.vertex_buffer.slice(..));
|
|
||||||
render_pass.set_index_buffer(self.index_buffer.slice(..), wgpu::IndexFormat::Uint16);
|
for shape in [Shape::Polygon, Shape::Circle] {
|
||||||
if !self.instances.is_empty() {
|
let geometry = &self.geometries[&shape];
|
||||||
|
|
||||||
|
let relevant_instances: Vec<_> = self.instances
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.filter(|(_, inst)| inst.shape == shape)
|
||||||
|
.map(|(i, _)| i as u32)
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
if relevant_instances.is_empty() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
render_pass.set_vertex_buffer(0, geometry.vertex_buffer.slice(..));
|
||||||
render_pass.set_vertex_buffer(1, self.instance_buffer.slice(..));
|
render_pass.set_vertex_buffer(1, self.instance_buffer.slice(..));
|
||||||
render_pass.draw_indexed(0..self.num_indices, 0, 0..self.instances.len() as u32);
|
render_pass.set_index_buffer(geometry.index_buffer.slice(..), wgpu::IndexFormat::Uint16);
|
||||||
|
render_pass.draw_indexed(0..geometry.index_count, 0, 0..relevant_instances.len() as u32);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user