commit 278db91aa4fe744eed70175ac422994071fcb517
parent 3a705c1c04cacb3565003db5b1ecea490602979e
Author: Christian Ermann <christianermann@gmail.com>
Date: Wed, 14 Jul 2021 18:11:47 -0700
Start of a chunking system
Diffstat:
5 files changed, 227 insertions(+), 16 deletions(-)
diff --git a/include/chunk.h b/include/chunk.h
@@ -0,0 +1,15 @@
+#ifndef CHUNK_H
+#define CHUNK_H
+
+extern const int CHUNK_RADIUS;
+
+typedef struct {
+ float center[3];
+} Chunk;
+
+Chunk Chunk_create(float x, float y, float z);
+
+void Chunk_outline(const Chunk* chunk, float corners[24], unsigned int offset,
+ unsigned int indices[24]);
+
+#endif
diff --git a/include/chunk_manager.h b/include/chunk_manager.h
@@ -0,0 +1,18 @@
+#ifndef CHUNK_MANAGER_H
+#define CHUNK_MANAGER_H
+
+#include "chunk.h"
+
+typedef struct {
+ int radius;
+ int chunk_count;
+ int center[3];
+ int* offsets;
+ Chunk* chunks;
+} ChunkManager;
+
+ChunkManager ChunkManager_create(int radius, float player[3]);
+
+void ChunkManager_update(ChunkManager* chunk_manager, float player[3]);
+
+#endif
diff --git a/src/chunk.c b/src/chunk.c
@@ -0,0 +1,89 @@
+#include "chunk.h"
+
+const int CHUNK_RADIUS = 8;
+
+Chunk Chunk_create(float x, float y, float z)
+{
+ Chunk chunk;
+
+ chunk.center[0] = x;
+ chunk.center[1] = y;
+ chunk.center[2] = z;
+
+ return chunk;
+}
+
+void Cube_corners(const float center[3], float radius, float corners[24])
+{
+ corners[0] = center[0] - radius;
+ corners[1] = center[1] - radius;
+ corners[2] = center[2] - radius;
+
+ corners[3] = center[0] + radius;
+ corners[4] = center[1] - radius;
+ corners[5] = center[2] - radius;
+
+ corners[6] = center[0] + radius;
+ corners[7] = center[1] - radius;
+ corners[8] = center[2] + radius;
+
+ corners[9] = center[0] - radius;
+ corners[10] = center[1] - radius;
+ corners[11] = center[2] + radius;
+
+ corners[12] = center[0] - radius;
+ corners[13] = center[1] + radius;
+ corners[14] = center[2] - radius;
+
+ corners[15] = center[0] + radius;
+ corners[16] = center[1] + radius;
+ corners[17] = center[2] - radius;
+
+ corners[18] = center[0] + radius;
+ corners[19] = center[1] + radius;
+ corners[20] = center[2] + radius;
+
+ corners[21] = center[0] - radius;
+ corners[22] = center[1] + radius;
+ corners[23] = center[2] + radius;
+}
+
+void Cube_outlineIndices(unsigned int offset, unsigned int indices[24])
+{
+ // Bottom edges
+ indices[0] = 0 + offset;
+ indices[1] = 1 + offset;
+ indices[2] = 1 + offset;
+ indices[3] = 2 + offset;
+ indices[4] = 2 + offset;
+ indices[5] = 3 + offset;
+ indices[6] = 3 + offset;
+ indices[7] = 0 + offset;
+
+ // Top edges
+ indices[8] = 4 + offset;
+ indices[9] = 5 + offset;
+ indices[10] = 5 + offset;
+ indices[11] = 6 + offset;
+ indices[12] = 6 + offset;
+ indices[13] = 7 + offset;
+ indices[14] = 7 + offset;
+ indices[15] = 4 + offset;
+
+ // Middle edges
+ indices[16] = 0 + offset;
+ indices[17] = 4 + offset;
+ indices[18] = 1 + offset;
+ indices[19] = 5 + offset;
+ indices[20] = 2 + offset;
+ indices[21] = 6 + offset;
+ indices[22] = 3 + offset;
+ indices[23] = 7 + offset;
+}
+
+void Chunk_outline(const Chunk* chunk, float corners[24],
+ unsigned int offset, unsigned int indices[24])
+{
+ Cube_corners(chunk->center, CHUNK_RADIUS, corners);
+ Cube_outlineIndices(offset, indices);
+}
diff --git a/src/chunk_manager.c b/src/chunk_manager.c
@@ -0,0 +1,77 @@
+
+#include "chunk_manager.h"
+
+#include <stdlib.h>
+#include <math.h>
+
+int ChunkManager_offsets(int radius, int* offsets)
+{
+ int count = 0;
+ for (int x = -radius; x <= radius; x++)
+ {
+ for (int y = -radius; y <= radius; y++)
+ {
+ for (int z = -radius; z <= radius; z++)
+ {
+ if (x * x + y * y + z * z <= radius * radius)
+ {
+ if (offsets != NULL)
+ {
+ offsets[count] = x * 2 * CHUNK_RADIUS;
+ offsets[count + 1] = y * 2 * CHUNK_RADIUS;
+ offsets[count + 2] = z * 2 * CHUNK_RADIUS;
+ }
+ count += 3;
+ }
+ }
+ }
+ }
+ return count;
+}
+
+ChunkManager ChunkManager_create(int radius, float player[3])
+{
+ ChunkManager chunk_manager;
+
+ chunk_manager.radius = radius;
+
+ int offset_count = ChunkManager_offsets(radius, NULL);
+ chunk_manager.offsets = (int*)malloc(offset_count * sizeof(int));
+ ChunkManager_offsets(radius, chunk_manager.offsets);
+
+ chunk_manager.chunk_count = offset_count / 3;
+ chunk_manager.chunks = (Chunk*)malloc(chunk_manager.chunk_count
+ * sizeof(Chunk));
+
+ chunk_manager.center[0] = 0;
+ chunk_manager.center[1] = 0;
+ chunk_manager.center[2] = 0;
+ ChunkManager_update(&chunk_manager, player);
+
+ return chunk_manager;
+}
+
+void ChunkManager_update(ChunkManager* chunk_manager, float player[3])
+{
+ int chunk_x = (int)floor(player[0] / (2 * CHUNK_RADIUS));
+ int chunk_y = (int)floor(player[1] / (2 * CHUNK_RADIUS));
+ int chunk_z = (int)floor(player[2] / (2 * CHUNK_RADIUS));
+ chunk_x = chunk_x * 2 * CHUNK_RADIUS + CHUNK_RADIUS;
+ chunk_y = chunk_y * 2 * CHUNK_RADIUS + CHUNK_RADIUS;
+ chunk_z = chunk_z * 2 * CHUNK_RADIUS + CHUNK_RADIUS;
+ if (chunk_x != chunk_manager->center[0] || chunk_y
+ != chunk_manager->center[1] || chunk_z != chunk_manager->center[2])
+ {
+ chunk_manager->center[0] = chunk_x;
+ chunk_manager->center[1] = chunk_y;
+ chunk_manager->center[2] = chunk_z;
+ for (int i = 0; i < chunk_manager->chunk_count; i++)
+ {
+ chunk_manager->chunks[i] = Chunk_create(
+ chunk_x + chunk_manager->offsets[i * 3],
+ chunk_y + chunk_manager->offsets[i * 3 + 1],
+ chunk_z + chunk_manager->offsets[i * 3 + 2]
+ );
+ }
+ }
+}
diff --git a/src/main.c b/src/main.c
@@ -1,4 +1,6 @@
#include "camera.h"
+#include "chunk.h"
+#include "chunk_manager.h"
#include "glh/buffer.h"
#include "glh/shader.h"
@@ -9,6 +11,7 @@
#include <SDL2/SDL.h>
#include <SDL2/SDL_opengl.h>
#include <stdbool.h>
+#include <stdio.h>
const int WIDTH = 512, HEIGHT = 512;
@@ -69,21 +72,19 @@ int main(int argc, char** argv)
glClearColor(0.4f, 0.4f, 0.6f, 1.0f);
- GLuint vertex_buffer = createVertexBuffer(3 * sizeof(vec3), NULL,
- GL_STATIC_DRAW);
- vec3 vertices[] = {
- {-0.5, -0.5, 0.0},
- { 0.0, 0.5, 0.0},
- { 0.5, -0.5, 0.0}
- };
- glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
- glBufferSubData(GL_ARRAY_BUFFER, 0, 3 * sizeof(vec3), vertices);
-
- GLuint index_buffer = createIndexBuffer(3 * sizeof(GLuint), NULL,
- GL_STATIC_DRAW);
- GLuint indices[] = {0, 1, 2};
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer);
- glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, 3 * sizeof(GLuint), indices);
+ ChunkManager chunk_manager = ChunkManager_create(2, camera.position);
+
+ float vertices[24 * chunk_manager.chunk_count];
+ unsigned int indices[24 * chunk_manager.chunk_count];
+ for (int i = 0; i < chunk_manager.chunk_count; i++)
+ {
+ Chunk_outline(&chunk_manager.chunks[i], &vertices[i * 24], i * 8,
+ &indices[i * 24]);
+ }
+ GLuint vertex_buffer = createVertexBuffer(24 * chunk_manager.chunk_count
+ * sizeof(float), vertices, GL_DYNAMIC_DRAW);
+ GLuint index_buffer = createIndexBuffer(24 * chunk_manager.chunk_count
+ * sizeof(unsigned int), indices, GL_STATIC_DRAW);
int vertex[] = { 3 };
GLuint vertex_array = createVertexArray(vertex_buffer, index_buffer, 1,
@@ -122,8 +123,19 @@ int main(int argc, char** argv)
Camera_update(&camera);
glUniformMatrix4fv(cam_loc, 1, GL_FALSE, camera.matrix[0]);
+ ChunkManager_update(&chunk_manager, camera.position);
+ for (int i = 0; i < chunk_manager.chunk_count; i++)
+ {
+ Chunk_outline(&chunk_manager.chunks[i], &vertices[i * 24], i * 8,
+ &indices[i * 24]);
+ }
+ glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
+ glBufferSubData(GL_ARRAY_BUFFER, 0, 24 * chunk_manager.chunk_count
+ * sizeof(float), vertices);
+
glBindVertexArray(vertex_array);
- glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, 0);
+ glDrawElements(GL_LINES, 24 * chunk_manager.chunk_count,
+ GL_UNSIGNED_INT, 0);
SDL_GL_SwapWindow(window);
}