Create Geometry struct to replace vertex/index tuples

This commit is contained in:
Sijmen 2021-06-02 02:33:26 +02:00
parent c8e455053b
commit 8bc41825d2
Signed by: vijfhoek
GPG key ID: 82D05C89B28B0DAE
9 changed files with 77 additions and 51 deletions

View file

@ -1,6 +1,6 @@
use std::{collections::VecDeque, convert::TryInto, usize};
use std::{collections::VecDeque, usize};
use crate::{cube, quad::Quad, vertex::BlockVertex};
use crate::{cube, geometry::Geometry, quad::Quad, vertex::BlockVertex};
use ahash::{AHashMap, AHashSet};
use cgmath::{Vector3, Zero};
use noise::utils::{NoiseMapBuilder, PlaneMapBuilder};
@ -321,13 +321,13 @@ impl Chunk {
fn quads_to_geometry(
quads: Vec<(BlockType, i32, Vector3<i32>, Quad, Vector3<i32>, FaceFlags)>,
) -> (Vec<BlockVertex>, Vec<u16>) {
let mut vertices = Vec::new();
let mut indices = Vec::new();
) -> Geometry<BlockVertex> {
let mut geometry: Geometry<BlockVertex> = Default::default();
for (block_type, y, offset, quad, highlighted, visible_faces) in quads {
let texture_indices = block_type.texture_indices();
let (quad_vertices, quad_indices) = &cube::vertices(
geometry.append(&mut cube::vertices(
&quad,
y,
1.0,
@ -335,21 +335,18 @@ impl Chunk {
texture_indices,
highlighted,
visible_faces,
vertices.len().try_into().unwrap(),
);
vertices.extend(quad_vertices);
indices.extend(quad_indices);
geometry.vertices.len() as u16,
));
}
(vertices, indices)
geometry
}
pub fn to_geometry(
&self,
offset: Vector3<i32>,
highlighted: Option<&(Vector3<usize>, Vector3<i32>)>,
) -> (Vec<BlockVertex>, Vec<u16>) {
) -> Geometry<BlockVertex> {
let mut quads: Vec<(BlockType, i32, Vector3<i32>, Quad, Vector3<i32>, FaceFlags)> =
Vec::new();

View file

@ -1,3 +1,4 @@
use crate::geometry::Geometry;
use cgmath::Vector3;
use crate::{
@ -17,7 +18,7 @@ pub fn vertices(
highlighted: Vector3<i32>,
visible_faces: FaceFlags,
start_index: u16,
) -> (Vec<BlockVertex>, Vec<u16>) {
) -> Geometry<BlockVertex> {
let w = quad.w as f32;
let h = quad.h as f32;
let zh = z_height;
@ -128,5 +129,5 @@ pub fn vertices(
]);
}
(vertices, indices)
Geometry::new(vertices, indices)
}

25
src/geometry.rs Normal file
View file

@ -0,0 +1,25 @@
use crate::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>,
}
impl<T: Vertex> Geometry<T> {
pub fn new(vertices: Vec<T>, indices: Vec<u16>) -> Self {
Self { vertices, indices }
}
/// Moves all the vertices and indices of `other` into `Self`, leaving `other` empty.
pub fn append(&mut self, other: &mut Self) {
self.vertices.append(&mut other.vertices);
self.indices.append(&mut other.indices);
}
/// Returns the number of indices in the vertex.
pub fn index_count(&self) -> usize {
self.indices.len()
}
}

View file

@ -2,6 +2,7 @@ mod aabb;
mod camera;
mod chunk;
mod cube;
mod geometry;
mod quad;
mod render_context;
mod state;

View file

@ -10,7 +10,7 @@ use crate::{
render_context::RenderContext,
text_renderer::{self, TextRenderer},
texture::Texture,
vertex::HudVertex,
vertex::{HudVertex, Vertex},
};
const UI_SCALE_X: f32 = 0.0045;

View file

@ -17,7 +17,7 @@ use crate::{
render_context::RenderContext,
texture::{Texture, TextureManager},
time::Time,
vertex::BlockVertex,
vertex::{BlockVertex, Vertex},
view::View,
world::World,
};
@ -220,7 +220,7 @@ impl WorldState {
let world_geometry = self.world.to_geometry(self.highlighted);
self.chunk_buffers.clear();
for (chunk_position, chunk_vertices, chunk_indices) in world_geometry {
for (chunk_position, chunk_geometry) in world_geometry {
self.chunk_buffers.insert(
chunk_position,
(
@ -228,17 +228,17 @@ impl WorldState {
.device
.create_buffer_init(&BufferInitDescriptor {
label: None,
contents: &bytemuck::cast_slice(&chunk_vertices),
contents: &bytemuck::cast_slice(&chunk_geometry.vertices),
usage: wgpu::BufferUsage::VERTEX,
}),
render_context
.device
.create_buffer_init(&BufferInitDescriptor {
label: None,
contents: &bytemuck::cast_slice(&chunk_indices),
contents: &bytemuck::cast_slice(&chunk_geometry.indices),
usage: wgpu::BufferUsage::INDEX,
}),
chunk_indices.len(),
chunk_geometry.index_count(),
),
);
}
@ -254,7 +254,7 @@ impl WorldState {
) {
let chunk = &mut self.world.chunks[chunk_position.y][chunk_position.z][chunk_position.x];
let offset = chunk_position.map(|f| (f * CHUNK_SIZE) as i32);
let (vertices, indices) = chunk.to_geometry(
let geometry = chunk.to_geometry(
offset,
World::highlighted_for_chunk(self.highlighted, chunk_position).as_ref(),
);
@ -266,17 +266,17 @@ impl WorldState {
.device
.create_buffer_init(&BufferInitDescriptor {
label: None,
contents: &bytemuck::cast_slice(&vertices),
contents: &bytemuck::cast_slice(&geometry.vertices),
usage: wgpu::BufferUsage::VERTEX,
}),
render_context
.device
.create_buffer_init(&BufferInitDescriptor {
label: None,
contents: &bytemuck::cast_slice(&indices),
contents: &bytemuck::cast_slice(&geometry.indices),
usage: wgpu::BufferUsage::INDEX,
}),
indices.len(),
geometry.index_count(),
),
);
}

View file

@ -2,7 +2,9 @@ use std::convert::TryInto;
use wgpu::util::{BufferInitDescriptor, DeviceExt};
use crate::{render_context::RenderContext, texture::Texture, vertex::HudVertex};
use crate::{
geometry::Geometry, render_context::RenderContext, texture::Texture, vertex::HudVertex,
};
pub const DX: f32 = 20.0 / 640.0;
pub const DY: f32 = 20.0 / 360.0;
@ -121,12 +123,7 @@ impl TextRenderer {
(vertices, indices)
}
pub fn string_geometry(
&self,
mut x: f32,
mut y: f32,
string: &str,
) -> (Vec<HudVertex>, Vec<u16>) {
pub fn string_geometry(&self, mut x: f32, mut y: f32, string: &str) -> Geometry<HudVertex> {
let mut vertices = Vec::new();
let mut indices = Vec::new();
@ -146,7 +143,7 @@ impl TextRenderer {
}
}
(vertices, indices)
Geometry::new(vertices, indices)
}
pub fn string_to_buffers(
@ -156,13 +153,13 @@ impl TextRenderer {
y: f32,
string: &str,
) -> (wgpu::Buffer, wgpu::Buffer, usize) {
let (vertices, indices) = self.string_geometry(x, y, string);
let geometry = self.string_geometry(x, y, string);
let vertex_buffer = render_context
.device
.create_buffer_init(&BufferInitDescriptor {
label: Some("font renderer"),
contents: bytemuck::cast_slice(&vertices),
contents: bytemuck::cast_slice(&geometry.vertices),
usage: wgpu::BufferUsage::VERTEX,
});
@ -170,10 +167,10 @@ impl TextRenderer {
.device
.create_buffer_init(&BufferInitDescriptor {
label: Some("font renderer"),
contents: bytemuck::cast_slice(&indices),
contents: bytemuck::cast_slice(&geometry.indices),
usage: wgpu::BufferUsage::INDEX,
});
(vertex_buffer, index_buffer, indices.len())
(vertex_buffer, index_buffer, geometry.index_count())
}
}

View file

@ -2,26 +2,30 @@ use std::mem::size_of;
use wgpu::VertexAttribute;
pub trait Vertex {
fn descriptor() -> wgpu::VertexBufferLayout<'static>;
}
#[repr(C)]
#[derive(Copy, Clone, Debug, Default, bytemuck::Pod, bytemuck::Zeroable)]
pub struct Vertex {
pub struct PlainVertex {
pub position: [f32; 3],
pub texture_coordinates: [f32; 2],
pub normal: [f32; 3],
}
const VERTEX_ATTRIBUTES: &[VertexAttribute] = &wgpu::vertex_attr_array![
const PLAIN_VERTEX_ATTRIBUTES: &[VertexAttribute] = &wgpu::vertex_attr_array![
0 => Float32x3,
1 => Float32x2,
2 => Float32x3,
];
impl Vertex {
pub fn descriptor() -> wgpu::VertexBufferLayout<'static> {
impl Vertex for PlainVertex {
fn descriptor() -> wgpu::VertexBufferLayout<'static> {
wgpu::VertexBufferLayout {
array_stride: size_of::<Self>() as wgpu::BufferAddress,
step_mode: wgpu::InputStepMode::Vertex,
attributes: VERTEX_ATTRIBUTES,
attributes: PLAIN_VERTEX_ATTRIBUTES,
}
}
}
@ -41,8 +45,8 @@ const HUD_VERTEX_ATTRIBUTES: &[VertexAttribute] = &wgpu::vertex_attr_array![
1 => Float32x2,
];
impl HudVertex {
pub fn descriptor() -> wgpu::VertexBufferLayout<'static> {
impl Vertex for HudVertex {
fn descriptor() -> wgpu::VertexBufferLayout<'static> {
wgpu::VertexBufferLayout {
array_stride: size_of::<Self>() as wgpu::BufferAddress,
step_mode: wgpu::InputStepMode::Vertex,
@ -74,8 +78,8 @@ const BLOCK_VERTEX_ATTRIBUTES: &[VertexAttribute] = &wgpu::vertex_attr_array![
4 => Sint32,
];
impl BlockVertex {
pub fn descriptor() -> wgpu::VertexBufferLayout<'static> {
impl Vertex for BlockVertex {
fn descriptor() -> wgpu::VertexBufferLayout<'static> {
wgpu::VertexBufferLayout {
array_stride: size_of::<Self>() as wgpu::BufferAddress,
step_mode: wgpu::InputStepMode::Vertex,

View file

@ -1,5 +1,6 @@
use crate::{
chunk::{Block, Chunk, CHUNK_SIZE},
geometry::Geometry,
vertex::BlockVertex,
};
use cgmath::{InnerSpace, Vector3};
@ -63,7 +64,7 @@ impl World {
pub fn to_geometry(
&self,
highlighted: Option<(Vector3<usize>, Vector3<i32>)>,
) -> Vec<(Vector3<usize>, Vec<BlockVertex>, Vec<u16>)> {
) -> Vec<(Vector3<usize>, Geometry<BlockVertex>)> {
let instant = std::time::Instant::now();
let chunks = &self.chunks;
@ -71,17 +72,17 @@ impl World {
.par_iter()
.enumerate()
.flat_map(|(y, chunks_y)| {
let mut geometry = Vec::new();
let mut chunk_geometry = Vec::new();
for (z, chunks_z) in chunks_y.iter().enumerate() {
for (x, chunk) in chunks_z.iter().enumerate() {
let chunk_position = Vector3::new(x as usize, y as usize, z as usize);
let offset = (chunk_position * CHUNK_SIZE).cast().unwrap();
let h = Self::highlighted_for_chunk(highlighted, chunk_position);
let (vertices, indices) = chunk.to_geometry(offset, h.as_ref());
geometry.push((Vector3::new(x, y, z), vertices, indices));
let geometry = chunk.to_geometry(offset, h.as_ref());
chunk_geometry.push((Vector3::new(x, y, z), geometry));
}
}
geometry
chunk_geometry
})
.collect();