Added circles and geometries
This commit is contained in:
parent
7eacf0d0a5
commit
e709e2dd3f
@ -1,4 +1,5 @@
|
||||
use std::cmp::max;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::{Arc, RwLock};
|
||||
use std::thread;
|
||||
use std::time::Duration;
|
||||
@ -21,11 +22,24 @@ pub async fn run() {
|
||||
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 {
|
||||
position: cgmath::Vector3<f32>,
|
||||
rotation: cgmath::Quaternion<f32>,
|
||||
color: [f32; 3],
|
||||
scale: f32
|
||||
scale: f32,
|
||||
shape: Shape,
|
||||
}
|
||||
|
||||
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> {
|
||||
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> {
|
||||
surface: Surface<'a>,
|
||||
device: Device,
|
||||
@ -158,14 +178,11 @@ struct State<'a> {
|
||||
window: Arc<Window>,
|
||||
|
||||
render_pipeline: wgpu::RenderPipeline,
|
||||
vertex_buffer: wgpu::Buffer,
|
||||
index_buffer: wgpu::Buffer,
|
||||
|
||||
instances: Vec<RenderInstance>,
|
||||
instance_buffer: wgpu::Buffer,
|
||||
|
||||
num_vertices: u32,
|
||||
num_indices: u32,
|
||||
geometries: HashMap<Shape, Geometry>,
|
||||
|
||||
simulator: Arc<RwLock<Simulator>>,
|
||||
}
|
||||
@ -183,11 +200,51 @@ impl<'a> State<'a> {
|
||||
surface.configure(&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 num_indices = INDICES.len() as u32;
|
||||
let mut geometries = HashMap::new();
|
||||
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);
|
||||
sim.add_body(Body {
|
||||
@ -231,6 +288,7 @@ impl<'a> State<'a> {
|
||||
_ => [0.5, 0.5, 0.5],
|
||||
},
|
||||
scale: 0.1,
|
||||
shape: Shape::Circle
|
||||
}).collect::<Vec<_>>()
|
||||
};
|
||||
|
||||
@ -250,15 +308,11 @@ impl<'a> State<'a> {
|
||||
window: window_arc,
|
||||
|
||||
render_pipeline,
|
||||
vertex_buffer,
|
||||
index_buffer,
|
||||
geometries,
|
||||
|
||||
instances,
|
||||
instance_buffer,
|
||||
|
||||
num_vertices,
|
||||
num_indices,
|
||||
|
||||
simulator,
|
||||
}
|
||||
}
|
||||
@ -279,6 +333,7 @@ impl<'a> State<'a> {
|
||||
_ => [0.5, 0.5, 0.5],
|
||||
},
|
||||
scale: 0.5,
|
||||
shape: Shape::Circle
|
||||
}).collect()
|
||||
};
|
||||
|
||||
@ -287,26 +342,6 @@ impl<'a> State<'a> {
|
||||
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 {
|
||||
let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor {
|
||||
label: Some("Shader"),
|
||||
@ -449,11 +484,25 @@ impl<'a> State<'a> {
|
||||
});
|
||||
|
||||
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);
|
||||
if !self.instances.is_empty() {
|
||||
|
||||
for shape in [Shape::Polygon, Shape::Circle] {
|
||||
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.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