Create Geometry struct to replace vertex/index tuples
This commit is contained in:
parent
c8e455053b
commit
8bc41825d2
9 changed files with 77 additions and 51 deletions
23
src/chunk.rs
23
src/chunk.rs
|
@ -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();
|
||||
|
||||
|
|
|
@ -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
25
src/geometry.rs
Normal 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()
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@ mod aabb;
|
|||
mod camera;
|
||||
mod chunk;
|
||||
mod cube;
|
||||
mod geometry;
|
||||
mod quad;
|
||||
mod render_context;
|
||||
mod state;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
11
src/world.rs
11
src/world.rs
|
@ -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();
|
||||
|
||||
|
|
Loading…
Reference in a new issue