diff options
author | Andy Belle-Isle <drumsetmonkey@gmail.com> | 2019-10-06 03:12:48 -0400 |
---|---|---|
committer | Andy Belle-Isle <drumsetmonkey@gmail.com> | 2019-10-06 03:12:48 -0400 |
commit | 1a909087ddfdfe3b947c65b07287a08a40f119ce (patch) | |
tree | 64df54d9634731b6fc1a60e8ec6d42afab5b608a | |
parent | a62d96ad0521b064e6ef61a6f80888e27966502b (diff) |
World is now saved as image files instead of generations
-rw-r--r-- | Scripts/world.lua | 233 | ||||
-rw-r--r-- | src/events/render.hpp | 34 | ||||
-rw-r--r-- | src/events/world.hpp | 12 | ||||
-rw-r--r-- | src/render.cpp | 23 | ||||
-rw-r--r-- | src/render.hpp | 17 | ||||
-rw-r--r-- | src/script.cpp | 3 | ||||
-rw-r--r-- | src/world.cpp | 190 | ||||
-rw-r--r-- | src/world.hpp | 39 |
8 files changed, 229 insertions, 322 deletions
diff --git a/Scripts/world.lua b/Scripts/world.lua index 40d7218..f1d2b66 100644 --- a/Scripts/world.lua +++ b/Scripts/world.lua @@ -1,133 +1,136 @@ -world = { - Seed = 5345345, - Layers = 2, - - -- This is run when the world is registered and not after, - -- although it is possible to register materials later - Register = function(self) - - -- TODO make world have global textures to speed up rendering - self:registerMaterial("grass", { - -- TODO combine both of these into 1 - texture = { - file = "Assets/world.png", - offset = { x = 0, y = 0 }, - size = { x = 64, y = 64 } - }, - normal = { - file = "Assets/world_normal.png", - offset = { x = 0, y = 0 }, - size = { x = 64, y = 64 } - } - }); - self:registerMaterial("dirt", { - texture = { - file = "Assets/world.png", - offset = { x = 64, y = 0 }, - size = { x = 64, y = 64 } - }, - normal = { - file = "Assets/world_normal.png", - offset = { x = 64, y = 0 }, - size = { x = 64, y = 64 } - } - }); - self:registerMaterial("stone", { - texture = { - file = "Assets/world.png", - offset = { x = 128, y = 0 }, - size = { x = 64, y = 64 } - }, - normal = { - file = "Assets/world_normal.png", - offset = { x = 128, y = 0 }, - size = { x = 64, y = 64 } - } - }); - self:registerMaterial("flower", { - texture = { - file = "Assets/world.png", - offset = { x = 192, y = 0 }, - size = { x = 64, y = 64 } - }, - normal = { - file = "Assets/world_normal.png", - offset = { x = 192, y = 0 }, - size = { x = 64, y = 64 } - }, - passable = true - }); - self:registerMaterial("trunk", { - texture = { - file = "Assets/world.png", - offset = { x = 256, y = 0 }, - size = { x = 64, y = 64 } - }, - normal = { - file = "Assets/world_normal.png", - offset = { x = 256, y = 0 }, - size = { x = 64, y = 64 } - } - }); - end, - - Generate = function(self) - math.randomseed(self.Seed) - xsize, ysize, zsize = self:setSize(250, 128, 3) - for Z = 0,zsize-1 do - for X = 0,xsize-1 do - if Z == 0 then - YGen = math.floor(6*math.sin(X/20)) + 64 - elseif Z == 1 then - YGen = math.floor(9*math.sin(X/20)) + 64 - else - YGen = math.floor(15*math.sin(X/20)) + 64 - end - YDepth = math.random(3,5) - for Y = 0,ysize-1 do - if Y == YGen then - self:setData(X, Y, Z, "grass"); - elseif Y < YGen and Y > (YGen - YDepth) then - self:setData(X, Y, Z, "dirt"); - elseif Y < YGen then - self:setData(X, Y, Z, "stone"); - elseif Y == YGen + 1 then - if math.random(0, 100) == 53 then - self:setData(X, Y, Z, "flower"); - elseif math.random(0, 100) == 45 then - self:setData(X, Y, Z, "trunk"); - end - end - --print(X..","..Y..","..Z); - end - end - end - self:setData(1000, 1345, 5, "grass"); -- Test error checking - print("Done with world gen"); - end -} - ---world:Generate() -game.worldRegister(world) - newWorld = { Register = function(self) self.unitSize = 8; self:createLayer(0, { texture = { file = "Assets/world/world1/layers/0/texture.png" }, normal = { file = "Assets/world/world1/layers/0/normal.png" }, - hitbox = { file = "Assets/world/world1/layers/0/hitbox.png" } + hitbox = "Assets/world/world1/layers/0/hitbox.png" }); self:createLayer(1, { texture = { file = "Assets/world/world1/layers/1/texture.png" }, normal = { file = "Assets/world/world1/layers/1/normal.png" }, - hitbox = { file = "Assets/world/world1/layers/1/hitbox.png" } + hitbox = "Assets/world/world1/layers/1/hitbox.png" }); self:createDecoLayer(10, { texture = { file = "Assets/world/world1/layers/deco/texture.png" }, normal = { file = "Assets/world/world1/layers/deco/normal.png" }, }); end, - Generate = function(self) end + Generate = function(self) + print("Generating"); + end } + game.worldRegister(newWorld); + +--world = { +-- Seed = 5345345, +-- Layers = 2, +-- +-- -- This is run when the world is registered and not after, +-- -- although it is possible to register materials later +-- Register = function(self) +-- +-- -- TODO make world have global textures to speed up rendering +-- self:registerMaterial("grass", { +-- -- TODO combine both of these into 1 +-- texture = { +-- file = "Assets/world.png", +-- offset = { x = 0, y = 0 }, +-- size = { x = 64, y = 64 } +-- }, +-- normal = { +-- file = "Assets/world_normal.png", +-- offset = { x = 0, y = 0 }, +-- size = { x = 64, y = 64 } +-- } +-- }); +-- self:registerMaterial("dirt", { +-- texture = { +-- file = "Assets/world.png", +-- offset = { x = 64, y = 0 }, +-- size = { x = 64, y = 64 } +-- }, +-- normal = { +-- file = "Assets/world_normal.png", +-- offset = { x = 64, y = 0 }, +-- size = { x = 64, y = 64 } +-- } +-- }); +-- self:registerMaterial("stone", { +-- texture = { +-- file = "Assets/world.png", +-- offset = { x = 128, y = 0 }, +-- size = { x = 64, y = 64 } +-- }, +-- normal = { +-- file = "Assets/world_normal.png", +-- offset = { x = 128, y = 0 }, +-- size = { x = 64, y = 64 } +-- } +-- }); +-- self:registerMaterial("flower", { +-- texture = { +-- file = "Assets/world.png", +-- offset = { x = 192, y = 0 }, +-- size = { x = 64, y = 64 } +-- }, +-- normal = { +-- file = "Assets/world_normal.png", +-- offset = { x = 192, y = 0 }, +-- size = { x = 64, y = 64 } +-- }, +-- passable = true +-- }); +-- self:registerMaterial("trunk", { +-- texture = { +-- file = "Assets/world.png", +-- offset = { x = 256, y = 0 }, +-- size = { x = 64, y = 64 } +-- }, +-- normal = { +-- file = "Assets/world_normal.png", +-- offset = { x = 256, y = 0 }, +-- size = { x = 64, y = 64 } +-- } +-- }); +-- end, +-- +-- Generate = function(self) +-- math.randomseed(self.Seed) +-- xsize, ysize, zsize = self:setSize(250, 128, 3) +-- for Z = 0,zsize-1 do +-- for X = 0,xsize-1 do +-- if Z == 0 then +-- YGen = math.floor(6*math.sin(X/20)) + 64 +-- elseif Z == 1 then +-- YGen = math.floor(9*math.sin(X/20)) + 64 +-- else +-- YGen = math.floor(15*math.sin(X/20)) + 64 +-- end +-- YDepth = math.random(3,5) +-- for Y = 0,ysize-1 do +-- if Y == YGen then +-- self:setData(X, Y, Z, "grass"); +-- elseif Y < YGen and Y > (YGen - YDepth) then +-- self:setData(X, Y, Z, "dirt"); +-- elseif Y < YGen then +-- self:setData(X, Y, Z, "stone"); +-- elseif Y == YGen + 1 then +-- if math.random(0, 100) == 53 then +-- self:setData(X, Y, Z, "flower"); +-- elseif math.random(0, 100) == 45 then +-- self:setData(X, Y, Z, "trunk"); +-- end +-- end +-- --print(X..","..Y..","..Z); +-- end +-- end +-- end +-- self:setData(1000, 1345, 5, "grass"); -- Test error checking +-- print("Done with world gen"); +-- end +--} + +--world:Generate() +--game.worldRegister(world) diff --git a/src/events/render.hpp b/src/events/render.hpp index bcecac6..a3eb7d6 100644 --- a/src/events/render.hpp +++ b/src/events/render.hpp @@ -1,3 +1,20 @@ +/* + * Copyright (C) 2019 Belle-Isle, Andrew <drumsetmonkey@gmail.com> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + #ifndef EVENTS_RENDER_HPP_ #define EVENTS_RENDER_HPP_ @@ -8,9 +25,24 @@ struct NewRenderEvent GLuint normal; unsigned int vertex; - NewRenderEvent(GLuint _vbo, GLuint _tex, GLuint _normal, unsigned int _vertex) : + NewRenderEvent(GLuint _vbo, GLuint _tex, + GLuint _normal, unsigned int _vertex) : vbo(_vbo), tex(_tex), normal(_normal), vertex(_vertex) {} }; +struct WorldMeshUpdateEvent +{ + GLuint worldVBO; + GLuint worldTexture; + GLuint worldNormal; + unsigned int numVertex; + + WorldMeshUpdateEvent(GLuint v, GLuint t, + GLuint n, unsigned int p) : + worldVBO(v), worldTexture(t), worldNormal(n), numVertex(p) {} + + WorldMeshUpdateEvent() {}; +}; + #endif // EVENTS_RENDER_HPP_ diff --git a/src/events/world.hpp b/src/events/world.hpp index e5969c0..e6f6d79 100644 --- a/src/events/world.hpp +++ b/src/events/world.hpp @@ -28,16 +28,4 @@ struct WorldChangeEvent newWorld(w) {} }; -struct WorldMeshUpdateEvent -{ - GLuint worldVBO; - unsigned int numVertex; - GLuint worldTexture; - GLuint worldNormal; - - WorldMeshUpdateEvent(GLuint v, unsigned int p, - GLuint t, GLuint n) : - worldVBO(v), numVertex(p), worldTexture(t), worldNormal(n) {} -}; - #endif//EVENTS_WORLD_HPP diff --git a/src/render.cpp b/src/render.cpp index cc7ecb1..cdd31f8 100644 --- a/src/render.cpp +++ b/src/render.cpp @@ -219,24 +219,25 @@ void RenderSystem::update([[maybe_unused]] entityx::EntityManager& entities, }); glUniform1i(f, 0); - // If we were given a world VBO render it - if (worldVBO) { + for (auto& w : worldRenders) { + auto& layer = w.second; + glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, worldTexture); + glBindTexture(GL_TEXTURE_2D, layer.tex); glUniform1i(q, 0); glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, worldNormal); + glBindTexture(GL_TEXTURE_2D, layer.normal); glUniform1i(n, 1); - glBindBuffer(GL_ARRAY_BUFFER, worldVBO); + glBindBuffer(GL_ARRAY_BUFFER, w.first); glVertexAttribPointer(a, 3, GL_FLOAT, GL_FALSE, 6*sizeof(float), 0); glVertexAttribPointer(t, 2, GL_FLOAT, GL_FALSE, 6*sizeof(float), (void*)(3*sizeof(float))); glVertexAttribPointer(r, 1, GL_FLOAT, GL_FALSE, 6*sizeof(float), (void*)(5*sizeof(float))); - glDrawArrays(GL_TRIANGLES, 0, worldVertex); + glDrawArrays(GL_TRIANGLES, 0, layer.vertex); } glDisableVertexAttribArray(a); @@ -408,10 +409,12 @@ void RenderSystem::receive(const NewRenderEvent &nre) void RenderSystem::receive(const WorldMeshUpdateEvent &wmu) { - worldVBO = wmu.worldVBO; - worldVertex = wmu.numVertex; - worldTexture = wmu.worldTexture; - worldNormal = wmu.worldNormal; + worldRenders.insert_or_assign( + wmu.worldVBO, + WorldRenderData(wmu.worldTexture, + wmu.worldNormal, + wmu.numVertex) + ); } void RenderSystem::receive(const entityx::ComponentAddedEvent<Player> &cae) diff --git a/src/render.hpp b/src/render.hpp index c4456cf..45fb548 100644 --- a/src/render.hpp +++ b/src/render.hpp @@ -37,8 +37,8 @@ #include "shader.hpp" #include "world.hpp" #include "components/Player.hpp" + #include "events/render.hpp" -#include "events/world.hpp" #include <map> @@ -52,6 +52,16 @@ struct UIRenderData tex(_tex), normal(_normal), vertex(_vertex) {} }; +struct WorldRenderData +{ + GLuint tex; + GLuint normal; + unsigned int vertex; + + WorldRenderData(GLuint _tex, GLuint _normal, unsigned int _vertex) : + tex(_tex), normal(_normal), vertex(_vertex) {} +}; + class RenderSystem : public entityx::System<RenderSystem>, public entityx::Receiver<RenderSystem> { @@ -69,11 +79,8 @@ private: // Map of VBOs and their render data std::map<GLuint, UIRenderData> uiRenders; + std::map<GLuint, WorldRenderData> worldRenders; - GLuint worldVBO = 0; - unsigned int worldVertex = 0; - GLuint worldTexture = 0; - GLuint worldNormal = 0; entityx::Entity player; // Save the player so we can track the camera public: RenderSystem() : diff --git a/src/script.cpp b/src/script.cpp index 629baa9..8109457 100644 --- a/src/script.cpp +++ b/src/script.cpp @@ -131,9 +131,6 @@ void ScriptSystem::scriptExport(void) sol::constructors<World(sol::object), World(void)>(), "Generate", &World::generate, "Seed", sol::property(&World::setSeed, &World::getSeed), - "setData", &World::setData, - "registerMaterial", &World::registerMaterial, - "setSize", &World::setSize, "getSize", &World::getSize, // New stuff diff --git a/src/world.cpp b/src/world.cpp index 8cfd906..7b82d32 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -18,7 +18,7 @@ */ #include "world.hpp" -#include "events/render.hpp" + #include "events/world.hpp" /***************** @@ -55,133 +55,55 @@ World::World(sol::object param) // If a generate function is defined, call it if (generate != sol::nil) generate(this); - - // Create our world VBO - glGenBuffers(1, &worldVBO); - // Generate our mesh - generateMesh(); -} - -/* REGISTRY */ -void World::registerMaterial(std::string name, sol::object data) -{ - if (data.get_type() == sol::type::table) { - sol::table tab = data; - - // Make sure this material has not been registered before - auto it = string_registry.find(name); - if (it == string_registry.end()) { - string_registry.emplace(name, registry.size()); - registry.push_back(WorldMaterial(tab)); - } else { - std::cerr << "Material: " << name - << " was already registered" << std::endl; - } - } else { - // TODO better logging - std::cerr << "Material registration must have a table" << std::endl; - } -} - -/* DATA */ -void World::setData(unsigned int x, - unsigned int y, - unsigned int z, - std::string d) -{ - unsigned int discovered = -1; - - auto found = string_registry.find(d); - if (found != string_registry.end()) - discovered = found->second; - - try { - data.at(z).at(x).at(y) = discovered; - } catch (std::out_of_range &oor) { - // Make sure any assignments that are outsize specified world size are - // caught to avoid any seg faults - std::cerr << "Unable to set data at: " - << x << "," << y << "," << z - << " Exception: " << oor.what() << std::endl; - } -} - -/* SIZE */ -std::tuple<unsigned int, unsigned int, unsigned int> -World::setSize(unsigned int x, unsigned int y, unsigned int z) -{ - width = x; - height = y; - layers = z; - - data = std::vector<std::vector<std::vector<int>>> - (z, std::vector<std::vector<int>> - (x,std::vector<int> - (y, -1) - ) - ); - - return {width, height, layers}; + std::cout << "flamingo" << std::endl; } +// TODO std::tuple<unsigned int, unsigned int, unsigned int> World::getSize() { - return {width, height, layers}; + //return {width, height, layers}; + return {0, 0, 0}; } /* RENDERING */ void World::generateMesh() { - //const unsigned int voxelLength = 6; // 2 triangles @ 3 points each - if (!data.size()) - return; - - // Preallocate size of vertexes - mesh = std::basic_string<WorldMeshData>(); - for (float Z = data.size() - 1; Z >= 0; Z--) { - for (float X = 0; X < data.at(Z).size(); X++) { - for (float Y = 0; Y < data.at(Z).at(X).size(); Y++) { - int d = data.at(Z).at(X).at(Y); - - if (d == -1) // Don't make a mesh for air of course - continue; - - Texture &t = registry.at(d).texture; - glm::vec2& to = t.offset; - glm::vec2& ts = t.size; - - float tr = 1.0f; - - // TODO play with this a bit so it only goes trans - // if player is behind the front layer - try { - if (Z < data.size() - 1 && Z >= 0) { - if (data.at(Z+1).at(X).at(Y) == -1) - tr = 1.0f; - } - } catch (...) { - tr = 1.0f; - } - - mesh += {X , Y , Z, to.x , to.y+ts.y, tr}; - mesh += {X+1, Y , Z, to.x+ts.x, to.y+ts.y, tr}; - mesh += {X , Y+1, Z, to.x , to.y , tr}; - - mesh += {X+1, Y , Z, to.x+ts.x, to.y+ts.y, tr}; - mesh += {X+1, Y+1, Z, to.x+ts.x, to.y , tr}; - mesh += {X , Y+1, Z, to.x , to.y , tr}; - } - } + for (auto &l : solidLayers) { + + // Preallocate size of vertexes + + float Z = l.drawLayer; + auto to = l.texture.offset; + auto ts = l.texture.size; + float tr = 1.0f; + + float w = l.texture.width/unitSize; + float h = l.texture.height/unitSize; + + GLfloat mesh[36] = {0 , 0 , Z, to.x , to.y+ts.y, tr, + 0+w, 0 , Z, to.x+ts.x, to.y+ts.y, tr, + 0 , 0+h, Z, to.x , to.y , tr, + + 0+w, 0 , Z, to.x+ts.x, to.y+ts.y, tr, + 0+w, 0+h, Z, to.x+ts.x, to.y , tr, + 0 , 0+h, Z, to.x , to.y , tr}; + + glBindBuffer(GL_ARRAY_BUFFER, l.layerVBO); + glBufferData(GL_ARRAY_BUFFER, + 36 * sizeof(GLfloat), + mesh, + GL_STATIC_DRAW); + + meshAdd.push_back(WorldMeshUpdateEvent(l.layerVBO, + l.texture.tex, + l.normal.tex, + 36)); } - glBindBuffer(GL_ARRAY_BUFFER, worldVBO); - glBufferData(GL_ARRAY_BUFFER, - mesh.size() * sizeof(WorldMeshData), - mesh.data(), - GL_STATIC_DRAW); - - meshUpdated = true; + for (auto &l : drawLayers) { + (void)l; + } } /* SEED */ @@ -199,27 +121,11 @@ unsigned int World::setSeed(unsigned int s) /* PHYSICS */ double World::getHeight(double x, double y, double z) { - unsigned int X = static_cast<unsigned int>(x); - unsigned int Z = static_cast<unsigned int>(z); - - double Y = 0.0; - try { - auto &d = data.at(Z).at(X); - for (int yi = d.size()-1; yi >= 0; yi--) { - if (d.at(yi) >= 0) { - if (!registry.at(d.at(yi)).passable) { - Y = static_cast<double>(yi); - Y += 1; - break; - } - } - } - } catch (...) { // If we get any errors, just let the character - //return y; - (void)y; - return 0.0; - } + (void)x; + (void)y; + (void)z; + double Y = 10.0f; return Y; } @@ -234,6 +140,7 @@ void World::registerLayer(float z, sol::object obj) } else { throw std::string("Layer must receive a table"); } + generateMesh(); } void World::registerDecoLayer(float z, sol::object obj) @@ -244,6 +151,7 @@ void World::registerDecoLayer(float z, sol::object obj) } else { throw std::string("Layer must receive a table"); } + generateMesh(); } @@ -272,12 +180,8 @@ void WorldSystem::update([[maybe_unused]]entityx::EntityManager& entities, events.emit<WorldChangeEvent>(currentWorld); } - if (currentWorld->meshUpdated) { - events.emit<WorldMeshUpdateEvent>( - currentWorld->worldVBO, - currentWorld->mesh.size(), - currentWorld->getTexture(), - currentWorld->getNormal() - ); + for (auto &ma : currentWorld->meshAdd) { + events.emit<WorldMeshUpdateEvent>(ma); } + currentWorld->meshAdd.clear(); } diff --git a/src/world.hpp b/src/world.hpp index acdb533..a6d2f1d 100644 --- a/src/world.hpp +++ b/src/world.hpp @@ -27,13 +27,7 @@ #include <sol/sol.hpp> #include "texture.hpp" - -struct WorldMeshData -{ - float posX, posY, posZ; - float texX, texY; - float transparency; -}__attribute__((packed)); +#include "events/render.hpp" struct WorldMaterial { @@ -59,12 +53,14 @@ struct WorldMaterial class Layer { + friend class World; private: Texture texture; Texture normal; float drawLayer = 0.0f; + GLuint layerVBO; public: Layer(float z, sol::table tab) { @@ -77,6 +73,8 @@ public: sol::object n = tab["normal"]; normal = Texture(n); } + + glGenBuffers(1, &layerVBO); } }; @@ -99,24 +97,14 @@ private: unsigned int seed; unsigned int layers; - unsigned int height; - unsigned int width; - - std::vector<std::vector<std::vector<int>>> data; - - std::unordered_map<std::string, int> string_registry; - std::vector<WorldMaterial> registry; - - // NEW unsigned int unitSize; std::vector<SolidLayer> solidLayers; std::vector<Layer> drawLayers; protected: // RENDER - std::basic_string<WorldMeshData> mesh; + std::vector<WorldMeshUpdateEvent> meshAdd; GLuint worldVBO; - bool meshUpdated = false; public: /* VARS */ sol::function generate; @@ -127,27 +115,12 @@ public: ~World() { registerMat = sol::nil; generate = sol::nil; - registry.clear(); - data.clear(); } - /* REGISTRY */ - void registerMaterial(std::string, sol::object); - - /* DATA */ - void setData(unsigned int, unsigned int, unsigned int, std::string); - - /* SIZE */ - std::tuple<unsigned int, unsigned int, unsigned int> setSize(unsigned int, - unsigned int, - unsigned int); std::tuple<unsigned int, unsigned int, unsigned int> getSize(); /* RENDERING */ void generateMesh(); - std::basic_string<WorldMeshData>& getMesh() {return mesh;} - GLuint getTexture() {return registry.at(0).texture.tex;} - GLuint getNormal() {return registry.at(0).normal.tex;}; /* SEED */ unsigned int getSeed(); |