]> git.lizzy.rs Git - dragonblocks_alpha.git/commitdiff
Add mapblock meshgen and mapgen
authorElias Fleckenstein <eliasfleckenstein@web.de>
Thu, 25 Mar 2021 14:09:22 +0000 (15:09 +0100)
committerElias Fleckenstein <eliasfleckenstein@web.de>
Thu, 25 Mar 2021 14:09:22 +0000 (15:09 +0100)
13 files changed:
src/Makefile
src/client.c
src/client.h
src/map.c
src/map.h
src/mapblock_meshgen.c
src/mapblock_meshgen.h
src/mapgen.c [new file with mode: 0644]
src/mapgen.h [new file with mode: 0644]
src/mesh.h
src/scene.c
src/scene.h
src/server.c

index 2649c590207b7ff9cf8970d993889855f6cd6ac2..b1014a9f4852f9aed42a623be01d853364d54c3c 100644 (file)
@@ -1,9 +1,9 @@
 COMMON = array.o binsearch.o list.o map.o signal.o util.o types.o
-SERVER = $(COMMON) server.o servercommands.o
-CLIENT = $(COMMON) client.o clientcommands.o mesh.o scene.o
+SERVER = $(COMMON) server.o servercommands.o mapgen.o
+CLIENT = $(COMMON) client.o clientcommands.o mesh.o scene.o mapblock_meshgen.o
 LIBRARIES = -lpthread -lm
 CLIENT_LIBRARIES = -lGL -lGLEW -lglfw
-FLAGS = -g
+FLAGS = -g -fmax-errors=4
 
 ifdef RELEASE
 FLAGS = -O3
index 2067463ab4219f58459acf0f33df06e13c5f35ad..16401596d4d56a0a346c9077a4af1c00502e533b 100644 (file)
@@ -9,6 +9,7 @@
 #include <GL/gl.h>
 #include <GLFW/glfw3.h>
 #include "client.h"
+#include "mapblock_meshgen.h"
 #include "signal.h"
 #include "util.h"
 
@@ -74,9 +75,7 @@ static void client_loop()
                glClear(GL_COLOR_BUFFER_BIT);
                glClearColor(0.52941176470588, 0.8078431372549, 0.92156862745098, 1.0);
 
-               mat4x4 view, proj;
-
-               scene_render(client.scene, shader_program, view, proj);
+               scene_render(client.scene, shader_program);
 
                glfwSwapBuffers(window);
                glfwPollEvents();
@@ -132,7 +131,8 @@ static void client_start(int fd)
        client.name = NULL;
        client.map = map_create();
        client.scene = scene_create();
-       //client.mapblock_meshgen = mapblock_meshgen_create();
+
+       mapblock_meshgen_init(client.map, client.scene);
 
        pthread_t recv_thread;
        pthread_create(&recv_thread, NULL, &reciever_thread, NULL);
@@ -146,9 +146,10 @@ static void client_start(int fd)
        if (client.name)
                free(client.name);
 
+       mapblock_meshgen_stop();
+
        map_delete(client.map);
        scene_delete(client.scene);
-       //mapblock_meshgen_delete(client.mapblock_meshgen);
 
        pthread_mutex_destroy(&client.mtx);
 }
index bfc2900e6a843127118a1ad50495ac519e3a2e51..00b9087a1c1405fe7557a534b06b65eacf0e351a 100644 (file)
@@ -7,7 +7,6 @@
 #include "clientcommands.h"
 #include "network.h"
 #include "map.h"
-//#include "mapblock_meshgen.h"
 #include "scene.h"
 
 typedef struct Client
@@ -18,7 +17,6 @@ typedef struct Client
        char *name;
        Map *map;
        Scene *scene;
-       //MapblockMeshgen *mapblock_meshgen;
 } Client;
 
 void client_disconnect(bool send, const char *detail);
index 847b45342fbd839893a2e54b50fab1e1a3538d7f..b239fbd5aad3c4d4041b6253c102e784a6a0cde1 100644 (file)
--- a/src/map.c
+++ b/src/map.c
@@ -87,19 +87,22 @@ MapBlock *map_get_block(Map *map, v3s32 pos, bool create)
 
        BinsearchResult res = binsearch(&pos.y, sector->blocks.ptr, sector->blocks.siz, &block_compare);
 
-       if (res.success)
-               return *get_block_ptr(sector, res.index);
-       if (! create)
-               return NULL;
+       MapBlock *block = NULL;
 
-       MapBlock *block = allocate_block(pos);
+       if (res.success) {
+               block = *get_block_ptr(sector, res.index);
+       } else if (create) {
+               block = allocate_block(pos);
 
-       MapNode air = map_node_create(NODE_AIR);
-       ITERATE_MAPBLOCK block->data[x][y][z] = air;
+               if (map->on_block_create)
+                       map->on_block_create(block);
 
-       array_insert(&sector->blocks, &block, res.index);
+               array_insert(&sector->blocks, &block, res.index);
+       } else {
+               return NULL;
+       }
 
-       return block;
+       return block->ready ? block : NULL;
 }
 
 void map_add_block(Map *map, MapBlock *block)
@@ -113,6 +116,8 @@ void map_add_block(Map *map, MapBlock *block)
        } else {
                array_insert(&sector->blocks, &block, res.index);
        }
+       if (map->on_block_add)
+               map->on_block_add(block);
 }
 
 void map_clear_block(MapBlock *block, v3u8 init_state)
@@ -216,10 +221,12 @@ MapNode map_get_node(Map *map, v3s32 pos)
 void map_set_node(Map *map, v3s32 pos, MapNode node)
 {
        v3u8 offset;
-       MapBlock *block = map_get_block(map, map_node_to_block_pos(pos, &offset), true);
-       MapNode *current_node = &block->data[offset.x][offset.y][offset.z];
-       map_node_clear(current_node);
-       *current_node = node;
+       MapBlock *block = map_get_block(map, map_node_to_block_pos(pos, &offset), false);
+       if (block) {
+               MapNode *current_node = &block->data[offset.x][offset.y][offset.z];
+               map_node_clear(current_node);
+               *current_node = node;
+       }
 }
 
 MapNode map_node_create(Node type)
index 43f8cd3269c79d128303a8f42a7bfff86b28fe47..c604141fcdabcfe900aa891c252aa5fb4fedd2b2 100644 (file)
--- a/src/map.h
+++ b/src/map.h
@@ -19,6 +19,7 @@ typedef struct
 {
        MapNode data[16][16][16];
        v3s32 pos;
+       bool ready;
        void *extra;
 } MapBlock;
 
@@ -29,9 +30,14 @@ typedef struct
        u64 hash;
 } MapSector;
 
+typedef void (*MapBlockCallback)(MapBlock *block);
+
 typedef struct
 {
        Array sectors;
+       MapBlockCallback on_block_create;
+       MapBlockCallback on_block_add;
+       MapBlockCallback on_block_change;
 } Map;
 
 Map *map_create();
index 3c8ecf484f908da3e72e9366f624f633c218367e..56882c1433cd63542ae2fbbfac20d1813f0600c9 100644 (file)
-static bool compare_positions(void *p1, void *p2)
+#include <stdlib.h>
+#include "mapblock_meshgen.h"
+
+static struct
 {
-       v3s32 *pos1 = p1;
-       v3s32 *pos2 = p2;
-       return pos1->x == pos2->x && pos1->y == pos2->y && pos->z == pos2->z;
-}
+       Map *map;
+       Scene *scene;
+       List queue;
+       pthread_mutex_t mtx;
+       pthread_t thread;
+       bool cancel;
+} meshgen;
 
-static void *mapblock_meshgen_thread(void *cliptr)
+static Array make_vertices(MapBlock *block)
 {
-       Client *client = cliptr;
+       Array vertices = array_create(sizeof(GLfloat));
 
-       for ever {
-               ListPair **lptr = &client->mapblock_meshgen_queue.first;
-               if (*lptr) {
-                       MapBlock *block = map_get_block(client->map, *(v3s32 *)(*lptr)->key, false);
-                       Array vertices(sizeof(GLfloat));
-
-                       ITERATE_MAPBLOCK {
-                               MapNode node = block->data[x][y][z];
-                               BlockDef *def = block->getDef();
-                               if (! def->drawable)
-                                       continue;
-                               ivec3 bpos(x, y, z);
-                               vec3 pos_from_mesh_origin = vec3(bpos) - vec3(SIZE / 2 + 0.5);
-                               for (int facenr = 0; facenr < 6; facenr++) {
-                                       ivec3 npos = bpos + face_dir[facenr];
-                                       const Block *neighbor_own, *neighbor;
-                                       neighbor_own = neighbor = getBlockNoEx(npos);
-                                       if (! neighbor)
-                                               neighbor = map->getBlock(pos * SIZE + npos);
-                                       if (neighbor && ! neighbor->getDef()->drawable)
-                                               any_drawable_block = true;
-                                       if (! mesh_created_before)
-                                               neighbor = neighbor_own;
-                                       if (! mesh_created_before && ! neighbor || neighbor && ! neighbor->getDef()->drawable) {
-                                               textures.push_back(def->tile_def.get(facenr));
-                                               for (int vertex_index = 0; vertex_index < 6; vertex_index++) {
-                                                       for (int attribute_index = 0; attribute_index < 5; attribute_index++) {
-                                                               GLdouble value = box_vertices[facenr][vertex_index][attribute_index];
-                                                               switch (attribute_index) {
-                                                                       case 0:
-                                                                       value += pos_from_mesh_origin.x;
-                                                                       break;
-                                                                       case 1:
-                                                                       value += pos_from_mesh_origin.y;
-                                                                       break;
-                                                                       case 2:
-                                                                       value += pos_from_mesh_origin.z;
-                                                                       break;
-                                                               }
-                                                               vertices.push_back(value);
-                                                       }
+       (void) block;
+
+       /*
+       ITERATE_MAPBLOCK {
+               MapNode node = block->data[x][y][z];
+               BlockDef *def = block->getDef();
+               if (! def->drawable)
+                       continue;
+               ivec3 bpos(x, y, z);
+               vec3 pos_from_mesh_origin = vec3(bpos) - vec3(SIZE / 2 + 0.5);
+               for (int facenr = 0; facenr < 6; facenr++) {
+                       ivec3 npos = bpos + face_dir[facenr];
+                       const Block *neighbor_own, *neighbor;
+                       neighbor_own = neighbor = getBlockNoEx(npos);
+                       if (! neighbor)
+                               neighbor = map->getBlock(pos * SIZE + npos);
+                       if (neighbor && ! neighbor->getDef()->drawable)
+                               any_drawable_block = true;
+                       if (! mesh_created_before)
+                               neighbor = neighbor_own;
+                       if (! mesh_created_before && ! neighbor || neighbor && ! neighbor->getDef()->drawable) {
+                               textures.push_back(def->tile_def.get(facenr));
+                               for (int vertex_index = 0; vertex_index < 6; vertex_index++) {
+                                       for (int attribute_index = 0; attribute_index < 5; attribute_index++) {
+                                               GLdouble value = box_vertices[facenr][vertex_index][attribute_index];
+                                               switch (attribute_index) {
+                                                       case 0:
+                                                       value += pos_from_mesh_origin.x;
+                                                       break;
+                                                       case 1:
+                                                       value += pos_from_mesh_origin.y;
+                                                       break;
+                                                       case 2:
+                                                       value += pos_from_mesh_origin.z;
+                                                       break;
                                                }
+                                               vertices.push_back(value);
                                        }
                                }
                        }
+               }
+       }
+       */
 
-                       client_create_mesh(client, create_mesh(vertices.ptr, vertices.siz));
-                       pthread_mutex_lock(client->mapblock_meshgen_mtx);
+       return vertices;
+}
+
+static void *meshgen_thread(void *unused)
+{
+       (void) unused;
+
+       while (! meshgen.cancel) {
+               ListPair **lptr = &meshgen.queue.first;
+               if (*lptr) {
+                       MapBlock *block = map_get_block(meshgen.map, *(v3s32 *)(*lptr)->key, false);
+
+                       pthread_mutex_lock(&meshgen.mtx);
+                       free((*lptr)->key);
                        *lptr = (*lptr)->next;
-                       pthread_mutex_unlock(client->mapblock_meshgen_mtx);
+                       pthread_mutex_unlock(&meshgen.mtx);
+
+                       Array vertices = make_vertices(block);
+                       Mesh *mesh = NULL;
+
+                       if (vertices.siz > 0) {
+                               mesh = mesh_create(vertices.ptr, vertices.siz);
+                               free(vertices.ptr);
+                               scene_add_mesh(meshgen.scene, mesh);
+                       }
+
+                       if (block->extra)
+                               mesh->remove = true;
+
+                       block->extra = mesh;
                } else {
                        sched_yield();
                }
        }
+
+       return NULL;
 }
 
-void client_mapblock_changed(Client *client, v3s32 pos)
+static void enqueue_block(MapBlock *block)
 {
        v3s32 *posptr = malloc(sizeof(v3s32));
-       *posptr = pos;
-       pthread_mutex_lock(client->mapblock_meshgen_mtx);
-       if (! list_put(&client->mapblock_meshgen_queue, posptr, NULL))
+       *posptr = block->pos;
+       pthread_mutex_lock(&meshgen.mtx);
+       if (! list_put(&meshgen.queue, posptr, NULL))
                free(posptr);
-       pthread_mutex_unlock(client->mapblock_meshgen_mtx);
+       pthread_mutex_unlock(&meshgen.mtx);
+}
+
+static bool compare_positions(void *p1, void *p2)
+{
+       v3s32 *pos1 = p1;
+       v3s32 *pos2 = p2;
+       return pos1->x == pos2->x && pos1->y == pos2->y && pos1->z == pos2->z;
+}
+
+void mapblock_meshgen_init(Map *map, Scene *scene)
+{
+       meshgen.map = map;
+       meshgen.scene = scene;
+       meshgen.queue = list_create(&compare_positions);
+       pthread_mutex_init(&meshgen.mtx, NULL);
+       map->on_block_add = &enqueue_block;
+       map->on_block_change = &enqueue_block;
+       pthread_create(&meshgen.thread, NULL, &meshgen_thread, NULL);
+}
+
+void mapblock_meshgen_stop()
+{
+       meshgen.cancel = true;
+       pthread_join(meshgen.thread, NULL);
+       pthread_mutex_destroy(&meshgen.mtx);
+       ITERATE_LIST(&meshgen.queue, pair) free(pair->key);
+       list_clear(&meshgen.queue);
 }
index 3501269b7882da2ac39bc0706b8f08cc08d8f540..2be1016d72a91e6bad1c9205d5e7f2c6a7945839 100644 (file)
@@ -1,11 +1,10 @@
 #ifndef _MAPBLOCK_MESHGEN_H_
 #define _MAPBLOCK_MESHGEN_H_
 
-typedef struct
-{
-       pthread_mutex_t mtx;
-} MapblockMeshgen;
-
+#include "map.h"
+#include "scene.h"
 
+void mapblock_meshgen_init(Map *map, Scene *scene);
+void mapblock_meshgen_stop();
 
 #endif
diff --git a/src/mapgen.c b/src/mapgen.c
new file mode 100644 (file)
index 0000000..6e24f2e
--- /dev/null
@@ -0,0 +1,18 @@
+#include <stdlib.h>
+#include "mapgen.h"
+
+// mapgen prototype
+static void generate_block(MapBlock *block)
+{
+       if (block->pos.y < 0 && rand() % 2 == 0) {
+               ITERATE_MAPBLOCK {
+                       block->data[x][y][z] = map_node_create(rand() % 4 + 1);
+               }
+       }
+       block->ready = true;
+}
+
+void mapgen_init(Map *map)
+{
+       map->on_block_create = &generate_block;
+}
diff --git a/src/mapgen.h b/src/mapgen.h
new file mode 100644 (file)
index 0000000..8062b6a
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef _MAPGEN_H_
+#define _MAPGEN_H_
+
+#include "map.h"
+
+void mapgen_init(Map *map);
+
+#endif
index de5aa2c706b29713a3872da96ff441ea83e22254..c3804e1c3c8fe28939e8eba18a2c44b1d5ddcfe9 100644 (file)
@@ -4,6 +4,7 @@
 #include <GL/glew.h>
 #include <GL/gl.h>
 #include <linmath.h/linmath.h>
+#include <stdbool.h>
 
 typedef struct
 {
@@ -11,9 +12,11 @@ typedef struct
        float angle;
        mat4x4 transform;
        GLuint VAO, VBO;
+       bool remove;
 } Mesh;
 
 Mesh *mesh_create(const GLvoid *vertices, GLsizei size);
 void mesh_delete(Mesh *mesh);
+void mesh_render(Mesh *mesh, int prog);
 
 #endif
index 9362b544fe9ef03abfd2e3e36293690f712f3e02..05dec086fc3a7e617467b72df21dd6ce8cf34131 100644 (file)
@@ -6,7 +6,6 @@ Scene *scene_create()
        Scene *scene = malloc(sizeof(Scene));
        scene->meshes = list_create(NULL),
        pthread_mutex_init(&scene->mtx, NULL);
-
        return scene;
 }
 
@@ -20,14 +19,25 @@ void scene_delete(Scene *scene)
 
 void scene_add_mesh(Scene *scene, Mesh *mesh)
 {
+       pthread_mutex_lock(&scene->mtx);
        list_put(&scene->meshes, mesh, NULL);
+       pthread_mutex_unlock(&scene->mtx);
 }
 
-void scene_remove_mesh(Scene *scene, Mesh *mesh)
+void scene_render(Scene *scene, int prog)
 {
-       pthread_mutex_lock(&scene->mtx);
-       list_delete(&scene->meshes, mesh);
-       pthread_mutex_unlock(&scene->mtx);
-       mesh_delete(mesh);
+       for (ListPair **pairptr = &scene->meshes.first; *pairptr != NULL; ) {
+               ListPair *pair = *pairptr;
+               Mesh *mesh = pair->key;
+               if (mesh->remove) {
+                       pthread_mutex_lock(&scene->mtx);
+                       *pairptr = pair->next;
+                       pthread_mutex_unlock(&scene->mtx);
+                       free(pair);
+                       mesh_delete(mesh);
+               } else {
+                       mesh_render(mesh, prog);
+                       pairptr = &pair->next;
+               }
+       }
 }
-
index b1a48c3dcae863a65f5704c495cd3e336380a55c..0f0ac92b9872c98cc4b0e63a24815842e2eb5d8d 100644 (file)
@@ -16,6 +16,6 @@ void scene_delete(Scene *scene);
 
 void scene_add_mesh(Scene *scene, Mesh *mesh);
 void scene_remove_mesh(Scene *scene, Mesh *mesh);
-void scene_render(Scene *scene, int prog, mat4x4 view, mat4x4 proj);   // ToDo
+void scene_render(Scene *scene, int prog);
 
 #endif
index 3cde37ce7a3822f73e78d04cf49158745d79cbc5..cf360d603932869360344decc3980f8827d6dec5 100644 (file)
@@ -3,6 +3,7 @@
 #include <unistd.h>
 #include <errno.h>
 #include <netdb.h>
+#include "mapgen.h"
 #include "server.h"
 #include "signal.h"
 #include "util.h"
@@ -89,6 +90,8 @@ void server_start(int fd)
                perror("fopen");
        }
 
+       mapgen_init(server.map);
+
        while (! interrupted)
                server_accept_client();