]> git.localhorst.tv Git - blank.git/commitdiff
very basic chunk model
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Thu, 19 Feb 2015 19:34:09 +0000 (20:34 +0100)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Thu, 19 Feb 2015 19:34:09 +0000 (20:34 +0100)
src/app.cpp
src/app.hpp
src/init.cpp
src/init.hpp
src/model.cpp
src/model.hpp
src/world.cpp [new file with mode: 0644]
src/world.hpp [new file with mode: 0644]

index e7ed579041a8e5cc2f620c329be199956b5e8c5a..8c957a78a815f348fb423f86c8840e6c35deea7f 100644 (file)
@@ -17,126 +17,12 @@ Application::Application()
 , move_velocity(0.003f)
 , pitch_sensitivity(-0.0025f)
 , yaw_sensitivity(-0.001f)
+, testBlockType(true)
 , cam()
-, model({
-       // vertices
-       {  0.0f,  0.0f,  1.0f }, // front, red
-       {  1.0f,  0.0f,  1.0f },
-       {  0.0f,  1.0f,  1.0f },
-       {  1.0f,  0.0f,  1.0f },
-       {  1.0f,  1.0f,  1.0f },
-       {  0.0f,  1.0f,  1.0f },
-       {  0.0f,  0.0f,  0.0f }, // back, cyan
-       {  0.0f,  1.0f,  0.0f },
-       {  1.0f,  0.0f,  0.0f },
-       {  1.0f,  0.0f,  0.0f },
-       {  0.0f,  1.0f,  0.0f },
-       {  1.0f,  1.0f,  0.0f },
-       {  0.0f,  1.0f,  0.0f }, // top, green
-       {  0.0f,  1.0f,  1.0f },
-       {  1.0f,  1.0f,  0.0f },
-       {  1.0f,  1.0f,  0.0f },
-       {  0.0f,  1.0f,  1.0f },
-       {  1.0f,  1.0f,  1.0f },
-       {  0.0f,  0.0f,  0.0f }, // bottom, magenta
-       {  1.0f,  0.0f,  0.0f },
-       {  0.0f,  0.0f,  1.0f },
-       {  1.0f,  0.0f,  0.0f },
-       {  1.0f,  0.0f,  1.0f },
-       {  0.0f,  0.0f,  1.0f },
-       {  0.0f,  0.0f,  0.0f }, // left, blue
-       {  0.0f,  0.0f,  1.0f },
-       {  0.0f,  1.0f,  0.0f },
-       {  0.0f,  1.0f,  0.0f },
-       {  0.0f,  0.0f,  1.0f },
-       {  0.0f,  1.0f,  1.0f },
-       {  1.0f,  0.0f,  0.0f }, // right, yellow
-       {  1.0f,  1.0f,  0.0f },
-       {  1.0f,  0.0f,  1.0f },
-       {  1.0f,  0.0f,  1.0f },
-       {  1.0f,  1.0f,  0.0f },
-       {  1.0f,  1.0f,  1.0f },
-}, {
-       // colors
-       {  1.0f,  0.0f,  0.0f }, // front, red
-       {  1.0f,  0.0f,  0.0f },
-       {  1.0f,  0.0f,  0.0f },
-       {  1.0f,  0.0f,  0.0f },
-       {  1.0f,  0.0f,  0.0f },
-       {  1.0f,  0.0f,  0.0f },
-       {  0.0f,  1.0f,  1.0f }, // back, cyan
-       {  0.0f,  1.0f,  1.0f },
-       {  0.0f,  1.0f,  1.0f },
-       {  0.0f,  1.0f,  1.0f },
-       {  0.0f,  1.0f,  1.0f },
-       {  0.0f,  1.0f,  1.0f },
-       {  0.0f,  1.0f,  0.0f }, // top, green
-       {  0.0f,  1.0f,  0.0f },
-       {  0.0f,  1.0f,  0.0f },
-       {  0.0f,  1.0f,  0.0f },
-       {  0.0f,  1.0f,  0.0f },
-       {  0.0f,  1.0f,  0.0f },
-       {  1.0f,  0.0f,  1.0f }, // bottom, magenta
-       {  1.0f,  0.0f,  1.0f },
-       {  1.0f,  0.0f,  1.0f },
-       {  1.0f,  0.0f,  1.0f },
-       {  1.0f,  0.0f,  1.0f },
-       {  1.0f,  0.0f,  1.0f },
-       {  0.0f,  0.0f,  1.0f }, // left, blue
-       {  0.0f,  0.0f,  1.0f },
-       {  0.0f,  0.0f,  1.0f },
-       {  0.0f,  0.0f,  1.0f },
-       {  0.0f,  0.0f,  1.0f },
-       {  0.0f,  0.0f,  1.0f },
-       {  1.0f,  1.0f,  0.0f }, // right, yellow
-       {  1.0f,  1.0f,  0.0f },
-       {  1.0f,  1.0f,  0.0f },
-       {  1.0f,  1.0f,  0.0f },
-       {  1.0f,  1.0f,  0.0f },
-       {  1.0f,  1.0f,  0.0f },
-}, {
-       // normals
-       {  0.0f,  0.0f,  1.0f }, // front, red
-       {  0.0f,  0.0f,  1.0f },
-       {  0.0f,  0.0f,  1.0f },
-       {  0.0f,  0.0f,  1.0f },
-       {  0.0f,  0.0f,  1.0f },
-       {  0.0f,  0.0f,  1.0f },
-       {  0.0f,  0.0f, -1.0f }, // back, cyan
-       {  0.0f,  0.0f, -1.0f },
-       {  0.0f,  0.0f, -1.0f },
-       {  0.0f,  0.0f, -1.0f },
-       {  0.0f,  0.0f, -1.0f },
-       {  0.0f,  0.0f, -1.0f },
-       {  0.0f,  1.0f,  0.0f }, // top, green
-       {  0.0f,  1.0f,  0.0f },
-       {  0.0f,  1.0f,  0.0f },
-       {  0.0f,  1.0f,  0.0f },
-       {  0.0f,  1.0f,  0.0f },
-       {  0.0f,  1.0f,  0.0f },
-       {  0.0f, -1.0f,  0.0f }, // bottom, magenta
-       {  0.0f, -1.0f,  0.0f },
-       {  0.0f, -1.0f,  0.0f },
-       {  0.0f, -1.0f,  0.0f },
-       {  0.0f, -1.0f,  0.0f },
-       {  0.0f, -1.0f,  0.0f },
-       { -1.0f,  0.0f,  0.0f }, // left, blue
-       { -1.0f,  0.0f,  0.0f },
-       { -1.0f,  0.0f,  0.0f },
-       { -1.0f,  0.0f,  0.0f },
-       { -1.0f,  0.0f,  0.0f },
-       { -1.0f,  0.0f,  0.0f },
-       {  1.0f,  0.0f,  0.0f }, // right, yellow
-       {  1.0f,  0.0f,  0.0f },
-       {  1.0f,  0.0f,  0.0f },
-       {  1.0f,  0.0f,  0.0f },
-       {  1.0f,  0.0f,  0.0f },
-       {  1.0f,  0.0f,  0.0f },
-})
-, modelCtrl()
-, light_position(5.0f, 5.0f, 5.0f)
+, chunk()
+, light_position(17.0f, 17.0f, 17.0f)
 , light_color(1.0f, 1.0f, 1.0f)
-, light_power(50.0f)
+, light_power(100.0f)
 , m_handle(0)
 , v_handle(0)
 , mv_handle(0)
@@ -152,6 +38,7 @@ Application::Application()
 , up(false)
 , down(false) {
        GLContext::EnableVSync();
+       GLContext::EnableDepthTest();
        GLContext::EnableBackfaceCulling();
        program.LoadShader(
                GL_VERTEX_SHADER,
@@ -218,8 +105,15 @@ Application::Application()
        glGenVertexArrays(1, &VertexArrayID);
        glBindVertexArray(VertexArrayID);
 
-       modelCtrl.Position(glm::vec3(0, 0, -4));
-       cam.Position(glm::vec3(0, 0, 4));
+       cam.Position(glm::vec3(0, 4, 4));
+
+       chunk.BlockAt(glm::vec3(0, 0, 0)) = Block(&testBlockType);
+       chunk.BlockAt(glm::vec3(1, 0, 0)) = Block(&testBlockType);
+       chunk.BlockAt(glm::vec3(1, 1, 0)) = Block(&testBlockType);
+       chunk.BlockAt(glm::vec3(1, 1, 1)) = Block(&testBlockType);
+       chunk.BlockAt(glm::vec3(2, 1, 1)) = Block(&testBlockType);
+       chunk.BlockAt(glm::vec3(2, 2, 1)) = Block(&testBlockType);
+       chunk.Invalidate();
 
        m_handle = program.UniformLocation("M");
        v_handle = program.UniformLocation("V");
@@ -325,15 +219,14 @@ void Application::Update(int dt) {
        cam.OrientationVelocity(vel);
 
        cam.Update(dt);
-       modelCtrl.Update(dt);
 }
 
 void Application::Render() {
-       glClear(GL_COLOR_BUFFER_BIT);
+       GLContext::Clear();
 
        program.Use();
 
-       glm::mat4 m(modelCtrl.Transform());
+       glm::mat4 m(1.0f);
        glm::mat4 mv(cam.View() * m);
        glm::mat4 mvp(cam.MakeMVP(m));
        glUniformMatrix4fv(m_handle, 1, GL_FALSE, &m[0][0]);
@@ -344,7 +237,7 @@ void Application::Render() {
        glUniform3f(light_color_handle, light_color.x, light_color.y, light_color.z);
        glUniform1f(light_power_handle, light_power);
 
-       model.Draw();
+       chunk.Draw();
 
        window.Flip();
 }
index f3ee1410f5ee405a29e2a01b25fb2ab091fa4969..d9b70469a527a98870ea279aabccdc6a3f7a4859 100644 (file)
@@ -7,8 +7,8 @@
 #include "camera.hpp"
 #include "controller.hpp"
 #include "init.hpp"
-#include "model.hpp"
 #include "shader.hpp"
+#include "world.hpp"
 
 
 namespace blank {
@@ -42,9 +42,10 @@ private:
        float pitch_sensitivity;
        float yaw_sensitivity;
 
+       BlockType testBlockType;
+
        Camera cam;
-       Model model;
-       FPSController modelCtrl;
+       Chunk chunk;
 
        glm::vec3 light_position;
        glm::vec3 light_color;
index 40f76de50ef06eed4995f065013fd1a2a135c23d..9e73c2890226e11cd20a271cefae00c79c4f3e7c 100644 (file)
@@ -142,10 +142,19 @@ void GLContext::EnableVSync() {
        }
 }
 
+void GLContext::EnableDepthTest() {
+       glEnable(GL_DEPTH_TEST);
+       glDepthFunc(GL_LESS);
+}
+
 void GLContext::EnableBackfaceCulling() {
        glEnable(GL_CULL_FACE);
 }
 
+void GLContext::Clear() {
+       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+}
+
 
 InitGLEW::InitGLEW() {
        glewExperimental = GL_TRUE;
index 51ab3f834b03054a2783b6838261fd0329d98fe4..d596cbc346f880247a98b8b3ceae9e278acdaa9a 100644 (file)
@@ -83,8 +83,11 @@ public:
        GLContext &operator =(const GLContext &) = delete;
 
        static void EnableVSync();
+       static void EnableDepthTest();
        static void EnableBackfaceCulling();
 
+       static void Clear();
+
 private:
        SDL_GLContext handle;
 
index bbfc97f4fcfb121f8646feec9d59680213958189..032fc150a9e449c12bc68d62c98609280fee09a8 100644 (file)
@@ -3,17 +3,35 @@
 
 namespace blank {
 
-Model::Model(
-       std::vector<glm::vec3> &&vtx,
-       std::vector<glm::vec3> &&col,
-       std::vector<glm::vec3> &&norm
-)
-: vertices(vtx)
-, colors(col)
-, normals(norm)
-, handle{} {
+Model::Model()
+: vertices()
+, colors()
+, normals()
+, handle{}
+, dirty(false) {
        glGenBuffers(ATTRIB_COUNT, handle);
+}
+
+Model::~Model() {
+       glDeleteBuffers(ATTRIB_COUNT, handle);
+}
+
+
+void Model::Clear() {
+       vertices.clear();
+       colors.clear();
+       normals.clear();
+       Invalidate();
+}
 
+void Model::Reserve(int s) {
+       vertices.reserve(s);
+       colors.reserve(s);
+       normals.reserve(s);
+}
+
+
+void Model::Update() {
        glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_VERTEX]);
        glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), vertices.data(), GL_STATIC_DRAW);
 
@@ -22,14 +40,16 @@ Model::Model(
 
        glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_NORMAL]);
        glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(glm::vec3), normals.data(), GL_STATIC_DRAW);
-}
 
-Model::~Model() {
-       glDeleteBuffers(ATTRIB_COUNT, handle);
+       dirty = false;
 }
 
 
 void Model::Draw() {
+       if (dirty) {
+               Update();
+       }
+
        glEnableVertexAttribArray(ATTRIB_VERTEX);
        glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_VERTEX]);
        glVertexAttribPointer(
index 02ab3f274bd5b096205f9c1d4a153bff004e7c4a..1e9dab9d1cde0132c30c1cdad9d656c3e5a47a7a 100644 (file)
@@ -11,27 +11,37 @@ namespace blank {
 class Model {
 
 public:
-       enum Attribute {
-               ATTRIB_VERTEX,
-               ATTRIB_COLOR,
-               ATTRIB_NORMAL,
-               ATTRIB_COUNT,
-       };
+       std::vector<glm::vec3> vertices;
+       std::vector<glm::vec3> colors;
+       std::vector<glm::vec3> normals;
 
 public:
-       explicit Model(
-               std::vector<glm::vec3> &&vertices,
-               std::vector<glm::vec3> &&colors,
-               std::vector<glm::vec3> &&normals);
+       Model();
        ~Model();
 
+       Model(const Model &) = delete;
+       Model &operator =(const Model &) = delete;
+
+       void Invalidate() { dirty = true; }
+
+       void Clear();
+       void Reserve(int);
+
        void Draw();
 
 private:
-       std::vector<glm::vec3> vertices;
-       std::vector<glm::vec3> colors;
-       std::vector<glm::vec3> normals;
+       void Update();
+
+private:
+       enum Attribute {
+               ATTRIB_VERTEX,
+               ATTRIB_COLOR,
+               ATTRIB_NORMAL,
+               ATTRIB_COUNT,
+       };
+
        GLuint handle[ATTRIB_COUNT];
+       bool dirty;
 
 };
 
diff --git a/src/world.cpp b/src/world.cpp
new file mode 100644 (file)
index 0000000..2dd7b30
--- /dev/null
@@ -0,0 +1,102 @@
+#include "world.hpp"
+
+
+namespace blank {
+
+const BlockType BlockType::DEFAULT;
+
+void BlockType::FillVBO(
+       const glm::vec3 &pos,
+       std::vector<glm::vec3> &vertices,
+       std::vector<glm::vec3> &colors,
+       std::vector<glm::vec3> &normals
+) const {
+       vertices.emplace_back(pos.x    , pos.y    , pos.z + 1); // front
+       vertices.emplace_back(pos.x + 1, pos.y    , pos.z + 1);
+       vertices.emplace_back(pos.x    , pos.y + 1, pos.z + 1);
+       vertices.emplace_back(pos.x + 1, pos.y    , pos.z + 1);
+       vertices.emplace_back(pos.x + 1, pos.y + 1, pos.z + 1);
+       vertices.emplace_back(pos.x    , pos.y + 1, pos.z + 1);
+       vertices.emplace_back(pos.x    , pos.y    , pos.z    ); // back
+       vertices.emplace_back(pos.x    , pos.y + 1, pos.z    );
+       vertices.emplace_back(pos.x + 1, pos.y    , pos.z    );
+       vertices.emplace_back(pos.x + 1, pos.y    , pos.z    );
+       vertices.emplace_back(pos.x    , pos.y + 1, pos.z    );
+       vertices.emplace_back(pos.x + 1, pos.y + 1, pos.z    );
+       vertices.emplace_back(pos.x    , pos.y + 1, pos.z    ); // top
+       vertices.emplace_back(pos.x    , pos.y + 1, pos.z + 1);
+       vertices.emplace_back(pos.x + 1, pos.y + 1, pos.z    );
+       vertices.emplace_back(pos.x + 1, pos.y + 1, pos.z    );
+       vertices.emplace_back(pos.x    , pos.y + 1, pos.z + 1);
+       vertices.emplace_back(pos.x + 1, pos.y + 1, pos.z + 1);
+       vertices.emplace_back(pos.x    , pos.y    , pos.z    ); // bottom
+       vertices.emplace_back(pos.x + 1, pos.y    , pos.z    );
+       vertices.emplace_back(pos.x    , pos.y    , pos.z + 1);
+       vertices.emplace_back(pos.x + 1, pos.y    , pos.z    );
+       vertices.emplace_back(pos.x + 1, pos.y    , pos.z + 1);
+       vertices.emplace_back(pos.x    , pos.y    , pos.z + 1);
+       vertices.emplace_back(pos.x    , pos.y    , pos.z    ); // left
+       vertices.emplace_back(pos.x    , pos.y    , pos.z + 1);
+       vertices.emplace_back(pos.x    , pos.y + 1, pos.z    );
+       vertices.emplace_back(pos.x    , pos.y + 1, pos.z    );
+       vertices.emplace_back(pos.x    , pos.y    , pos.z + 1);
+       vertices.emplace_back(pos.x    , pos.y + 1, pos.z + 1);
+       vertices.emplace_back(pos.x + 1, pos.y    , pos.z    ); // right
+       vertices.emplace_back(pos.x + 1, pos.y + 1, pos.z    );
+       vertices.emplace_back(pos.x + 1, pos.y    , pos.z + 1);
+       vertices.emplace_back(pos.x + 1, pos.y    , pos.z + 1);
+       vertices.emplace_back(pos.x + 1, pos.y + 1, pos.z    );
+       vertices.emplace_back(pos.x + 1, pos.y + 1, pos.z + 1);
+
+       colors.insert(colors.end(), 6, glm::vec3(1.0f, 1.0f, 1.0f)); // front
+       colors.insert(colors.end(), 6, glm::vec3(1.0f, 1.0f, 1.0f)); // back
+       colors.insert(colors.end(), 6, glm::vec3(1.0f, 1.0f, 1.0f)); // top
+       colors.insert(colors.end(), 6, glm::vec3(1.0f, 1.0f, 1.0f)); // bottom
+       colors.insert(colors.end(), 6, glm::vec3(1.0f, 1.0f, 1.0f)); // left
+       colors.insert(colors.end(), 6, glm::vec3(1.0f, 1.0f, 1.0f)); // right
+
+       normals.insert(normals.end(), 6, glm::vec3( 0.0f,  0.0f,  1.0f)); // front
+       normals.insert(normals.end(), 6, glm::vec3( 0.0f,  0.0f, -1.0f)); // back
+       normals.insert(normals.end(), 6, glm::vec3( 0.0f,  1.0f,  0.0f)); // top
+       normals.insert(normals.end(), 6, glm::vec3( 0.0f, -1.0f,  0.0f)); // bottom
+       normals.insert(normals.end(), 6, glm::vec3(-1.0f,  0.0f,  0.0f)); // left
+       normals.insert(normals.end(), 6, glm::vec3( 1.0f,  0.0f,  0.0f)); // right
+}
+
+
+Chunk::Chunk()
+: blocks(Size())
+, model()
+, dirty(false) {
+
+}
+
+
+void Chunk::Draw() {
+       if (dirty) {
+               Update();
+       }
+       model.Draw();
+}
+
+
+int Chunk::VertexCount() const {
+       // TODO: query blocks as soon as type shapes are implemented
+       return Size() * 6 * 6;
+}
+
+void Chunk::Update() {
+       model.Clear();
+       model.Reserve(VertexCount());
+
+       for (int i = 0; i < Size(); ++i) {
+               if (blocks[i].type->visible) {
+                       blocks[i].type->FillModel(ToCoords(i), model);
+               }
+       }
+
+       model.Invalidate();
+       dirty = false;
+}
+
+}
diff --git a/src/world.hpp b/src/world.hpp
new file mode 100644 (file)
index 0000000..304c63a
--- /dev/null
@@ -0,0 +1,91 @@
+#ifndef BLANK_WORLD_HPP_
+#define BLANK_WORLD_HPP_
+
+#include "model.hpp"
+
+#include <vector>
+#include <GL/glew.h>
+#include <glm/glm.hpp>
+
+
+namespace blank {
+
+/// attributes of a type of block
+struct BlockType {
+
+       bool visible;
+
+       constexpr explicit BlockType(bool v = false)
+       : visible(v) { }
+
+       static const BlockType DEFAULT;
+
+
+       void FillVBO(
+               const glm::vec3 &pos,
+               std::vector<glm::vec3> &vertices,
+               std::vector<glm::vec3> &colors,
+               std::vector<glm::vec3> &normals
+       ) const;
+
+       void FillModel(const glm::vec3 &pos, Model &m) const {
+               FillVBO(pos, m.vertices, m.colors, m.normals);
+       }
+
+};
+
+
+/// single 1x1x1 cube
+struct Block {
+
+       const BlockType *type;
+
+       constexpr explicit Block(const BlockType *t = &BlockType::DEFAULT)
+       : type(t) { }
+
+};
+
+
+/// cube of size 16 (256 tiles, 4096 blocks)
+class Chunk {
+
+public:
+       Chunk();
+
+       static constexpr int Width() { return 16; }
+       static constexpr int Height() { return 16; }
+       static constexpr int Depth() { return 16; }
+       static constexpr int Size() { return Width() * Height() * Depth(); }
+
+       static constexpr int ToIndex(const glm::vec3 &pos) {
+               return pos.x + pos.y * Width() + pos.z * Width() * Height();
+       }
+       static glm::vec3 ToCoords(int idx) {
+               return glm::vec3(
+                       idx % Width(),
+                       (idx / Width()) % Height(),
+                       idx / (Width() * Height())
+               );
+       }
+
+       void Invalidate() { dirty = true; }
+
+       Block &BlockAt(const glm::vec3 &pos) { return blocks[ToIndex(pos)]; }
+       const Block &BlockAt(const glm::vec3 &pos) const { return blocks[ToIndex(pos)]; }
+
+       void Draw();
+
+private:
+       int VertexCount() const;
+       void Update();
+
+private:
+       std::vector<Block> blocks;
+       Model model;
+       bool dirty;
+
+};
+
+}
+
+#endif