From c923d264215635dcdd7f2b76456574611559afcd Mon Sep 17 00:00:00 2001 From: Brendan Hansen Date: Sat, 18 Dec 2021 21:37:46 -0600 Subject: [PATCH] starting chunking --- run_tree/assets/shaders/world_vertex.glsl | 2 +- src/chunk.onyx | 80 +++++++++++++++++++++-- src/main.onyx | 56 +++++----------- src/mesh.onyx | 68 ++++++++++--------- src/vecmath.onyx | 3 + 5 files changed, 130 insertions(+), 79 deletions(-) diff --git a/run_tree/assets/shaders/world_vertex.glsl b/run_tree/assets/shaders/world_vertex.glsl index d267002..d93598a 100644 --- a/run_tree/assets/shaders/world_vertex.glsl +++ b/run_tree/assets/shaders/world_vertex.glsl @@ -19,5 +19,5 @@ void main() { float((a_data & 0x00F00U) >> 8U) / 15.0 ) * (float((a_data & 0x0F000U) >> 12U) / 15.0); - v_color = vec4(block_color, 0.6); + v_color = vec4(block_color, 1); } diff --git a/src/chunk.onyx b/src/chunk.onyx index 3cc27d2..25c2eb4 100644 --- a/src/chunk.onyx +++ b/src/chunk.onyx @@ -1,27 +1,33 @@ use package core Block :: #distinct u32; +#operator == (b1, b2: Block) => cast(u32) b1 == cast(u32) b2; +#operator != (b1, b2: Block) => cast(u32) b1 != cast(u32) b2; + Block_Empty :: cast(Block) 0; block_make :: (red, green, blue: f32, brightness: f32) -> Block { - r := cast(u32) (red * 16.0f); - g := cast(u32) (green * 16.0f); - b := cast(u32) (blue * 16.0f); - i := cast(u32) (brightness * 16.0f); + r := cast(u32) (red * 15.0f); + g := cast(u32) (green * 15.0f); + b := cast(u32) (blue * 15.0f); + i := cast(u32) (brightness * 15.0f); - return ~~(i << 12 | b << 8 | g << 4 | r); + return ~~((i << 12) | (b << 8) | (g << 4) | r); } Chunk_Size :: 16 Chunk :: struct { blocks: [] Block; + + mesh: ^Mesh = null; } chunk_make :: (allocator := context.allocator) -> ^Chunk { chunk := new(Chunk, allocator); memory.alloc_slice(^chunk.blocks, Chunk_Size * Chunk_Size * Chunk_Size); - memory.fill_slice(chunk.blocks, block_make(0.2, 1, 0.2, 1)); + memory.fill_slice(chunk.blocks, block_make(0,0,0,0)); + return chunk; } #local in_chunk_bounds :: macro (x, y, z: i32) -> bool { @@ -44,6 +50,66 @@ chunk_get :: (use chunk: ^Chunk, x, y, z: i32) -> Block { return blocks[x * Chunk_Size * Chunk_Size + y * Chunk_Size + z]; } +#local block_neighbors := Vector3i.[ + Vector3i.{ 0, 0, -1 }, + Vector3i.{ 1, 0, 0 }, + Vector3i.{ -1, 0, 0 }, + Vector3i.{ 0, 0, 1 }, + Vector3i.{ 0, 1, 0 }, + Vector3i.{ 0, -1, 0 }, +]; + +#local block_verticies := Vector3.[ + Vector3.{ 0, 0, 0 }, + Vector3.{ 0, 1, 0 }, + Vector3.{ 1, 1, 0 }, + Vector3.{ 1, 0, 0 }, + Vector3.{ 0, 0, 1 }, + Vector3.{ 0, 1, 1 }, + Vector3.{ 1, 1, 1 }, + Vector3.{ 1, 0, 1 }, +]; + +#local block_indicies := ([6] u32).[ + u32.[ 0, 2, 1, 0, 3, 2 ], + u32.[ 3, 6, 2, 3, 7, 6 ], + u32.[ 5, 0, 1, 5, 4, 0 ], + u32.[ 4, 5, 6, 4, 6, 7 ], + u32.[ 5, 1, 2, 5, 2, 6 ], + u32.[ 0, 4, 7, 0, 7, 3 ] +]; + chunk_build_mesh :: (use chunk: ^Chunk) -> ^Mesh { - + verticies := array.make(Vertex, capacity=512); + defer array.free(^verticies); + + chunk_foreach(chunk) #{ + if block == Block_Empty do continue; + + for i: 6 { + n := ^block_neighbors[i]; + nx := x + n.x; + ny := y + n.y; + nz := z + n.z; + + if chunk_get(chunk, nx, ny, nz) != Block_Empty do continue; + + indicies := cast([] u32) block_indicies[i]; + for j: 6 { + v := block_verticies[indicies[j]]; + verticies << .{ ~~x+v.x, ~~y+v.y, ~~z+v.z, ~~block }; + } + } + }; + + return mesh_make(verticies, .[]); } + + + +chunk_foreach :: macro (chunk: ^Chunk, body: Code) { + for x: Chunk_Size do for y: Chunk_Size do for z: Chunk_Size { + block := chunk.blocks[x * Chunk_Size * Chunk_Size + y * Chunk_Size + z]; + #insert body; + } +} \ No newline at end of file diff --git a/src/main.onyx b/src/main.onyx index 43a1f6f..37ba4f4 100644 --- a/src/main.onyx +++ b/src/main.onyx @@ -51,40 +51,7 @@ toggle_cursor_grabbed :: () { } } -make_plane_mesh :: () -> Mesh { - vertex_data := memory.make_slice(Vertex, 4); - vertex_data[0] = .{-10, 0, 10, 0 }; - vertex_data[1] = .{-10, 0, -10, 0 }; - vertex_data[2] = .{ 10, 0, -10, 0 }; - vertex_data[3] = .{ 10, 0, 10, 0 }; - - #persist index_data := u32.[ 0, 1, 2, 0, 2, 3 ]; - - mesh: Mesh; - mesh.verticies = vertex_data; - mesh.indicies = index_data; - - glGenVertexArrays(1, ^mesh.handle); - glBindVertexArray(mesh.handle); - - vbo: GLuint; - glGenBuffers(1, ^vbo); - glBindBuffer(GL_ARRAY_BUFFER, vbo); - glBufferData(GL_ARRAY_BUFFER, sizeof Vertex * vertex_data.count, vertex_data.data, GL_STATIC_DRAW); - - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, false, 3 * sizeof GLfloat, ~~0); - - ibo: GLuint; - glGenBuffers(1, ^ibo); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof i32 * 6, ~~index_data, GL_STATIC_DRAW); - - return mesh; -} - -cubes: [..] Mesh; -plane_mesh: Mesh; +chunk: ^Chunk; matrix_block_buffer: GLuint; setup_opengl :: () { @@ -151,12 +118,15 @@ setup_opengl :: () { matrix_block_index := glGetUniformBlockIndex(prog, #cstr "u_matrix_block"); glUniformBlockBinding(prog, matrix_block_index, 0); - for 1000 { - x := random.between(0, 31); - y := random.between(0, 31); - z := random.between(0, 31); - cubes << mesh_make_cube(~~x, ~~y, ~~z); + chunk = chunk_make(); + for z: 32 do for x: 32 { + chunk_set(chunk, x, 0, z, block_make(0.2, 1, 0.2, 0.8)); } + for z: 32 do for x: 32 { + if random.between(0, 10) >= 7 do continue; + chunk_set(chunk, x, 1, z, block_make(0.6, 0.6, 0.6, 0.8)); + } + chunk.mesh = chunk_build_mesh(chunk); __initialize(^camera); camera.position = .{5,5,5}; @@ -235,6 +205,7 @@ draw :: () { glClearColor(.7, .7, .9, 1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); +/* #persist forward : Vector3; forward = camera_get_forward(^camera); array.sort(cubes, (x, y) => { @@ -244,10 +215,13 @@ draw :: () { return 0; }); - for^ cubes { - if Vector3.dot(forward, *(cast(^Vector3) ^it.verticies[0]) - camera.position) < 0 do continue; + for cubes { + // if Vector3.dot(forward, *(cast(^Vector3) ^it.verticies[0]) - camera.position) < 0 do continue; mesh_draw(it); } + */ + + mesh_draw(chunk.mesh); glfwSwapBuffers(window); } diff --git a/src/mesh.onyx b/src/mesh.onyx index 6176f02..feb3b79 100644 --- a/src/mesh.onyx +++ b/src/mesh.onyx @@ -14,21 +14,51 @@ Vertex :: struct { } Mesh :: struct { - handle: GLuint; - vertex_handle: GLuint; - index_handle: GLuint; + handle: GLint; + vertex_handle: GLint; + index_handle: GLint; - verticies: [] Vertex; - indicies: [] u32; + vertex_count: u32; + index_count: u32; +} + +mesh_make :: (verticies: [] Vertex, indicies: [] u32) -> ^Mesh { + mesh := new(Mesh); + mesh.vertex_count = verticies.count; + mesh.index_count = indicies.count; + + glGenVertexArrays(1, ^mesh.handle); + glBindVertexArray(mesh.handle); + + glGenBuffers(1, ^mesh.vertex_handle); + glBindBuffer(GL_ARRAY_BUFFER, mesh.vertex_handle); + glBufferData(GL_ARRAY_BUFFER, sizeof Vertex * verticies.count, verticies.data, GL_STATIC_DRAW); + + glEnableVertexAttribArray(0); + glEnableVertexAttribArray(1); + glVertexAttribPointer(0, 3, GL_FLOAT, false, sizeof Vertex, ~~0); + glVertexAttribIPointer(1, 1, GL_UNSIGNED_INT, sizeof Vertex, ~~12); + + glGenBuffers(1, ^mesh.index_handle); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh.index_handle); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof i32 * indicies.count, indicies.data, GL_STATIC_DRAW); + + glBindVertexArray(-1); + + return mesh; } mesh_draw :: (use mesh: ^Mesh) { glBindVertexArray(handle); - glDrawElements(GL_TRIANGLES, indicies.count, GL_UNSIGNED_INT, ~~0); + if index_count > 0 { + glDrawElements(GL_TRIANGLES, index_count, GL_UNSIGNED_INT, ~~0); + } else { + glDrawArrays(GL_TRIANGLES, 0, vertex_count); + } glBindVertexArray(-1); } -mesh_make_cube :: (x, y, z: f32) -> Mesh { +mesh_make_cube :: (x, y, z: f32) -> ^Mesh { data := random.between(0x0000, 0xffff); vertex_data := memory.make_slice(Vertex, 8); @@ -61,29 +91,7 @@ mesh_make_cube :: (x, y, z: f32) -> Mesh { 0, 7, 3, ]; - mesh: Mesh; - mesh.verticies = vertex_data; - mesh.indicies = index_data; - - glGenVertexArrays(1, ^mesh.handle); - glBindVertexArray(mesh.handle); - - glGenBuffers(1, ^mesh.vertex_handle); - glBindBuffer(GL_ARRAY_BUFFER, mesh.vertex_handle); - glBufferData(GL_ARRAY_BUFFER, sizeof Vertex * vertex_data.count, vertex_data.data, GL_STATIC_DRAW); - - glEnableVertexAttribArray(0); - glEnableVertexAttribArray(1); - glVertexAttribPointer(0, 3, GL_FLOAT, false, sizeof Vertex, ~~0); - glVertexAttribIPointer(1, 1, GL_UNSIGNED_INT, sizeof Vertex, ~~12); - - glGenBuffers(1, ^mesh.index_handle); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh.index_handle); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof i32 * 36, ~~index_data, GL_STATIC_DRAW); - - glBindVertexArray(-1); - - return mesh; + return mesh_make(vertex_data, index_data); } mesh_free :: (mesh: ^Mesh) { diff --git a/src/vecmath.onyx b/src/vecmath.onyx index ddc33ea..bded115 100644 --- a/src/vecmath.onyx +++ b/src/vecmath.onyx @@ -1,3 +1,6 @@ +Vector3i :: struct { + x, y, z: i32; +} Vector3 :: struct { x, y, z: f32; -- 2.25.1