Allow for selecting a block to place
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
6c2151ffb9
commit
ec6978fee9
9 changed files with 170 additions and 66 deletions
|
@ -1,7 +1,10 @@
|
||||||
|
use crate::texture::TextureManager;
|
||||||
|
|
||||||
pub struct RenderContext {
|
pub struct RenderContext {
|
||||||
pub surface: wgpu::Surface,
|
pub surface: wgpu::Surface,
|
||||||
pub device: wgpu::Device,
|
pub device: wgpu::Device,
|
||||||
pub queue: wgpu::Queue,
|
pub queue: wgpu::Queue,
|
||||||
pub swap_chain_descriptor: wgpu::SwapChainDescriptor,
|
pub swap_chain_descriptor: wgpu::SwapChainDescriptor,
|
||||||
pub swap_chain: wgpu::SwapChain,
|
pub swap_chain: wgpu::SwapChain,
|
||||||
|
pub texture_manager: Option<TextureManager>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
struct VertexInput {
|
struct VertexInput {
|
||||||
[[location(0)]] position: vec2<f32>;
|
[[location(0)]] position: vec2<f32>;
|
||||||
[[location(1)]] texture_coordinates: vec2<f32>;
|
[[location(1)]] texture_coordinates: vec2<f32>;
|
||||||
|
[[location(2)]] texture_index: i32;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct VertexOutput {
|
struct VertexOutput {
|
||||||
[[builtin(position)]] clip_position: vec4<f32>;
|
[[builtin(position)]] clip_position: vec4<f32>;
|
||||||
[[location(0)]] texture_coordinates: vec2<f32>;
|
[[location(0)]] texture_coordinates: vec2<f32>;
|
||||||
|
[[location(1)]] texture_index: i32;
|
||||||
};
|
};
|
||||||
|
|
||||||
[[stage(vertex)]]
|
[[stage(vertex)]]
|
||||||
|
@ -13,13 +15,14 @@ fn main(model: VertexInput) -> VertexOutput {
|
||||||
var out: VertexOutput;
|
var out: VertexOutput;
|
||||||
out.texture_coordinates = model.texture_coordinates;
|
out.texture_coordinates = model.texture_coordinates;
|
||||||
out.clip_position = vec4<f32>(model.position, 0.0, 1.0);
|
out.clip_position = vec4<f32>(model.position, 0.0, 1.0);
|
||||||
|
out.texture_index = model.texture_index;
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
[[group(0), binding(0)]] var sampler: sampler;
|
[[group(0), binding(0)]] var sampler: sampler;
|
||||||
[[group(0), binding(1)]] var texture: texture_2d<f32>;
|
[[group(0), binding(1)]] var texture: texture_2d_array<f32>;
|
||||||
|
|
||||||
[[stage(fragment)]]
|
[[stage(fragment)]]
|
||||||
fn main(in: VertexOutput) -> [[location(0)]] vec4<f32> {
|
fn main(in: VertexOutput) -> [[location(0)]] vec4<f32> {
|
||||||
return textureSample(texture, sampler, in.texture_coordinates);
|
return textureSample(texture, sampler, in.texture_coordinates, in.texture_index);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
use std::time::{Duration, Instant};
|
use std::{
|
||||||
|
convert::TryInto,
|
||||||
|
time::{Duration, Instant},
|
||||||
|
};
|
||||||
|
|
||||||
use cgmath::Vector3;
|
use cgmath::Vector3;
|
||||||
use wgpu::{BufferUsage, CommandEncoder, SwapChainTexture};
|
use wgpu::{BufferUsage, CommandEncoder, SwapChainTexture};
|
||||||
|
@ -10,6 +13,7 @@ use crate::{
|
||||||
text_renderer::{self, TextRenderer},
|
text_renderer::{self, TextRenderer},
|
||||||
texture::Texture,
|
texture::Texture,
|
||||||
vertex::{HudVertex, Vertex},
|
vertex::{HudVertex, Vertex},
|
||||||
|
world::block::BlockType,
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO update aspect ratio when resizing
|
// TODO update aspect ratio when resizing
|
||||||
|
@ -30,7 +34,10 @@ pub struct HudState {
|
||||||
|
|
||||||
coordinates_geometry_buffers: GeometryBuffers<u16>,
|
coordinates_geometry_buffers: GeometryBuffers<u16>,
|
||||||
coordinates_last: Vector3<f32>,
|
coordinates_last: Vector3<f32>,
|
||||||
pub hotbar_cursor_position: i32,
|
|
||||||
|
pub hotbar_cursor_position: usize,
|
||||||
|
hotbar_blocks: [Option<BlockType>; 9],
|
||||||
|
hotbar_block_buffers: Option<GeometryBuffers<u16>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HudState {
|
impl HudState {
|
||||||
|
@ -55,7 +62,19 @@ impl HudState {
|
||||||
let coordinates_geometry_buffers =
|
let coordinates_geometry_buffers =
|
||||||
text_renderer.string_to_buffers(&render_context, -0.98, 0.97 - text_renderer::DY, "");
|
text_renderer.string_to_buffers(&render_context, -0.98, 0.97 - text_renderer::DY, "");
|
||||||
|
|
||||||
Self {
|
let hotbar_blocks = [
|
||||||
|
Some(BlockType::Dirt),
|
||||||
|
Some(BlockType::Stone),
|
||||||
|
Some(BlockType::Sand),
|
||||||
|
None,
|
||||||
|
Some(BlockType::Grass),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
];
|
||||||
|
|
||||||
|
let mut hud_state = Self {
|
||||||
texture_bind_group,
|
texture_bind_group,
|
||||||
render_pipeline,
|
render_pipeline,
|
||||||
text_renderer,
|
text_renderer,
|
||||||
|
@ -71,7 +90,17 @@ impl HudState {
|
||||||
coordinates_last: Vector3::new(0.0, 0.0, 0.0),
|
coordinates_last: Vector3::new(0.0, 0.0, 0.0),
|
||||||
|
|
||||||
hotbar_cursor_position: 0,
|
hotbar_cursor_position: 0,
|
||||||
}
|
hotbar_blocks,
|
||||||
|
hotbar_block_buffers: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
hud_state.hotbar_block_buffers = Some(GeometryBuffers::from_geometry(
|
||||||
|
render_context,
|
||||||
|
&hud_state.hotbar_block_vertices(),
|
||||||
|
wgpu::BufferUsage::empty(),
|
||||||
|
));
|
||||||
|
|
||||||
|
hud_state
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(&mut self, render_context: &RenderContext, position: &Vector3<f32>) {
|
pub fn update(&mut self, render_context: &RenderContext, position: &Vector3<f32>) {
|
||||||
|
@ -106,6 +135,7 @@ impl HudState {
|
||||||
|
|
||||||
pub fn render(
|
pub fn render(
|
||||||
&self,
|
&self,
|
||||||
|
render_context: &RenderContext,
|
||||||
frame: &SwapChainTexture,
|
frame: &SwapChainTexture,
|
||||||
render_encoder: &mut CommandEncoder,
|
render_encoder: &mut CommandEncoder,
|
||||||
) -> anyhow::Result<usize> {
|
) -> anyhow::Result<usize> {
|
||||||
|
@ -141,18 +171,65 @@ impl HudState {
|
||||||
self.coordinates_geometry_buffers
|
self.coordinates_geometry_buffers
|
||||||
.draw_indexed(&mut render_pass);
|
.draw_indexed(&mut render_pass);
|
||||||
|
|
||||||
|
// Render the blocks on the hot bar
|
||||||
|
let texture_manager = render_context.texture_manager.as_ref().unwrap();
|
||||||
|
render_pass.set_bind_group(0, texture_manager.bind_group.as_ref().unwrap(), &[]);
|
||||||
|
self.hotbar_block_buffers
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.apply_buffers(&mut render_pass);
|
||||||
|
self.hotbar_block_buffers
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.draw_indexed(&mut render_pass);
|
||||||
|
|
||||||
Ok(HUD_INDICES.len() / 3)
|
Ok(HUD_INDICES.len() / 3)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn selected_block_type(&self) -> Option<BlockType> {
|
||||||
|
self.hotbar_blocks[self.hotbar_cursor_position]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn hotbar_block_vertices(&self) -> Geometry<HudVertex, u16> {
|
||||||
|
let mut vertices = Vec::new();
|
||||||
|
let mut indices = Vec::new();
|
||||||
|
|
||||||
|
let mut index = 0;
|
||||||
|
for cursor_index in 0..9 {
|
||||||
|
if let Some(block) = self.hotbar_blocks[cursor_index as usize] {
|
||||||
|
let x = (-92 + 20 * cursor_index as i32) as f32;
|
||||||
|
let texture_index = block.texture_indices().2.try_into().unwrap();
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
|
vertices.extend(&[
|
||||||
|
HudVertex { position: [UI_SCALE_X * (x + 5.0), -1.0 + UI_SCALE_Y * 18.0], texture_coordinates: [0.0, 0.0], texture_index },
|
||||||
|
HudVertex { position: [UI_SCALE_X * (x + 19.0), -1.0 + UI_SCALE_Y * 18.0], texture_coordinates: [1.0, 0.0], texture_index },
|
||||||
|
HudVertex { position: [UI_SCALE_X * (x + 19.0), -1.0 + UI_SCALE_Y * 4.0], texture_coordinates: [1.0, 1.0], texture_index },
|
||||||
|
HudVertex { position: [UI_SCALE_X * (x + 5.0), -1.0 + UI_SCALE_Y * 4.0], texture_coordinates: [0.0, 1.0], texture_index },
|
||||||
|
]);
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
|
indices.extend(&[
|
||||||
|
index, 2 + index, 1 + index,
|
||||||
|
index, 3 + index, 2 + index,
|
||||||
|
]);
|
||||||
|
index += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Geometry::new(vertices, indices)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn redraw_hotbar_cursor(&self, render_context: &RenderContext) {
|
pub fn redraw_hotbar_cursor(&self, render_context: &RenderContext) {
|
||||||
let x = (-92 + 20 * self.hotbar_cursor_position) as f32;
|
let x = (-92 + 20 * self.hotbar_cursor_position as i32) as f32;
|
||||||
|
let texture_index = 0;
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
let vertices = [
|
let vertices = [
|
||||||
HudVertex { position: [UI_SCALE_X * (x ), -1.0 + UI_SCALE_Y * 23.0], texture_coordinates: [ 0.0 / 256.0, 22.0 / 256.0] },
|
HudVertex { position: [UI_SCALE_X * (x ), -1.0 + UI_SCALE_Y * 23.0], texture_coordinates: [ 0.0 / 256.0, 22.0 / 256.0], texture_index },
|
||||||
HudVertex { position: [UI_SCALE_X * (x + 24.0), -1.0 + UI_SCALE_Y * 23.0], texture_coordinates: [ 24.0 / 256.0, 22.0 / 256.0] },
|
HudVertex { position: [UI_SCALE_X * (x + 24.0), -1.0 + UI_SCALE_Y * 23.0], texture_coordinates: [ 24.0 / 256.0, 22.0 / 256.0], texture_index },
|
||||||
HudVertex { position: [UI_SCALE_X * (x + 24.0), -1.0 + UI_SCALE_Y * -1.0], texture_coordinates: [ 24.0 / 256.0, 46.0 / 256.0] },
|
HudVertex { position: [UI_SCALE_X * (x + 24.0), -1.0 + UI_SCALE_Y * -1.0], texture_coordinates: [ 24.0 / 256.0, 46.0 / 256.0], texture_index },
|
||||||
HudVertex { position: [UI_SCALE_X * (x ), -1.0 + UI_SCALE_Y * -1.0], texture_coordinates: [ 0.0 / 256.0, 46.0 / 256.0] },
|
HudVertex { position: [UI_SCALE_X * (x ), -1.0 + UI_SCALE_Y * -1.0], texture_coordinates: [ 0.0 / 256.0, 46.0 / 256.0], texture_index },
|
||||||
];
|
];
|
||||||
|
|
||||||
render_context.queue.write_buffer(
|
render_context.queue.write_buffer(
|
||||||
|
@ -162,13 +239,14 @@ impl HudState {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_hotbar_cursor(&mut self, render_context: &RenderContext, i: i32) {
|
pub fn set_hotbar_cursor(&mut self, render_context: &RenderContext, i: usize) {
|
||||||
self.hotbar_cursor_position = i;
|
self.hotbar_cursor_position = i;
|
||||||
self.redraw_hotbar_cursor(render_context);
|
self.redraw_hotbar_cursor(render_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn move_hotbar_cursor(&mut self, render_context: &RenderContext, delta: i32) {
|
pub fn move_hotbar_cursor(&mut self, render_context: &RenderContext, delta: i32) {
|
||||||
self.hotbar_cursor_position = (self.hotbar_cursor_position + delta).rem_euclid(9);
|
self.hotbar_cursor_position =
|
||||||
|
(self.hotbar_cursor_position as i32 + delta).rem_euclid(9) as usize;
|
||||||
self.redraw_hotbar_cursor(render_context);
|
self.redraw_hotbar_cursor(render_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,7 +286,7 @@ impl HudState {
|
||||||
visibility: wgpu::ShaderStage::FRAGMENT,
|
visibility: wgpu::ShaderStage::FRAGMENT,
|
||||||
ty: wgpu::BindingType::Texture {
|
ty: wgpu::BindingType::Texture {
|
||||||
sample_type: wgpu::TextureSampleType::Float { filterable: true },
|
sample_type: wgpu::TextureSampleType::Float { filterable: true },
|
||||||
view_dimension: wgpu::TextureViewDimension::D2,
|
view_dimension: wgpu::TextureViewDimension::D2Array,
|
||||||
multisampled: false,
|
multisampled: false,
|
||||||
},
|
},
|
||||||
count: None,
|
count: None,
|
||||||
|
@ -286,22 +364,22 @@ impl HudState {
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
pub const HUD_VERTICES: [HudVertex; 12] = [
|
pub const HUD_VERTICES: [HudVertex; 12] = [
|
||||||
// Crosshair
|
// 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: [240.0 / 256.0, 0.0 / 256.0], texture_index: 0 },
|
||||||
HudVertex { position: [UI_SCALE_X * 8.0, UI_SCALE_Y * 8.0], texture_coordinates: [ 1.0, 0.0 / 256.0] },
|
HudVertex { position: [UI_SCALE_X * 8.0, UI_SCALE_Y * 8.0], texture_coordinates: [ 1.0, 0.0 / 256.0], texture_index: 0 },
|
||||||
HudVertex { position: [UI_SCALE_X * 8.0, UI_SCALE_Y * -8.0], texture_coordinates: [ 1.0, 16.0 / 256.0] },
|
HudVertex { position: [UI_SCALE_X * 8.0, UI_SCALE_Y * -8.0], texture_coordinates: [ 1.0, 16.0 / 256.0], texture_index: 0 },
|
||||||
HudVertex { position: [UI_SCALE_X * -8.0, UI_SCALE_Y * -8.0], texture_coordinates: [240.0 / 256.0, 16.0 / 256.0] },
|
HudVertex { position: [UI_SCALE_X * -8.0, UI_SCALE_Y * -8.0], texture_coordinates: [240.0 / 256.0, 16.0 / 256.0], texture_index: 0 },
|
||||||
|
|
||||||
// Hotbar
|
// Hotbar
|
||||||
HudVertex { position: [UI_SCALE_X * -91.0, -1.0 + UI_SCALE_Y * 22.0], texture_coordinates: [ 0.0 / 256.0, 0.0 / 256.0] },
|
HudVertex { position: [UI_SCALE_X * -91.0, -1.0 + UI_SCALE_Y * 22.0], texture_coordinates: [ 0.0 / 256.0, 0.0 / 256.0], texture_index: 0 },
|
||||||
HudVertex { position: [UI_SCALE_X * 91.0, -1.0 + UI_SCALE_Y * 22.0], texture_coordinates: [182.0 / 256.0, 0.0 / 256.0] },
|
HudVertex { position: [UI_SCALE_X * 91.0, -1.0 + UI_SCALE_Y * 22.0], texture_coordinates: [182.0 / 256.0, 0.0 / 256.0], texture_index: 0 },
|
||||||
HudVertex { position: [UI_SCALE_X * 91.0, -1.0 ], texture_coordinates: [182.0 / 256.0, 22.0 / 256.0] },
|
HudVertex { position: [UI_SCALE_X * 91.0, -1.0 ], texture_coordinates: [182.0 / 256.0, 22.0 / 256.0], texture_index: 0 },
|
||||||
HudVertex { position: [UI_SCALE_X * -91.0, -1.0 ], texture_coordinates: [ 0.0 / 256.0, 22.0 / 256.0] },
|
HudVertex { position: [UI_SCALE_X * -91.0, -1.0 ], texture_coordinates: [ 0.0 / 256.0, 22.0 / 256.0], texture_index: 0 },
|
||||||
|
|
||||||
// Hotbar cursor
|
// Hotbar cursor
|
||||||
HudVertex { position: [UI_SCALE_X * -92.0, -1.0 + UI_SCALE_Y * 23.0], texture_coordinates: [ 0.0 / 256.0, 22.0 / 256.0] },
|
HudVertex { position: [UI_SCALE_X * -92.0, -1.0 + UI_SCALE_Y * 23.0], texture_coordinates: [ 0.0 / 256.0, 22.0 / 256.0], texture_index: 0 },
|
||||||
HudVertex { position: [UI_SCALE_X * -68.0, -1.0 + UI_SCALE_Y * 23.0], texture_coordinates: [ 24.0 / 256.0, 22.0 / 256.0] },
|
HudVertex { position: [UI_SCALE_X * -68.0, -1.0 + UI_SCALE_Y * 23.0], texture_coordinates: [ 24.0 / 256.0, 22.0 / 256.0], texture_index: 0 },
|
||||||
HudVertex { position: [UI_SCALE_X * -68.0, -1.0 + UI_SCALE_Y * -1.0], texture_coordinates: [ 24.0 / 256.0, 46.0 / 256.0] },
|
HudVertex { position: [UI_SCALE_X * -68.0, -1.0 + UI_SCALE_Y * -1.0], texture_coordinates: [ 24.0 / 256.0, 46.0 / 256.0], texture_index: 0 },
|
||||||
HudVertex { position: [UI_SCALE_X * -92.0, -1.0 + UI_SCALE_Y * -1.0], texture_coordinates: [ 0.0 / 256.0, 46.0 / 256.0] },
|
HudVertex { position: [UI_SCALE_X * -92.0, -1.0 + UI_SCALE_Y * -1.0], texture_coordinates: [ 0.0 / 256.0, 46.0 / 256.0], texture_index: 0 },
|
||||||
];
|
];
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
|
|
|
@ -13,7 +13,7 @@ use winit::{
|
||||||
use hud_state::HudState;
|
use hud_state::HudState;
|
||||||
use world_state::WorldState;
|
use world_state::WorldState;
|
||||||
|
|
||||||
use crate::render_context::RenderContext;
|
use crate::{render_context::RenderContext, texture::TextureManager};
|
||||||
|
|
||||||
pub const PRIMITIVE_STATE: wgpu::PrimitiveState = wgpu::PrimitiveState {
|
pub const PRIMITIVE_STATE: wgpu::PrimitiveState = wgpu::PrimitiveState {
|
||||||
topology: wgpu::PrimitiveTopology::TriangleList,
|
topology: wgpu::PrimitiveTopology::TriangleList,
|
||||||
|
@ -96,15 +96,20 @@ impl State {
|
||||||
let (swap_chain_descriptor, swap_chain) =
|
let (swap_chain_descriptor, swap_chain) =
|
||||||
Self::create_swap_chain(window, &render_adapter, &render_device, &render_surface);
|
Self::create_swap_chain(window, &render_adapter, &render_device, &render_surface);
|
||||||
|
|
||||||
let render_context = RenderContext {
|
let mut render_context = RenderContext {
|
||||||
surface: render_surface,
|
surface: render_surface,
|
||||||
device: render_device,
|
device: render_device,
|
||||||
queue: render_queue,
|
queue: render_queue,
|
||||||
|
|
||||||
swap_chain_descriptor,
|
swap_chain_descriptor,
|
||||||
swap_chain,
|
swap_chain,
|
||||||
|
texture_manager: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let mut texture_manager = TextureManager::new(&render_context);
|
||||||
|
texture_manager.load_all(&render_context).unwrap();
|
||||||
|
render_context.texture_manager = Some(texture_manager);
|
||||||
|
|
||||||
let world_state = WorldState::new(&render_context);
|
let world_state = WorldState::new(&render_context);
|
||||||
let hud_state = HudState::new(&render_context);
|
let hud_state = HudState::new(&render_context);
|
||||||
|
|
||||||
|
@ -169,9 +174,11 @@ impl State {
|
||||||
button,
|
button,
|
||||||
state: ElementState::Pressed,
|
state: ElementState::Pressed,
|
||||||
..
|
..
|
||||||
} if self.mouse_grabbed => self
|
} if self.mouse_grabbed => self.world_state.input_mouse_button(
|
||||||
.world_state
|
button,
|
||||||
.input_mouse_button(button, &self.render_context),
|
&self.render_context,
|
||||||
|
self.hud_state.selected_block_type(),
|
||||||
|
),
|
||||||
|
|
||||||
WindowEvent::MouseWheel {
|
WindowEvent::MouseWheel {
|
||||||
delta: MouseScrollDelta::LineDelta(_, delta),
|
delta: MouseScrollDelta::LineDelta(_, delta),
|
||||||
|
@ -211,8 +218,12 @@ impl State {
|
||||||
.create_command_encoder(&Default::default());
|
.create_command_encoder(&Default::default());
|
||||||
|
|
||||||
let mut triangle_count = 0;
|
let mut triangle_count = 0;
|
||||||
triangle_count += self.world_state.render(&frame, &mut render_encoder);
|
triangle_count +=
|
||||||
triangle_count += self.hud_state.render(&frame, &mut render_encoder)?;
|
self.world_state
|
||||||
|
.render(&self.render_context, &frame, &mut render_encoder);
|
||||||
|
triangle_count +=
|
||||||
|
self.hud_state
|
||||||
|
.render(&self.render_context, &frame, &mut render_encoder)?;
|
||||||
|
|
||||||
self.render_context
|
self.render_context
|
||||||
.queue
|
.queue
|
||||||
|
|
|
@ -15,12 +15,12 @@ use crate::{
|
||||||
camera::{Camera, Projection},
|
camera::{Camera, Projection},
|
||||||
render_context::RenderContext,
|
render_context::RenderContext,
|
||||||
renderable::Renderable,
|
renderable::Renderable,
|
||||||
texture::{Texture, TextureManager},
|
texture::Texture,
|
||||||
time::Time,
|
time::Time,
|
||||||
utils,
|
utils,
|
||||||
vertex::{BlockVertex, Vertex},
|
vertex::{BlockVertex, Vertex},
|
||||||
view::View,
|
view::View,
|
||||||
world::World,
|
world::{block::BlockType, World},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct WorldState {
|
pub struct WorldState {
|
||||||
|
@ -28,7 +28,6 @@ pub struct WorldState {
|
||||||
pub view: View,
|
pub view: View,
|
||||||
pub view_buffer: wgpu::Buffer,
|
pub view_buffer: wgpu::Buffer,
|
||||||
pub view_bind_group: wgpu::BindGroup,
|
pub view_bind_group: wgpu::BindGroup,
|
||||||
pub texture_manager: TextureManager,
|
|
||||||
pub camera: Camera,
|
pub camera: Camera,
|
||||||
pub projection: Projection,
|
pub projection: Projection,
|
||||||
pub depth_texture: Texture,
|
pub depth_texture: Texture,
|
||||||
|
@ -52,12 +51,6 @@ pub struct WorldState {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WorldState {
|
impl WorldState {
|
||||||
fn create_textures(render_context: &RenderContext) -> TextureManager {
|
|
||||||
let mut texture_manager = TextureManager::new(&render_context);
|
|
||||||
texture_manager.load_all(render_context).unwrap();
|
|
||||||
texture_manager
|
|
||||||
}
|
|
||||||
|
|
||||||
fn create_camera(render_context: &RenderContext) -> (Camera, Projection) {
|
fn create_camera(render_context: &RenderContext) -> (Camera, Projection) {
|
||||||
let camera = Camera::new(
|
let camera = Camera::new(
|
||||||
(10.0, 140.0, 10.0).into(),
|
(10.0, 140.0, 10.0).into(),
|
||||||
|
@ -226,8 +219,6 @@ impl WorldState {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new(render_context: &RenderContext) -> WorldState {
|
pub fn new(render_context: &RenderContext) -> WorldState {
|
||||||
let texture_manager = Self::create_textures(render_context);
|
|
||||||
|
|
||||||
let (camera, projection) = Self::create_camera(render_context);
|
let (camera, projection) = Self::create_camera(render_context);
|
||||||
|
|
||||||
let (view, view_buffer, view_bind_group_layout, view_bind_group) =
|
let (view, view_buffer, view_bind_group_layout, view_bind_group) =
|
||||||
|
@ -246,6 +237,7 @@ impl WorldState {
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let texture_manager = render_context.texture_manager.as_ref().unwrap();
|
||||||
let render_pipeline_layout =
|
let render_pipeline_layout =
|
||||||
render_context
|
render_context
|
||||||
.device
|
.device
|
||||||
|
@ -267,7 +259,6 @@ impl WorldState {
|
||||||
view,
|
view,
|
||||||
view_buffer,
|
view_buffer,
|
||||||
view_bind_group,
|
view_bind_group,
|
||||||
texture_manager,
|
|
||||||
camera,
|
camera,
|
||||||
projection,
|
projection,
|
||||||
depth_texture,
|
depth_texture,
|
||||||
|
@ -292,7 +283,12 @@ impl WorldState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render(&self, frame: &SwapChainTexture, render_encoder: &mut CommandEncoder) -> usize {
|
pub fn render(
|
||||||
|
&self,
|
||||||
|
render_context: &RenderContext,
|
||||||
|
frame: &SwapChainTexture,
|
||||||
|
render_encoder: &mut CommandEncoder,
|
||||||
|
) -> usize {
|
||||||
let mut triangle_count = 0;
|
let mut triangle_count = 0;
|
||||||
|
|
||||||
let mut render_pass = render_encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
let mut render_pass = render_encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||||
|
@ -322,8 +318,8 @@ impl WorldState {
|
||||||
|
|
||||||
render_pass.set_pipeline(&self.render_pipeline);
|
render_pass.set_pipeline(&self.render_pipeline);
|
||||||
|
|
||||||
let tm = &self.texture_manager;
|
let texture_manager = render_context.texture_manager.as_ref().unwrap();
|
||||||
render_pass.set_bind_group(0, tm.bind_group.as_ref().unwrap(), &[]);
|
render_pass.set_bind_group(0, texture_manager.bind_group.as_ref().unwrap(), &[]);
|
||||||
render_pass.set_bind_group(1, &self.view_bind_group, &[]);
|
render_pass.set_bind_group(1, &self.view_bind_group, &[]);
|
||||||
render_pass.set_bind_group(2, &self.time_bind_group, &[]);
|
render_pass.set_bind_group(2, &self.time_bind_group, &[]);
|
||||||
|
|
||||||
|
@ -344,11 +340,19 @@ impl WorldState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn input_mouse_button(&mut self, button: &MouseButton, render_context: &RenderContext) {
|
pub fn input_mouse_button(
|
||||||
|
&mut self,
|
||||||
|
button: &MouseButton,
|
||||||
|
render_context: &RenderContext,
|
||||||
|
selected: Option<BlockType>,
|
||||||
|
) {
|
||||||
if button == &MouseButton::Left {
|
if button == &MouseButton::Left {
|
||||||
self.world.break_at_crosshair(render_context, &self.camera);
|
self.world.break_at_crosshair(render_context, &self.camera);
|
||||||
} else if button == &MouseButton::Right {
|
} else if button == &MouseButton::Right {
|
||||||
self.world.place_at_crosshair(render_context, &self.camera);
|
if let Some(selected) = selected {
|
||||||
|
self.world
|
||||||
|
.place_at_crosshair(render_context, &self.camera, selected);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,7 +60,7 @@ impl TextRenderer {
|
||||||
visibility: wgpu::ShaderStage::FRAGMENT,
|
visibility: wgpu::ShaderStage::FRAGMENT,
|
||||||
ty: wgpu::BindingType::Texture {
|
ty: wgpu::BindingType::Texture {
|
||||||
sample_type: wgpu::TextureSampleType::Float { filterable: true },
|
sample_type: wgpu::TextureSampleType::Float { filterable: true },
|
||||||
view_dimension: wgpu::TextureViewDimension::D2,
|
view_dimension: wgpu::TextureViewDimension::D2Array,
|
||||||
multisampled: false,
|
multisampled: false,
|
||||||
},
|
},
|
||||||
count: None,
|
count: None,
|
||||||
|
@ -109,10 +109,10 @@ impl TextRenderer {
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
let vertices = [
|
let vertices = [
|
||||||
HudVertex { position: [x, y ], texture_coordinates: [tx, ty ] },
|
HudVertex { position: [x, y ], texture_coordinates: [tx, ty ], texture_index: 0 },
|
||||||
HudVertex { position: [x + DX, y ], texture_coordinates: [tx + s, ty ] },
|
HudVertex { position: [x + DX, y ], texture_coordinates: [tx + s, ty ], texture_index: 0 },
|
||||||
HudVertex { position: [x + DX, y - DY], texture_coordinates: [tx + s, ty + s] },
|
HudVertex { position: [x + DX, y - DY], texture_coordinates: [tx + s, ty + s], texture_index: 0 },
|
||||||
HudVertex { position: [x, y - DY], texture_coordinates: [tx, ty + s] },
|
HudVertex { position: [x, y - DY], texture_coordinates: [tx, ty + s], texture_index: 0 },
|
||||||
];
|
];
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
|
|
|
@ -102,7 +102,7 @@ impl Texture {
|
||||||
|
|
||||||
let view = texture.create_view(&wgpu::TextureViewDescriptor {
|
let view = texture.create_view(&wgpu::TextureViewDescriptor {
|
||||||
label: Some(&format!("texture_view_{}", label)),
|
label: Some(&format!("texture_view_{}", label)),
|
||||||
dimension: Some(wgpu::TextureViewDimension::D2),
|
dimension: Some(wgpu::TextureViewDimension::D2Array),
|
||||||
..wgpu::TextureViewDescriptor::default()
|
..wgpu::TextureViewDescriptor::default()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -38,11 +38,13 @@ impl Vertex for PlainVertex {
|
||||||
pub struct HudVertex {
|
pub struct HudVertex {
|
||||||
pub position: [f32; 2],
|
pub position: [f32; 2],
|
||||||
pub texture_coordinates: [f32; 2],
|
pub texture_coordinates: [f32; 2],
|
||||||
|
pub texture_index: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
const HUD_VERTEX_ATTRIBUTES: &[VertexAttribute] = &wgpu::vertex_attr_array![
|
const HUD_VERTEX_ATTRIBUTES: &[VertexAttribute] = &wgpu::vertex_attr_array![
|
||||||
0 => Float32x2,
|
0 => Float32x2,
|
||||||
1 => Float32x2,
|
1 => Float32x2,
|
||||||
|
2 => Sint32,
|
||||||
];
|
];
|
||||||
|
|
||||||
impl Vertex for HudVertex {
|
impl Vertex for HudVertex {
|
||||||
|
|
|
@ -125,15 +125,15 @@ impl Renderable for World {
|
||||||
eprintln!("Failed to save chunk {:?}: {:?}", position, err);
|
eprintln!("Failed to save chunk {:?}: {:?}", position, err);
|
||||||
} else {
|
} else {
|
||||||
if unload {
|
if unload {
|
||||||
self.chunks.remove(&position);
|
self.chunks.remove(&position);
|
||||||
|
|
||||||
if DEBUG_IO {
|
if DEBUG_IO {
|
||||||
println!("Saved and unloaded chunk {:?}", position);
|
println!("Saved and unloaded chunk {:?}", position);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if DEBUG_IO {
|
if DEBUG_IO {
|
||||||
println!("Saved chunk {:?}", position);
|
println!("Saved chunk {:?}", position);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -249,7 +249,12 @@ impl World {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn place_at_crosshair(&mut self, render_context: &RenderContext, camera: &Camera) {
|
pub fn place_at_crosshair(
|
||||||
|
&mut self,
|
||||||
|
render_context: &RenderContext,
|
||||||
|
camera: &Camera,
|
||||||
|
block_type: BlockType,
|
||||||
|
) {
|
||||||
if let Some((pos, face_normal)) = self.raycast(camera.position, camera.direction()) {
|
if let Some((pos, face_normal)) = self.raycast(camera.position, camera.direction()) {
|
||||||
let new_pos = pos.cast().unwrap() + face_normal;
|
let new_pos = pos.cast().unwrap() + face_normal;
|
||||||
|
|
||||||
|
@ -257,9 +262,7 @@ impl World {
|
||||||
new_pos.x as isize,
|
new_pos.x as isize,
|
||||||
new_pos.y as isize,
|
new_pos.y as isize,
|
||||||
new_pos.z as isize,
|
new_pos.z as isize,
|
||||||
Some(Block {
|
Some(Block { block_type }),
|
||||||
block_type: BlockType::Cobblestone,
|
|
||||||
}),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
self.update_chunk_geometry(render_context, pos / CHUNK_ISIZE);
|
self.update_chunk_geometry(render_context, pos / CHUNK_ISIZE);
|
||||||
|
|
Loading…
Reference in a new issue