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);
}
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 {
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
}
}
-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 :: () {
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};
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) => {
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);
}
}
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);
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) {
+Vector3i :: struct {
+ x, y, z: i32;
+}
Vector3 :: struct {
x, y, z: f32;