]> git.lizzy.rs Git - dragonblocks3d.git/commitdiff
Multithreading
authorElias Fleckenstein <eliasfleckenstein@web.de>
Tue, 8 Sep 2020 17:03:09 +0000 (19:03 +0200)
committerElias Fleckenstein <eliasfleckenstein@web.de>
Tue, 8 Sep 2020 17:03:09 +0000 (19:03 +0200)
33 files changed:
dragonblockslauncher [deleted file]
libdragonblocks.so [deleted file]
src/dragonblocks/CMakeLists.txt
src/dragonblocks/block_def.cpp
src/dragonblocks/camera.cpp
src/dragonblocks/chunk.cpp
src/dragonblocks/chunk.hpp
src/dragonblocks/client.cpp
src/dragonblocks/client.hpp
src/dragonblocks/core.cpp
src/dragonblocks/gldebug.cpp
src/dragonblocks/gldebug.hpp
src/dragonblocks/input_handler.cpp
src/dragonblocks/input_handler.hpp
src/dragonblocks/mainmenu.cpp
src/dragonblocks/mainmenu.hpp
src/dragonblocks/map.cpp
src/dragonblocks/map.hpp
src/dragonblocks/mesh.cpp
src/dragonblocks/mesh.hpp
src/dragonblocks/mesh_gen_mgr.cpp [new file with mode: 0644]
src/dragonblocks/mesh_gen_mgr.hpp [new file with mode: 0644]
src/dragonblocks/mesh_gen_thread.cpp [deleted file]
src/dragonblocks/mesh_gen_thread.hpp [deleted file]
src/dragonblocks/render_engine.cpp
src/dragonblocks/render_engine.hpp
src/dragonblocks/scene.cpp
src/dragonblocks/scene.hpp
src/dragonblocks/server.cpp
src/dragonblocks/server.hpp
src/dragonblocks/texture.cpp
src/dragonblocks/window.cpp
src/dragonblocks/window.hpp

diff --git a/dragonblockslauncher b/dragonblockslauncher
deleted file mode 100755 (executable)
index 7565e91..0000000
Binary files a/dragonblockslauncher and /dev/null differ
diff --git a/libdragonblocks.so b/libdragonblocks.so
deleted file mode 100755 (executable)
index 44eeea2..0000000
Binary files a/libdragonblocks.so and /dev/null differ
index 61953127439d8a2152483af0accd13cccbca2276..5a62d2582e6dd4f7b17e0c22798e1d376c83b687 100644 (file)
@@ -19,7 +19,7 @@ add_library(dragonblocks SHARED
        map.cpp
        mapgen.cpp
        mesh.cpp
-       mesh_gen_thread.cpp
+       mesh_gen_mgr.cpp
        render_engine.cpp
        scene.cpp
        server.cpp
index 5e95f29d77688287f243eef032976fec44f77ccf..2e200eee123c5c8a3a5cafa35ac628ecc806a87c 100644 (file)
@@ -1,5 +1,3 @@
-#include <iostream>
-#include <stdexcept>
 #include "block_def.hpp"
 
 using namespace std;
index 8c8db0a26bd253c0d1786d38fd3d551574d15694..2aa749de19a60fdcf29c03c89025ce795908c9d3 100644 (file)
@@ -12,7 +12,7 @@ mat4 Camera::getViewMatrix() const
 void Camera::update(double yaw, double pitch)
 {
        yaw = radians(yaw);
-       pitch = radians(clamp(pitch, -89.0, 89.0));
+       pitch = radians(pitch);
        
        m_front = normalize(vec3(cos(yaw) * cos(pitch), sin(pitch), sin(yaw) * cos(pitch)));
        m_right = normalize(cross(m_front, m_world_up));
index 862371086c281e2aec9d42a90cb64b89b71f1e61..267b6dc4b35eb0e5b3af0b33150cda5254931078 100644 (file)
@@ -3,6 +3,7 @@
 #include "chunk.hpp" 
 #include "cube.hpp"
 #include "face_dir.hpp" 
+#include "log.hpp" 
 #include "map.hpp" 
 #include "mesh.hpp" 
 #include "texture.hpp" 
@@ -29,7 +30,7 @@ const Block *Chunk::getBlockNoEx(const ivec3 &pos) const
 {
        try {
                return getBlock(pos);
-       } catch (std::out_of_range &) {
+       } catch (out_of_range &) {
                return nullptr;
        }
 }
@@ -44,14 +45,38 @@ void Chunk::setBlockNoEx(const ivec3 &pos, const Block &block)
 {
        try {
                setBlock(pos, block);
-       } catch (std::out_of_range &) {
+       } catch (out_of_range &) {
+       }
+}
+
+void Chunk::addMeshUpdateTask()
+{
+       mesh_gen_mgr->addTask(this);
+}
+
+void Chunk::addMeshUpdateTaskWithEdge()
+{
+       addMeshUpdateTask();
+       for (int i = 0; i < 6; i++) {
+               if (Chunk *neighbor = map->getChunk(pos + face_dir[i])) {
+                       neighbor->addMeshUpdateTask();
+               }
        }
 }
 
 void Chunk::updateMesh()
 {
-       std::vector<GLfloat> vertices;
-       std::vector<Texture> textures;
+       log(string("Update Chunk Mesh at ") + to_string(pos.x) + " " + to_string(pos.y) +  " " + to_string(pos.z));
+               
+       if (mesh_created && ! effect_finished)
+               return;
+       
+       bool mesh_created_before = mesh_created;
+       mesh_created = true;
+       
+       vector<GLfloat> vertices;
+       vector<Texture> textures;
+       bool any_drawable_block = false;
        
        for (int x = 0; x < SIZE; x++) {
                for (int y = 0; y < SIZE; y++) {
@@ -60,11 +85,19 @@ void Chunk::updateMesh()
                                BlockDef *def = block->getDef();
                                if (! def->drawable)
                                        continue;
-                               vec3 pos(x, y, z);
-                               vec3 pos_from_mesh_origin = pos - vec3(SIZE / 2 + 0.5);
+                               ivec3 bpos(x, y, z);
+                               vec3 pos_from_mesh_origin = vec3(bpos) - vec3(SIZE / 2 + 0.5);
                                for (int facenr = 0; facenr < 6; facenr++) {
-                                       const Block *neighbor = map->getBlockRelativePos(this, pos + (vec3)face_dir[facenr]);
-                                       if (neighbor && ! neighbor->getDef()->drawable) {
+                                       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->tiles[facenr]);
                                                for (int vertex_index = 0; vertex_index < 6; vertex_index++) {
                                                        for (int attribute_index = 0; attribute_index < 5; attribute_index++) {
@@ -89,46 +122,53 @@ void Chunk::updateMesh()
                        }
                }
        }
-
-       bool is_new = ! deleteMesh();
        
-       if (textures.size() == 0) {
+       if (! any_drawable_block) {
+               if (! mesh_created_before) {
+                       afterEffect();
+               } else if (mesh) {
+                       mesh->reset();
+               }
                return;
        }
-
-       mesh = new Mesh(scene);
+       
+       if (! mesh) {
+               mesh = new Mesh(scene);
+       } else {
+               mesh->reset();
+       }
        mesh->pos = pos * SIZE + SIZE / 2;
-       mesh->size = vec3(1.0);
-       mesh->configureVertexObjects(&vertices[0], vertices.size() * sizeof(GLfloat));
+       mesh->vertexConfig(&vertices[0], vertices.size() * sizeof(GLfloat));
        mesh->textures = textures;
        mesh->vertices_per_texture = 6;
-       if (is_new)
-               mesh->effect = Mesh::Effect::Type::FLYIN;
+       if (! mesh_created_before) {
+               mesh->effect = Mesh::Effect(Mesh::Effect::Type::FLYIN, Chunk::staticAfterEffect, this);
+       }
        mesh->addToScene();
 }
 
-void Chunk::addMeshUpdateTask()
+Chunk::Chunk(Map *m, const glm::ivec3 &p, const Data &d, MeshGenMgr *mgt, Scene *s) : map(m), data(d), pos(p), mesh_gen_mgr(mgt), scene(s)
 {
-       mesh_gen_thread->addTask(this);
+       addMeshUpdateTask();
 }
 
-bool Chunk::deleteMesh()
+Chunk::~Chunk()
 {
        if (mesh) {
                mesh->removeFromScene();
                delete mesh;
-               mesh = nullptr;
-               return true;
        }
-       return false;
 }
 
-Chunk::Chunk(Map *m, const glm::ivec3 &p, const Data &d, MeshGenThread *mgt, Scene *s) : map(m), data(d), pos(p), mesh_gen_thread(mgt), scene(s)
+void Chunk::staticAfterEffect(void *chunk)
 {
-       addMeshUpdateTask();
+       if (chunk) {
+               ((Chunk *)chunk)->afterEffect();
+       }
 }
 
-Chunk::~Chunk()
+void Chunk::afterEffect()
 {
-       deleteMesh();
+       effect_finished = true;
+       addMeshUpdateTaskWithEdge();
 }
index 220cd0b1726291a4ae829bc44468be54dde85a04..43921c1f1f147dbcf20650a07f4f788a2fdd9f35 100644 (file)
@@ -2,7 +2,7 @@
 
 #include "block.hpp"
 #include "gl.hpp"
-#include "mesh_gen_thread.hpp"
+#include "mesh_gen_mgr.hpp"
 
 #define DRAGONBLOCKS_CHUNK_SIZE 16
 
@@ -12,7 +12,7 @@ namespace dragonblocks
        class Mesh;
        class Scene;
        
-       class Chunk : public MeshGenThread::MeshGenerator
+       class Chunk : public MeshGenMgr::MeshGenerator
        {
                public:
                static void checkPos(const glm::ivec3 &);
@@ -32,18 +32,24 @@ namespace dragonblocks
                void setBlock(const glm::ivec3 &, const Block &);
                void setBlockNoEx(const glm::ivec3 &, const Block &);
                void addMeshUpdateTask();
+               void addMeshUpdateTaskWithEdge();
                void updateMesh();
                
-               Chunk(Map *, const glm::ivec3 &, const Data &, MeshGenThread *, Scene *);
+               Chunk(Map *, const glm::ivec3 &, const Data &, MeshGenMgr *, Scene *);
                ~Chunk();
                
                private:
+               static void staticAfterEffect(void *);
+               
                Map *map;
                Mesh *mesh = nullptr;
-               MeshGenThread *mesh_gen_thread;
+               MeshGenMgr *mesh_gen_mgr;
                Scene *scene;
                Data data;
+               bool effect_finished = false;
+               bool mesh_created = false;
                
-               bool deleteMesh();
+               void afterEffect();
+               void deleteMesh();
        };
 }; 
index 51ba5598624461f096b8a157edb59e13152028fa..4e49d3683e47eb623d06e3ee0b59c0e9a9a2ea68 100644 (file)
@@ -21,7 +21,7 @@ Client::Client()
        Texture::bilinear_filter = false;
        Texture::initArgs();
        
-       render_engine = RenderEngine::create();
+       render_engine = new RenderEngine;
        
        render_engine->window->setSize(1250, 750);
        render_engine->window->setPos(0, 0);
@@ -39,9 +39,15 @@ Client::Client()
        
        mapgen = new Mapgen;
        
-       map = new Map(mapgen, render_engine->mesh_gen_thread, render_engine->scene);
+       map = new Map(mapgen, render_engine->mesh_gen_mgr, render_engine->scene);
        
        game = new Game(mapgen);
-       
+
        log("Initialisation complete.");
 }
+
+void Client::start()
+{
+       render_engine->mesh_gen_mgr->start();
+       render_engine->loop();
+}
index 09699d3d117c3cbd1a5d6937bf86e78529945545..a1a02b7ea69722275939caf8430c5e6b281012db 100644 (file)
@@ -15,6 +15,8 @@ namespace dragonblocks
                Mapgen *mapgen;
                RenderEngine *render_engine;
                
+               void start();
+               
                Client();
                ~Client();
        };
index 321050a5c30e0b7c173bff3925ce8120c5cdbad2..9a7c5a702197c5472f18390334546e55e9b5a6c6 100644 (file)
@@ -15,17 +15,19 @@ extern "C" void _dragonblocks_start_client()
 {
        gametype = Gametype::CLIENT; 
        client = new Client();
-       client->render_engine->loop();
+       client->start();
 }
 
 extern "C" void _dragonblocks_start_server()
 {
        gametype = Gametype::SERVER;
        server = new Server();
+       server->start();
 }
 
 extern "C" void _dragonblocks_start_mainmenu()
 {
        gametype = Gametype::MAINMENU;
        mainmenu = new Mainmenu();
+       mainmenu->start();
 }
index c65a7c90e851873d8b3791d3524a5b0e9f79cde9..44a91fe85dab4ba3c8412bdf2b52fcd926c32afb 100644 (file)
@@ -1,10 +1,11 @@
-#include <iostream>
 #include <string>
 #include "gldebug.hpp" 
+#include "log.hpp" 
 
 using namespace std;
+using namespace dragonblocks;
 
-GLenum glCheckError_(const char *file, int line)
+GLenum dragonblocks::checkGLError(const char *file, int line)
 {
     GLenum errorCode;
     if ((errorCode = glGetError()) != GL_NO_ERROR)
@@ -20,7 +21,7 @@ GLenum glCheckError_(const char *file, int line)
             case GL_OUT_OF_MEMORY:                 error = "OUT_OF_MEMORY"; break;
             case GL_INVALID_FRAMEBUFFER_OPERATION: error = "INVALID_FRAMEBUFFER_OPERATION"; break;
         }
-        cout << error << " | " << file << " (" << line << ")" << endl;
+               log(string("OpenGL Error: ") + error + " | " + file + " (" + ")");
     }
     return errorCode;
 }
index af0387c8a1dad8e1223498fa267dd7395e2ae113..bc56bb665baa0fb42ffa757a9cda4c8bdcf56df3 100644 (file)
@@ -2,8 +2,9 @@
 
 #include "gl.hpp"
 
-#define glCheckError() glCheckError_(__FILE__, __LINE__)
-#define CHECKERR glCheckError();
-
-GLenum glCheckError_(const char *file, int line);
+#define CHECKERR dragonblocks::checkGLError(__FILE__, __LINE__);
 
+namespace dragonblocks
+{
+       GLenum checkGLError(const char *file, int line);
+}
index beda411e2c39a99ce936d9b9b3fade748d2812f1..5e48c82013e96675e4934c5ab47eb847fc91e474 100644 (file)
@@ -20,10 +20,11 @@ void InputHandler::processMouseInput(double dtime)
 
 void InputHandler::processKeyInput(double dtime)
 {
-       map<int, bool> keysDown;
+       set<int> keysDown;
        for (auto it = listened_keys.begin(); it != listened_keys.end(); it++) {
-               if (window->wasKeyDown(it->first)) {
-                       keysDown[it->first] = true;
+               int key = *it;
+               if (window->wasKeyDown(key)) {
+                       keysDown.insert(key);
                }
        }
        onKeyPress(dtime, keysDown);
@@ -33,10 +34,11 @@ void InputHandler::onMouseMove(double dtime, double x, double y)
 {
        yaw += x;
        pitch -= y;
+       pitch = clamp(pitch, -89.0, 89.0);
        camera->update(yaw, pitch);
 }
 
-void InputHandler::onKeyPress(double dtime, map<int, bool> keysDown)
+void InputHandler::onKeyPress(double dtime, set<int> keys)
 {
        vec3 vel = vec3(speed * dtime);
        vec3 front = camera->front(), right = camera->right(), up = camera->up();
@@ -44,26 +46,26 @@ void InputHandler::onKeyPress(double dtime, map<int, bool> keysDown)
                front = normalize(vec3(front.x, 0, front.z));
                up = normalize(vec3(0, up.y, 0));
        }
-       if (keysDown[GLFW_KEY_W]) {
+       if (keys.find(GLFW_KEY_W) != keys.end()) {
                camera->pos += vel * front;
-       } else if (keysDown[GLFW_KEY_S]) {
+       } else if (keys.find(GLFW_KEY_S) != keys.end()) {
                camera->pos -= vel * front;
        }
-       if (keysDown[GLFW_KEY_D]) {
+       if (keys.find(GLFW_KEY_D) != keys.end()) {
                camera->pos += vel * right;
-       } else if (keysDown[GLFW_KEY_A]) {
+       } else if (keys.find(GLFW_KEY_A) != keys.end()) {
                camera->pos -= vel * right;
        }
-       if (keysDown[GLFW_KEY_SPACE]) {
+       if (keys.find(GLFW_KEY_SPACE) != keys.end()) {
                camera->pos += vel * up;
-       } else if (keysDown[GLFW_KEY_LEFT_SHIFT]) {
+       } else if (keys.find(GLFW_KEY_LEFT_SHIFT) != keys.end()) {
                camera->pos -= vel * up;
        }       
 }
 
 void InputHandler::listenFor(int key)
 {
-       listened_keys[key] = true;
+       listened_keys.insert(key);
 }
 
 void InputHandler::dontListenFor(int key)
index a311028a7b81592ce5feff1920b117764ab34802..a54f1adfadb115aa4d4d4c0d268fdd7573b636b8 100644 (file)
@@ -1,6 +1,6 @@
 #pragma once
 
-#include <map>
+#include <set>
 #include "gl.hpp"
 
 namespace dragonblocks
@@ -15,7 +15,7 @@ namespace dragonblocks
                void processMouseInput(double);
                void processKeyInput(double);
                void onMouseMove(double, double, double);
-               void onKeyPress(double, std::map<int, bool>);
+               void onKeyPress(double, std::set<int>);
                void listenFor(int);
                void dontListenFor(int);
                
@@ -29,6 +29,6 @@ namespace dragonblocks
                private:                
                Camera *camera;
                Window *window;
-               std::map<int, bool> listened_keys;
+               std::set<int> listened_keys;
        };
 }
index 92b9be675715941af823f2ebbb194cb5c40a4852..7b05b21199fa99d686f9c878bb5d13cb71f6bf27 100644 (file)
@@ -3,7 +3,7 @@
 
 using namespace dragonblocks;
 
-Mainmenu::Mainmenu()
+void Mainmenu::start()
 {
        log("Main Menu is not available yet.");
 }
index 11e103999c53c02db5c25b69c9981946d1311bc4..54a7d2639bd69e72e89897b04f1e389baf8f3974 100644 (file)
@@ -5,7 +5,7 @@ namespace dragonblocks
        class Mainmenu
        {
                public:
-               Mainmenu();
+               void start();
        };
 } 
  
index e9030cb22c544db5d2eb3db2c4508bdd16c9273d..de246a4b8437a0653398ebfbf39b755e2abd8240 100644 (file)
@@ -1,5 +1,4 @@
 #include <stdexcept>
-#include "face_dir.hpp"
 #include "map.hpp"
 #include "mapgen.hpp"
 
@@ -9,17 +8,17 @@ using namespace dragonblocks;
 
 ivec3 Map::getChunkPos(const vec3 &p)
 {
-       return floor(p / 16.0F);
+       return floor(p / (float)DRAGONBLOCKS_CHUNK_SIZE);
 }
 
 ivec3 Map::getBlockPos(const ivec3 &p)
 {
-       return ((p % 16) + ivec3(16)) % 16;
+       return ((p % DRAGONBLOCKS_CHUNK_SIZE) + ivec3(DRAGONBLOCKS_CHUNK_SIZE)) % DRAGONBLOCKS_CHUNK_SIZE;
 }
 
 uint16_t Map::getChunkPosHash(const ivec3 &p)
 {
-       return (uint16_t)p.x + (uint16_t)p.y * 1000 + (uint16_t)p.z * 1000000;
+       return (uint16_t)p.x + (uint16_t)p.y * DRAGONBLOCKS_MAP_SIZE + (uint16_t)p.z * DRAGONBLOCKS_MAP_SIZE * DRAGONBLOCKS_MAP_SIZE;
 }
 
 const Block *Map::getBlock(const glm::ivec3 &p)
@@ -31,17 +30,6 @@ const Block *Map::getBlock(const glm::ivec3 &p)
        return nullptr;
 }
 
-const Block *Map::getBlockRelativePos(Chunk *chunk, const glm::ivec3 &p)
-{
-       const Block *b = nullptr;
-       try {
-               b = chunk->getBlock(p);
-       } catch (std::out_of_range &) {
-               b = getBlock(chunk->pos * 16 + p);
-       }
-       return b;
-}
-
 void Map::setBlock(const glm::ivec3 &p, BlockDef *def)
 {
        Chunk *chunk = getChunk(Map::getChunkPos(p));
@@ -56,12 +44,7 @@ void Map::createChunk(const glm::ivec3 &p, const Chunk::Data &data)
        if (chunks[poshash])
                return;
 
-       chunks[poshash] = new Chunk(this, p, data, mesh_gen_thread, scene);
-       
-       for (int i = 0; i < 6; i++) {
-               if (Chunk *neighbor = getChunk(p + face_dir[i]))
-                       neighbor->addMeshUpdateTask();
-       }
+       chunks[poshash] = new Chunk(this, p, data, mesh_gen_mgr, scene);
 }
 
 void Map::createChunk(const glm::ivec3 &p)
@@ -82,7 +65,7 @@ void Map::clear()
        chunks.clear();
 }
 
-Map::Map(Mapgen *m, MeshGenThread *mgt, Scene *s) : mapgen(m), mesh_gen_thread(mgt), scene(s)
+Map::Map(Mapgen *m, MeshGenMgr *mgt, Scene *s) : mapgen(m), mesh_gen_mgr(mgt), scene(s)
 {
 }
 
index ba1a1620081451d422fe9d38249d3d6829df993c..e7b9f7ed90684c7028e6cef4c873afe14d751589 100644 (file)
@@ -11,7 +11,7 @@ namespace dragonblocks
        class BlockDef;
        class Block;
        class Mapgen;
-       class MeshGenThread;
+       class MeshGenMgr;
        class Scene;
        
        class Map
@@ -29,13 +29,13 @@ namespace dragonblocks
                Chunk *getChunk(const glm::ivec3 &);
                void clear();
                
-               Map(Mapgen *, MeshGenThread *, Scene *);
+               Map(Mapgen *, MeshGenMgr *, Scene *);
                ~Map();
                
                private:
                std::map<uint16_t, Chunk*> chunks;
                Mapgen *mapgen;
-               MeshGenThread *mesh_gen_thread;
+               MeshGenMgr *mesh_gen_mgr;
                Scene *scene;
        };
 }
index a37ac3a4d6827d7e4d0dfa1649c036e92f90811f..f934e8e58f005d5e78f8a66a1a8ba46fd67d9dc8 100644 (file)
@@ -1,3 +1,6 @@
+#include <stdexcept>
+#include <cstdlib>
+#include <cstring>
 #include <glm/gtc/matrix_transform.hpp>
 #include <glm/gtc/constants.hpp>
 #include "gldebug.hpp"
@@ -9,12 +12,12 @@ using namespace std;
 using namespace glm;
 using namespace dragonblocks;
 
-double Mesh::Effect::grow_time = 0.5;  // s
-double Mesh::Effect::flyin_time = 0.5; // s
+double Mesh::Effect::grow_time = 0.25; // s
+double Mesh::Effect::flyin_time = 0.4; // s
 double Mesh::Effect::flyin_offset = 20;        // m
 double Mesh::Effect::rotate_speed = 1; // turns/s
 
-mat4 Mesh::Effect::getModelMatrix(double dtime, vec3 pos, vec3 size, vec3 rotation_axis, float rotation_angle, void *extra_data)
+mat4 Mesh::Effect::getModelMatrix(double dtime, vec3 pos, vec3 size, vec3 rotation_axis, float rotation_angle)
 {
        mat4 trans = mat4(1.0);
 
@@ -54,10 +57,8 @@ mat4 Mesh::Effect::getModelMatrix(double dtime, vec3 pos, vec3 size, vec3 rotati
        return trans;
 }
 
-Mesh::Effect::Effect(Mesh::Effect::Type t, void (*callback)(void *))
+Mesh::Effect::Effect(Mesh::Effect::Type t, void (*o)(void *), void *e) : type(t), on_finish(o), extra_data(e)
 {
-       type = t;
-       on_finish = callback;
        switch(type) {
                case Mesh::Effect::Type::FLYIN:
                expires = true;
@@ -74,32 +75,28 @@ Mesh::Effect::Effect(Mesh::Effect::Type t, void (*callback)(void *))
        }
 }
 
-void Mesh::configureVertexObjects(const GLvoid *vertices, GLsizeiptr vertices_size)
+void Mesh::vertexConfig(const GLvoid *v, GLsizei s)
 {
-       glGenVertexArrays(1, &VAO); CHECKERR
-       glGenBuffers(1, &VBO); CHECKERR
-       
-       glBindVertexArray(VAO); CHECKERR
-       glBindBuffer(GL_ARRAY_BUFFER, VBO); CHECKERR
-       
-       glBufferData(GL_ARRAY_BUFFER, vertices_size, vertices, GL_STATIC_DRAW); CHECKERR
-       
-       GLsizei stride = 5 * sizeof(GLfloat); CHECKERR
-       
-       glVertexAttribPointer(0, 3, GL_FLOAT, false, stride, (GLvoid *)(0 * sizeof(GLfloat))); CHECKERR
-       glEnableVertexAttribArray(0); CHECKERR
-       glVertexAttribPointer(1, 2, GL_FLOAT, false, stride, (GLvoid *)(3 * sizeof(GLfloat))); CHECKERR
-       glEnableVertexAttribArray(1); CHECKERR
-       
-       glBindBuffer(GL_ARRAY_BUFFER, 0); CHECKERR
-       glBindVertexArray(0); CHECKERR
+       if (vertices_changed || configured)
+               throw runtime_error("Attempt to configure Mesh that is already configured");
+       vertices = malloc(s);
+       memcpy(vertices, v, s);
+       vertices_size = s;
+       vertices_changed = true;
 }
 
 void Mesh::render(double dtime, ShaderProgram *shader_program)
 {
+       if (vertices_changed) {
+               runVertexConfig();
+       }
+               
+       if (! configured)
+               return;
+
        shader_program->use(); CHECKERR
        
-       mat4 model_matrix = effect.getModelMatrix(dtime, pos, size, rotation_axis, rotation_angle, extra_data); CHECKERR
+       mat4 model_matrix = effect.getModelMatrix(dtime, pos, size, rotation_axis, rotation_angle); CHECKERR
        
        shader_program->set("model", model_matrix); CHECKERR
        
@@ -112,6 +109,29 @@ void Mesh::render(double dtime, ShaderProgram *shader_program)
        glBindTexture(GL_TEXTURE_2D, 0); CHECKERR
 }
 
+void Mesh::reset()
+{
+       removeFromScene();
+       pos = vec3(0.0);
+       size = vec3(1.0);
+       rotation_axis = vec3(0.0, 1.0, 0.0);
+       vertices_per_texture = 0;
+       textures = {};
+       rotation_angle = 0;
+       if (VAO) {
+               glDeleteVertexArrays(1, &VAO); CHECKERR
+       }
+       if (VBO) {
+               glDeleteBuffers(1, &VAO); CHECKERR
+       }
+       vertices_changed = false;
+       if (vertices) {
+               free(vertices);
+       }
+       vertices = NULL;
+       configured = false;
+}
+
 void Mesh::addToScene()
 {
        scene->add(this);
@@ -122,6 +142,36 @@ void Mesh::removeFromScene()
        scene->remove(this);
 }
 
-Mesh::Mesh(Scene *s): pos(0.0), size(1.0), rotation_axis(0.0, 1.0, 0.0), scene(s)
+Mesh::Mesh(Scene *s): scene(s)
 {
+       reset();
+}
+
+void Mesh::runVertexConfig()
+{              
+       if (! vertices || vertices_size == 0)
+               throw runtime_error("Invalid Mesh configuration");
+       
+       glGenVertexArrays(1, &VAO); CHECKERR
+       glGenBuffers(1, &VBO); CHECKERR
+       
+       glBindVertexArray(VAO); CHECKERR
+       glBindBuffer(GL_ARRAY_BUFFER, VBO); CHECKERR
+               
+       glBufferData(GL_ARRAY_BUFFER, vertices_size, vertices, GL_STATIC_DRAW); CHECKERR
+       
+       GLsizei stride = 5 * sizeof(GLfloat); CHECKERR
+       
+       glVertexAttribPointer(0, 3, GL_FLOAT, false, stride, (GLvoid *)(0 * sizeof(GLfloat))); CHECKERR
+       glEnableVertexAttribArray(0); CHECKERR
+       glVertexAttribPointer(1, 2, GL_FLOAT, false, stride, (GLvoid *)(3 * sizeof(GLfloat))); CHECKERR
+       glEnableVertexAttribArray(1); CHECKERR
+       
+       glBindBuffer(GL_ARRAY_BUFFER, 0); CHECKERR
+       glBindVertexArray(0); CHECKERR
+       
+       free(vertices);
+       vertices = NULL;
+       vertices_changed = false;
+       configured = true;
 }
index 57530fc6dbc5fd12c2b9165e1eae48298fcf9cd3..0bb06c894e70e0ec52f6ca780d0809f522f41939 100644 (file)
@@ -28,35 +28,42 @@ namespace dragonblocks
                                ROTATE
                        };
                        
-                       glm::mat4 getModelMatrix(double, glm::vec3, glm::vec3, glm::vec3, float, void *);
+                       glm::mat4 getModelMatrix(double, glm::vec3, glm::vec3, glm::vec3, float);
                        
                        Effect() = default;
-                       Effect(Type, void (*)(void *) = nullptr);
+                       Effect(Type, void (*)(void *) = nullptr, void * = nullptr);
                        Effect(const Effect &) = default;
                        
                        private:
                        Type type = Type::NONE;
                        double time_left;
-                       void (*on_finish)(void *) = nullptr;
+                       void (*on_finish)(void *);
+                       void *extra_data;
                        bool expires;
                };
                
                int vertices_per_texture;
                glm::vec3 pos, size, rotation_axis;
-               float rotation_angle = 0;
-               std::vector<Texture> textures;
-               void *extra_data = nullptr;             
+               float rotation_angle;
+               std::vector<Texture> textures;  
                Effect effect;
                
-               void configureVertexObjects(const GLvoid *, GLsizeiptr);
+               void reset();
+               void vertexConfig(const GLvoid *v, GLsizei s);
                void render(double dtime, ShaderProgram *);
                void addToScene();
                void removeFromScene();
-       
+               void runVertexConfig();
+               
                Mesh(Scene *);
 
                private:
-               GLuint VAO, VBO;
+               GLuint VAO = 0, VBO = 0;
                Scene *scene;
+               GLvoid *vertices = NULL;
+               GLsizeiptr vertices_size;
+               bool configured;
+               bool vertices_changed;
+               
        };
 }
diff --git a/src/dragonblocks/mesh_gen_mgr.cpp b/src/dragonblocks/mesh_gen_mgr.cpp
new file mode 100644 (file)
index 0000000..7d0c0b6
--- /dev/null
@@ -0,0 +1,60 @@
+#include <set>
+#include "mesh_gen_mgr.hpp"
+#include "window.hpp"
+
+using namespace std;
+using namespace dragonblocks;
+
+void MeshGenMgr::MeshGenerator::updateMesh()
+{
+}
+
+void MeshGenMgr::addTask(MeshGenMgr::MeshGenerator *gen)
+{
+       queued_jobs.push(gen);
+}
+
+void MeshGenMgr::step()
+{
+       if (! runJob()) {
+               generateJobList();
+       }
+}
+
+void MeshGenMgr::run()
+{
+       while (true) {
+               step();
+       }
+}
+
+void MeshGenMgr::generateJobList()
+{
+       set<MeshGenMgr::MeshGenerator *> active_jobs_set;
+       while (! queued_jobs.empty()) {
+               MeshGenMgr::MeshGenerator *gen = queued_jobs.front();
+               queued_jobs.pop();
+               if (active_jobs_set.find(gen) == active_jobs_set.end()) {
+                       active_jobs_set.insert(gen);
+                       active_jobs.push(gen);
+               }
+       }
+}
+
+
+bool MeshGenMgr::runJob()
+{
+       if (active_jobs.empty())
+               return false;
+       MeshGenMgr::MeshGenerator *gen = active_jobs.front();
+       active_jobs.pop();
+       if (gen) {
+               gen->updateMesh();
+       }
+       return true;
+}
+
+void MeshGenMgr::start()
+{
+       mesh_gen_thread = thread(&MeshGenMgr::run, this);
+}
diff --git a/src/dragonblocks/mesh_gen_mgr.hpp b/src/dragonblocks/mesh_gen_mgr.hpp
new file mode 100644 (file)
index 0000000..57b6192
--- /dev/null
@@ -0,0 +1,32 @@
+#pragma once
+
+#include <thread>
+#include <queue>
+
+namespace dragonblocks
+{
+       class Window;
+       
+       class MeshGenMgr : public std::thread
+       {
+               public:
+               class MeshGenerator
+               {
+                       public:
+                       virtual void updateMesh();
+               };
+               
+               void addTask(MeshGenerator *);
+               void step();
+               void run();
+               void start();
+                               
+               private:
+               void generateJobList();
+               bool runJob();
+               
+               std::queue<MeshGenerator *> queued_jobs;
+               std::queue<MeshGenerator *> active_jobs;
+               std::thread mesh_gen_thread;
+       };
+}
diff --git a/src/dragonblocks/mesh_gen_thread.cpp b/src/dragonblocks/mesh_gen_thread.cpp
deleted file mode 100644 (file)
index 01c9b74..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-#include "mesh_gen_thread.hpp"
-
-using namespace std;
-using namespace dragonblocks;
-
-void MeshGenThread::MeshGenerator::updateMesh()
-{
-}
-
-void MeshGenThread::addTask(MeshGenThread::MeshGenerator *gen)
-{
-       queued_jobs[gen] = true;
-}
-
-void MeshGenThread::step()
-{
-       if (! runJob()) {
-               generateJobList();
-       }
-}
-
-void MeshGenThread::generateJobList()
-{
-       for (auto it = queued_jobs.begin(); it != queued_jobs.end(); it++) {
-               active_jobs.push_back(it->first);
-       }
-       queued_jobs.clear();
-}
-
-
-bool MeshGenThread::runJob()
-{
-       int s = active_jobs.size();
-       if (s == 0)
-               return false;
-       MeshGenThread::MeshGenerator *gen = active_jobs[s - 1];
-       active_jobs.pop_back();
-       if (gen) {
-               gen->updateMesh();
-       }
-       return true;
-}
-
diff --git a/src/dragonblocks/mesh_gen_thread.hpp b/src/dragonblocks/mesh_gen_thread.hpp
deleted file mode 100644 (file)
index 7a1809e..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-#pragma once
-
-#include <map>
-#include <vector>
-
-namespace dragonblocks
-{
-       class MeshGenThread                                                                                             // TODO: extend std::thread or something
-       {
-               public:
-               class MeshGenerator
-               {
-                       public:
-                       virtual void updateMesh();
-               };
-               
-               void addTask(MeshGenerator *);
-               void step();
-               
-               private:                
-               void generateJobList();
-               bool runJob();
-               
-               std::map<MeshGenerator *, bool> queued_jobs;                                    // This sucks i should use std::queue instead but i need to somehow make sure that a task isnt in there twice
-               std::vector<MeshGenerator *> active_jobs;
-               
-       };
-}
index 14c1da09f99fdc83b85c64896a82321cb91570ff..e5d23fba1cb2f23a2d132e391f6c17e8793c5565 100644 (file)
@@ -6,7 +6,7 @@
 #include "gldebug.hpp"
 #include "input_handler.hpp"
 #include "map.hpp"                                             // this one three
-#include "mesh_gen_thread.hpp"
+#include "mesh_gen_mgr.hpp"
 #include "render_engine.hpp"
 #include "scene.hpp"
 #include "shader_program.hpp"
@@ -16,15 +16,6 @@ using namespace std;
 using namespace glm;
 using namespace dragonblocks;
 
-RenderEngine *RenderEngine::singleton = nullptr;
-
-RenderEngine *RenderEngine::create()
-{
-       if (singleton)
-               throw runtime_error("RenderEngine already exists");
-       return singleton = new RenderEngine;
-}
-
 void RenderEngine::render()
 {
        double dtime = glfwGetTime() - last_time;
@@ -59,7 +50,6 @@ void RenderEngine::loop()
 {
        while (! window->shouldClose()) {
                render();
-               mesh_gen_thread->step();
                loadChunks();
        }
 }
@@ -94,16 +84,6 @@ void RenderEngine::setFov(double f)
        updateProjectionMatrix();
 }
 
-RenderEngine::~RenderEngine()
-{
-       delete window;
-       delete camera;
-       delete input_handler;
-       delete mesh_gen_thread;
-       delete scene;
-       delete shader_program;
-}
-
 RenderEngine::RenderEngine()
 {
        if (! glfwInit())
@@ -115,7 +95,7 @@ RenderEngine::RenderEngine()
        window = Window::create(this);
        camera = new Camera;
        input_handler = new InputHandler(camera, window);
-       mesh_gen_thread = new MeshGenThread;
+       mesh_gen_mgr = new MeshGenMgr;
        scene = new Scene;
        
        GLenum glew_init_err = glewInit();
@@ -130,3 +110,13 @@ RenderEngine::RenderEngine()
        
        last_time = glfwGetTime();
 }
+
+RenderEngine::~RenderEngine()
+{
+       delete window;
+       delete camera;
+       delete input_handler;
+       delete mesh_gen_mgr;
+       delete scene;
+       delete shader_program;
+}
index d244af8bc322469a5b4bd36d4d53877b36915dbc..e0fc25908ac4efc45b38745f6f3920387a0c4259 100644 (file)
@@ -6,7 +6,7 @@ namespace dragonblocks
 {      
        class Camera;
        class InputHandler;
-       class MeshGenThread;
+       class MeshGenMgr;
        class ShaderProgram;
        class Scene;
        class Window;
@@ -14,11 +14,9 @@ namespace dragonblocks
        class RenderEngine
        {
                public:
-               static RenderEngine *create();
-
                Camera *camera;
                InputHandler *input_handler;
-               MeshGenThread *mesh_gen_thread;
+               MeshGenMgr *mesh_gen_mgr;
                Scene *scene;
                ShaderProgram *shader_program;
                Window *window;
@@ -32,15 +30,12 @@ namespace dragonblocks
                void setRenderDistance(double);
                void setFov(double);
                
+               RenderEngine();
                ~RenderEngine();
                
-               private:
-               static RenderEngine *singleton;
-               
+               private:                
                double last_time;
                double render_distance;
                double fov;
-               
-               RenderEngine();
        };
 }
index 6ef5bb715386c349ce147afda6d47081efdb1dae..fa230b5d6738ccce1b5967bd03c75423c45bf69d 100644 (file)
@@ -6,24 +6,26 @@ using namespace dragonblocks;
 
 void Scene::add(Mesh *m)
 {
-       list[m] = true;
+       meshes.insert(m);
 }
 
 void Scene::remove(Mesh *m)
 {
-       list.erase(m);
+       meshes.erase(m);
 }
 
 void Scene::render(double dtime, ShaderProgram *shader_program)
 {
-       for (auto it = list.begin(); it != list.end(); it++) {
-               it->first->render(dtime, shader_program);
+       auto renderlist = meshes;
+       for (auto it = renderlist.begin(); it != renderlist.end(); it++) {
+               Mesh *mesh = *it;
+               mesh->render(dtime, shader_program);
        }
 }
 
 void Scene::clear()
 {
-       list.clear();
+       meshes.clear();
 }
 
 Scene::~Scene()
index 610081ccce33cd2ce3b05e56348a0f19193851ca..fdf0d860224ad41d2d8b8dd688bb10b84ffcf5cd 100644 (file)
@@ -1,6 +1,6 @@
 #pragma once
 
-#include <map>
+#include <set>
 
 namespace dragonblocks
 {
@@ -13,10 +13,11 @@ namespace dragonblocks
                void remove(Mesh *);
                void render(double, ShaderProgram *);
                void clear();
+               void run();
 
                ~Scene();
                
                private:
-               std::map<Mesh *, bool> list;
+               std::set<Mesh *> meshes;
        };
 } 
index e06c51325659b247be2478207455f4db6589be0c..0c1fa88758f7e669b414fbe251e939c33c071688 100644 (file)
@@ -3,7 +3,7 @@
 
 using namespace dragonblocks;
 
-Server::Server()
+void Server::start()
 {
        log("Server is not available yet.");
 }
index e2d764c0ae0f8b2d50cc5960f20b52e1fa3bef88..782e6d1dacc9b6f2cd21b955bc53a21f67e21341 100644 (file)
@@ -5,7 +5,7 @@ namespace dragonblocks
        class Server
        {
                public:
-               Server();
+               void start();
        };
 } 
  
index 1a96efc135b368b62664d52ba72eb78e5d927ea8..ab0b4b10c8dd52daa1e67e43fec30d869333d142 100644 (file)
@@ -1,6 +1,7 @@
 #include <stdexcept>
 #define STB_IMAGE_IMPLEMENTATION
 #include "stb_image.h"
+#include "gldebug.hpp"
 #include "log.hpp"
 #include "texture.hpp"
 
@@ -26,7 +27,7 @@ void Texture::initArgs()
 
 void Texture::bind() const
 {
-       glBindTexture(GL_TEXTURE_2D, id);
+       glBindTexture(GL_TEXTURE_2D, id); CHECKERR
 }
 
 void Texture::load(const string &path)
@@ -35,17 +36,17 @@ void Texture::load(const string &path)
        unsigned char *data = stbi_load(path.c_str(), &width, &height, &nrChannels, 0);
        if (! data)
                throw runtime_error("Failed to load texture " + path);
-       glGenTextures(1, &id);
+       glGenTextures(1, &id); CHECKERR
        bind();
-       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, Texture::min_filter);
-       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, Texture::mag_filter);
-       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-       glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
+       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, Texture::min_filter); CHECKERR
+       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, Texture::mag_filter); CHECKERR
+       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); CHECKERR
+       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); CHECKERR
+       glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); CHECKERR
        if (Texture::mipmap)
-               glGenerateMipmap(GL_TEXTURE_2D);
+               glGenerateMipmap(GL_TEXTURE_2D); CHECKERR
        stbi_image_free(data);
-       glBindTexture(GL_TEXTURE_2D, 0);
+       glBindTexture(GL_TEXTURE_2D, 0); CHECKERR
        log("Loaded texture " + path);
 }
 
index 7259e0d8dd92eaca1950d9c8188234b6e9b7fb17..9bb3541aee76fc7ee50188ad25d200b1585e1843 100644 (file)
@@ -80,6 +80,11 @@ bool Window::wasKeyDown(int key) const
        return glfwGetKey(id, key) == GLFW_PRESS;
 }
 
+void Window::makeContextCurrent() const
+{
+       glfwMakeContextCurrent(id);
+}
+
 ivec2 Window::getSize() const
 {
        return ivec2(width, height);
@@ -141,7 +146,7 @@ Window::Window(RenderEngine *r) : render_engine(r)
                glfwTerminate();
                throw runtime_error("Failed to create GLFW window");
        }
-       glfwMakeContextCurrent(id);
+       makeContextCurrent();
        glfwSetInputMode(id, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
        glfwSetWindowPosCallback(id, Window::windowPosCallback);
        glfwSetFramebufferSizeCallback(id, Window::framebufferSizeCallback);
index 949f5f4af10d6cd26b4919ec8e37f5b023822dc5..1ca300a1389e046f47d9b83f91fa3e2920f468c2 100644 (file)
@@ -23,6 +23,7 @@ namespace dragonblocks
                void swapBuffers();
                bool shouldClose() const;
                bool wasKeyDown(int) const;
+               void makeContextCurrent() const;
                glm::ivec2 getSize() const;
                glm::ivec2 getCursorPos() const;
                glm::ivec2 getCursorDelta();