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
}
fn quads_to_geometry(quads: Vec<Quad>) -> Geometry<BlockVertex> {
let mut geometry: Geometry<BlockVertex> = Default::default();
fn quads_to_geometry(quads: Vec<Quad>) -> Geometry<BlockVertex, u16> {
let mut geometry: Geometry<BlockVertex, u16> = 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<isize>,
highlighted: Option<&(Point3<usize>, Vector3<i32>)>,
) -> Geometry<BlockVertex> {
) -> Geometry<BlockVertex, u16> {
let quads: Vec<Quad> = (0..CHUNK_SIZE)
.into_par_iter()
.flat_map(|y| {

View file

@ -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<T: Vertex> {
pub vertices: Vec<T>,
pub indices: Vec<u16>,
pub struct Geometry<V: Vertex, I> {
pub vertices: Vec<V>,
pub indices: Vec<I>,
}
impl<T: Vertex> Geometry<T> {
pub fn new(vertices: Vec<T>, indices: Vec<u16>) -> Self {
impl<T: Vertex, I> Geometry<T, I> {
pub fn new(vertices: Vec<T>, indices: Vec<I>) -> Self {
Self { vertices, indices }
}
@ -29,16 +31,19 @@ impl<T: Vertex> Geometry<T> {
}
}
pub struct GeometryBuffers {
pub struct GeometryBuffers<I> {
pub vertices: wgpu::Buffer,
pub indices: wgpu::Buffer,
pub index_count: usize,
// Phantom data to store the index type
_phantom: PhantomData<I>,
}
impl GeometryBuffers {
pub fn from_geometry<T: Vertex + bytemuck::Pod>(
impl<I: bytemuck::Pod> GeometryBuffers<I> {
pub fn from_geometry<V: Vertex + bytemuck::Pod>(
render_context: &RenderContext,
geometry: &Geometry<T>,
geometry: &Geometry<V, I>,
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<u16> {
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<u32> {
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;
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<f32>,
pub scale: Vector3<f32>,
pub rotation: Vector3<f32>,
pub vertices: Vec<BlockVertex>,
pub indices: Vec<u32>,
pub vertex_buffer: Option<wgpu::Buffer>,
pub index_buffer: Option<wgpu::Buffer>,
pub geometry: Geometry<BlockVertex, u32>,
pub geometry_buffers: Option<GeometryBuffers<u32>>,
}
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(),
));
}
}

View file

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

View file

@ -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<u16>,
text_renderer: TextRenderer,
fps_geometry_buffers: GeometryBuffers,
fps_geometry_buffers: GeometryBuffers<u16>,
fps_instant: Instant,
fps_frames: u32,
fps_elapsed: Duration,
coordinates_geometry_buffers: GeometryBuffers,
coordinates_geometry_buffers: GeometryBuffers<u16>,
coordinates_last: Vector3<f32>,
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) {
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 {

View file

@ -124,7 +124,12 @@ impl TextRenderer {
(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 indices = Vec::new();
@ -153,7 +158,7 @@ impl TextRenderer {
x: f32,
y: f32,
string: &str,
) -> GeometryBuffers {
) -> GeometryBuffers<u16> {
let geometry = self.string_geometry(x, y, string);
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_load_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>)>,
}
@ -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