Added Spheres and improved geometry creation

This commit is contained in:
Verox001 2025-05-05 21:52:42 +02:00
parent 5a680e73f0
commit d5f5949107
3 changed files with 70 additions and 33 deletions

View File

@ -64,7 +64,7 @@ pub async fn run() {
_ => [0.5, 0.5, 0.5], _ => [0.5, 0.5, 0.5],
}, },
scale: 0.05, scale: 0.05,
shape: solar_engine::Shape::Circle, shape: solar_engine::Shape::Sphere,
} }
}) })
.collect(); .collect();

View File

@ -8,6 +8,7 @@ pub struct Globals {
pub enum Shape { pub enum Shape {
Polygon, Polygon,
Circle, Circle,
Sphere,
} }
pub struct Geometry { pub struct Geometry {
@ -107,3 +108,42 @@ pub fn create_circle_vertices(segment_count: usize, radius: f32, color: [f32; 3]
(vertices, indices) (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();
vertices.push(Vertex {
position: [x * radius, y * radius, z * radius],
color,
});
}
}
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)
}

View File

@ -9,7 +9,7 @@ use wgpu::{Adapter, Device, Instance, PresentMode, Queue, Surface, SurfaceCapabi
use winit::dpi::PhysicalSize; use winit::dpi::PhysicalSize;
use winit::window::{Window}; use winit::window::{Window};
use crate::camera::Camera; use crate::camera::Camera;
use crate::render::{create_circle_vertices, Geometry, Globals, InstanceRaw, RenderInstance, SampleCount, Shape, Vertex}; use crate::render::{create_circle_vertices, create_sphere_vertices, Geometry, Globals, InstanceRaw, RenderInstance, SampleCount, Shape, Vertex};
pub struct State<'a> { pub struct State<'a> {
surface: Surface<'a>, surface: Surface<'a>,
@ -123,42 +123,39 @@ impl<'a> State<'a> {
]; ];
let polygon_indices = vec![0, 1, 4, 1, 2, 4, 2, 3, 4]; let polygon_indices = vec![0, 1, 4, 1, 2, 4, 2, 3, 4];
let polygon_vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { let polygon_geometry = Self::create_geometry(device, &polygon_vertices, &polygon_indices);
label: Some("Polygon Vertex Buffer"), geometries.insert(Shape::Polygon, polygon_geometry);
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(512, 0.5, [0.5, 0.5, 0.5]); let (circle_vertices, circle_indices) = create_circle_vertices(512, 0.5, [0.5, 0.5, 0.5]);
let circle_vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { let circle_geometry = Self::create_geometry(device, &circle_vertices, &circle_indices);
label: Some("Circle Vertex Buffer"), geometries.insert(Shape::Circle, circle_geometry);
contents: bytemuck::cast_slice(&circle_vertices),
usage: wgpu::BufferUsages::VERTEX, let (sphere_vertices, sphere_indices) = create_sphere_vertices(32, 32, 0.5, [0.5, 0.5, 0.5]);
}); let sphere_geometry = Self::create_geometry(device, &sphere_vertices, &sphere_indices);
let circle_index_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { geometries.insert(Shape::Sphere, sphere_geometry);
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,
});
geometries geometries
} }
fn create_geometry(device: &Device, vertices: &[Vertex], indices: &[u16]) -> Geometry {
let vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
label: Some("Vertex Buffer"),
contents: bytemuck::cast_slice(vertices),
usage: wgpu::BufferUsages::VERTEX,
});
let index_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
label: Some("Index Buffer"),
contents: bytemuck::cast_slice(indices),
usage: wgpu::BufferUsages::INDEX,
});
Geometry {
vertex_buffer,
index_buffer,
index_count: indices.len() as u32,
}
}
fn probe_msaa_support(device: &Device, config: &SurfaceConfiguration) -> u32 { fn probe_msaa_support(device: &Device, config: &SurfaceConfiguration) -> u32 {
pollster::block_on(async { pollster::block_on(async {
for &count in &[16, 8, 4, 2] { for &count in &[16, 8, 4, 2] {
@ -361,7 +358,7 @@ impl<'a> State<'a> {
render_pass.set_pipeline(&self.render_pipeline); render_pass.set_pipeline(&self.render_pipeline);
render_pass.set_bind_group(0, &self.global_bind_group, &[]); render_pass.set_bind_group(0, &self.global_bind_group, &[]);
for shape in [Shape::Polygon, Shape::Circle] { for shape in self.geometries.keys().copied() {
let geometry = &self.geometries[&shape]; let geometry = &self.geometries[&shape];
let relevant_instances: Vec<_> = self.instances let relevant_instances: Vec<_> = self.instances