wip: current project state

This commit is contained in:
Emil
2026-06-21 22:27:20 +03:00
parent 88892db493
commit a5436897ed
48 changed files with 4583 additions and 760 deletions
+5 -5
View File
@@ -3,14 +3,14 @@ use crate::entity::EntityManager;
use crate::render::lighting;
use crate::ui::UiLayer;
use crate::world::cell::MaterialId;
use crate::world::grid::Grid;
use crate::world::chunked_grid::ChunkedGrid;
use image::{ImageBuffer, RgbImage};
pub const CELL_SIZE: u32 = 8;
pub const UI_CELL_SIZE: u32 = 2;
pub fn capture_frame(
grid: &Grid,
grid: &ChunkedGrid,
entities: &EntityManager,
items: &ItemManager,
ui: &UiLayer,
@@ -145,7 +145,7 @@ fn entity_positions(
fn shadow_positions(
entity_positions: &std::collections::HashMap<(i32, i32), [u8; 3]>,
grid: &Grid,
grid: &ChunkedGrid,
cam_x: i32,
cam_y: i32,
view_w: u32,
@@ -203,7 +203,7 @@ fn draw_cell(img: &mut RgbImage, vx: u32, vy: u32, color: [u8; 3]) {
pub fn save_capture(
path: &str,
grid: &Grid,
grid: &ChunkedGrid,
entities: &EntityManager,
items: &ItemManager,
ui: &UiLayer,
@@ -221,7 +221,7 @@ pub fn save_capture(
}
pub fn capture_from_state(
grid: &Grid,
grid: &ChunkedGrid,
entities: &EntityManager,
items: &ItemManager,
ui: &UiLayer,
+15 -17
View File
@@ -5,7 +5,8 @@ use std::sync::Arc;
use crate::entity::EntityManager;
use crate::render::lighting;
use crate::world::cell::MaterialId;
use crate::world::grid::{Grid, WORLD_H, WORLD_W};
use crate::world::chunked_grid::ChunkedGrid;
use crate::world::grid::{MAX_WORLD_H, MAX_WORLD_W};
const CHAR_W: u32 = 8;
const CHAR_H: u32 = 8;
@@ -552,13 +553,14 @@ impl GraphicsRenderer {
Ok((buf, mem))
};
let grid_data = vec![0u32; WORLD_W * WORLD_H];
let grid_count = MAX_WORLD_W * MAX_WORLD_H;
let grid_data = vec![0u32; grid_count];
let (grid_buffer, grid_memory) = make_buf(
bytemuck::cast_slice(&grid_data),
vk::BufferUsageFlags::STORAGE_BUFFER,
)?;
let grid_ptr = unsafe {
let sz = (WORLD_W * WORLD_H * std::mem::size_of::<u32>()) as vk::DeviceSize;
let sz = (grid_count * std::mem::size_of::<u32>()) as vk::DeviceSize;
let ptr = device
.map_memory(grid_memory, 0, sz, vk::MemoryMapFlags::default())
.map_err(|e| format!("map grid: {e:?}"))?;
@@ -602,7 +604,7 @@ impl GraphicsRenderer {
let grid_info = vk::DescriptorBufferInfo::default()
.buffer(grid_buffer)
.offset(0)
.range((WORLD_W * WORLD_H * std::mem::size_of::<u32>()) as vk::DeviceSize);
.range((MAX_WORLD_W * MAX_WORLD_H * std::mem::size_of::<u32>()) as vk::DeviceSize);
let light_info = vk::DescriptorBufferInfo::default()
.buffer(light_buffer)
.offset(0)
@@ -764,7 +766,7 @@ impl GraphicsRenderer {
pub fn render(
&mut self,
grid: &Grid,
grid: &ChunkedGrid,
entities: &EntityManager,
items: &crate::entity::item::ItemManager,
ui: &crate::ui::UiLayer,
@@ -921,16 +923,12 @@ impl GraphicsRenderer {
}
unsafe {
let margin = 30i32;
let x_min = (cam_x - margin).max(0) as usize;
let x_max = (cam_x + self.grid_w as i32 + margin).min(WORLD_W as i32) as usize;
let y_min = (cam_y - margin).max(0) as usize;
let y_max = (cam_y + self.grid_h as i32 + margin).min(WORLD_H as i32) as usize;
for y in y_min..y_max {
let row_offset = y * WORLD_W;
for x in x_min..x_max {
let i = row_offset + x;
*self.grid_ptr.add(i) = grid.cells[i].material as u32;
for dy in 0..self.grid_h {
for dx in 0..self.grid_w {
let wx = cam_x + dx as i32;
let wy = cam_y + dy as i32;
let idx = dy * self.grid_w + dx;
*self.grid_ptr.add(idx) = grid.get(wx, wy).material as u32;
}
}
}
@@ -1033,7 +1031,7 @@ impl GraphicsRenderer {
self.swapchain_extent.height as f32,
],
cell_size: [CHAR_W as f32, CHAR_H as f32],
world_size: [WORLD_W as i32, WORLD_H as i32],
world_size: [self.grid_w as i32, self.grid_h as i32],
cam_pos: [cam_x, cam_y],
ambient,
is_ui: 0,
@@ -1062,7 +1060,7 @@ impl GraphicsRenderer {
self.swapchain_extent.height as f32,
],
cell_size: [UI_CELL_SIZE as f32, UI_CELL_SIZE as f32],
world_size: [WORLD_W as i32, WORLD_H as i32],
world_size: [self.grid_w as i32, self.grid_h as i32],
cam_pos: [0, 0],
ambient: [1.0, 1.0, 1.0],
is_ui: 1,
+19 -11
View File
@@ -1,5 +1,5 @@
use crate::world::cell::MaterialId;
use crate::world::grid::Grid;
use crate::world::chunked_grid::ChunkedGrid;
#[derive(Clone, Copy, Debug)]
pub struct LightSource {
@@ -67,7 +67,7 @@ pub fn material_light(material: MaterialId) -> Option<LightSource> {
}
}
pub fn gather_sources(grid: &Grid) -> Vec<LightSource> {
pub fn gather_sources(grid: &ChunkedGrid) -> Vec<LightSource> {
let mut sources = Vec::new();
let w = grid.width;
let h = grid.height;
@@ -85,7 +85,7 @@ pub fn gather_sources(grid: &Grid) -> Vec<LightSource> {
}
pub fn gather_sources_in_range(
grid: &Grid,
grid: &ChunkedGrid,
cam_x: i32,
cam_y: i32,
view_w: usize,
@@ -94,9 +94,17 @@ pub fn gather_sources_in_range(
) -> Vec<LightSource> {
let mut sources = Vec::new();
let min_x = (cam_x - margin).max(0);
let max_x = (cam_x + view_w as i32 + margin).min(grid.width as i32);
let max_x = if grid.is_infinite() {
cam_x + view_w as i32 + margin
} else {
(cam_x + view_w as i32 + margin).min(grid.width as i32)
};
let min_y = (cam_y - margin).max(0);
let max_y = (cam_y + view_h as i32 + margin).min(grid.height as i32);
let max_y = if grid.is_infinite() {
cam_y + view_h as i32 + margin
} else {
(cam_y + view_h as i32 + margin).min(grid.height as i32)
};
for y in min_y..max_y {
for x in min_x..max_x {
let cell = grid.get(x, y);
@@ -111,7 +119,7 @@ pub fn gather_sources_in_range(
}
pub fn compute_lighting(
grid: &Grid,
grid: &ChunkedGrid,
cam_x: i32,
cam_y: i32,
view_w: usize,
@@ -176,7 +184,7 @@ pub fn compute_lighting(
grid_light
}
pub fn line_of_sight(grid: &Grid, x0: i32, y0: i32, x1: i32, y1: i32) -> bool {
pub fn line_of_sight(grid: &ChunkedGrid, x0: i32, y0: i32, x1: i32, y1: i32) -> bool {
let mut x = x0;
let mut y = y0;
let dx = (x1 - x0).abs();
@@ -236,10 +244,10 @@ pub fn ambient_light() -> [u8; 3] {
#[cfg(test)]
mod tests {
use super::*;
use crate::world::grid::Grid;
use crate::world::chunked_grid::ChunkedGrid;
fn grid_with_lava() -> (Grid, i32, i32) {
let mut grid = Grid::new();
fn grid_with_lava() -> (ChunkedGrid, i32, i32) {
let mut grid = ChunkedGrid::with_size(250, 250);
grid.set_material(10, 10, MaterialId::Lava);
(grid, 10, 10)
}
@@ -267,7 +275,7 @@ mod tests {
#[test]
fn walls_block_light() {
let mut grid = Grid::new();
let mut grid = ChunkedGrid::with_size(250, 250);
grid.set_material(5, 10, MaterialId::Lava);
for y in 7..13 {
grid.set_material(8, y, MaterialId::Stone);
+2 -2
View File
@@ -8,13 +8,13 @@ pub mod window_input;
use crate::entity::item::ItemManager;
use crate::entity::EntityManager;
use crate::ui::UiLayer;
use crate::world::grid::Grid;
use crate::world::chunked_grid::ChunkedGrid;
pub trait Renderer {
fn init(&mut self) -> std::io::Result<()>;
fn render(
&mut self,
grid: &Grid,
grid: &ChunkedGrid,
entities: &EntityManager,
items: &ItemManager,
ui: &UiLayer,
+2 -2
View File
@@ -16,7 +16,7 @@ use crate::entity::EntityManager;
use crate::render::lighting::{self, apply_light_tuple, LightGrid};
use crate::render::Renderer;
use crate::world::cell::MaterialId;
use crate::world::grid::Grid;
use crate::world::chunked_grid::ChunkedGrid;
fn entity_priority(kind: crate::entity::EntityKind) -> u32 {
match kind {
@@ -96,7 +96,7 @@ impl Renderer for TerminalRenderer {
fn render(
&mut self,
grid: &Grid,
grid: &ChunkedGrid,
entities: &EntityManager,
items: &crate::entity::item::ItemManager,
ui: &crate::ui::UiLayer,
+14 -17
View File
@@ -6,7 +6,8 @@ use std::sync::Arc;
use crate::entity::{EntityKind, EntityManager};
use crate::render::lighting;
use crate::world::cell::MaterialId;
use crate::world::grid::{Grid, WORLD_H, WORLD_W};
use crate::world::chunked_grid::ChunkedGrid;
use crate::world::grid::{MAX_WORLD_H, MAX_WORLD_W};
const CHAR_W: u32 = 8;
const CHAR_H: u32 = 8;
@@ -225,7 +226,7 @@ impl VulkanRenderer {
let (ui_instance_buffer, ui_instance_memory, ui_instance_ptr) =
create_instance_buffer(&device, &instance, physical_device, ui_instance_capacity)?;
let grid_data = vec![0u32; WORLD_W * WORLD_H];
let grid_data = vec![0u32; MAX_WORLD_W * MAX_WORLD_H];
let (grid_buffer, grid_memory) = create_buffer_with_data(
&device,
&instance,
@@ -234,7 +235,7 @@ impl VulkanRenderer {
vk::BufferUsageFlags::STORAGE_BUFFER,
)?;
let grid_ptr = unsafe {
let sz = (WORLD_W * WORLD_H * std::mem::size_of::<u32>()) as vk::DeviceSize;
let sz = (MAX_WORLD_W * MAX_WORLD_H * std::mem::size_of::<u32>()) as vk::DeviceSize;
let ptr = device
.map_memory(grid_memory, 0, sz, vk::MemoryMapFlags::default())
.map_err(|e| format!("map grid: {e:?}"))?;
@@ -339,7 +340,7 @@ impl VulkanRenderer {
pub fn render(
&mut self,
grid: &Grid,
grid: &ChunkedGrid,
entities: &EntityManager,
items: &crate::entity::item::ItemManager,
ui: &crate::ui::UiLayer,
@@ -441,16 +442,12 @@ impl VulkanRenderer {
}
unsafe {
let margin = 30i32;
let x_min = (cam_x - margin).max(0) as usize;
let x_max = (cam_x + self.grid_w as i32 + margin).min(WORLD_W as i32) as usize;
let y_min = (cam_y - margin).max(0) as usize;
let y_max = (cam_y + self.grid_h as i32 + margin).min(WORLD_H as i32) as usize;
for y in y_min..y_max {
let row_offset = y * WORLD_W;
for x in x_min..x_max {
let i = row_offset + x;
*self.grid_ptr.add(i) = grid.cells[i].material as u32;
for dy in 0..self.grid_h {
for dx in 0..self.grid_w {
let wx = cam_x + dx as i32;
let wy = cam_y + dy as i32;
let idx = dy * self.grid_w + dx;
*self.grid_ptr.add(idx) = grid.get(wx, wy).material as u32;
}
}
}
@@ -627,7 +624,7 @@ impl VulkanRenderer {
self.swapchain_extent.height as f32,
],
cell_size: [CHAR_W as f32, CHAR_H as f32],
world_size: [WORLD_W as i32, WORLD_H as i32],
world_size: [self.grid_w as i32, self.grid_h as i32],
cam_pos: [cam_x, cam_y],
ambient: [
ambient[0] as f32 / 255.0,
@@ -660,7 +657,7 @@ impl VulkanRenderer {
self.swapchain_extent.height as f32,
],
cell_size: [UI_CELL_SIZE as f32, UI_CELL_SIZE as f32],
world_size: [WORLD_W as i32, WORLD_H as i32],
world_size: [self.grid_w as i32, self.grid_h as i32],
cam_pos: [0, 0],
ambient: [0.0, 0.0, 0.0],
is_ui: 1,
@@ -1824,7 +1821,7 @@ fn update_descriptor_set(
let bi = vk::DescriptorBufferInfo::default()
.buffer(grid_buffer)
.offset(0)
.range((WORLD_W * WORLD_H * std::mem::size_of::<u32>()) as vk::DeviceSize);
.range((MAX_WORLD_W * MAX_WORLD_H * std::mem::size_of::<u32>()) as vk::DeviceSize);
let li = vk::DescriptorBufferInfo::default()
.buffer(light_buffer)
.offset(0)