diff --git a/.gitignore b/.gitignore index d328d35..d14a2ee 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -/monke \ No newline at end of file +/monke +/db/* \ No newline at end of file diff --git a/const.h b/const.h index 103c34c..6b02dfe 100644 --- a/const.h +++ b/const.h @@ -26,10 +26,12 @@ typedef struct Vertex2 { #define CHUNK_ALL CHUNK_DIAMETER_H *CHUNK_DIAMETER_H *CHUNK_DIAMETER_V #define BLOCK_ALL CHUNK_LENGTH *CHUNK_LENGTH *CHUNK_LENGTH #define CBLOCK_ALL BLOCK_ALL *CHUNK_ALL -#define CBUF_ALL 10 +#define CBUF_ALL 25 #define CTRI_ALL CBLOCK_ALL * 18 * sizeof(Vertex) +#define MAX_R 1 + typedef struct Chunk { unsigned char exists; unsigned int x; diff --git a/cubes.c b/cubes.c index ec92330..333c63b 100644 --- a/cubes.c +++ b/cubes.c @@ -2,17 +2,20 @@ #include "gen.h" #include #include +#include struct args { Vertex *cube; + Vertex *text; VertexI pos; - int is_text; + // int is_text; int a; int i; + int a3; }; void gen_face(Vertex *cube, int i, int x, int y, int z, int x2, int y2, int z2, - int j, int is_text, Chunk dat, int ci) { + int *j, int is_text, Chunk dat, int ci, int a3) { VertexI a = {{x, y, z}}; Vertex a2 = {{x, y, z}}; @@ -25,6 +28,10 @@ void gen_face(Vertex *cube, int i, int x, int y, int z, int x2, int y2, int z2, a2.pos[0] = exists ? TEXT_GAP_H * i : -1.0; a2.pos[1] = exists ? TEXT_GAP_V * i : -1.0; a2.pos[2] = 0; + if (!exists) { + *j = (*j - 6 * a3); + return; + } } Vertex b = a2; @@ -43,33 +50,37 @@ void gen_face(Vertex *cube, int i, int x, int y, int z, int x2, int y2, int z2, d.pos[(i == 2) ? 1 : 2]++; } - cube[j] = a2; - cube[j + 1] = b; - cube[j + 2] = c; - cube[j + 3] = c; - cube[j + 4] = b; - cube[j + 5] = d; + cube[*j] = a2; + cube[*j + 1] = b; + cube[*j + 2] = c; + cube[*j + 3] = c; + cube[*j + 4] = b; + cube[*j + 5] = d; } void *gen_chunk(void *args) { + struct args args2 = ((struct args *)args)[0]; int i = args2.i; - int a = args2.a % CHUNK_DIAMETER_H; + int a3 = args2.a3; int a2 = args2.a; + int a = a2 % a3; + int x2 = args2.pos.pos[0]; int y2 = args2.pos.pos[1]; int z2 = args2.pos.pos[2]; Vertex *cube = args2.cube; - int is_text = args2.is_text; + Vertex *text = args2.text; + // int is_text = args2.is_text; - purge_chunks(a % CHUNK_DIAMETER_H); + Chunk chunk = + fetch_chunk(x2 / CHUNK_LENGTH, y2 / CHUNK_LENGTH, z2 / CHUNK_LENGTH, a); - Chunk chunk = fetch_chunk(x2 / CHUNK_LENGTH, y2 / CHUNK_LENGTH, - z2 / CHUNK_LENGTH, a); - - printf("progress on this thread (%i / %i)\n", a2, CHUNK_ALL); + //printf("progress on this thread (%i / %i)\n", a2, CHUNK_ALL); + if (i > CBLOCK_ALL * 18) + return (void *)i; for (int y4 = 0; y4 < CHUNK_LENGTH; y4++) { for (int x4 = 0; x4 < CHUNK_LENGTH; x4++) { @@ -79,56 +90,89 @@ void *gen_chunk(void *args) { int x3 = x2 + x4; int z3 = z2 + z4; - gen_face(cube, 0, x3, y3, z3, x4, y4, z4, i, is_text, chunk, a ); - gen_face(cube, 1, x3, y3, z3, x4, y4, z4, i + 6, is_text, chunk, a ); - gen_face(cube, 2, x3, y3, z3, x4, y4, z4, i + 12, is_text, chunk, a); - i += 18; + for (int m = 0; m < 3; m++) { + gen_face(cube, m, x3, y3, z3, x4, y4, z4, &i, 0, chunk, a, a3); + gen_face(text, m, x3, y3, z3, x4, y4, z4, &i, 1, chunk, a, a3); + i += 6 * a3; + if (i > CBLOCK_ALL * 18) + return (void *)i; + } } } } - return NULL; + return (void *)i; } -void gen_cubes(Vertex *cube, int x, int y, int z, int is_text) { +int gen_cubes(Vertex *cube, Vertex *text, int x, int y, int z, int r, int is_purge) { + Vertex noth = {{-1, -1, -1}}; + for (int i = 0; i < CBLOCK_ALL * 18; i++) { + cube[i] = noth; + text[i] = noth; + } + int i = 0; - int a = 0; x *= CHUNK_LENGTH; y *= CHUNK_LENGTH; z *= CHUNK_LENGTH; + int a3 = CHUNK_DIAMETER_H + (r * 2); + int a = (z % CHUNK_DIAMETER_H) + (x % CHUNK_DIAMETER_H) * CHUNK_DIAMETER_H + (y % CHUNK_DIAMETER_V) * CHUNK_DIAMETER_H * CHUNK_DIAMETER_H; + a = a % a3; + if (a < 0) a = -a; -struct args args[CHUNK_DIAMETER_H]; + struct args args[a3]; + int thread_return[a3]; - pthread_t thread_id[CHUNK_DIAMETER_H]; - for (int y2 = y - CHUNK_RADIUS_V * CHUNK_LENGTH; - y2 <= y + CHUNK_RADIUS_V * CHUNK_LENGTH; y2 += CHUNK_LENGTH) { + pthread_t thread_id[a3]; + for (int y2 = y - (CHUNK_RADIUS_V + r) * CHUNK_LENGTH; + y2 <= y + (CHUNK_RADIUS_V + r) * CHUNK_LENGTH; y2 += CHUNK_LENGTH) { - for (int x2 = x - CHUNK_RADIUS_H * CHUNK_LENGTH; - x2 <= x + CHUNK_RADIUS_H * CHUNK_LENGTH; x2 += CHUNK_LENGTH) { + for (int x2 = x - (CHUNK_RADIUS_H + r) * CHUNK_LENGTH; + x2 <= x + (CHUNK_RADIUS_H + r) * CHUNK_LENGTH; x2 += CHUNK_LENGTH) { - for (int z2 = z - CHUNK_RADIUS_H * CHUNK_LENGTH; - z2 <= z + CHUNK_RADIUS_H * CHUNK_LENGTH; z2 += CHUNK_LENGTH) { + for (int z2 = z - (CHUNK_RADIUS_H + r) * CHUNK_LENGTH; + z2 <= z + (CHUNK_RADIUS_H + r) * CHUNK_LENGTH; z2 += CHUNK_LENGTH) { VertexI pos = {{x2, y2, z2}}; - int a2 = a % CHUNK_DIAMETER_H; + int a2 = a % a3; args[a2].cube = cube; + args[a2].text = text; args[a2].pos = pos; - args[a2].is_text = is_text; + // args[a2].is_text = is_text; args[a2].a = a; - args[a2].i = i; + args[a2].i = i; + args[a2].a3 = a3; /*gen_chunk((void *)&args); */ - pthread_create(&(thread_id[a2]), NULL, gen_chunk, - (void *)&(args[a2])); + if (is_purge) purge_chunks(a2); + pthread_create(&(thread_id[a2]), NULL, gen_chunk, (void *)&(args[a2])); - i += CHUNK_LENGTH * CHUNK_LENGTH * CHUNK_LENGTH * 18; + i += 6; a++; } - for (int k = 0; k < CHUNK_DIAMETER_H; k++) { - pthread_join((thread_id[k]), NULL); + for (int k = 0; k < a3; k++) { + pthread_join((thread_id[k]), (void **)&thread_return[k]); } + + int max = 0; + int min = 0xFFFFFFF; + + for (int a = 0; a < a3; a++) { + max = (max > thread_return[a]) ? max : thread_return[a]; + min = (min < thread_return[a]) ? min : thread_return[a]; + } + i = max + 6; } } + + /* if (i < CBLOCK_ALL * 9 && r < MAX_R) { + printf("Expanding radius...\n"); + return gen_cubes(cube, text, x / CHUNK_LENGTH, y / CHUNK_LENGTH, + z / CHUNK_LENGTH, r + 1); + } + */ + + return i; } \ No newline at end of file diff --git a/cubes.h b/cubes.h index d82f6fb..f3eea5e 100644 --- a/cubes.h +++ b/cubes.h @@ -1,4 +1,3 @@ #include "const.h" -void gen_cubes(Vertex *cube, int x, int y, int z, int is_text); -void gen_face(Vertex *cube, int i, int x, int y, int z, int j, int is_text); \ No newline at end of file +int gen_cubes(Vertex *cube, Vertex *text, int x, int y, int z, int r, int is_purge); \ No newline at end of file diff --git a/gen.c b/gen.c index 78841d9..13842ac 100644 --- a/gen.c +++ b/gen.c @@ -2,6 +2,7 @@ #include #include #include +#include Chunk *chunks = NULL; int lastI = 0; @@ -58,31 +59,37 @@ double perlin_calc(double x, double y, double s) { } Chunk fetch_chunk(int x, int y, int z, int ci) { - if (chunks == NULL) { - chunks = calloc(CBUF_ALL * CHUNK_DIAMETER_H, sizeof(Chunk)); - } - Chunk *chunks2 = &chunks[CBUF_ALL * ci]; Chunk chunk; int i, j; for (j = 0; j < CBUF_ALL; j++) { - i = (j + lastI) % CBUF_ALL; + i = j; chunk = chunks2[i]; if (chunk.x == x && chunk.y == y && chunk.z == z && chunk.exists) { // lastI = i; return chunk; } - } - for (j = CBUF_ALL - 1; j >= 0; j--) { - i = j; - chunk = chunks2[i]; if (!chunk.exists) break; } + char fname[1024]; + snprintf(fname, 1023, "./db/chunk_%i_%i_%i.dat", x, y, z); + + FILE *fp = fopen(fname, "rb+"); + + int code = (fp) ? fread(&chunk, sizeof(Chunk), 1, fp) : 0; + if (code != 0) { + fclose(fp); + return chunk; + } + if (!fp) { + fp = fopen(fname, "wb"); + } + lastI = i; if (i > CBUF_ALL - 1) @@ -100,7 +107,7 @@ Chunk fetch_chunk(int x, int y, int z, int ci) { for (int z2 = 0; z2 < CHUNK_LENGTH; z2++) { int z3 = z2 + z * CHUNK_LENGTH; double hp = perlin_calc(x3, z3, 128.0); - hp = ((hp > 0.0) ? -1.0 : 1.0) * (pow(fabs(hp),0.7)); + hp = ((hp > 0.0) ? -1.0 : 1.0) * (pow(fabs(hp), 0.7)); hp *= 32.0; int h = hp + 32; @@ -114,6 +121,9 @@ Chunk fetch_chunk(int x, int y, int z, int ci) { chunks2[i] = chunk; + fwrite(&chunk, sizeof(Chunk), 1, fp); + fclose(fp); + return chunk; } @@ -123,7 +133,7 @@ void purge_chunks(int ci) { chunks = calloc(CBUF_ALL, sizeof(Chunk)); */ if (chunks == NULL) { - chunks = calloc(CBUF_ALL * CHUNK_DIAMETER_H, sizeof(Chunk)); + chunks = calloc(CBUF_ALL * (CHUNK_DIAMETER_H + (MAX_R * 2)), sizeof(Chunk)); } memset(&chunks[CBUF_ALL * ci], 0, sizeof(Chunk) * CBUF_ALL); } diff --git a/main.c b/main.c index 7ac82e0..add749d 100644 --- a/main.c +++ b/main.c @@ -1,3 +1,4 @@ +#include #define GLAD_GL_IMPLEMENTATION #include "gl.h" #define GLFW_INCLUDE_NONE @@ -5,6 +6,8 @@ #define STB_IMAGE_IMPLEMENTATION #include "stb_image.h" +#include + #include "const.h" #include "cubes.h" #include "linmath.h" @@ -63,6 +66,33 @@ static void cursor_position_callback(GLFWwindow *window, double x, double y) { return; } +struct args { + int *cube_count; + Vertex **cube; + Vertex **text; + vec3 pos; + GLuint *vertex_buffer; + int *is_render; +}; + +void *render_chunks(void *args) { + struct args args2 = ((struct args *)args)[0]; + + int *cube_count = args2.cube_count; + // printf("%i\n", *cube_count); + GLuint *vertex_buffer = args2.vertex_buffer; + + *args2.is_render = 0; + + *cube_count = + gen_cubes(*args2.cube, *args2.text, args2.pos[0] / CHUNK_LENGTH, + args2.pos[1] / CHUNK_LENGTH, args2.pos[2] / CHUNK_LENGTH, 0, 0); + + *args2.is_render = 2; + + return NULL; +} + int main(void) { if (!glfwInit()) exit(EXIT_FAILURE); @@ -84,8 +114,9 @@ int main(void) { Vertex *cube = malloc(CTRI_ALL); Vertex *text = malloc(CTRI_ALL); - gen_cubes(cube, 1024,0,1024, 0); - gen_cubes(text, 1024,0,1024, 1); + + int cube_count = gen_cubes(cube, text, 0 / CHUNK_LENGTH, 0 / CHUNK_LENGTH, + 0 / CHUNK_LENGTH, 0,1); GLuint vertex_buffer[2]; GLuint vertex_array; @@ -132,29 +163,25 @@ int main(void) { glfwSetKeyCallback(window, key_callback); glfwSetCursorPosCallback(window, cursor_position_callback); - vec3 pos = {1024*CHUNK_LENGTH, 0, 1024*CHUNK_LENGTH}; + vec3 pos = {1024, 0, 1024}; - int x = 0, y = 25, z = 0; + // int x = 0, y = 25, z = 0; glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); + double frames = 0.0; + pthread_t thread_id; + int is_render = 1; + glfwSetTime(7.5); + while (!glfwWindowShouldClose(window)) { glfwGetFramebufferSize(window, &width, &height); const float ratio = width / (float)height; glViewport(0, 0, width, height); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glUseProgram(program); - glBindTexture(GL_TEXTURE_2D, GL_TEXTURE0); - - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tx, ty, 0, GL_RGB, GL_UNSIGNED_BYTE, - pixels); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - mat4x4 m, v, p, mvp; mat4x4_identity(m); mat4x4_perspective(p, 45.0 / 180.0 * M_PI, ratio, 0.1, 1000); @@ -189,12 +216,55 @@ int main(void) { mat4x4_mul(mvp, mvp, m); glUniformMatrix4fv(mvp_location, 1, GL_FALSE, (const GLfloat *)&mvp); - glBindVertexArray(vertex_array); - glDrawArrays(GL_TRIANGLES, 0, CBLOCK_ALL * 18); + if (frames >= 8) { + struct args args; + args.cube_count = &cube_count; + + args.cube = &cube; + args.text = &text; + args.pos[0] = pos[0]; + args.pos[1] = pos[1]; + args.pos[2] = pos[2]; + args.vertex_buffer = vertex_buffer; + args.is_render = &is_render; + + pthread_create(&(thread_id), NULL, render_chunks, (void *)&(args)); + + frames = 0; + glfwSetTime(0); + } + + frames = glfwGetTime(); + printf("%f\n", frames); glfwSwapBuffers(window); glfwPollEvents(); + + if (is_render == 2) { + glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer[1]); + glBufferSubData(GL_ARRAY_BUFFER, 0, (long)cube_count*sizeof(Vertex), text); + + glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer[0]); + glBufferSubData(GL_ARRAY_BUFFER, 0, (long)cube_count*sizeof(Vertex), cube); + is_render = 1; + } + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBindTexture(GL_TEXTURE_2D, GL_TEXTURE0); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tx, ty, 0, GL_RGB, GL_UNSIGNED_BYTE, + pixels); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + int val = CTRI_ALL; + + glBindVertexArray(vertex_array); + + glDrawArrays(GL_TRIANGLES, 0, cube_count); } free(cube);