Add GeometryBuffers struct containing vertex and index buffers
This commit is contained in:
parent
8bc41825d2
commit
14a2e91b26
4 changed files with 104 additions and 129 deletions
|
@ -1,4 +1,9 @@
|
|||
use crate::vertex::Vertex;
|
||||
use wgpu::{
|
||||
util::{BufferInitDescriptor, DeviceExt},
|
||||
RenderPass,
|
||||
};
|
||||
|
||||
use crate::{render_context::RenderContext, vertex::Vertex};
|
||||
|
||||
/// Represents a set of triangles by its vertices and indices.
|
||||
#[derive(Default)]
|
||||
|
@ -23,3 +28,48 @@ impl<T: Vertex> Geometry<T> {
|
|||
self.indices.len()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct GeometryBuffers {
|
||||
pub vertices: wgpu::Buffer,
|
||||
pub indices: wgpu::Buffer,
|
||||
pub index_count: usize,
|
||||
}
|
||||
|
||||
impl GeometryBuffers {
|
||||
pub fn from_geometry<T: Vertex + bytemuck::Pod>(
|
||||
render_context: &RenderContext,
|
||||
geometry: &Geometry<T>,
|
||||
usage: wgpu::BufferUsage,
|
||||
) -> Self {
|
||||
let vertices = render_context
|
||||
.device
|
||||
.create_buffer_init(&BufferInitDescriptor {
|
||||
label: None,
|
||||
contents: bytemuck::cast_slice(&geometry.vertices),
|
||||
usage: wgpu::BufferUsage::VERTEX | usage,
|
||||
});
|
||||
|
||||
let indices = render_context
|
||||
.device
|
||||
.create_buffer_init(&BufferInitDescriptor {
|
||||
label: None,
|
||||
contents: bytemuck::cast_slice(&geometry.indices),
|
||||
usage: wgpu::BufferUsage::INDEX | usage,
|
||||
});
|
||||
|
||||
Self {
|
||||
vertices,
|
||||
indices,
|
||||
index_count: geometry.index_count(),
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
use std::time::{Duration, Instant};
|
||||
|
||||
use cgmath::Vector3;
|
||||
use wgpu::{
|
||||
util::{BufferInitDescriptor, DeviceExt},
|
||||
CommandEncoder, SwapChainTexture,
|
||||
};
|
||||
use wgpu::{BufferUsage, CommandEncoder, SwapChainTexture};
|
||||
|
||||
use crate::{
|
||||
geometry::{Geometry, GeometryBuffers},
|
||||
render_context::RenderContext,
|
||||
text_renderer::{self, TextRenderer},
|
||||
texture::Texture,
|
||||
|
@ -19,21 +17,16 @@ const UI_SCALE_Y: f32 = 0.008;
|
|||
pub struct HudState {
|
||||
texture_bind_group: wgpu::BindGroup,
|
||||
render_pipeline: wgpu::RenderPipeline,
|
||||
hud_vertex_buffer: wgpu::Buffer,
|
||||
hud_index_buffer: wgpu::Buffer,
|
||||
hud_geometry_buffers: GeometryBuffers,
|
||||
|
||||
text_renderer: TextRenderer,
|
||||
|
||||
fps_vertex_buffer: wgpu::Buffer,
|
||||
fps_index_buffer: wgpu::Buffer,
|
||||
fps_index_count: usize,
|
||||
fps_geometry_buffers: GeometryBuffers,
|
||||
fps_instant: Instant,
|
||||
fps_frames: u32,
|
||||
fps_elapsed: Duration,
|
||||
|
||||
coordinates_vertex_buffer: wgpu::Buffer,
|
||||
coordinates_index_buffer: wgpu::Buffer,
|
||||
coordinates_index_count: usize,
|
||||
coordinates_geometry_buffers: GeometryBuffers,
|
||||
coordinates_last: Vector3<f32>,
|
||||
pub hotbar_cursor_position: i32,
|
||||
}
|
||||
|
@ -46,45 +39,33 @@ impl HudState {
|
|||
Self::create_render_pipeline(render_context, &[&texture_bind_group_layout]);
|
||||
|
||||
// HUD buffers
|
||||
let hud_vertex_buffer = render_context
|
||||
.device
|
||||
.create_buffer_init(&BufferInitDescriptor {
|
||||
label: Some("HUD crosshair vertex buffer"),
|
||||
contents: bytemuck::cast_slice(HUD_VERTICES),
|
||||
usage: wgpu::BufferUsage::VERTEX | wgpu::BufferUsage::COPY_DST,
|
||||
});
|
||||
let hud_index_buffer = render_context
|
||||
.device
|
||||
.create_buffer_init(&BufferInitDescriptor {
|
||||
label: Some("HUD crosshair index buffer"),
|
||||
contents: bytemuck::cast_slice(HUD_INDICES),
|
||||
usage: wgpu::BufferUsage::INDEX,
|
||||
});
|
||||
let hud_geometry = Geometry {
|
||||
vertices: HUD_VERTICES.to_vec(),
|
||||
indices: HUD_INDICES.to_vec(),
|
||||
};
|
||||
let hud_geometry_buffers =
|
||||
GeometryBuffers::from_geometry(render_context, &hud_geometry, BufferUsage::COPY_DST);
|
||||
|
||||
// Text buffers
|
||||
let text_renderer = TextRenderer::new(render_context).unwrap();
|
||||
let (fps_vertex_buffer, fps_index_buffer, fps_index_count) =
|
||||
let fps_geometry_buffers =
|
||||
text_renderer.string_to_buffers(&render_context, -0.98, 0.97, "");
|
||||
let (coordinates_vertex_buffer, coordinates_index_buffer, coordinates_index_count) =
|
||||
let coordinates_geometry_buffers =
|
||||
text_renderer.string_to_buffers(&render_context, -0.98, 0.97 - text_renderer::DY, "");
|
||||
|
||||
Self {
|
||||
texture_bind_group,
|
||||
render_pipeline,
|
||||
hud_vertex_buffer,
|
||||
hud_index_buffer,
|
||||
text_renderer,
|
||||
|
||||
fps_vertex_buffer,
|
||||
fps_index_buffer,
|
||||
fps_index_count,
|
||||
hud_geometry_buffers,
|
||||
|
||||
fps_geometry_buffers,
|
||||
fps_instant: Instant::now(),
|
||||
fps_frames: 0,
|
||||
fps_elapsed: Duration::from_secs(0),
|
||||
|
||||
coordinates_vertex_buffer,
|
||||
coordinates_index_buffer,
|
||||
coordinates_index_count,
|
||||
coordinates_geometry_buffers,
|
||||
coordinates_last: Vector3::new(0.0, 0.0, 0.0),
|
||||
|
||||
hotbar_cursor_position: 0,
|
||||
|
@ -102,12 +83,9 @@ impl HudState {
|
|||
let fps = 1.0 / frametime.as_secs_f32();
|
||||
|
||||
let string = format!("{:<5.0} fps", fps);
|
||||
let (vertices, indices, index_count) =
|
||||
self.fps_geometry_buffers =
|
||||
self.text_renderer
|
||||
.string_to_buffers(render_context, -0.98, 0.97, &string);
|
||||
self.fps_vertex_buffer = vertices;
|
||||
self.fps_index_buffer = indices;
|
||||
self.fps_index_count = index_count;
|
||||
|
||||
self.fps_elapsed = Duration::from_secs(0);
|
||||
self.fps_frames = 0;
|
||||
|
@ -115,15 +93,12 @@ impl HudState {
|
|||
|
||||
if position != &self.coordinates_last {
|
||||
let string = format!("({:.1},{:.1},{:.1})", position.x, position.y, position.z,);
|
||||
let (vertices, indices, index_count) = self.text_renderer.string_to_buffers(
|
||||
self.coordinates_geometry_buffers = self.text_renderer.string_to_buffers(
|
||||
render_context,
|
||||
-0.98,
|
||||
0.97 - text_renderer::DY * 1.3,
|
||||
&string,
|
||||
);
|
||||
self.coordinates_vertex_buffer = vertices;
|
||||
self.coordinates_index_buffer = indices;
|
||||
self.coordinates_index_count = index_count;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -147,26 +122,23 @@ impl HudState {
|
|||
|
||||
render_pass.set_pipeline(&self.render_pipeline);
|
||||
|
||||
// Render the crosshair and hotbar
|
||||
render_pass.set_vertex_buffer(0, self.hud_vertex_buffer.slice(..));
|
||||
render_pass.set_index_buffer(self.hud_index_buffer.slice(..), wgpu::IndexFormat::Uint16);
|
||||
// Render the crosshair and
|
||||
self.hud_geometry_buffers.set_buffers(&mut render_pass);
|
||||
render_pass.set_bind_group(0, &self.texture_bind_group, &[]);
|
||||
render_pass.draw_indexed(0..HUD_INDICES.len() as u32, 0, 0..1);
|
||||
self.hud_geometry_buffers.draw_indexed(&mut render_pass);
|
||||
render_pass.draw_indexed(0..self.hud_geometry_buffers.index_count as u32, 0, 0..1);
|
||||
|
||||
// Render the FPS text
|
||||
render_pass.set_vertex_buffer(0, self.fps_vertex_buffer.slice(..));
|
||||
render_pass.set_index_buffer(self.fps_index_buffer.slice(..), wgpu::IndexFormat::Uint16);
|
||||
self.fps_geometry_buffers.set_buffers(&mut render_pass);
|
||||
render_pass.set_bind_group(0, &self.text_renderer.bind_group, &[]);
|
||||
render_pass.draw_indexed(0..self.fps_index_count as u32, 0, 0..1);
|
||||
self.fps_geometry_buffers.draw_indexed(&mut render_pass);
|
||||
|
||||
// Render the coordinates text
|
||||
render_pass.set_vertex_buffer(0, self.coordinates_vertex_buffer.slice(..));
|
||||
render_pass.set_index_buffer(
|
||||
self.coordinates_index_buffer.slice(..),
|
||||
wgpu::IndexFormat::Uint16,
|
||||
);
|
||||
self.coordinates_geometry_buffers
|
||||
.set_buffers(&mut render_pass);
|
||||
render_pass.set_bind_group(0, &self.text_renderer.bind_group, &[]);
|
||||
render_pass.draw_indexed(0..self.coordinates_index_count as u32, 0, 0..1);
|
||||
self.coordinates_geometry_buffers
|
||||
.draw_indexed(&mut render_pass);
|
||||
|
||||
Ok(HUD_INDICES.len() / 3)
|
||||
}
|
||||
|
@ -183,7 +155,7 @@ impl HudState {
|
|||
];
|
||||
|
||||
render_context.queue.write_buffer(
|
||||
&self.hud_vertex_buffer,
|
||||
&self.hud_geometry_buffers.vertices,
|
||||
HudVertex::descriptor().array_stride * 8,
|
||||
bytemuck::cast_slice(&vertices),
|
||||
);
|
||||
|
@ -323,7 +295,7 @@ impl HudState {
|
|||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
pub const HUD_VERTICES: &[HudVertex] = &[
|
||||
pub const HUD_VERTICES: [HudVertex; 12] = [
|
||||
// Crosshair
|
||||
HudVertex { position: [UI_SCALE_X * -8.0, UI_SCALE_Y * 8.0], texture_coordinates: [240.0 / 256.0, 0.0 / 256.0] },
|
||||
HudVertex { position: [UI_SCALE_X * 8.0, UI_SCALE_Y * 8.0], texture_coordinates: [256.0 / 256.0, 0.0 / 256.0] },
|
||||
|
@ -344,7 +316,7 @@ pub const HUD_VERTICES: &[HudVertex] = &[
|
|||
];
|
||||
|
||||
#[rustfmt::skip]
|
||||
pub const HUD_INDICES: &[u16] = &[
|
||||
pub const HUD_INDICES: [u16; 18] = [
|
||||
// Crosshair
|
||||
1, 0, 3,
|
||||
1, 3, 2,
|
||||
|
|
|
@ -4,7 +4,7 @@ use ahash::AHashMap;
|
|||
use cgmath::{EuclideanSpace, InnerSpace, Point3, Rad, Vector2, Vector3};
|
||||
use wgpu::{
|
||||
util::{BufferInitDescriptor, DeviceExt},
|
||||
CommandEncoder, SwapChainTexture,
|
||||
BufferUsage, CommandEncoder, SwapChainTexture,
|
||||
};
|
||||
use winit::{
|
||||
dpi::PhysicalSize,
|
||||
|
@ -14,6 +14,7 @@ use winit::{
|
|||
use crate::{
|
||||
camera::{Camera, Projection},
|
||||
chunk::{Block, BlockType, CHUNK_SIZE},
|
||||
geometry::GeometryBuffers,
|
||||
render_context::RenderContext,
|
||||
texture::{Texture, TextureManager},
|
||||
time::Time,
|
||||
|
@ -34,7 +35,7 @@ pub struct WorldState {
|
|||
pub time_bind_group: wgpu::BindGroup,
|
||||
pub world: World,
|
||||
|
||||
pub chunk_buffers: AHashMap<Vector3<usize>, (wgpu::Buffer, wgpu::Buffer, usize)>,
|
||||
pub chunk_buffers: AHashMap<Vector3<usize>, GeometryBuffers>,
|
||||
time: Time,
|
||||
time_buffer: wgpu::Buffer,
|
||||
wireframe: bool,
|
||||
|
@ -221,26 +222,12 @@ impl WorldState {
|
|||
let world_geometry = self.world.to_geometry(self.highlighted);
|
||||
self.chunk_buffers.clear();
|
||||
for (chunk_position, chunk_geometry) in world_geometry {
|
||||
self.chunk_buffers.insert(
|
||||
chunk_position,
|
||||
(
|
||||
render_context
|
||||
.device
|
||||
.create_buffer_init(&BufferInitDescriptor {
|
||||
label: None,
|
||||
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_geometry.indices),
|
||||
usage: wgpu::BufferUsage::INDEX,
|
||||
}),
|
||||
chunk_geometry.index_count(),
|
||||
),
|
||||
let buffers = GeometryBuffers::from_geometry(
|
||||
render_context,
|
||||
&chunk_geometry,
|
||||
BufferUsage::empty(),
|
||||
);
|
||||
self.chunk_buffers.insert(chunk_position, buffers);
|
||||
}
|
||||
|
||||
let elapsed = instant.elapsed();
|
||||
|
@ -259,26 +246,9 @@ impl WorldState {
|
|||
World::highlighted_for_chunk(self.highlighted, chunk_position).as_ref(),
|
||||
);
|
||||
|
||||
self.chunk_buffers.insert(
|
||||
chunk_position,
|
||||
(
|
||||
render_context
|
||||
.device
|
||||
.create_buffer_init(&BufferInitDescriptor {
|
||||
label: None,
|
||||
contents: &bytemuck::cast_slice(&geometry.vertices),
|
||||
usage: wgpu::BufferUsage::VERTEX,
|
||||
}),
|
||||
render_context
|
||||
.device
|
||||
.create_buffer_init(&BufferInitDescriptor {
|
||||
label: None,
|
||||
contents: &bytemuck::cast_slice(&geometry.indices),
|
||||
usage: wgpu::BufferUsage::INDEX,
|
||||
}),
|
||||
geometry.index_count(),
|
||||
),
|
||||
);
|
||||
let buffers =
|
||||
GeometryBuffers::from_geometry(render_context, &geometry, BufferUsage::empty());
|
||||
self.chunk_buffers.insert(chunk_position, buffers);
|
||||
}
|
||||
|
||||
pub fn toggle_wireframe(&mut self, render_context: &RenderContext) {
|
||||
|
@ -401,17 +371,16 @@ impl WorldState {
|
|||
let camera_pos = self.camera.position.to_vec();
|
||||
let camera_pos = Vector2::new(camera_pos.x, camera_pos.z);
|
||||
|
||||
for (position, (chunk_vertices, chunk_indices, index_count)) in &self.chunk_buffers {
|
||||
for (position, buffers) in &self.chunk_buffers {
|
||||
let pos = (position * CHUNK_SIZE).cast().unwrap();
|
||||
let pos = Vector2::new(pos.x, pos.z);
|
||||
if (pos - camera_pos).magnitude() > 300.0 {
|
||||
continue;
|
||||
}
|
||||
|
||||
render_pass.set_vertex_buffer(0, chunk_vertices.slice(..));
|
||||
render_pass.set_index_buffer(chunk_indices.slice(..), wgpu::IndexFormat::Uint16);
|
||||
render_pass.draw_indexed(0..*index_count as u32, 0, 0..1);
|
||||
triangle_count += index_count / 3;
|
||||
buffers.set_buffers(&mut render_pass);
|
||||
buffers.draw_indexed(&mut render_pass);
|
||||
triangle_count += buffers.index_count / 3;
|
||||
}
|
||||
|
||||
triangle_count
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
use std::convert::TryInto;
|
||||
|
||||
use wgpu::util::{BufferInitDescriptor, DeviceExt};
|
||||
|
||||
use crate::{
|
||||
geometry::Geometry, render_context::RenderContext, texture::Texture, vertex::HudVertex,
|
||||
geometry::{Geometry, GeometryBuffers},
|
||||
render_context::RenderContext,
|
||||
texture::Texture,
|
||||
vertex::HudVertex,
|
||||
};
|
||||
|
||||
pub const DX: f32 = 20.0 / 640.0;
|
||||
|
@ -152,25 +153,8 @@ impl TextRenderer {
|
|||
x: f32,
|
||||
y: f32,
|
||||
string: &str,
|
||||
) -> (wgpu::Buffer, wgpu::Buffer, usize) {
|
||||
) -> GeometryBuffers {
|
||||
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(&geometry.vertices),
|
||||
usage: wgpu::BufferUsage::VERTEX,
|
||||
});
|
||||
|
||||
let index_buffer = render_context
|
||||
.device
|
||||
.create_buffer_init(&BufferInitDescriptor {
|
||||
label: Some("font renderer"),
|
||||
contents: bytemuck::cast_slice(&geometry.indices),
|
||||
usage: wgpu::BufferUsage::INDEX,
|
||||
});
|
||||
|
||||
(vertex_buffer, index_buffer, geometry.index_count())
|
||||
GeometryBuffers::from_geometry(render_context, &geometry, wgpu::BufferUsage::empty())
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue