Make Geometry indices generic, make The Crab use it
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Sijmen 2021-06-03 12:13:24 +02:00
parent bd54a1bc14
commit 206f7857fa
Signed by: vijfhoek
GPG key ID: 82D05C89B28B0DAE
8 changed files with 66 additions and 60 deletions

View file

@ -368,8 +368,8 @@ impl Chunk {
quads quads
} }
fn quads_to_geometry(quads: Vec<Quad>) -> Geometry<BlockVertex> { fn quads_to_geometry(quads: Vec<Quad>) -> Geometry<BlockVertex, u16> {
let mut geometry: Geometry<BlockVertex> = Default::default(); let mut geometry: Geometry<BlockVertex, u16> = Default::default();
for quad in quads { for quad in quads {
geometry.append(&mut quad.to_geometry(geometry.vertices.len() as u16)); geometry.append(&mut quad.to_geometry(geometry.vertices.len() as u16));
} }
@ -380,7 +380,7 @@ impl Chunk {
&self, &self,
position: Point3<isize>, position: Point3<isize>,
highlighted: Option<&(Point3<usize>, Vector3<i32>)>, highlighted: Option<&(Point3<usize>, Vector3<i32>)>,
) -> Geometry<BlockVertex> { ) -> Geometry<BlockVertex, u16> {
let quads: Vec<Quad> = (0..CHUNK_SIZE) let quads: Vec<Quad> = (0..CHUNK_SIZE)
.into_par_iter() .into_par_iter()
.flat_map(|y| { .flat_map(|y| {

View file

@ -1,3 +1,5 @@
use std::marker::PhantomData;
use wgpu::{ use wgpu::{
util::{BufferInitDescriptor, DeviceExt}, util::{BufferInitDescriptor, DeviceExt},
RenderPass, RenderPass,
@ -7,13 +9,13 @@ use crate::{render_context::RenderContext, vertex::Vertex};
/// Represents a set of triangles by its vertices and indices. /// Represents a set of triangles by its vertices and indices.
#[derive(Default)] #[derive(Default)]
pub struct Geometry<T: Vertex> { pub struct Geometry<V: Vertex, I> {
pub vertices: Vec<T>, pub vertices: Vec<V>,
pub indices: Vec<u16>, pub indices: Vec<I>,
} }
impl<T: Vertex> Geometry<T> { impl<T: Vertex, I> Geometry<T, I> {
pub fn new(vertices: Vec<T>, indices: Vec<u16>) -> Self { pub fn new(vertices: Vec<T>, indices: Vec<I>) -> Self {
Self { vertices, indices } Self { vertices, indices }
} }
@ -29,16 +31,19 @@ impl<T: Vertex> Geometry<T> {
} }
} }
pub struct GeometryBuffers { pub struct GeometryBuffers<I> {
pub vertices: wgpu::Buffer, pub vertices: wgpu::Buffer,
pub indices: wgpu::Buffer, pub indices: wgpu::Buffer,
pub index_count: usize, pub index_count: usize,
// Phantom data to store the index type
_phantom: PhantomData<I>,
} }
impl GeometryBuffers { impl<I: bytemuck::Pod> GeometryBuffers<I> {
pub fn from_geometry<T: Vertex + bytemuck::Pod>( pub fn from_geometry<V: Vertex + bytemuck::Pod>(
render_context: &RenderContext, render_context: &RenderContext,
geometry: &Geometry<T>, geometry: &Geometry<V, I>,
usage: wgpu::BufferUsage, usage: wgpu::BufferUsage,
) -> Self { ) -> Self {
let vertices = render_context let vertices = render_context
@ -61,15 +66,26 @@ impl GeometryBuffers {
vertices, vertices,
indices, indices,
index_count: geometry.index_count(), 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<u16> {
pub fn set_buffers<'a>(&'a self, render_pass: &mut RenderPass<'a>) { pub fn set_buffers<'a>(&'a self, render_pass: &mut RenderPass<'a>) {
render_pass.set_vertex_buffer(0, self.vertices.slice(..)); render_pass.set_vertex_buffer(0, self.vertices.slice(..));
render_pass.set_index_buffer(self.indices.slice(..), wgpu::IndexFormat::Uint16); render_pass.set_index_buffer(self.indices.slice(..), wgpu::IndexFormat::Uint16);
} }
}
pub fn draw_indexed(&self, render_pass: &mut RenderPass) { impl GeometryBuffers<u32> {
render_pass.draw_indexed(0..self.index_count as u32, 0, 0..1); 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);
} }
} }

View file

@ -2,17 +2,20 @@ extern crate gltf;
extern crate wgpu; extern crate wgpu;
use cgmath::Vector3; use cgmath::Vector3;
use wgpu::BufferUsage;
use crate::vertex::BlockVertex; use crate::{
geometry::{Geometry, GeometryBuffers},
render_context::RenderContext,
vertex::BlockVertex,
};
pub struct Npc { pub struct Npc {
pub position: Vector3<f32>, pub position: Vector3<f32>,
pub scale: Vector3<f32>, pub scale: Vector3<f32>,
pub rotation: Vector3<f32>, pub rotation: Vector3<f32>,
pub vertices: Vec<BlockVertex>, pub geometry: Geometry<BlockVertex, u32>,
pub indices: Vec<u32>, pub geometry_buffers: Option<GeometryBuffers<u32>>,
pub vertex_buffer: Option<wgpu::Buffer>,
pub index_buffer: Option<wgpu::Buffer>,
} }
impl Npc { impl Npc {
@ -56,10 +59,16 @@ impl Npc {
position, position,
scale, scale,
rotation, rotation,
indices, geometry: Geometry::new(vertices, indices),
vertices, geometry_buffers: None,
vertex_buffer: None,
index_buffer: None,
}; };
} }
pub fn load_geometry(&mut self, render_context: &RenderContext) {
self.geometry_buffers = Some(GeometryBuffers::from_geometry(
render_context,
&self.geometry,
BufferUsage::empty(),
));
}
} }

View file

@ -52,7 +52,7 @@ impl Quad {
pub fn to_geometry( pub fn to_geometry(
&self, &self,
start_index: u16, start_index: u16,
) -> Geometry<BlockVertex> { ) -> Geometry<BlockVertex, u16> {
let dx = self.dx as f32; let dx = self.dx as f32;
let dz = self.dz as f32; let dz = self.dz as f32;
let dy = 1.0; let dy = 1.0;

View file

@ -19,16 +19,16 @@ const UI_SCALE_Y: f32 = 0.008;
pub struct HudState { pub struct HudState {
texture_bind_group: wgpu::BindGroup, texture_bind_group: wgpu::BindGroup,
render_pipeline: wgpu::RenderPipeline, render_pipeline: wgpu::RenderPipeline,
hud_geometry_buffers: GeometryBuffers, hud_geometry_buffers: GeometryBuffers<u16>,
text_renderer: TextRenderer, text_renderer: TextRenderer,
fps_geometry_buffers: GeometryBuffers, fps_geometry_buffers: GeometryBuffers<u16>,
fps_instant: Instant, fps_instant: Instant,
fps_frames: u32, fps_frames: u32,
fps_elapsed: Duration, fps_elapsed: Duration,
coordinates_geometry_buffers: GeometryBuffers, coordinates_geometry_buffers: GeometryBuffers<u16>,
coordinates_last: Vector3<f32>, coordinates_last: Vector3<f32>,
pub hotbar_cursor_position: i32, pub hotbar_cursor_position: i32,
} }

View file

@ -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) { pub fn toggle_wireframe(&mut self, render_context: &RenderContext) {
self.wireframe = !self.wireframe; self.wireframe = !self.wireframe;
self.render_pipeline = Self::create_render_pipeline( 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 (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( let shader = render_context.device.create_shader_module(
&(wgpu::ShaderModuleDescriptor { &(wgpu::ShaderModuleDescriptor {
@ -277,7 +259,7 @@ impl WorldState {
Self::create_render_pipeline(&render_context, &shader, &render_pipeline_layout, false); Self::create_render_pipeline(&render_context, &shader, &render_pipeline_layout, false);
let depth_texture = Texture::create_depth_texture(render_context, "depth_texture"); let depth_texture = Texture::create_depth_texture(render_context, "depth_texture");
let mut world_state = Self { Self {
render_pipeline, render_pipeline,
view, view,
view_buffer, view_buffer,
@ -304,11 +286,7 @@ impl WorldState {
left_pressed: false, left_pressed: false,
right_pressed: false, right_pressed: false,
creative: true, creative: true,
}; }
world_state.load_npc_geometry(render_context);
world_state
} }
pub fn render(&self, frame: &SwapChainTexture, render_encoder: &mut CommandEncoder) -> usize { pub fn render(&self, frame: &SwapChainTexture, render_encoder: &mut CommandEncoder) -> usize {

View file

@ -124,7 +124,12 @@ impl TextRenderer {
(vertices, indices) (vertices, indices)
} }
pub fn string_geometry(&self, mut x: f32, mut y: f32, string: &str) -> Geometry<HudVertex> { pub fn string_geometry(
&self,
mut x: f32,
mut y: f32,
string: &str,
) -> Geometry<HudVertex, u16> {
let mut vertices = Vec::new(); let mut vertices = Vec::new();
let mut indices = Vec::new(); let mut indices = Vec::new();
@ -153,7 +158,7 @@ impl TextRenderer {
x: f32, x: f32,
y: f32, y: f32,
string: &str, string: &str,
) -> GeometryBuffers { ) -> GeometryBuffers<u16> {
let geometry = self.string_geometry(x, y, string); let geometry = self.string_geometry(x, y, string);
GeometryBuffers::from_geometry(render_context, &geometry, wgpu::BufferUsage::empty()) GeometryBuffers::from_geometry(render_context, &geometry, wgpu::BufferUsage::empty())
} }

View file

@ -19,7 +19,7 @@ pub struct World {
pub chunk_save_queue: VecDeque<Point3<isize>>, pub chunk_save_queue: VecDeque<Point3<isize>>,
pub chunk_load_queue: VecDeque<Point3<isize>>, pub chunk_load_queue: VecDeque<Point3<isize>>,
pub chunk_generate_queue: VecDeque<Point3<isize>>, pub chunk_generate_queue: VecDeque<Point3<isize>>,
pub chunk_buffers: AHashMap<Point3<isize>, GeometryBuffers>, pub chunk_buffers: AHashMap<Point3<isize>, GeometryBuffers<u16>>,
pub highlighted: Option<(Point3<isize>, Vector3<i32>)>, pub highlighted: Option<(Point3<isize>, Vector3<i32>)>,
} }
@ -117,15 +117,13 @@ impl World {
} }
buffers.set_buffers(render_pass); buffers.set_buffers(render_pass);
buffers.draw_indexed(render_pass); triangle_count += buffers.draw_indexed(render_pass);
triangle_count += buffers.index_count / 3;
} }
{ {
let buffers = self.npc.geometry_buffers.as_ref().unwrap(); let buffers = self.npc.geometry_buffers.as_ref().unwrap();
buffers.set_buffers(render_pass); buffers.set_buffers(render_pass);
render_pass.draw_indexed(0..self.npc.indices.len() as u32, 0, 0..1); triangle_count += buffers.draw_indexed(render_pass);
triangle_count += self.npc.indices.len() / 3;
} }
triangle_count triangle_count