diff --git a/src/chunk.rs b/src/chunk.rs index 9e65c42..9a50bd5 100644 --- a/src/chunk.rs +++ b/src/chunk.rs @@ -368,8 +368,8 @@ impl Chunk { quads } - fn quads_to_geometry(quads: Vec) -> Geometry { - let mut geometry: Geometry = Default::default(); + fn quads_to_geometry(quads: Vec) -> Geometry { + let mut geometry: Geometry = Default::default(); for quad in quads { geometry.append(&mut quad.to_geometry(geometry.vertices.len() as u16)); } @@ -380,7 +380,7 @@ impl Chunk { &self, position: Point3, highlighted: Option<&(Point3, Vector3)>, - ) -> Geometry { + ) -> Geometry { let quads: Vec = (0..CHUNK_SIZE) .into_par_iter() .flat_map(|y| { diff --git a/src/geometry.rs b/src/geometry.rs index 98127a8..52b8b7c 100644 --- a/src/geometry.rs +++ b/src/geometry.rs @@ -1,3 +1,5 @@ +use std::marker::PhantomData; + use wgpu::{ util::{BufferInitDescriptor, DeviceExt}, RenderPass, @@ -7,13 +9,13 @@ use crate::{render_context::RenderContext, vertex::Vertex}; /// Represents a set of triangles by its vertices and indices. #[derive(Default)] -pub struct Geometry { - pub vertices: Vec, - pub indices: Vec, +pub struct Geometry { + pub vertices: Vec, + pub indices: Vec, } -impl Geometry { - pub fn new(vertices: Vec, indices: Vec) -> Self { +impl Geometry { + pub fn new(vertices: Vec, indices: Vec) -> Self { Self { vertices, indices } } @@ -29,16 +31,19 @@ impl Geometry { } } -pub struct GeometryBuffers { +pub struct GeometryBuffers { pub vertices: wgpu::Buffer, pub indices: wgpu::Buffer, pub index_count: usize, + + // Phantom data to store the index type + _phantom: PhantomData, } -impl GeometryBuffers { - pub fn from_geometry( +impl GeometryBuffers { + pub fn from_geometry( render_context: &RenderContext, - geometry: &Geometry, + geometry: &Geometry, usage: wgpu::BufferUsage, ) -> Self { let vertices = render_context @@ -61,15 +66,26 @@ impl GeometryBuffers { vertices, indices, index_count: geometry.index_count(), + _phantom: PhantomData, } } + pub fn draw_indexed(&self, render_pass: &mut RenderPass) -> usize { + render_pass.draw_indexed(0..self.index_count as u32, 0, 0..1); + self.index_count / 3 + } +} + +impl GeometryBuffers { pub fn set_buffers<'a>(&'a self, render_pass: &mut RenderPass<'a>) { render_pass.set_vertex_buffer(0, self.vertices.slice(..)); render_pass.set_index_buffer(self.indices.slice(..), wgpu::IndexFormat::Uint16); } +} - pub fn draw_indexed(&self, render_pass: &mut RenderPass) { - render_pass.draw_indexed(0..self.index_count as u32, 0, 0..1); +impl GeometryBuffers { + pub fn set_buffers<'a>(&'a self, render_pass: &mut RenderPass<'a>) { + render_pass.set_vertex_buffer(0, self.vertices.slice(..)); + render_pass.set_index_buffer(self.indices.slice(..), wgpu::IndexFormat::Uint32); } } diff --git a/src/npc.rs b/src/npc.rs index 080b281..546885f 100644 --- a/src/npc.rs +++ b/src/npc.rs @@ -2,17 +2,20 @@ extern crate gltf; extern crate wgpu; use cgmath::Vector3; +use wgpu::BufferUsage; -use crate::vertex::BlockVertex; +use crate::{ + geometry::{Geometry, GeometryBuffers}, + render_context::RenderContext, + vertex::BlockVertex, +}; pub struct Npc { pub position: Vector3, pub scale: Vector3, pub rotation: Vector3, - pub vertices: Vec, - pub indices: Vec, - pub vertex_buffer: Option, - pub index_buffer: Option, + pub geometry: Geometry, + pub geometry_buffers: Option>, } impl Npc { @@ -56,10 +59,16 @@ impl Npc { position, scale, rotation, - indices, - vertices, - vertex_buffer: None, - index_buffer: None, + geometry: Geometry::new(vertices, indices), + geometry_buffers: None, }; } + + pub fn load_geometry(&mut self, render_context: &RenderContext) { + self.geometry_buffers = Some(GeometryBuffers::from_geometry( + render_context, + &self.geometry, + BufferUsage::empty(), + )); + } } diff --git a/src/quad.rs b/src/quad.rs index 0bbd25b..8803e5c 100644 --- a/src/quad.rs +++ b/src/quad.rs @@ -52,7 +52,7 @@ impl Quad { pub fn to_geometry( &self, start_index: u16, - ) -> Geometry { + ) -> Geometry { let dx = self.dx as f32; let dz = self.dz as f32; let dy = 1.0; diff --git a/src/state/hud_state.rs b/src/state/hud_state.rs index b201cf9..a78881d 100644 --- a/src/state/hud_state.rs +++ b/src/state/hud_state.rs @@ -19,16 +19,16 @@ const UI_SCALE_Y: f32 = 0.008; pub struct HudState { texture_bind_group: wgpu::BindGroup, render_pipeline: wgpu::RenderPipeline, - hud_geometry_buffers: GeometryBuffers, + hud_geometry_buffers: GeometryBuffers, text_renderer: TextRenderer, - fps_geometry_buffers: GeometryBuffers, + fps_geometry_buffers: GeometryBuffers, fps_instant: Instant, fps_frames: u32, fps_elapsed: Duration, - coordinates_geometry_buffers: GeometryBuffers, + coordinates_geometry_buffers: GeometryBuffers, coordinates_last: Vector3, pub hotbar_cursor_position: i32, } diff --git a/src/state/world_state.rs b/src/state/world_state.rs index 6b87f84..fe509cb 100644 --- a/src/state/world_state.rs +++ b/src/state/world_state.rs @@ -212,25 +212,6 @@ impl WorldState { }) } - /// TODO Move to World - pub fn load_npc_geometry(&mut self, render_context: &RenderContext) { - self.world.npc.vertex_buffer = Some(render_context.device.create_buffer_init( - &BufferInitDescriptor { - label: None, - contents: &bytemuck::cast_slice(&self.world.npc.vertices), - usage: wgpu::BufferUsage::VERTEX, - }, - )); - - self.world.npc.index_buffer = Some(render_context.device.create_buffer_init( - &BufferInitDescriptor { - label: None, - contents: &bytemuck::cast_slice(&self.world.npc.indices), - usage: wgpu::BufferUsage::INDEX, - }, - )); - } - pub fn toggle_wireframe(&mut self, render_context: &RenderContext) { self.wireframe = !self.wireframe; self.render_pipeline = Self::create_render_pipeline( @@ -251,7 +232,8 @@ impl WorldState { let (time, time_buffer, time_layout, time_bind_group) = Self::create_time(render_context); - let world = World::new(); + let mut world = World::new(); + world.npc.load_geometry(render_context); let shader = render_context.device.create_shader_module( &(wgpu::ShaderModuleDescriptor { @@ -277,7 +259,7 @@ impl WorldState { Self::create_render_pipeline(&render_context, &shader, &render_pipeline_layout, false); let depth_texture = Texture::create_depth_texture(render_context, "depth_texture"); - let mut world_state = Self { + Self { render_pipeline, view, view_buffer, @@ -304,11 +286,7 @@ impl WorldState { left_pressed: false, right_pressed: false, creative: true, - }; - - world_state.load_npc_geometry(render_context); - - world_state + } } pub fn render(&self, frame: &SwapChainTexture, render_encoder: &mut CommandEncoder) -> usize { diff --git a/src/text_renderer.rs b/src/text_renderer.rs index 524fe5d..8815d98 100644 --- a/src/text_renderer.rs +++ b/src/text_renderer.rs @@ -124,7 +124,12 @@ impl TextRenderer { (vertices, indices) } - pub fn string_geometry(&self, mut x: f32, mut y: f32, string: &str) -> Geometry { + pub fn string_geometry( + &self, + mut x: f32, + mut y: f32, + string: &str, + ) -> Geometry { let mut vertices = Vec::new(); let mut indices = Vec::new(); @@ -153,7 +158,7 @@ impl TextRenderer { x: f32, y: f32, string: &str, - ) -> GeometryBuffers { + ) -> GeometryBuffers { let geometry = self.string_geometry(x, y, string); GeometryBuffers::from_geometry(render_context, &geometry, wgpu::BufferUsage::empty()) } diff --git a/src/world.rs b/src/world.rs index 709dd86..1ef3915 100644 --- a/src/world.rs +++ b/src/world.rs @@ -19,7 +19,7 @@ pub struct World { pub chunk_save_queue: VecDeque>, pub chunk_load_queue: VecDeque>, pub chunk_generate_queue: VecDeque>, - pub chunk_buffers: AHashMap, GeometryBuffers>, + pub chunk_buffers: AHashMap, GeometryBuffers>, pub highlighted: Option<(Point3, Vector3)>, } @@ -117,15 +117,13 @@ impl World { } buffers.set_buffers(render_pass); - buffers.draw_indexed(render_pass); - triangle_count += buffers.index_count / 3; + triangle_count += buffers.draw_indexed(render_pass); } { let buffers = self.npc.geometry_buffers.as_ref().unwrap(); buffers.set_buffers(render_pass); - render_pass.draw_indexed(0..self.npc.indices.len() as u32, 0, 0..1); - triangle_count += self.npc.indices.len() / 3; + triangle_count += buffers.draw_indexed(render_pass); } triangle_count