starting chunking
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Sun, 19 Dec 2021 03:37:46 +0000 (21:37 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Sun, 19 Dec 2021 03:37:46 +0000 (21:37 -0600)
run_tree/assets/shaders/world_vertex.glsl
src/chunk.onyx
src/main.onyx
src/mesh.onyx
src/vecmath.onyx

index d267002ec32da9d1cdc2fca717a1149a55967c53..d93598aa9e1ea034eb67d38788087c41bd6200c5 100644 (file)
@@ -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);
 }
index 3cc27d2e7559f35e424724866ed660fad642b46a..25c2eb419dc7560f5dec8719c48951cc2c2f988a 100644 (file)
@@ -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
index 43a1f6f3e0ecb7431aba4c90c7e7a20a4bfda541..37ba4f46219845103a7d9f9e0e1a1845d3fb74c7 100644 (file)
@@ -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);
 }
index 6176f02ebaec260e22a5696cc14417016d9194e6..feb3b79862144a3ef80607c90c5e384af60cadce 100644 (file)
@@ -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) {
index ddc33ea94ae0e6cb207199eabd622fd941231936..bded1157f4f9baf8a9f16800e2e4a43b9edabcdc 100644 (file)
@@ -1,3 +1,6 @@
+Vector3i :: struct {
+    x, y, z: i32;
+}
 
 Vector3 :: struct {
     x, y, z: f32;