mgecumshooter/esotera
made basic chunk rendering system
Commit 1126251a8c02 · silentevermore · 2026-10-09 13:36 +0300
Comments
No comments yet.
Diff
diff --git a/shaders/frag.glsl b/shaders/frag.glsl
--- a/shaders/frag.glsl
+++ b/shaders/frag.glsl
@@ -1,15 +1,29 @@
#version 330
-in vec3 fragPosition;
+in vec2 fragTexCoord;
+in vec4 fragColor;
in vec3 fragNormal;
-in vec2 fragTexCoord;
uniform sampler2D texture0;
+uniform vec4 colDiffuse;
out vec4 finalColor;
void main() {
- vec4 color = texture(texture0, fragTexCoord);
+ vec4 texel = texture(texture0, fragTexCoord) * colDiffuse * fragColor;
+
+ vec3 normal = normalize(fragNormal);
+ vec3 lightDir = normalize(vec3(-0.5, 1.0, 0.5));
+
+ float diffuse = max(dot(normal, lightDir), 0.0);
- finalColor = color;
+ float shade;
+ if (diffuse > 0.65)
+ shade = 1.0;
+ else if (diffuse > 0.25)
+ shade = 0.65;
+ else
+ shade = 0.3;
+
+ finalColor = vec4(texel.rgb * shade, texel.a);
}
diff --git a/shaders/vert.glsl b/shaders/vert.glsl
--- a/shaders/vert.glsl
+++ b/shaders/vert.glsl
@@ -1,20 +1,21 @@
#version 330
in vec3 vertexPosition;
+in vec2 vertexTexCoord;
in vec3 vertexNormal;
-in vec2 vertexTexCoord;
-
-out vec3 fragPosition;
-out vec3 fragNormal;
-out vec2 fragTexCoord;
+in vec4 vertexColor;
uniform mat4 mvp;
uniform mat4 matModel;
+out vec2 fragTexCoord;
+out vec4 fragColor;
+out vec3 fragNormal;
+
void main() {
- fragPosition = vec3(matModel * vec4(vertexPosition, 1.0));
- fragNormal = normalize(mat3(matModel) * vertexNormal);
fragTexCoord = vertexTexCoord;
+ fragColor = vertexColor;
+ fragNormal = mat3(transpose(inverse(matModel))) * vertexNormal;
gl_Position = mvp * vec4(vertexPosition, 1.0);
}
diff --git a/src/chunk/mod.rs b/src/chunk/mod.rs
--- a/src/chunk/mod.rs
+++ b/src/chunk/mod.rs
@@ -1,5 +1,12 @@
+use sola_raylib as rlb;
+use rlb::{
+ prelude::*,
+ core::*,
+ consts::*,
+};
+use crate::voxel;
+
pub use super::voxel::Voxel;
-use super::rlb::core::math::Vector3;
pub const CHUNK_SIZE: usize = 32;
@@ -7,14 +14,91 @@
pub chunk_pos: Vector3,
pub voxels: [Voxel; CHUNK_SIZE*CHUNK_SIZE*CHUNK_SIZE],
pub dirty: bool,
+ pub mesh: Option<Mesh>
} // pending: add events stack
impl Chunk {
pub fn new(pos: Vector3) -> Self {
- Self {
+ let mut s = Self {
chunk_pos: pos,
- voxels: [Voxel::Stone; CHUNK_SIZE*CHUNK_SIZE*CHUNK_SIZE],
+ voxels: [Voxel::Air; CHUNK_SIZE*CHUNK_SIZE*CHUNK_SIZE],
dirty: false,
+ mesh: None
+ };
+ for x in 0..31 {
+ for z in 0..31 {
+ let y = x + z;
+ let i = x + (y * CHUNK_SIZE) + (z * CHUNK_SIZE * CHUNK_SIZE);
+ s.voxels[i] = Voxel::Stone;
+ }
}
+ s
+ }
+ pub fn get_voxel(&self, x: usize, y: usize, z: usize) -> Option<&Voxel> {
+ if x >= CHUNK_SIZE || y >= CHUNK_SIZE || z >= CHUNK_SIZE {
+ return None;
+ }
+ let idx = x + y * CHUNK_SIZE + z * CHUNK_SIZE * CHUNK_SIZE;
+ Some(&self.voxels[idx])
+ }
+ pub fn voxel_idx(&self, x: usize, y: usize, z: usize) -> usize {
+ x + (y * CHUNK_SIZE) + (z * CHUNK_SIZE * CHUNK_SIZE)
+ }
+ pub fn voxel_pos(&self, idx: usize) -> Vector3 {
+ assert!(idx < CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE);
+
+ let x = (idx % CHUNK_SIZE) as f32;
+ let y = ((idx / CHUNK_SIZE) % CHUNK_SIZE) as f32;
+ let z = (idx / (CHUNK_SIZE * CHUNK_SIZE)) as f32;
+
+ Vector3::new(x, y, z)
+ }
+ pub fn global_voxel_pos(&self, idx: usize) -> Vector3 {
+ self.chunk_pos + self.voxel_pos(idx)
+ }
+ fn is_exposed(&self, x: usize, y: usize, z: usize) -> bool {
+ let directions = [
+ (1, 0, 0), (-1, 0, 0),
+ (0, 1, 0), (0, -1, 0),
+ (0, 0, 1), (0, 0, -1),
+ ];
+
+ for (dx, dy, dz) in directions.iter() {
+ let nx = x as isize + dx;
+ let ny = y as isize + dy;
+ let nz = z as isize + dz;
+
+ if nx < 0 || ny < 0 || nz < 0 || nx >= CHUNK_SIZE as isize || ny >= CHUNK_SIZE as isize || nz >= CHUNK_SIZE as isize {
+ return true;
+ }
+
+ if let Some(Voxel::Air) = self.get_voxel(nx as usize, ny as usize, nz as usize) {
+ return true;
+ }
+ }
+ false
+ }
+ pub fn draw(
+ &self,
+ ctx: &mut RaylibMode3D<'_, RaylibTextureMode<'_, RaylibDrawHandle<'_>>>,
+ ) -> &Self {
+ for x in 0..CHUNK_SIZE {
+ for y in 0..CHUNK_SIZE {
+ for z in 0..CHUNK_SIZE {
+ if let Some(Voxel::Air) = self.get_voxel(x, y, z) { continue; }
+
+ if self.is_exposed(x, y, z) {
+ ctx.draw_cube(
+ self.chunk_pos + Vector3::new(x as f32, y as f32, z as f32),
+ voxel::VOXEL_SIZE as f32,
+ voxel::VOXEL_SIZE as f32,
+ voxel::VOXEL_SIZE as f32,
+ rlb::color::Color::GRAY
+ );
+ }
+ }
+ }
+ }
+ self
}
}
diff --git a/src/main.rs b/src/main.rs
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,7 +1,9 @@
mod chunk;
mod voxel;
-use sola_raylib::{self as rlb, ffi::Rectangle};
+use std::ffi;
+
+use sola_raylib::{self as rlb, ffi::{GenMeshCube, LoadMaterialDefault, Material, Rectangle}};
use rlb::{
prelude::*,
core::*,
@@ -24,12 +26,12 @@
);
// shader stuff
- let mut shader = rl.load_shader(&rl_thd, None, Some("shaders/frag.glsl")).unwrap();
+ let mut shader = rl.load_shader(&rl_thd, Some("shaders/vert.glsl"), Some("shaders/frag.glsl")).unwrap();
let mut post_shader = rl.load_shader(&rl_thd, None, Some("shaders/post.glsl")).unwrap();
let mut rend_tex = rl.load_render_texture(&rl_thd, rl.get_render_width() as u32, rl.get_render_height() as u32).unwrap();
// chunks
- let mut test_chunk = Chunk::new(Vector3::zero());
+ let test_chunk = Chunk::new(Vector3::zero());
rl.hide_cursor();
rl.disable_cursor();
@@ -45,6 +47,9 @@
tx.clear_background(Color::new(30, 30, 30, 255));
tx.draw_mode3D(cam, |mut d3, _| {
d3.draw_grid(100, 1.0);
+ d3.draw_shader_mode(&mut shader, |mut shd| {
+ test_chunk.draw(&mut shd);
+ });
});
});
d.draw_shader_mode(&mut post_shader, |mut shd| {
diff --git a/src/voxel/mod.rs b/src/voxel/mod.rs
--- a/src/voxel/mod.rs
+++ b/src/voxel/mod.rs
@@ -1,5 +1,4 @@
-#[derive(Clone)]
-#[derive(Copy)]
+#[derive(Clone, Copy, PartialEq, Eq)]
pub enum Voxel {
Air,
Stone,