From fc73b44e0f90affd42cac2f944f46633a6b8364e Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Mon, 23 Mar 2015 19:47:59 +0100 Subject: [PATCH 01/16] fix chunk neighbors there was something seriously wrong with light propagation now I know why ^^ don't get me wrong, it's still borky, but at least not irrational --- src/chunk.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/chunk.cpp b/src/chunk.cpp index cc53e91..de30ae9 100644 --- a/src/chunk.cpp +++ b/src/chunk.cpp @@ -13,6 +13,7 @@ Chunk::Chunk(const BlockTypeRegistry &types) : types(&types) , neighbor{ 0, 0, 0, 0, 0, 0 } , blocks() +, light() , model() , position(0, 0, 0) , dirty(false) { @@ -22,7 +23,9 @@ Chunk::Chunk(const BlockTypeRegistry &types) Chunk::Chunk(Chunk &&other) : types(other.types) , blocks(std::move(other.blocks)) +, light(std::move(other.light)) , model(std::move(other.model)) +, position(other.position) , dirty(other.dirty) { for (size_t i = 0; i < Block::FACE_COUNT; ++i) { neighbor[i] = other.neighbor[i]; @@ -35,29 +38,31 @@ Chunk &Chunk::operator =(Chunk &&other) { neighbor[i] = other.neighbor[i]; } blocks = std::move(other.blocks); + light = std::move(other.light); model = std::move(other.model); + position = other.position; dirty = other.dirty; return *this; } void Chunk::SetNeighbor(Chunk &other) { - if (other.position == position - Pos(-1, 0, 0)) { + if (other.position == position + Pos(-1, 0, 0)) { neighbor[Block::FACE_LEFT] = &other; other.neighbor[Block::FACE_RIGHT] = this; - } else if (other.position == position - Pos(1, 0, 0)) { + } else if (other.position == position + Pos(1, 0, 0)) { neighbor[Block::FACE_RIGHT] = &other; other.neighbor[Block::FACE_LEFT] = this; - } else if (other.position == position - Pos(0, -1, 0)) { + } else if (other.position == position + Pos(0, -1, 0)) { neighbor[Block::FACE_DOWN] = &other; other.neighbor[Block::FACE_UP] = this; - } else if (other.position == position - Pos(0, 1, 0)) { + } else if (other.position == position + Pos(0, 1, 0)) { neighbor[Block::FACE_UP] = &other; other.neighbor[Block::FACE_DOWN] = this; - } else if (other.position == position - Pos(0, 0, -1)) { + } else if (other.position == position + Pos(0, 0, -1)) { neighbor[Block::FACE_BACK] = &other; other.neighbor[Block::FACE_FRONT] = this; - } else if (other.position == position - Pos(0, 0, 1)) { + } else if (other.position == position + Pos(0, 0, 1)) { neighbor[Block::FACE_FRONT] = &other; other.neighbor[Block::FACE_BACK] = this; } -- 2.39.2 From e74f1ad236429f05db90c0ace825277e2a3fbc05 Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Mon, 23 Mar 2015 20:49:20 +0100 Subject: [PATCH 02/16] use light levels for shading of blocks --- src/app.cpp | 11 +-- src/app.hpp | 3 +- src/block.cpp | 9 +++ src/block.hpp | 22 ++++++ src/chunk.cpp | 172 ++++++++++++++++++++++++++++++++++++++++++---- src/chunk.hpp | 21 +++++- src/interface.cpp | 14 ++-- src/model.cpp | 114 ++++++++++++++++++++++++++++++ src/model.hpp | 73 ++++++++++++++++++++ src/shader.cpp | 104 ++++++++++++++++++++++++++++ src/shader.hpp | 37 ++++++++++ src/world.cpp | 21 +++--- src/world.hpp | 2 +- 13 files changed, 568 insertions(+), 35 deletions(-) diff --git a/src/app.cpp b/src/app.cpp index a6f81f1..6a87042 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -13,7 +13,8 @@ Application::Application(const Config &config) , window() , ctx(window.CreateContext()) , init_glew() -, program() +, chunk_prog() +, entity_prog() , cam() , world(config.world) , interface(config.interface, world) @@ -134,12 +135,12 @@ void Application::Update(int dt) { void Application::Render() { GLContext::Clear(); - program.Activate(); + chunk_prog.SetProjection(cam.Projection()); + entity_prog.SetProjection(cam.Projection()); - program.SetProjection(cam.Projection()); - world.Render(program); + world.Render(chunk_prog, entity_prog); - interface.Render(program); + interface.Render(entity_prog); window.Flip(); } diff --git a/src/app.hpp b/src/app.hpp index 23dcd0c..e6226dc 100644 --- a/src/app.hpp +++ b/src/app.hpp @@ -52,7 +52,8 @@ private: Window window; GLContext ctx; InitGLEW init_glew; - DirectionalLighting program; + BlockLighting chunk_prog; + DirectionalLighting entity_prog; Camera cam; World world; diff --git a/src/block.cpp b/src/block.cpp index 5fc3cc0..6e6ac18 100644 --- a/src/block.cpp +++ b/src/block.cpp @@ -102,6 +102,15 @@ void BlockType::FillModel( buf.colors.insert(buf.colors.end(), shape->VertexCount(), color); } +void BlockType::FillBlockModel( + BlockModel::Buffer &buf, + const glm::mat4 &transform, + BlockModel::Index idx_offset +) const { + shape->Vertices(buf.vertices, buf.normals, buf.indices, transform, idx_offset); + buf.colors.insert(buf.colors.end(), shape->VertexCount(), color); +} + void BlockType::FillOutlineModel( OutlineModel &model, const glm::vec3 &pos_offset, diff --git a/src/block.hpp b/src/block.hpp index 0d7d75a..56f9eac 100644 --- a/src/block.hpp +++ b/src/block.hpp @@ -66,6 +66,23 @@ struct Block { } } + static Face NormalFace(const glm::vec3 &norm) { + const glm::vec3 anorm(abs(norm)); + if (anorm.x > anorm.y) { + if (anorm.x > anorm.z) { + return norm.x > 0.0f ? FACE_RIGHT : FACE_LEFT; + } else { + return norm.z > 0.0f ? FACE_FRONT : FACE_BACK; + } + } else { + if (anorm.y > anorm.z) { + return norm.y > 0.0f ? FACE_UP : FACE_DOWN; + } else { + return norm.z > 0.0f ? FACE_FRONT : FACE_BACK; + } + } + } + }; @@ -111,6 +128,11 @@ struct BlockType { const glm::mat4 &transform = glm::mat4(1.0f), Model::Index idx_offset = 0 ) const; + void FillBlockModel( + BlockModel::Buffer &m, + const glm::mat4 &transform = glm::mat4(1.0f), + BlockModel::Index idx_offset = 0 + ) const; void FillOutlineModel( OutlineModel &m, const glm::vec3 &pos_offset = { 0, 0, 0 }, diff --git a/src/chunk.cpp b/src/chunk.cpp index de30ae9..994d68e 100644 --- a/src/chunk.cpp +++ b/src/chunk.cpp @@ -131,16 +131,12 @@ struct SetNode { void Set(int level) { chunk->SetLight(pos, level); } bool HasNext(Block::Face face) { - const Block *next = chunk->FindNext(pos, face); - return next && !chunk->Type(*next).block_light; + const BlockLookup next(chunk, pos, face); + return next.result && !next.chunk->Type(*next.result).block_light; } SetNode GetNext(Block::Face face) { - Chunk::Pos next_pos(pos + Block::FaceNormal(face)); - if (Chunk::InBounds(next_pos)) { - return SetNode(chunk, next_pos); - } else { - return SetNode(&chunk->GetNeighbor(face), next_pos - (Block::FaceNormal(face) * Chunk::Extent())); - } + const BlockLookup next(chunk, pos, face); + return SetNode(next.chunk, next.pos); } }; @@ -156,6 +152,11 @@ struct UnsetNode UnsetNode(const SetNode &set) : SetNode(set), level(Get()) { } + + bool HasNext(Block::Face face) { + const BlockLookup next(chunk, pos, face); + return next.result; + } UnsetNode GetNext(Block::Face face) { return UnsetNode(SetNode::GetNext(face)); } }; @@ -269,13 +270,51 @@ const Block *Chunk::FindNext(const Pos &pos, Block::Face face) const { void Chunk::SetLight(int index, int level) { - light[index] = level; + if (light[index] != level) { + light[index] = level; + Invalidate(); + } } int Chunk::GetLight(int index) const { return light[index]; } +float Chunk::GetVertexLight(int index, const BlockModel::Position &vtx, const BlockModel::Normal &norm) const { + float light = GetLight(index); + Chunk::Pos pos(ToPos(index)); + + Block::Face direct_face(Block::NormalFace(norm)); + const Chunk *direct_chunk = this; + Chunk::Pos direct_pos(pos + Block::FaceNormal(direct_face)); + if (!InBounds(direct_pos)) { + if (HasNeighbor(direct_face)) { + direct_chunk = &GetNeighbor(direct_face); + direct_pos -= (Block::FaceNormal(direct_face) * Extent()); + float direct_light = direct_chunk->GetLight(direct_pos); + if (direct_light > light) { + light = direct_light; + } + } + } else { + float direct_light = direct_chunk->GetLight(direct_pos); + if (direct_light > light) { + light = direct_light; + } + } + + // cheap alternative until AO etc are implemented + // to tell the faces apart + + if (direct_face == Block::FACE_LEFT || direct_face == Block::FACE_RIGHT) { + light -= 0.2; + } else if (direct_face == Block::FACE_FRONT || direct_face == Block::FACE_BACK) { + light -= 0.4; + } + + return light; +} + bool Chunk::IsSurface(const Pos &pos) const { const Block &block = BlockAt(pos); @@ -355,7 +394,7 @@ glm::mat4 Chunk::Transform(const Pos &offset) const { namespace { -Model::Buffer buf; +BlockModel::Buffer buf; } @@ -375,14 +414,19 @@ void Chunk::Update() { buf.Clear(); buf.Reserve(vtx_count, idx_count); - Model::Index vtx_counter = 0; + BlockModel::Index vtx_counter = 0; for (size_t i = 0; i < Size(); ++i) { const BlockType &type = Type(blocks[i]); if (!type.visible || Obstructed(i)) continue; - type.FillModel(buf, ToTransform(i), vtx_counter); + type.FillBlockModel(buf, ToTransform(i), vtx_counter); + size_t vtx_begin = vtx_counter; vtx_counter += type.shape->VertexCount(); + + for (size_t vtx = vtx_begin; vtx < vtx_counter; ++vtx) { + buf.lights.emplace_back(GetVertexLight(i, buf.vertices[vtx], buf.normals[vtx])); + } } model.Update(buf); @@ -484,6 +528,74 @@ glm::mat4 Chunk::ToTransform(int idx) const { } +BlockLookup::BlockLookup(Chunk *c, const Chunk::Pos &p) +: chunk(c), pos(p), result(nullptr) { + while (pos.x >= Chunk::Width()) { + if (chunk->HasNeighbor(Block::FACE_RIGHT)) { + chunk = &chunk->GetNeighbor(Block::FACE_RIGHT); + pos.x -= Chunk::Width(); + } else { + return; + } + } + while (pos.x < 0) { + if (chunk->HasNeighbor(Block::FACE_LEFT)) { + chunk = &chunk->GetNeighbor(Block::FACE_LEFT); + pos.x += Chunk::Width(); + } else { + return; + } + } + while (pos.y >= Chunk::Height()) { + if (chunk->HasNeighbor(Block::FACE_UP)) { + chunk = &chunk->GetNeighbor(Block::FACE_UP); + pos.y -= Chunk::Height(); + } else { + return; + } + } + while (pos.y < 0) { + if (chunk->HasNeighbor(Block::FACE_DOWN)) { + chunk = &chunk->GetNeighbor(Block::FACE_DOWN); + pos.y += Chunk::Height(); + } else { + return; + } + } + while (pos.z >= Chunk::Depth()) { + if (chunk->HasNeighbor(Block::FACE_FRONT)) { + chunk = &chunk->GetNeighbor(Block::FACE_FRONT); + pos.z -= Chunk::Depth(); + } else { + return; + } + } + while (pos.z < 0) { + if (chunk->HasNeighbor(Block::FACE_BACK)) { + chunk = &chunk->GetNeighbor(Block::FACE_BACK); + pos.z += Chunk::Depth(); + } else { + return; + } + } + result = &chunk->BlockAt(pos); +} + +BlockLookup::BlockLookup(Chunk *c, const Chunk::Pos &p, Block::Face face) +: chunk(c), pos(p), result(nullptr) { + pos += Block::FaceNormal(face); + if (Chunk::InBounds(pos)) { + result = &chunk->BlockAt(pos); + } else { + pos -= Block::FaceNormal(face) * Chunk::Extent(); + if (chunk->HasNeighbor(face)) { + chunk = &chunk->GetNeighbor(face); + result = &chunk->BlockAt(pos); + } + } +} + + ChunkLoader::ChunkLoader(const Config &config, const BlockTypeRegistry ®, const Generator &gen) : base(0, 0, 0) , reg(reg) @@ -527,6 +639,42 @@ void ChunkLoader::Generate(const Chunk::Pos &from, const Chunk::Pos &to) { } else if (pos == base) { Generate(pos); + // light testing + // for (int i = 0; i < 16; ++i) { + // for (int j = 0; j < 16; ++j) { + // loaded.back().SetBlock(Chunk::Pos{ i, j, 0 }, Block(1)); + // loaded.back().SetBlock(Chunk::Pos{ i, j, 15 }, Block(1)); + // loaded.back().SetBlock(Chunk::Pos{ 0, j, i }, Block(1)); + // loaded.back().SetBlock(Chunk::Pos{ 15, j, i }, Block(1)); + // } + // } + // loaded.back().SetBlock(Chunk::Pos{ 1, 0, 1 }, Block(13)); + // loaded.back().SetBlock(Chunk::Pos{ 14, 0, 1 }, Block(13)); + // loaded.back().SetBlock(Chunk::Pos{ 1, 0, 14 }, Block(13)); + // loaded.back().SetBlock(Chunk::Pos{ 14, 0, 14 }, Block(13)); + // loaded.back().SetBlock(Chunk::Pos{ 1, 15, 1 }, Block(13)); + // loaded.back().SetBlock(Chunk::Pos{ 14, 15, 1 }, Block(13)); + // loaded.back().SetBlock(Chunk::Pos{ 1, 15, 14 }, Block(13)); + // loaded.back().SetBlock(Chunk::Pos{ 14, 15, 14 }, Block(13)); + // loaded.back().SetBlock(Chunk::Pos{ 7, 7, 0 }, Block(13)); + // loaded.back().SetBlock(Chunk::Pos{ 8, 7, 0 }, Block(13)); + // loaded.back().SetBlock(Chunk::Pos{ 7, 8, 0 }, Block(13)); + // loaded.back().SetBlock(Chunk::Pos{ 8, 8, 0 }, Block(13)); + // loaded.back().SetBlock(Chunk::Pos{ 7, 7, 15 }, Block(13)); + // loaded.back().SetBlock(Chunk::Pos{ 8, 7, 15 }, Block(13)); + // loaded.back().SetBlock(Chunk::Pos{ 7, 8, 15 }, Block(13)); + // loaded.back().SetBlock(Chunk::Pos{ 8, 8, 15 }, Block(13)); + // loaded.back().SetBlock(Chunk::Pos{ 0, 7, 7 }, Block(13)); + // loaded.back().SetBlock(Chunk::Pos{ 0, 7, 8 }, Block(13)); + // loaded.back().SetBlock(Chunk::Pos{ 0, 8, 7 }, Block(13)); + // loaded.back().SetBlock(Chunk::Pos{ 0, 8, 8 }, Block(13)); + // loaded.back().SetBlock(Chunk::Pos{ 15, 7, 7 }, Block(13)); + // loaded.back().SetBlock(Chunk::Pos{ 15, 7, 8 }, Block(13)); + // loaded.back().SetBlock(Chunk::Pos{ 15, 8, 7 }, Block(13)); + // loaded.back().SetBlock(Chunk::Pos{ 15, 8, 8 }, Block(13)); + // loaded.back().Invalidate(); + // loaded.back().CheckUpdate(); + // orientation testing // for (int i = 0; i < Block::FACE_COUNT; ++i) { // for (int j = 0; j < Block::TURN_COUNT; ++j) { diff --git a/src/chunk.hpp b/src/chunk.hpp index 840bac0..0b1e5bd 100644 --- a/src/chunk.hpp +++ b/src/chunk.hpp @@ -116,6 +116,8 @@ public: int GetLight(const Pos &pos) const { return GetLight(ToIndex(pos)); } int GetLight(const Block::Pos &pos) const { return GetLight(ToIndex(pos)); } + float GetVertexLight(int index, const BlockModel::Position &, const BlockModel::Normal &) const; + bool Intersection( const Ray &ray, const glm::mat4 &M, @@ -146,13 +148,30 @@ private: Chunk *neighbor[Block::FACE_COUNT]; std::vector blocks; std::vector light; - Model model; + BlockModel model; Pos position; bool dirty; }; +struct BlockLookup { + + Chunk *chunk; + Chunk::Pos pos; + const Block *result; + + // resolve chunk/position/block from oob coordinates + // result will be nullptr if unsuccessful + BlockLookup(Chunk *c, const Chunk::Pos &p); + + // resolve chunk/position/block from ib coordinates and direction + // result will be nullptr if unsuccessful + BlockLookup(Chunk *c, const Chunk::Pos &p, Block::Face dir); + +}; + + class Generator; class ChunkLoader { diff --git a/src/interface.cpp b/src/interface.cpp index dddb732..45439da 100644 --- a/src/interface.cpp +++ b/src/interface.cpp @@ -124,24 +124,24 @@ void Interface::PrintChunkInfo() { << aim_chunk->Position() << std::endl; - std::cout << " neighbors:"; + std::cout << " neighbors:" << std::endl; if (aim_chunk->HasNeighbor(Block::FACE_LEFT)) { - std::cout << " left"; + std::cout << " left " << aim_chunk->GetNeighbor(Block::FACE_LEFT).Position() << std::endl; } if (aim_chunk->HasNeighbor(Block::FACE_RIGHT)) { - std::cout << " right"; + std::cout << " right " << aim_chunk->GetNeighbor(Block::FACE_RIGHT).Position() << std::endl; } if (aim_chunk->HasNeighbor(Block::FACE_UP)) { - std::cout << " up"; + std::cout << " up " << aim_chunk->GetNeighbor(Block::FACE_UP).Position() << std::endl; } if (aim_chunk->HasNeighbor(Block::FACE_DOWN)) { - std::cout << " down"; + std::cout << " down " << aim_chunk->GetNeighbor(Block::FACE_DOWN).Position() << std::endl; } if (aim_chunk->HasNeighbor(Block::FACE_FRONT)) { - std::cout << " front"; + std::cout << " front " << aim_chunk->GetNeighbor(Block::FACE_FRONT).Position() << std::endl; } if (aim_chunk->HasNeighbor(Block::FACE_BACK)) { - std::cout << " back"; + std::cout << " back " << aim_chunk->GetNeighbor(Block::FACE_BACK).Position() << std::endl; } std::cout << std::endl; } diff --git a/src/model.cpp b/src/model.cpp index d26968a..125d57a 100644 --- a/src/model.cpp +++ b/src/model.cpp @@ -103,6 +103,120 @@ void Model::Draw() const { } +BlockModel::BlockModel() +: va(0) +, handle{} +, count(0) { + glGenVertexArrays(1, &va); + glGenBuffers(ATTRIB_COUNT, handle); +} + +BlockModel::~BlockModel() { + glDeleteBuffers(ATTRIB_COUNT, handle); + glDeleteVertexArrays(1, &va); +} + +BlockModel::BlockModel(BlockModel &&other) +: va(other.va) +, count(other.count) { + other.va = 0; + for (int i = 0; i < ATTRIB_COUNT; ++i) { + handle[i] = other.handle[i]; + other.handle[i] = 0; + } +} + +BlockModel &BlockModel::operator =(BlockModel &&other) { + std::swap(va, other.va); + for (int i = 0; i < ATTRIB_COUNT; ++i) { + std::swap(handle[i], other.handle[i]); + } + count = other.count; + return *this; +} + +void BlockModel::Update(const Buffer &buf) { + glBindVertexArray(va); + glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_VERTEX]); + glBufferData(GL_ARRAY_BUFFER, buf.vertices.size() * sizeof(glm::vec3), buf.vertices.data(), GL_STATIC_DRAW); + glEnableVertexAttribArray(ATTRIB_VERTEX); + glVertexAttribPointer( + ATTRIB_VERTEX, // location (for shader) + 3, // size + GL_FLOAT, // type + GL_FALSE, // normalized + 0, // stride + nullptr // offset + ); + +#ifndef NDEBUG + if (buf.colors.size() < buf.vertices.size()) { + std::cerr << "BlockModel: not enough colors!" << std::endl; + } +#endif + glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_COLOR]); + glBufferData(GL_ARRAY_BUFFER, buf.colors.size() * sizeof(glm::vec3), buf.colors.data(), GL_STATIC_DRAW); + glEnableVertexAttribArray(ATTRIB_COLOR); + glVertexAttribPointer( + ATTRIB_COLOR, // location (for shader) + 3, // size + GL_FLOAT, // type + GL_FALSE, // normalized + 0, // stride + nullptr // offset + ); + +#ifndef NDEBUG + if (buf.normals.size() < buf.vertices.size()) { + std::cerr << "BlockModel: not enough normals!" << std::endl; + } +#endif + glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_NORMAL]); + glBufferData(GL_ARRAY_BUFFER, buf.normals.size() * sizeof(glm::vec3), buf.normals.data(), GL_STATIC_DRAW); + glEnableVertexAttribArray(ATTRIB_NORMAL); + glVertexAttribPointer( + ATTRIB_NORMAL, // location (for shader) + 3, // size + GL_FLOAT, // type + GL_FALSE, // normalized + 0, // stride + nullptr // offset + ); + +#ifndef NDEBUG + if (buf.lights.size() < buf.vertices.size()) { + std::cerr << "BlockModel: not enough lights!" << std::endl; + } +#endif + glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_LIGHT]); + glBufferData(GL_ARRAY_BUFFER, buf.lights.size() * sizeof(float), buf.lights.data(), GL_STATIC_DRAW); + glEnableVertexAttribArray(ATTRIB_LIGHT); + glVertexAttribPointer( + ATTRIB_LIGHT, // location (for shader) + 1, // size + GL_FLOAT, // type + GL_FALSE, // normalized + 0, // stride + nullptr // offset + ); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, handle[ATTRIB_INDEX]); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, buf.indices.size() * sizeof(Index), buf.indices.data(), GL_STATIC_DRAW); + count = buf.indices.size(); +} + + +void BlockModel::Draw() const { + glBindVertexArray(va); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, handle[ATTRIB_INDEX]); + glDrawElements( + GL_TRIANGLES, // how + count, // count + GL_UNSIGNED_INT, // type + nullptr // offset + ); +} + OutlineModel::OutlineModel() : vertices() , colors() diff --git a/src/model.hpp b/src/model.hpp index d5c77d1..7b9fc3d 100644 --- a/src/model.hpp +++ b/src/model.hpp @@ -75,6 +75,79 @@ private: }; +class BlockModel { + +public: + using Position = glm::vec3; + using Color = glm::vec3; + using Normal = glm::vec3; + using Light = float; + using Index = unsigned int; + + using Positions = std::vector; + using Colors = std::vector; + using Normals = std::vector; + using Lights = std::vector; + using Indices = std::vector; + +public: + struct Buffer { + + Positions vertices; + Colors colors; + Normals normals; + Lights lights; + Indices indices; + + void Clear() { + vertices.clear(); + colors.clear(); + normals.clear(); + lights.clear(); + indices.clear(); + } + + void Reserve(size_t p, size_t i) { + vertices.reserve(p); + colors.reserve(p); + normals.reserve(p); + lights.reserve(p); + indices.reserve(i); + } + + }; + +public: + BlockModel(); + ~BlockModel(); + + BlockModel(const BlockModel &) = delete; + BlockModel &operator =(const Model &) = delete; + + BlockModel(BlockModel &&); + BlockModel &operator =(BlockModel &&); + + void Update(const Buffer &); + + void Draw() const; + +private: + enum Attribute { + ATTRIB_VERTEX, + ATTRIB_COLOR, + ATTRIB_NORMAL, + ATTRIB_LIGHT, + ATTRIB_INDEX, + ATTRIB_COUNT, + }; + + GLuint va; + GLuint handle[ATTRIB_COUNT]; + size_t count; + +}; + + class OutlineModel { public: diff --git a/src/shader.cpp b/src/shader.cpp index eb09b10..134f710 100644 --- a/src/shader.cpp +++ b/src/shader.cpp @@ -253,4 +253,108 @@ void DirectionalLighting::SetMVP(const glm::mat4 &m, const glm::mat4 &v, const g SetM(m); } + +BlockLighting::BlockLighting() +: program() +, vp(1.0f) +, m_handle(0) +, mv_handle(0) +, mvp_handle(0) +, fog_density_handle(0) { + program.LoadShader( + GL_VERTEX_SHADER, + "#version 330 core\n" + "layout(location = 0) in vec3 vtx_position;\n" + "layout(location = 1) in vec3 vtx_color;\n" + "layout(location = 2) in vec3 vtx_normal;\n" + "layout(location = 3) in float vtx_light;\n" + "uniform mat4 M;\n" + "uniform mat4 MV;\n" + "uniform mat4 MVP;\n" + "out vec3 frag_color;\n" + "out vec3 vtx_viewspace;\n" + "out vec3 normal;\n" + "out float frag_light;\n" + "void main() {\n" + "gl_Position = MVP * vec4(vtx_position, 1);\n" + "frag_color = vtx_color;\n" + "vtx_viewspace = (MV * vec4(vtx_position, 1)).xyz;\n" + "normal = (M * vec4(vtx_normal, 0)).xyz;\n" + "frag_light = vtx_light;\n" + "}\n" + ); + program.LoadShader( + GL_FRAGMENT_SHADER, + "#version 330 core\n" + "in vec3 frag_color;\n" + "in vec3 vtx_viewspace;\n" + "in float frag_light;\n" + "uniform float fog_density;\n" + "out vec3 color;\n" + "void main() {\n" + "vec3 ambient = vec3(0.1, 0.1, 0.1) * frag_color;\n" + "float light_power = clamp(pow(0.8, 15 - frag_light), 0, 1);\n" + //"float light_power = clamp(frag_light / 15, 0, 1);\n" + // this should be the same as the clear color, otherwise looks really weird + "vec3 fog_color = vec3(0, 0, 0);\n" + "float e = 2.718281828;\n" + //"vec3 reflect_color = ambient + frag_color * light_power;\n" + "vec3 reflect_color = frag_color * light_power;\n" + "float value = pow(e, -pow(fog_density * length(vtx_viewspace), 5));" + "color = mix(fog_color, reflect_color, value);\n" + "}\n" + ); + program.Link(); + if (!program.Linked()) { + program.Log(std::cerr); + throw std::runtime_error("link program"); + } + + m_handle = program.UniformLocation("M"); + mv_handle = program.UniformLocation("MV"); + mvp_handle = program.UniformLocation("MVP"); + fog_density_handle = program.UniformLocation("fog_density"); +} + + +void BlockLighting::Activate() { + GLContext::EnableDepthTest(); + GLContext::EnableBackfaceCulling(); + program.Use(); +} + +void BlockLighting::SetM(const glm::mat4 &m) { + glm::mat4 mv(view * m); + glm::mat4 mvp(vp * m); + glUniformMatrix4fv(m_handle, 1, GL_FALSE, &m[0][0]); + glUniformMatrix4fv(mv_handle, 1, GL_FALSE, &mv[0][0]); + glUniformMatrix4fv(mvp_handle, 1, GL_FALSE, &mvp[0][0]); +} + +void BlockLighting::SetFogDensity(float f) { + fog_density = f; + glUniform1f(fog_density_handle, fog_density); +} + +void BlockLighting::SetProjection(const glm::mat4 &p) { + projection = p; + vp = p * view; +} + +void BlockLighting::SetView(const glm::mat4 &v) { + view = v; + vp = projection * v; +} + +void BlockLighting::SetVP(const glm::mat4 &v, const glm::mat4 &p) { + projection = p; + view = v; + vp = p * v; +} + +void BlockLighting::SetMVP(const glm::mat4 &m, const glm::mat4 &v, const glm::mat4 &p) { + SetVP(v, p); + SetM(m); +} + } diff --git a/src/shader.hpp b/src/shader.hpp index f42d19b..873460b 100644 --- a/src/shader.hpp +++ b/src/shader.hpp @@ -102,6 +102,43 @@ private: }; +class BlockLighting { + +public: + BlockLighting(); + + void Activate(); + + void SetFogDensity(float); + + void SetM(const glm::mat4 &m); + void SetProjection(const glm::mat4 &p); + void SetView(const glm::mat4 &v); + void SetVP(const glm::mat4 &v, const glm::mat4 &p); + void SetMVP(const glm::mat4 &m, const glm::mat4 &v, const glm::mat4 &p); + + const glm::mat4 &Projection() const { return projection; } + const glm::mat4 &View() const { return view; } + const glm::mat4 &GetVP() const { return vp; } + +private: + Program program; + + float fog_density; + + glm::mat4 projection; + glm::mat4 view; + glm::mat4 vp; + + GLuint m_handle; + GLuint mv_handle; + GLuint mvp_handle; + GLuint light_direction_handle; + GLuint light_color_handle; + GLuint fog_density_handle; + +}; + } #endif diff --git a/src/world.cpp b/src/world.cpp index 756c66f..137fd2a 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -99,7 +99,7 @@ World::World(const Config &config) { // glowing yellow block BlockType type(true, { 1.0f, 1.0f, 0.0f }, &blockShape); - type.luminosity = 10; + type.luminosity = 15; type.block_light = true; type.fill = block_fill; blockType.Add(type); @@ -200,23 +200,28 @@ void World::Update(int dt) { } -void World::Render(DirectionalLighting &program) { - program.SetLightDirection(light_direction); - program.SetFogDensity(fog_density); - program.SetView(glm::inverse(player->Transform(player->ChunkCoords()))); +void World::Render(BlockLighting &chunk_prog, DirectionalLighting &entity_prog) { + chunk_prog.Activate(); + chunk_prog.SetFogDensity(fog_density); + chunk_prog.SetView(glm::inverse(player->Transform(player->ChunkCoords()))); for (Chunk &chunk : chunks.Loaded()) { glm::mat4 m(chunk.Transform(player->ChunkCoords())); - program.SetM(m); - glm::mat4 mvp(program.GetVP() * m); + chunk_prog.SetM(m); + glm::mat4 mvp(chunk_prog.GetVP() * m); if (!CullTest(Chunk::Bounds(), mvp)) { chunk.Draw(); } } + entity_prog.Activate(); + entity_prog.SetLightDirection(light_direction); + entity_prog.SetFogDensity(fog_density); + entity_prog.SetView(glm::inverse(player->Transform(player->ChunkCoords()))); + for (Entity &entity : entities) { if (entity.HasShape()) { - program.SetM(entity.Transform(player->ChunkCoords())); + entity_prog.SetM(entity.Transform(player->ChunkCoords())); entity.Draw(); } } diff --git a/src/world.hpp b/src/world.hpp index 3dd04fb..1d43fbe 100644 --- a/src/world.hpp +++ b/src/world.hpp @@ -52,7 +52,7 @@ public: void Update(int dt); - void Render(DirectionalLighting &); + void Render(BlockLighting &, DirectionalLighting &); private: BlockTypeRegistry blockType; -- 2.39.2 From 7ef94f4e55a0b798eecbcc7166a80b8364b21ea4 Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Mon, 23 Mar 2015 23:28:41 +0100 Subject: [PATCH 03/16] use 3 octaves for solid generation noise also, that other perlin implementation sucked noodles --- TODO | 2 -- src/generator.cpp | 6 +++--- src/generator.hpp | 2 +- src/noise.cpp | 5 ++--- src/noise.hpp | 24 ++++++++++++++++++++++++ 5 files changed, 30 insertions(+), 9 deletions(-) diff --git a/TODO b/TODO index 244e938..363c635 100644 --- a/TODO +++ b/TODO @@ -79,5 +79,3 @@ entity/world collision better noise current simplex noise implementation repeats itself pretty quickly - also there seems to be a (imo) better implementation here: - http://flafla2.github.io/2014/08/09/perlinnoise.html diff --git a/src/generator.cpp b/src/generator.cpp index 43d932c..dc83b89 100644 --- a/src/generator.cpp +++ b/src/generator.cpp @@ -8,7 +8,7 @@ namespace blank { Generator::Generator(const Config &config) : solidNoise(config.solid_seed) , typeNoise(config.type_seed) -, stretch(config.stretch) +, stretch(1.0f/config.stretch) , solid_threshold(config.solid_threshold) , space(0) , light(0) @@ -25,8 +25,8 @@ void Generator::operator ()(Chunk &chunk) const { for (int y = 0; y < Chunk::Height(); ++y) { for (int x = 0; x < Chunk::Width(); ++x) { Block::Pos block_pos(x, y, z); - glm::vec3 gen_pos = (coords + block_pos) / stretch; - float val = solidNoise(gen_pos); + glm::vec3 gen_pos = (coords + block_pos) * stretch; + float val = OctaveNoise(solidNoise, coords + block_pos, 3, 0.5f, stretch, 2.0f); if (val > solid_threshold) { int type_val = int((typeNoise(gen_pos) + 1.0f) * solids.size()) % solids.size(); chunk.SetBlock(block_pos, Block(solids[type_val])); diff --git a/src/generator.hpp b/src/generator.hpp index 3d7ceaf..70c38f5 100644 --- a/src/generator.hpp +++ b/src/generator.hpp @@ -17,7 +17,7 @@ public: unsigned int solid_seed = 0; unsigned int type_seed = 0; float stretch = 64.0f; - float solid_threshold = 0.8f; + float solid_threshold = 0.5f; }; explicit Generator(const Config &); diff --git a/src/noise.cpp b/src/noise.cpp index 6d59224..8b71614 100644 --- a/src/noise.cpp +++ b/src/noise.cpp @@ -45,10 +45,9 @@ SimplexNoise::SimplexNoise(unsigned int seed) { 0.0f, 1.0f, -1.0f }, { 0.0f, -1.0f, -1.0f }, }) { - unsigned int val = seed; + GaloisLFSR random(seed ^ 0x0123456789ACBDEF); for (size_t i = 0; i < 256; ++i) { - val = 2346765 * val + 6446345; - perm[i] = val % 256; + random(perm[i]); perm[i + 256] = perm[i]; } } diff --git a/src/noise.hpp b/src/noise.hpp index 166a60a..26e3766 100644 --- a/src/noise.hpp +++ b/src/noise.hpp @@ -35,6 +35,7 @@ private: }; + /// (3D only) adaptation of Stefan Gustavson's SimplexNoise java class class SimplexNoise { @@ -68,6 +69,29 @@ private: }; + +template +float OctaveNoise( + const Noise &noise, + const glm::vec3 &in, + int num, + float persistence, + float frequency = 1.0f, + float amplitude = 1.0f, + float growth = 2.0f +) { + float total = 0.0f; + float max = 0.0f; + for (int i = 0; i < num; ++i) { + total += noise(in * frequency) * amplitude; + max += amplitude; + amplitude *= persistence; + frequency *= growth; + } + + return total / max; +} + } #endif -- 2.39.2 From d910f0fdc2bb2f991690fd1e879ce2eccb8f3714 Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Tue, 24 Mar 2015 17:45:29 +0100 Subject: [PATCH 04/16] trying to fix the initial aiming issue not successful --- TODO | 2 ++ src/entity.cpp | 2 +- src/geometry.cpp | 67 ++++++++++++++++++----------------------------- src/interface.cpp | 2 ++ 4 files changed, 30 insertions(+), 43 deletions(-) diff --git a/TODO b/TODO index 363c635..29fd94f 100644 --- a/TODO +++ b/TODO @@ -76,6 +76,8 @@ entity/world collision entities should be stopped from entering solid parts of the world + also, current ray/obb intersection test sucks + better noise current simplex noise implementation repeats itself pretty quickly diff --git a/src/entity.cpp b/src/entity.cpp index 52502c2..2358601 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -94,7 +94,7 @@ glm::mat4 Entity::Transform(const Chunk::Pos &chunk_offset) const { Ray Entity::Aim(const Chunk::Pos &chunk_offset) const { glm::mat4 transform = Transform(chunk_offset); - glm::vec4 from = transform * glm::vec4(0.0f, 0.0f, 1.0f, 1.0f); + glm::vec4 from = transform * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); from /= from.w; glm::vec4 to = transform * glm::vec4(0.0f, 0.0f, -1.0f, 1.0f); to /= to.w; diff --git a/src/geometry.cpp b/src/geometry.cpp index 44217e9..05387a5 100644 --- a/src/geometry.cpp +++ b/src/geometry.cpp @@ -13,12 +13,11 @@ bool Intersection( glm::vec3 *normal ) { float t_min = 0.0f; - float t_max = 1.0e5f; + float t_max = std::numeric_limits::infinity(); const glm::vec3 aabb_pos(M[3].x, M[3].y, M[3].z); const glm::vec3 delta = aabb_pos - ray.orig; glm::vec3 t1(t_min, t_min, t_min), t2(t_max, t_max, t_max); - bool x_swap = false, y_swap = false, z_swap = false; { // X const glm::vec3 xaxis(M[0].x, M[0].y, M[0].z); @@ -29,21 +28,14 @@ bool Intersection( t1.x = (e + aabb.min.x) / f; t2.x = (e + aabb.max.x) / f; - if (t1.x > t2.x) { - std::swap(t1.x, t2.x); - x_swap = true; - } - if (t1.x > t_min) { - t_min = t1.x; - } - if (t2.x < t_max) { - t_max = t2.x; - } + t_min = std::max(t_min, std::min(t1.x, t2.x)); + t_max = std::min(t_max, std::max(t1.x, t2.x)); + if (t_max < t_min) { return false; } } else { - if (aabb.min.x - e > 0.0f || aabb.max.x < 0.0f) { + if (aabb.min.x - e < 0.0f || -aabb.max.x - e > 0.0f) { return false; } } @@ -58,21 +50,14 @@ bool Intersection( t1.y = (e + aabb.min.y) / f; t2.y = (e + aabb.max.y) / f; - if (t1.y > t2.y) { - std::swap(t1.y, t2.y); - y_swap = true; - } - if (t1.y > t_min) { - t_min = t1.y; - } - if (t2.y < t_max) { - t_max = t2.y; - } + t_min = std::max(t_min, std::min(t1.y, t2.y)); + t_max = std::min(t_max, std::max(t1.y, t2.y)); + if (t_max < t_min) { return false; } } else { - if (aabb.min.y - e > 0.0f || aabb.max.y < 0.0f) { + if (aabb.min.y - e < 0.0f || -aabb.max.y - e > 0.0f) { return false; } } @@ -87,41 +72,39 @@ bool Intersection( t1.z = (e + aabb.min.z) / f; t2.z = (e + aabb.max.z) / f; - if (t1.z > t2.z) { - std::swap(t1.z, t2.z); - z_swap = true; - } - if (t1.z > t_min) { - t_min = t1.z; - } - if (t2.z < t_max) { - t_max = t2.z; - } + t_min = std::max(t_min, std::min(t1.z, t2.z)); + t_max = std::min(t_max, std::max(t1.z, t2.z)); + if (t_max < t_min) { return false; } } else { - if (aabb.min.z - e > 0.0f || aabb.max.z < 0.0f) { + if (aabb.min.z - e < 0.0f || -aabb.max.z - e > 0.0f) { return false; } } } + glm::vec3 min_all(min(t1, t2)); + if (dist) { *dist = t_min; } if (normal) { - if (t1.x > t1.y) { - if (t1.x > t1.z) { - *normal = glm::vec3(x_swap ? 1 : -1, 0, 0); + glm::vec4 norm(0.0f); + if (min_all.x > min_all.y) { + if (min_all.x > min_all.z) { + norm.x = t2.x < t1.x ? 1 : -1; } else { - *normal = glm::vec3(0, 0, z_swap ? 1 : -1); + norm.z = t2.z < t1.z ? 1 : -1; } - } else if (t1.y > t1.z) { - *normal = glm::vec3(0, y_swap ? 1 : -1, 0); + } else if (min_all.y > min_all.z) { + norm.y = t2.y < t1.y ? 1 : -1; } else { - *normal = glm::vec3(0, 0, z_swap ? 1 : -1); + norm.z = t2.z < t1.z ? 1 : -1; } + norm = M * norm; + *normal = glm::vec3(norm); } return true; } diff --git a/src/interface.cpp b/src/interface.cpp index 45439da..b5aac96 100644 --- a/src/interface.cpp +++ b/src/interface.cpp @@ -105,6 +105,8 @@ void Interface::PrintBlockInfo() { std::cout << std::endl; if (!aim_chunk) { std::cout << "not looking at any block" << std::endl; + Ray aim = ctrl.Aim(); + std::cout << "aim ray: " << aim.orig << ", " << aim.dir << std::endl; return; } std::cout << "looking at block " << aim_block -- 2.39.2 From 38abfe4f5342f20b56052ac3090694eabf028d16 Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Wed, 25 Mar 2015 18:12:41 +0100 Subject: [PATCH 05/16] update light levels from border on neighbor change --- src/chunk.cpp | 247 +++++++++++++++++++++++++++++++--------------- src/generator.cpp | 1 - 2 files changed, 170 insertions(+), 78 deletions(-) diff --git a/src/chunk.cpp b/src/chunk.cpp index 994d68e..5162952 100644 --- a/src/chunk.cpp +++ b/src/chunk.cpp @@ -46,77 +46,6 @@ Chunk &Chunk::operator =(Chunk &&other) { } -void Chunk::SetNeighbor(Chunk &other) { - if (other.position == position + Pos(-1, 0, 0)) { - neighbor[Block::FACE_LEFT] = &other; - other.neighbor[Block::FACE_RIGHT] = this; - } else if (other.position == position + Pos(1, 0, 0)) { - neighbor[Block::FACE_RIGHT] = &other; - other.neighbor[Block::FACE_LEFT] = this; - } else if (other.position == position + Pos(0, -1, 0)) { - neighbor[Block::FACE_DOWN] = &other; - other.neighbor[Block::FACE_UP] = this; - } else if (other.position == position + Pos(0, 1, 0)) { - neighbor[Block::FACE_UP] = &other; - other.neighbor[Block::FACE_DOWN] = this; - } else if (other.position == position + Pos(0, 0, -1)) { - neighbor[Block::FACE_BACK] = &other; - other.neighbor[Block::FACE_FRONT] = this; - } else if (other.position == position + Pos(0, 0, 1)) { - neighbor[Block::FACE_FRONT] = &other; - other.neighbor[Block::FACE_BACK] = this; - } -} - -void Chunk::ClearNeighbors() { - for (int i = 0; i < Block::FACE_COUNT; ++i) { - neighbor[i] = nullptr; - } -} - -void Chunk::Unlink() { - if (neighbor[Block::FACE_UP]) { - neighbor[Block::FACE_UP]->neighbor[Block::FACE_DOWN] = nullptr; - } - if (neighbor[Block::FACE_DOWN]) { - neighbor[Block::FACE_DOWN]->neighbor[Block::FACE_UP] = nullptr; - } - if (neighbor[Block::FACE_LEFT]) { - neighbor[Block::FACE_LEFT]->neighbor[Block::FACE_RIGHT] = nullptr; - } - if (neighbor[Block::FACE_RIGHT]) { - neighbor[Block::FACE_RIGHT]->neighbor[Block::FACE_LEFT] = nullptr; - } - if (neighbor[Block::FACE_FRONT]) { - neighbor[Block::FACE_FRONT]->neighbor[Block::FACE_BACK] = nullptr; - } - if (neighbor[Block::FACE_BACK]) { - neighbor[Block::FACE_BACK]->neighbor[Block::FACE_FRONT] = nullptr; - } -} - -void Chunk::Relink() { - if (neighbor[Block::FACE_UP]) { - neighbor[Block::FACE_UP]->neighbor[Block::FACE_DOWN] = this; - } - if (neighbor[Block::FACE_DOWN]) { - neighbor[Block::FACE_DOWN]->neighbor[Block::FACE_UP] = this; - } - if (neighbor[Block::FACE_LEFT]) { - neighbor[Block::FACE_LEFT]->neighbor[Block::FACE_RIGHT] = this; - } - if (neighbor[Block::FACE_RIGHT]) { - neighbor[Block::FACE_RIGHT]->neighbor[Block::FACE_LEFT] = this; - } - if (neighbor[Block::FACE_FRONT]) { - neighbor[Block::FACE_FRONT]->neighbor[Block::FACE_BACK] = this; - } - if (neighbor[Block::FACE_BACK]) { - neighbor[Block::FACE_BACK]->neighbor[Block::FACE_FRONT] = this; - } -} - - namespace { struct SetNode { @@ -227,10 +156,12 @@ void Chunk::SetBlock(int index, const Block &block) { work_light(); } else if (new_type.block_light && !old_type.block_light) { // obstacle added - dark_queue.emplace(this, ToPos(index)); - SetLight(index, 0); - work_dark(); - work_light(); + if (GetLight(index) > 0) { + dark_queue.emplace(this, ToPos(index)); + SetLight(index, 0); + work_dark(); + work_light(); + } } else if (!new_type.block_light && old_type.block_light) { // obstacle removed int level = 0; @@ -268,6 +199,166 @@ const Block *Chunk::FindNext(const Pos &pos, Block::Face face) const { } } +void Chunk::SetNeighbor(Chunk &other) { + if (other.position == position + Pos(-1, 0, 0)) { + if (neighbor[Block::FACE_LEFT] != &other) { + neighbor[Block::FACE_LEFT] = &other; + other.neighbor[Block::FACE_RIGHT] = this; + for (int z = 0; z < Depth(); ++z) { + for (int y = 0; y < Height(); ++y) { + Pos my_pos(0, y, z); + Pos other_pos(Width() - 1, y, z); + if (GetLight(my_pos) > 0) { + light_queue.emplace(this, my_pos); + } + if (other.GetLight(other_pos) > 0) { + light_queue.emplace(&other, other_pos); + } + } + } + work_light(); + } + } else if (other.position == position + Pos(1, 0, 0)) { + if (neighbor[Block::FACE_RIGHT] != &other) { + neighbor[Block::FACE_RIGHT] = &other; + other.neighbor[Block::FACE_LEFT] = this; + for (int z = 0; z < Depth(); ++z) { + for (int y = 0; y < Height(); ++y) { + Pos my_pos(Width() - 1, y, z); + Pos other_pos(0, y, z); + if (GetLight(my_pos) > 0) { + light_queue.emplace(this, my_pos); + } + if (other.GetLight(other_pos) > 0) { + light_queue.emplace(&other, other_pos); + } + } + } + work_light(); + } + } else if (other.position == position + Pos(0, -1, 0)) { + if (neighbor[Block::FACE_DOWN] != &other) { + neighbor[Block::FACE_DOWN] = &other; + other.neighbor[Block::FACE_UP] = this; + for (int z = 0; z < Depth(); ++z) { + for (int x = 0; x < Width(); ++x) { + Pos my_pos(x, 0, z); + Pos other_pos(x, Height() - 1, z); + if (GetLight(my_pos) > 0) { + light_queue.emplace(this, my_pos); + } + if (other.GetLight(other_pos) > 0) { + light_queue.emplace(&other, other_pos); + } + } + } + work_light(); + } + } else if (other.position == position + Pos(0, 1, 0)) { + if (neighbor[Block::FACE_UP] != &other) { + neighbor[Block::FACE_UP] = &other; + other.neighbor[Block::FACE_DOWN] = this; + for (int z = 0; z < Depth(); ++z) { + for (int x = 0; x < Width(); ++x) { + Pos my_pos(x, Height() - 1, z); + Pos other_pos(x, 0, z); + if (GetLight(my_pos) > 0) { + light_queue.emplace(this, my_pos); + } + if (other.GetLight(other_pos) > 0) { + light_queue.emplace(&other, other_pos); + } + } + } + work_light(); + } + } else if (other.position == position + Pos(0, 0, -1)) { + if (neighbor[Block::FACE_BACK] != &other) { + neighbor[Block::FACE_BACK] = &other; + other.neighbor[Block::FACE_FRONT] = this; + for (int y = 0; y < Height(); ++y) { + for (int x = 0; x < Width(); ++x) { + Pos my_pos(x, y, 0); + Pos other_pos(x, y, Depth() - 1); + if (GetLight(my_pos) > 0) { + light_queue.emplace(this, my_pos); + } + if (other.GetLight(other_pos) > 0) { + light_queue.emplace(&other, other_pos); + } + } + } + work_light(); + } + } else if (other.position == position + Pos(0, 0, 1)) { + if (neighbor[Block::FACE_FRONT] != &other) { + neighbor[Block::FACE_FRONT] = &other; + other.neighbor[Block::FACE_BACK] = this; + for (int y = 0; y < Height(); ++y) { + for (int x = 0; x < Width(); ++x) { + Pos my_pos(x, y, Depth() - 1); + Pos other_pos(x, y, 0); + if (GetLight(my_pos) > 0) { + light_queue.emplace(this, my_pos); + } + if (other.GetLight(other_pos) > 0) { + light_queue.emplace(&other, other_pos); + } + } + } + work_light(); + } + } +} + +void Chunk::ClearNeighbors() { + for (int i = 0; i < Block::FACE_COUNT; ++i) { + neighbor[i] = nullptr; + } +} + +void Chunk::Unlink() { + if (neighbor[Block::FACE_UP]) { + neighbor[Block::FACE_UP]->neighbor[Block::FACE_DOWN] = nullptr; + } + if (neighbor[Block::FACE_DOWN]) { + neighbor[Block::FACE_DOWN]->neighbor[Block::FACE_UP] = nullptr; + } + if (neighbor[Block::FACE_LEFT]) { + neighbor[Block::FACE_LEFT]->neighbor[Block::FACE_RIGHT] = nullptr; + } + if (neighbor[Block::FACE_RIGHT]) { + neighbor[Block::FACE_RIGHT]->neighbor[Block::FACE_LEFT] = nullptr; + } + if (neighbor[Block::FACE_FRONT]) { + neighbor[Block::FACE_FRONT]->neighbor[Block::FACE_BACK] = nullptr; + } + if (neighbor[Block::FACE_BACK]) { + neighbor[Block::FACE_BACK]->neighbor[Block::FACE_FRONT] = nullptr; + } +} + +void Chunk::Relink() { + if (neighbor[Block::FACE_UP]) { + neighbor[Block::FACE_UP]->neighbor[Block::FACE_DOWN] = this; + } + if (neighbor[Block::FACE_DOWN]) { + neighbor[Block::FACE_DOWN]->neighbor[Block::FACE_UP] = this; + } + if (neighbor[Block::FACE_LEFT]) { + neighbor[Block::FACE_LEFT]->neighbor[Block::FACE_RIGHT] = this; + } + if (neighbor[Block::FACE_RIGHT]) { + neighbor[Block::FACE_RIGHT]->neighbor[Block::FACE_LEFT] = this; + } + if (neighbor[Block::FACE_FRONT]) { + neighbor[Block::FACE_FRONT]->neighbor[Block::FACE_BACK] = this; + } + if (neighbor[Block::FACE_BACK]) { + neighbor[Block::FACE_BACK]->neighbor[Block::FACE_FRONT] = this; + } +} + void Chunk::SetLight(int index, int level) { if (light[index] != level) { @@ -696,8 +787,9 @@ Chunk &ChunkLoader::Generate(const Chunk::Pos &pos) { loaded.emplace_back(reg); Chunk &chunk = loaded.back(); chunk.Position(pos); - Insert(chunk); + chunk.Allocate(); gen(chunk); + Insert(chunk); return chunk; } @@ -812,8 +904,9 @@ void ChunkLoader::Update() { } Chunk &chunk = loaded.back(); chunk.Position(pos); - Insert(chunk); + chunk.Allocate(); gen(chunk); + Insert(chunk); } to_generate.pop_front(); } diff --git a/src/generator.cpp b/src/generator.cpp index dc83b89..373374f 100644 --- a/src/generator.cpp +++ b/src/generator.cpp @@ -18,7 +18,6 @@ Generator::Generator(const Config &config) void Generator::operator ()(Chunk &chunk) const { - chunk.Allocate(); Chunk::Pos pos(chunk.Position()); glm::vec3 coords(pos * Chunk::Extent()); for (int z = 0; z < Chunk::Depth(); ++z) { -- 2.39.2 From 8795094374130820e36ec4fd7e08e13b6b316fba Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Wed, 25 Mar 2015 18:43:53 +0100 Subject: [PATCH 06/16] optimized block lookup a little --- src/chunk.cpp | 43 +++++++++++++++++-------------------------- src/chunk.hpp | 27 ++++++++++++++++++--------- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/src/chunk.cpp b/src/chunk.cpp index 5162952..2da6639 100644 --- a/src/chunk.cpp +++ b/src/chunk.cpp @@ -61,11 +61,11 @@ struct SetNode { bool HasNext(Block::Face face) { const BlockLookup next(chunk, pos, face); - return next.result && !next.chunk->Type(*next.result).block_light; + return next && !next.GetType().block_light; } SetNode GetNext(Block::Face face) { const BlockLookup next(chunk, pos, face); - return SetNode(next.chunk, next.pos); + return SetNode(&next.GetChunk(), next.GetBlockPos()); } }; @@ -84,7 +84,7 @@ struct UnsetNode bool HasNext(Block::Face face) { const BlockLookup next(chunk, pos, face); - return next.result; + return next; } UnsetNode GetNext(Block::Face face) { return UnsetNode(SetNode::GetNext(face)); } @@ -376,19 +376,10 @@ float Chunk::GetVertexLight(int index, const BlockModel::Position &vtx, const Bl Chunk::Pos pos(ToPos(index)); Block::Face direct_face(Block::NormalFace(norm)); - const Chunk *direct_chunk = this; - Chunk::Pos direct_pos(pos + Block::FaceNormal(direct_face)); - if (!InBounds(direct_pos)) { - if (HasNeighbor(direct_face)) { - direct_chunk = &GetNeighbor(direct_face); - direct_pos -= (Block::FaceNormal(direct_face) * Extent()); - float direct_light = direct_chunk->GetLight(direct_pos); - if (direct_light > light) { - light = direct_light; - } - } - } else { - float direct_light = direct_chunk->GetLight(direct_pos); + // tis okay + BlockLookup direct(const_cast(this), pos, Block::NormalFace(norm)); + if (direct) { + float direct_light = direct.GetLight(); if (direct_light > light) { light = direct_light; } @@ -620,12 +611,13 @@ glm::mat4 Chunk::ToTransform(int idx) const { BlockLookup::BlockLookup(Chunk *c, const Chunk::Pos &p) -: chunk(c), pos(p), result(nullptr) { +: chunk(c), pos(p) { while (pos.x >= Chunk::Width()) { if (chunk->HasNeighbor(Block::FACE_RIGHT)) { chunk = &chunk->GetNeighbor(Block::FACE_RIGHT); pos.x -= Chunk::Width(); } else { + chunk = nullptr; return; } } @@ -634,6 +626,7 @@ BlockLookup::BlockLookup(Chunk *c, const Chunk::Pos &p) chunk = &chunk->GetNeighbor(Block::FACE_LEFT); pos.x += Chunk::Width(); } else { + chunk = nullptr; return; } } @@ -642,6 +635,7 @@ BlockLookup::BlockLookup(Chunk *c, const Chunk::Pos &p) chunk = &chunk->GetNeighbor(Block::FACE_UP); pos.y -= Chunk::Height(); } else { + chunk = nullptr; return; } } @@ -650,6 +644,7 @@ BlockLookup::BlockLookup(Chunk *c, const Chunk::Pos &p) chunk = &chunk->GetNeighbor(Block::FACE_DOWN); pos.y += Chunk::Height(); } else { + chunk = nullptr; return; } } @@ -658,6 +653,7 @@ BlockLookup::BlockLookup(Chunk *c, const Chunk::Pos &p) chunk = &chunk->GetNeighbor(Block::FACE_FRONT); pos.z -= Chunk::Depth(); } else { + chunk = nullptr; return; } } @@ -666,23 +662,18 @@ BlockLookup::BlockLookup(Chunk *c, const Chunk::Pos &p) chunk = &chunk->GetNeighbor(Block::FACE_BACK); pos.z += Chunk::Depth(); } else { + chunk = nullptr; return; } } - result = &chunk->BlockAt(pos); } BlockLookup::BlockLookup(Chunk *c, const Chunk::Pos &p, Block::Face face) -: chunk(c), pos(p), result(nullptr) { +: chunk(c), pos(p) { pos += Block::FaceNormal(face); - if (Chunk::InBounds(pos)) { - result = &chunk->BlockAt(pos); - } else { + if (!Chunk::InBounds(pos)) { pos -= Block::FaceNormal(face) * Chunk::Extent(); - if (chunk->HasNeighbor(face)) { - chunk = &chunk->GetNeighbor(face); - result = &chunk->BlockAt(pos); - } + chunk = &chunk->GetNeighbor(face); } } diff --git a/src/chunk.hpp b/src/chunk.hpp index 0b1e5bd..32f7505 100644 --- a/src/chunk.hpp +++ b/src/chunk.hpp @@ -155,20 +155,29 @@ private: }; -struct BlockLookup { +class BlockLookup { - Chunk *chunk; - Chunk::Pos pos; - const Block *result; - - // resolve chunk/position/block from oob coordinates - // result will be nullptr if unsuccessful +public: + // resolve chunk/position from oob coordinates BlockLookup(Chunk *c, const Chunk::Pos &p); - // resolve chunk/position/block from ib coordinates and direction - // result will be nullptr if unsuccessful + // resolve chunk/position from ib coordinates and direction BlockLookup(Chunk *c, const Chunk::Pos &p, Block::Face dir); + // check if lookup was successful + operator bool() const { return chunk; } + + // only valid if lookup was successful + Chunk &GetChunk() const { return *chunk; } + const Chunk::Pos &GetBlockPos() const { return pos; } + const Block &GetBlock() const { return GetChunk().BlockAt(GetBlockPos()); } + const BlockType &GetType() const { return GetChunk().Type(GetBlock()); } + int GetLight() const { return GetChunk().GetLight(GetBlockPos()); } + +private: + Chunk *chunk; + Chunk::Pos pos; + }; -- 2.39.2 From e2a346914a3b90ca7feed2e07d83faa06834bb95 Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Wed, 20 May 2015 18:46:13 +0200 Subject: [PATCH 07/16] better chunk memory management --- Makefile | 2 +- src/chunk.cpp | 78 ++++++++++++++++++++------------------------------- src/chunk.hpp | 5 ++-- 3 files changed, 33 insertions(+), 52 deletions(-) diff --git a/Makefile b/Makefile index 67b9bf1..36c7048 100644 --- a/Makefile +++ b/Makefile @@ -59,7 +59,7 @@ callgrind: blank.profile --branch-sim=yes --cacheuse=yes --cache-sim=yes \ --collect-bus=yes --collect-systime=yes --collect-jumps=yes \ --dump-instr=yes --simulate-hwpref=yes --simulate-wb=yes \ - ./blank.profile + ./blank.profile -n 128 -t 16 --no-keyboard --no-mouse -d --no-vsync clean: rm -df $(OBJ) $(DEP) $(DIR) diff --git a/src/chunk.cpp b/src/chunk.cpp index 2da6639..a64e184 100644 --- a/src/chunk.cpp +++ b/src/chunk.cpp @@ -2,6 +2,7 @@ #include "generator.hpp" +#include #include #include #include @@ -11,9 +12,9 @@ namespace blank { Chunk::Chunk(const BlockTypeRegistry &types) : types(&types) -, neighbor{ 0, 0, 0, 0, 0, 0 } -, blocks() -, light() +, neighbor{0} +, blocks{} +, light{0} , model() , position(0, 0, 0) , dirty(false) { @@ -22,23 +23,19 @@ Chunk::Chunk(const BlockTypeRegistry &types) Chunk::Chunk(Chunk &&other) : types(other.types) -, blocks(std::move(other.blocks)) -, light(std::move(other.light)) , model(std::move(other.model)) , position(other.position) , dirty(other.dirty) { - for (size_t i = 0; i < Block::FACE_COUNT; ++i) { - neighbor[i] = other.neighbor[i]; - } + std::copy(other.neighbor, other.neighbor + sizeof(neighbor), neighbor); + std::copy(other.blocks, other.blocks + sizeof(blocks), blocks); + std::copy(other.light, other.light + sizeof(light), light); } Chunk &Chunk::operator =(Chunk &&other) { types = other.types; - for (size_t i = 0; i < Block::FACE_COUNT; ++i) { - neighbor[i] = other.neighbor[i]; - } - blocks = std::move(other.blocks); - light = std::move(other.light); + std::copy(other.neighbor, other.neighbor + sizeof(neighbor), neighbor); + std::copy(other.blocks, other.blocks + sizeof(blocks), blocks); + std::copy(other.light, other.light + sizeof(light), light); model = std::move(other.model); position = other.position; dirty = other.dirty; @@ -413,12 +410,6 @@ bool Chunk::IsSurface(const Pos &pos) const { } -void Chunk::Allocate() { - blocks.resize(Size(), Block(0)); - light.resize(Size(), 0); -} - - void Chunk::Draw() { if (dirty) { Update(); @@ -778,7 +769,6 @@ Chunk &ChunkLoader::Generate(const Chunk::Pos &pos) { loaded.emplace_back(reg); Chunk &chunk = loaded.back(); chunk.Position(pos); - chunk.Allocate(); gen(chunk); Insert(chunk); return chunk; @@ -872,39 +862,31 @@ void ChunkLoader::GenerateSurrounding(const Chunk::Pos &pos) { } void ChunkLoader::Update() { - bool reused = false; - if (!to_generate.empty()) { - Chunk::Pos pos(to_generate.front()); - - for (auto iter(to_free.begin()), end(to_free.end()); iter != end; ++iter) { - if (iter->Position() == pos) { - iter->Relink(); - loaded.splice(loaded.end(), to_free, iter); - reused = true; - break; - } - } + if (to_generate.empty()) { + return; + } - if (!reused) { - if (to_free.empty()) { - loaded.emplace_back(reg); - } else { - to_free.front().ClearNeighbors(); - loaded.splice(loaded.end(), to_free, to_free.begin()); - reused = true; - } - Chunk &chunk = loaded.back(); - chunk.Position(pos); - chunk.Allocate(); - gen(chunk); - Insert(chunk); + Chunk::Pos pos(to_generate.front()); + to_generate.pop_front(); + + for (auto iter(to_free.begin()), end(to_free.end()); iter != end; ++iter) { + if (iter->Position() == pos) { + iter->Relink(); + loaded.splice(loaded.end(), to_free, iter); + return; } - to_generate.pop_front(); } - if (!reused && !to_free.empty()) { - to_free.pop_front(); + if (to_free.empty()) { + loaded.emplace_back(reg); + } else { + to_free.front().ClearNeighbors(); + loaded.splice(loaded.end(), to_free, to_free.begin()); } + Chunk &chunk = loaded.back(); + chunk.Position(pos); + gen(chunk); + Insert(chunk); } } diff --git a/src/chunk.hpp b/src/chunk.hpp index 32f7505..fa19776 100644 --- a/src/chunk.hpp +++ b/src/chunk.hpp @@ -91,7 +91,6 @@ public: // check if block at given index is completely enclosed (and therefore invisible) bool Obstructed(int idx) const; - void Allocate(); void Invalidate() { dirty = true; } void SetBlock(int index, const Block &); @@ -146,8 +145,8 @@ private: private: const BlockTypeRegistry *types; Chunk *neighbor[Block::FACE_COUNT]; - std::vector blocks; - std::vector light; + Block blocks[16 * 16 * 16]; + unsigned char light[16 * 16 * 16]; BlockModel model; Pos position; bool dirty; -- 2.39.2 From c899292fd5dee11bee0fafadf051f4204eb4bf2a Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Wed, 20 May 2015 18:46:38 +0200 Subject: [PATCH 08/16] remove move branching from interface --- src/interface.cpp | 39 +++++++++------------------------------ src/interface.hpp | 3 ++- 2 files changed, 11 insertions(+), 31 deletions(-) diff --git a/src/interface.cpp b/src/interface.cpp index b5aac96..e4888c5 100644 --- a/src/interface.cpp +++ b/src/interface.cpp @@ -4,7 +4,6 @@ #include "world.hpp" #include -#include #include #include @@ -23,12 +22,8 @@ Interface::Interface(const Config &config, World &world) , config(config) , remove(0) , selection(1) -, front(false) -, back(false) -, left(false) -, right(false) -, up(false) -, down(false) { +, fwd(0) +, rev(0) { hud.Viewport(960, 600); hud.Display(selection); } @@ -39,22 +34,22 @@ void Interface::Handle(const SDL_KeyboardEvent &event) { switch (event.keysym.sym) { case SDLK_w: - front = event.state == SDL_PRESSED; + rev.z = event.state == SDL_PRESSED; break; case SDLK_s: - back = event.state == SDL_PRESSED; + fwd.z = event.state == SDL_PRESSED; break; case SDLK_a: - left = event.state == SDL_PRESSED; + rev.x = event.state == SDL_PRESSED; break; case SDLK_d: - right = event.state == SDL_PRESSED; + fwd.x = event.state == SDL_PRESSED; break; case SDLK_SPACE: - up = event.state == SDL_PRESSED; + fwd.y = event.state == SDL_PRESSED; break; case SDLK_LSHIFT: - down = event.state == SDL_PRESSED; + rev.y = event.state == SDL_PRESSED; break; case SDLK_q: @@ -247,23 +242,7 @@ void Interface::Handle(const SDL_WindowEvent &event) { void Interface::Update(int dt) { - glm::vec3 vel; - if (right && !left) { - vel.x = config.move_velocity; - } else if (left && !right) { - vel.x = -config.move_velocity; - } - if (up && !down) { - vel.y = config.move_velocity; - } else if (down && !up) { - vel.y = -config.move_velocity; - } - if (back && !front) { - vel.z = config.move_velocity; - } else if (front && !back) { - vel.z = -config.move_velocity; - } - ctrl.Velocity(vel); + ctrl.Velocity(glm::vec3(fwd - rev) * config.move_velocity); ctrl.Update(dt); Ray aim = ctrl.Aim(); diff --git a/src/interface.hpp b/src/interface.hpp index 8bdb8fb..1f4bb90 100644 --- a/src/interface.hpp +++ b/src/interface.hpp @@ -8,6 +8,7 @@ #include "shader.hpp" #include +#include namespace blank { @@ -73,7 +74,7 @@ private: Block remove; Block selection; - bool front, back, left, right, up, down; + glm::tvec3 fwd, rev; }; -- 2.39.2 From f577e22966a636653ca266a6e30f1834c4bb8464 Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Thu, 21 May 2015 18:07:28 +0200 Subject: [PATCH 09/16] simplified ray/aabb intersection code it's still wrong, but at least it not as long now :) --- src/geometry.cpp | 62 +++++++----------------------------------------- 1 file changed, 9 insertions(+), 53 deletions(-) diff --git a/src/geometry.cpp b/src/geometry.cpp index 05387a5..cd28bab 100644 --- a/src/geometry.cpp +++ b/src/geometry.cpp @@ -19,67 +19,23 @@ bool Intersection( glm::vec3 t1(t_min, t_min, t_min), t2(t_max, t_max, t_max); - { // X - const glm::vec3 xaxis(M[0].x, M[0].y, M[0].z); - const float e = glm::dot(xaxis, delta); - const float f = glm::dot(ray.dir, xaxis); + for (int i = 0; i < 3; ++i) { + const glm::vec3 axis(M[i].x, M[i].y, M[i].z); + const float e = glm::dot(axis, delta); + const float f = glm::dot(axis, ray.dir); if (std::abs(f) > std::numeric_limits::epsilon()) { - t1.x = (e + aabb.min.x) / f; - t2.x = (e + aabb.max.x) / f; + t1[i] = (e + aabb.min[i]) / f; + t2[i] = (e + aabb.max[i]) / f; - t_min = std::max(t_min, std::min(t1.x, t2.x)); - t_max = std::min(t_max, std::max(t1.x, t2.x)); + t_min = std::max(t_min, std::min(t1[i], t2[i])); + t_max = std::min(t_max, std::max(t1[i], t2[i])); if (t_max < t_min) { return false; } } else { - if (aabb.min.x - e < 0.0f || -aabb.max.x - e > 0.0f) { - return false; - } - } - } - - { // Y - const glm::vec3 yaxis(M[1].x, M[1].y, M[1].z); - const float e = glm::dot(yaxis, delta); - const float f = glm::dot(ray.dir, yaxis); - - if (std::abs(f) > std::numeric_limits::epsilon()) { - t1.y = (e + aabb.min.y) / f; - t2.y = (e + aabb.max.y) / f; - - t_min = std::max(t_min, std::min(t1.y, t2.y)); - t_max = std::min(t_max, std::max(t1.y, t2.y)); - - if (t_max < t_min) { - return false; - } - } else { - if (aabb.min.y - e < 0.0f || -aabb.max.y - e > 0.0f) { - return false; - } - } - } - - { // Z - const glm::vec3 zaxis(M[2].x, M[2].y, M[2].z); - const float e = glm::dot(zaxis, delta); - const float f = glm::dot(ray.dir, zaxis); - - if (std::abs(f) > std::numeric_limits::epsilon()) { - t1.z = (e + aabb.min.z) / f; - t2.z = (e + aabb.max.z) / f; - - t_min = std::max(t_min, std::min(t1.z, t2.z)); - t_max = std::min(t_max, std::max(t1.z, t2.z)); - - if (t_max < t_min) { - return false; - } - } else { - if (aabb.min.z - e < 0.0f || -aabb.max.z - e > 0.0f) { + if (aabb.min[i] - e < 0.0f || -aabb.max[i] - e > 0.0f) { return false; } } -- 2.39.2 From 4485397da18a25dfd1a51e864814887b66ba0f2e Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Fri, 22 May 2015 17:15:07 +0200 Subject: [PATCH 10/16] simplified block face stuff --- src/block.hpp | 8 ++- src/chunk.cpp | 160 ++++++-------------------------------------------- src/chunk.hpp | 4 -- 3 files changed, 25 insertions(+), 147 deletions(-) diff --git a/src/block.hpp b/src/block.hpp index 56f9eac..4fcee4c 100644 --- a/src/block.hpp +++ b/src/block.hpp @@ -42,11 +42,15 @@ struct Block { const glm::mat4 &Transform() const; - Face GetFace() const { return Face(orient / 4); } + Face GetFace() const { return Face(orient / TURN_COUNT); } void SetFace(Face face) { orient = face * TURN_COUNT + GetTurn(); } - Turn GetTurn() const { return Turn(orient % 4); } + Turn GetTurn() const { return Turn(orient % TURN_COUNT); } void SetTurn(Turn turn) { orient = GetFace() * TURN_COUNT + turn; } + static Face Opposite(Face f) { + return Face(f ^ 1); + } + static glm::tvec3 FaceNormal(Face face) { switch (face) { case FACE_UP: diff --git a/src/chunk.cpp b/src/chunk.cpp index a64e184..2a764f3 100644 --- a/src/chunk.cpp +++ b/src/chunk.cpp @@ -163,18 +163,9 @@ void Chunk::SetBlock(int index, const Block &block) { // obstacle removed int level = 0; for (int face = 0; face < Block::FACE_COUNT; ++face) { - Pos next_pos(ToPos(index) + Block::FaceNormal(Block::Face(face))); - int next_level = 0; - if (InBounds(next_pos)) { - next_level = GetLight(next_pos); - } else { - if (HasNeighbor(Block::Face(face))) { - next_pos -= (Block::FaceNormal(Block::Face(face)) * Chunk::Extent()); - next_level = GetNeighbor(Block::Face(face)).GetLight(next_pos); - } - } - if (level < next_level) { - level = next_level; + BlockLookup next_block(this, ToPos(index), Block::Face(face)); + if (next_block) { + level = std::min(level, next_block.GetLight()); } } if (level > 1) { @@ -185,17 +176,6 @@ void Chunk::SetBlock(int index, const Block &block) { } } -const Block *Chunk::FindNext(const Pos &pos, Block::Face face) const { - Pos next_pos(pos + Block::FaceNormal(face)); - if (InBounds(next_pos)) { - return &BlockAt(pos + Block::FaceNormal(face)); - } else if (HasNeighbor(face)) { - return &GetNeighbor(face).BlockAt(next_pos - (Block::FaceNormal(face) * Extent())); - } else { - return nullptr; - } -} - void Chunk::SetNeighbor(Chunk &other) { if (other.position == position + Pos(-1, 0, 0)) { if (neighbor[Block::FACE_LEFT] != &other) { @@ -315,44 +295,18 @@ void Chunk::ClearNeighbors() { } void Chunk::Unlink() { - if (neighbor[Block::FACE_UP]) { - neighbor[Block::FACE_UP]->neighbor[Block::FACE_DOWN] = nullptr; - } - if (neighbor[Block::FACE_DOWN]) { - neighbor[Block::FACE_DOWN]->neighbor[Block::FACE_UP] = nullptr; - } - if (neighbor[Block::FACE_LEFT]) { - neighbor[Block::FACE_LEFT]->neighbor[Block::FACE_RIGHT] = nullptr; - } - if (neighbor[Block::FACE_RIGHT]) { - neighbor[Block::FACE_RIGHT]->neighbor[Block::FACE_LEFT] = nullptr; - } - if (neighbor[Block::FACE_FRONT]) { - neighbor[Block::FACE_FRONT]->neighbor[Block::FACE_BACK] = nullptr; - } - if (neighbor[Block::FACE_BACK]) { - neighbor[Block::FACE_BACK]->neighbor[Block::FACE_FRONT] = nullptr; + for (int face = 0; face < Block::FACE_COUNT; ++face) { + if (neighbor[face]) { + neighbor[face]->neighbor[Block::Opposite(Block::Face(face))] = nullptr; + } } } void Chunk::Relink() { - if (neighbor[Block::FACE_UP]) { - neighbor[Block::FACE_UP]->neighbor[Block::FACE_DOWN] = this; - } - if (neighbor[Block::FACE_DOWN]) { - neighbor[Block::FACE_DOWN]->neighbor[Block::FACE_UP] = this; - } - if (neighbor[Block::FACE_LEFT]) { - neighbor[Block::FACE_LEFT]->neighbor[Block::FACE_RIGHT] = this; - } - if (neighbor[Block::FACE_RIGHT]) { - neighbor[Block::FACE_RIGHT]->neighbor[Block::FACE_LEFT] = this; - } - if (neighbor[Block::FACE_FRONT]) { - neighbor[Block::FACE_FRONT]->neighbor[Block::FACE_BACK] = this; - } - if (neighbor[Block::FACE_BACK]) { - neighbor[Block::FACE_BACK]->neighbor[Block::FACE_FRONT] = this; + for (int face = 0; face < Block::FACE_COUNT; ++face) { + if (neighbor[face]) { + neighbor[face]->neighbor[Block::Opposite(Block::Face(face))] = this; + } } } @@ -401,8 +355,8 @@ bool Chunk::IsSurface(const Pos &pos) const { return false; } for (int face = 0; face < Block::FACE_COUNT; ++face) { - const Block *next = FindNext(pos, Block::Face(face)); - if (!next || !Type(*next).visible) { + BlockLookup next = BlockLookup(const_cast(this), pos, Block::Face(face)); + if (!next || !next.GetType().visible) { return true; } } @@ -509,88 +463,12 @@ void Chunk::Update() { bool Chunk::Obstructed(int idx) const { Chunk::Pos pos(ToPos(idx)); - Chunk::Pos left_pos(pos + Chunk::Pos(-1, 0, 0)); - const Block *left_block = nullptr; - if (InBounds(left_pos)) { - left_block = &BlockAt(left_pos); - } else if (HasNeighbor(Block::FACE_LEFT)) { - left_pos += Chunk::Pos(Width(), 0, 0); - left_block = &GetNeighbor(Block::FACE_LEFT).BlockAt(left_pos); - } else { - return false; - } - if (!Type(*left_block).FaceFilled(*left_block, Block::FACE_RIGHT)) { - return false; - } - - Chunk::Pos right_pos(pos + Chunk::Pos(1, 0, 0)); - const Block *right_block = nullptr; - if (InBounds(right_pos)) { - right_block = &BlockAt(right_pos); - } else if (HasNeighbor(Block::FACE_RIGHT)) { - right_pos += Chunk::Pos(-Width(), 0, 0); - right_block = &GetNeighbor(Block::FACE_RIGHT).BlockAt(right_pos); - } else { - return false; - } - if (!Type(*right_block).FaceFilled(*right_block, Block::FACE_LEFT)) { - return false; - } - - Chunk::Pos down_pos(pos + Chunk::Pos(0, -1, 0)); - const Block *down_block = nullptr; - if (InBounds(down_pos)) { - down_block = &BlockAt(down_pos); - } else if (HasNeighbor(Block::FACE_DOWN)) { - down_pos += Chunk::Pos(0, Height(), 0); - down_block = &GetNeighbor(Block::FACE_DOWN).BlockAt(down_pos); - } else { - return false; - } - if (!Type(*down_block).FaceFilled(*down_block, Block::FACE_UP)) { - return false; - } - - Chunk::Pos up_pos(pos + Chunk::Pos(0, 1, 0)); - const Block *up_block = nullptr; - if (InBounds(up_pos)) { - up_block = &BlockAt(up_pos); - } else if (HasNeighbor(Block::FACE_UP)) { - up_pos += Chunk::Pos(0, -Height(), 0); - up_block = &GetNeighbor(Block::FACE_UP).BlockAt(up_pos); - } else { - return false; - } - if (!Type(*up_block).FaceFilled(*up_block, Block::FACE_DOWN)) { - return false; - } - - Chunk::Pos back_pos(pos + Chunk::Pos(0, 0, -1)); - const Block *back_block = nullptr; - if (InBounds(back_pos)) { - back_block = &BlockAt(back_pos); - } else if (HasNeighbor(Block::FACE_BACK)) { - back_pos += Chunk::Pos(0, 0, Depth()); - back_block = &GetNeighbor(Block::FACE_BACK).BlockAt(back_pos); - } else { - return false; - } - if (!Type(*back_block).FaceFilled(*back_block, Block::FACE_FRONT)) { - return false; - } - - Chunk::Pos front_pos(pos + Chunk::Pos(0, 0, 1)); - const Block *front_block = nullptr; - if (InBounds(front_pos)) { - front_block = &BlockAt(front_pos); - } else if (HasNeighbor(Block::FACE_FRONT)) { - front_pos += Chunk::Pos(0, 0, -Depth()); - front_block = &GetNeighbor(Block::FACE_FRONT).BlockAt(front_pos); - } else { - return false; - } - if (!Type(*front_block).FaceFilled(*front_block, Block::FACE_BACK)) { - return false; + for (int f = 0; f < Block::FACE_COUNT; ++f) { + Block::Face face = Block::Face(f); + BlockLookup next(const_cast(this), pos, face); + if (!next || !next.GetType().FaceFilled(next.GetBlock(), Block::Opposite(face))) { + return false; + } } return true; diff --git a/src/chunk.hpp b/src/chunk.hpp index fa19776..4f6732d 100644 --- a/src/chunk.hpp +++ b/src/chunk.hpp @@ -101,10 +101,6 @@ public: const Block &BlockAt(const Block::Pos &pos) const { return BlockAt(ToIndex(pos)); } const Block &BlockAt(const Pos &pos) const { return BlockAt(ToIndex(pos)); } - const Block *FindNext(const Pos &pos, Block::Face face) const; - const Block *FindNext(const Block::Pos &pos, Block::Face face) const { return FindNext(Pos(pos), face); } - const Block *FindNext(int index, Block::Face face) const { return FindNext(ToPos(index), face); } - const BlockType &Type(const Block &b) const { return *types->Get(b.type); } void SetLight(int index, int level); -- 2.39.2 From 15ff5ed48855c6bd09bc8f5152f46065484c1e94 Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Tue, 26 May 2015 18:44:24 +0200 Subject: [PATCH 11/16] don't push block normals to GPU --- src/block.cpp | 4 ++-- src/chunk.cpp | 8 ++++++-- src/chunk.hpp | 2 +- src/model.cpp | 17 ----------------- src/model.hpp | 6 ------ src/shader.cpp | 15 +++++---------- src/shader.hpp | 2 +- src/shape.cpp | 26 ++++++++++++++++++++------ src/shape.hpp | 19 +++++++++++++++---- 9 files changed, 50 insertions(+), 49 deletions(-) diff --git a/src/block.cpp b/src/block.cpp index 6e6ac18..dea5267 100644 --- a/src/block.cpp +++ b/src/block.cpp @@ -61,7 +61,7 @@ BlockType::BlockType(bool v, const glm::vec3 &col, const Shape *s) namespace { const Block::Face face_map[Block::FACE_COUNT * Block::TURN_COUNT][Block::FACE_COUNT] = { - { Block::FACE_UP, Block::FACE_DOWN, Block::FACE_RIGHT, Block::FACE_LEFT, Block::FACE_FRONT, Block::FACE_BACK, }, // face: up, turn: none x + { Block::FACE_UP, Block::FACE_DOWN, Block::FACE_RIGHT, Block::FACE_LEFT, Block::FACE_FRONT, Block::FACE_BACK, }, // face: up, turn: none { Block::FACE_UP, Block::FACE_DOWN, Block::FACE_FRONT, Block::FACE_BACK, Block::FACE_LEFT, Block::FACE_RIGHT, }, // face: up, turn: left { Block::FACE_UP, Block::FACE_DOWN, Block::FACE_LEFT, Block::FACE_RIGHT, Block::FACE_BACK, Block::FACE_FRONT, }, // face: up, turn: around { Block::FACE_UP, Block::FACE_DOWN, Block::FACE_BACK, Block::FACE_FRONT, Block::FACE_RIGHT, Block::FACE_LEFT, }, // face: up, turn: right @@ -107,7 +107,7 @@ void BlockType::FillBlockModel( const glm::mat4 &transform, BlockModel::Index idx_offset ) const { - shape->Vertices(buf.vertices, buf.normals, buf.indices, transform, idx_offset); + shape->Vertices(buf.vertices, buf.indices, transform, idx_offset); buf.colors.insert(buf.colors.end(), shape->VertexCount(), color); } diff --git a/src/chunk.cpp b/src/chunk.cpp index 2a764f3..74ca1bc 100644 --- a/src/chunk.cpp +++ b/src/chunk.cpp @@ -322,7 +322,7 @@ int Chunk::GetLight(int index) const { return light[index]; } -float Chunk::GetVertexLight(int index, const BlockModel::Position &vtx, const BlockModel::Normal &norm) const { +float Chunk::GetVertexLight(int index, const BlockModel::Position &vtx, const Model::Normal &norm) const { float light = GetLight(index); Chunk::Pos pos(ToPos(index)); @@ -452,7 +452,11 @@ void Chunk::Update() { vtx_counter += type.shape->VertexCount(); for (size_t vtx = vtx_begin; vtx < vtx_counter; ++vtx) { - buf.lights.emplace_back(GetVertexLight(i, buf.vertices[vtx], buf.normals[vtx])); + buf.lights.emplace_back(GetVertexLight( + i, + buf.vertices[vtx], + type.shape->VertexNormal(vtx - vtx_begin, blocks[i].Transform()) + )); } } diff --git a/src/chunk.hpp b/src/chunk.hpp index 4f6732d..4addb56 100644 --- a/src/chunk.hpp +++ b/src/chunk.hpp @@ -111,7 +111,7 @@ public: int GetLight(const Pos &pos) const { return GetLight(ToIndex(pos)); } int GetLight(const Block::Pos &pos) const { return GetLight(ToIndex(pos)); } - float GetVertexLight(int index, const BlockModel::Position &, const BlockModel::Normal &) const; + float GetVertexLight(int index, const BlockModel::Position &, const Model::Normal &) const; bool Intersection( const Ray &ray, diff --git a/src/model.cpp b/src/model.cpp index 125d57a..62a90e5 100644 --- a/src/model.cpp +++ b/src/model.cpp @@ -166,23 +166,6 @@ void BlockModel::Update(const Buffer &buf) { nullptr // offset ); -#ifndef NDEBUG - if (buf.normals.size() < buf.vertices.size()) { - std::cerr << "BlockModel: not enough normals!" << std::endl; - } -#endif - glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_NORMAL]); - glBufferData(GL_ARRAY_BUFFER, buf.normals.size() * sizeof(glm::vec3), buf.normals.data(), GL_STATIC_DRAW); - glEnableVertexAttribArray(ATTRIB_NORMAL); - glVertexAttribPointer( - ATTRIB_NORMAL, // location (for shader) - 3, // size - GL_FLOAT, // type - GL_FALSE, // normalized - 0, // stride - nullptr // offset - ); - #ifndef NDEBUG if (buf.lights.size() < buf.vertices.size()) { std::cerr << "BlockModel: not enough lights!" << std::endl; diff --git a/src/model.hpp b/src/model.hpp index 7b9fc3d..557b4ac 100644 --- a/src/model.hpp +++ b/src/model.hpp @@ -80,13 +80,11 @@ class BlockModel { public: using Position = glm::vec3; using Color = glm::vec3; - using Normal = glm::vec3; using Light = float; using Index = unsigned int; using Positions = std::vector; using Colors = std::vector; - using Normals = std::vector; using Lights = std::vector; using Indices = std::vector; @@ -95,14 +93,12 @@ public: Positions vertices; Colors colors; - Normals normals; Lights lights; Indices indices; void Clear() { vertices.clear(); colors.clear(); - normals.clear(); lights.clear(); indices.clear(); } @@ -110,7 +106,6 @@ public: void Reserve(size_t p, size_t i) { vertices.reserve(p); colors.reserve(p); - normals.reserve(p); lights.reserve(p); indices.reserve(i); } @@ -135,7 +130,6 @@ private: enum Attribute { ATTRIB_VERTEX, ATTRIB_COLOR, - ATTRIB_NORMAL, ATTRIB_LIGHT, ATTRIB_INDEX, ATTRIB_COUNT, diff --git a/src/shader.cpp b/src/shader.cpp index 134f710..01f7861 100644 --- a/src/shader.cpp +++ b/src/shader.cpp @@ -132,6 +132,10 @@ void Program::Log(std::ostream &out) const { } +GLint Program::AttributeLocation(const GLchar *name) const { + return glGetAttribLocation(handle, name); +} + GLint Program::UniformLocation(const GLchar *name) const { return glGetUniformLocation(handle, name); } @@ -257,7 +261,6 @@ void DirectionalLighting::SetMVP(const glm::mat4 &m, const glm::mat4 &v, const g BlockLighting::BlockLighting() : program() , vp(1.0f) -, m_handle(0) , mv_handle(0) , mvp_handle(0) , fog_density_handle(0) { @@ -266,20 +269,16 @@ BlockLighting::BlockLighting() "#version 330 core\n" "layout(location = 0) in vec3 vtx_position;\n" "layout(location = 1) in vec3 vtx_color;\n" - "layout(location = 2) in vec3 vtx_normal;\n" - "layout(location = 3) in float vtx_light;\n" - "uniform mat4 M;\n" + "layout(location = 2) in float vtx_light;\n" "uniform mat4 MV;\n" "uniform mat4 MVP;\n" "out vec3 frag_color;\n" "out vec3 vtx_viewspace;\n" - "out vec3 normal;\n" "out float frag_light;\n" "void main() {\n" "gl_Position = MVP * vec4(vtx_position, 1);\n" "frag_color = vtx_color;\n" "vtx_viewspace = (MV * vec4(vtx_position, 1)).xyz;\n" - "normal = (M * vec4(vtx_normal, 0)).xyz;\n" "frag_light = vtx_light;\n" "}\n" ); @@ -294,8 +293,6 @@ BlockLighting::BlockLighting() "void main() {\n" "vec3 ambient = vec3(0.1, 0.1, 0.1) * frag_color;\n" "float light_power = clamp(pow(0.8, 15 - frag_light), 0, 1);\n" - //"float light_power = clamp(frag_light / 15, 0, 1);\n" - // this should be the same as the clear color, otherwise looks really weird "vec3 fog_color = vec3(0, 0, 0);\n" "float e = 2.718281828;\n" //"vec3 reflect_color = ambient + frag_color * light_power;\n" @@ -310,7 +307,6 @@ BlockLighting::BlockLighting() throw std::runtime_error("link program"); } - m_handle = program.UniformLocation("M"); mv_handle = program.UniformLocation("MV"); mvp_handle = program.UniformLocation("MVP"); fog_density_handle = program.UniformLocation("fog_density"); @@ -326,7 +322,6 @@ void BlockLighting::Activate() { void BlockLighting::SetM(const glm::mat4 &m) { glm::mat4 mv(view * m); glm::mat4 mvp(vp * m); - glUniformMatrix4fv(m_handle, 1, GL_FALSE, &m[0][0]); glUniformMatrix4fv(mv_handle, 1, GL_FALSE, &mv[0][0]); glUniformMatrix4fv(mvp_handle, 1, GL_FALSE, &mvp[0][0]); } diff --git a/src/shader.hpp b/src/shader.hpp index 873460b..bb9ad84 100644 --- a/src/shader.hpp +++ b/src/shader.hpp @@ -49,6 +49,7 @@ public: bool Linked() const; void Log(std::ostream &) const; + GLint AttributeLocation(const GLchar *name) const; GLint UniformLocation(const GLchar *name) const; void Use() const { glUseProgram(handle); } @@ -130,7 +131,6 @@ private: glm::mat4 view; glm::mat4 vp; - GLuint m_handle; GLuint mv_handle; GLuint mvp_handle; GLuint light_direction_handle; diff --git a/src/shape.cpp b/src/shape.cpp index 8111258..545a8e4 100644 --- a/src/shape.cpp +++ b/src/shape.cpp @@ -6,16 +6,16 @@ namespace blank { void Shape::Vertices( Model::Positions &vertex, Model::Normals &normal, - Model::Indices &index, - const Model::Position &elem_offset, - Model::Index idx_offset + Model::Indices &index ) const { for (const auto &pos : vtx_pos) { - vertex.emplace_back(elem_offset + pos); + vertex.emplace_back(pos); + } + for (const auto &nrm : vtx_nrm) { + normal.emplace_back(nrm); } - normal.insert(normal.end(), vtx_nrm.begin(), vtx_nrm.end()); for (auto idx : vtx_idx) { - index.emplace_back(idx_offset + idx); + index.emplace_back(idx); } } @@ -37,6 +37,20 @@ void Shape::Vertices( } } +void Shape::Vertices( + BlockModel::Positions &vertex, + BlockModel::Indices &index, + const glm::mat4 &transform, + BlockModel::Index idx_offset +) const { + for (const auto &pos : vtx_pos) { + vertex.emplace_back(transform * glm::vec4(pos, 1.0f)); + } + for (auto idx : vtx_idx) { + index.emplace_back(idx_offset + idx); + } +} + void Shape::Outline( OutlineModel::Positions &vertex, OutlineModel::Indices &index, diff --git a/src/shape.hpp b/src/shape.hpp index f31075b..abf8795 100644 --- a/src/shape.hpp +++ b/src/shape.hpp @@ -17,14 +17,19 @@ struct Shape { /// the number of vertex indices this shape has size_t VertexIndexCount() const { return vtx_idx.size(); } + const Model::Normal &VertexNormal(size_t idx) const { return vtx_nrm[idx]; } + Model::Normal VertexNormal( + size_t idx, const glm::mat4 &transform + ) const { + return Model::Normal(transform * glm::vec4(vtx_nrm[idx], 0.0f)); + } + /// fill given buffers with this shape's elements with an - /// optional offset + /// optional transform and offset void Vertices( Model::Positions &vertex, Model::Normals &normal, - Model::Indices &index, - const Model::Position &elem_offset = { 0.0f, 0.0f, 0.0f }, - Model::Index idx_offset = 0 + Model::Indices &index ) const; void Vertices( Model::Positions &vertex, @@ -33,6 +38,12 @@ struct Shape { const glm::mat4 &transform, Model::Index idx_offset = 0 ) const; + void Vertices( + BlockModel::Positions &vertex, + BlockModel::Indices &index, + const glm::mat4 &transform, + BlockModel::Index idx_offset = 0 + ) const; /// the number of vertices this shape's outline has size_t OutlineCount() const { return out_pos.size(); } -- 2.39.2 From d01ca2cb76681d7795bb4b483d7033b86410725a Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Wed, 27 May 2015 16:28:43 +0200 Subject: [PATCH 12/16] remove unneccessary buffer binds before draw calls --- src/model.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/model.cpp b/src/model.cpp index 62a90e5..1d4edef 100644 --- a/src/model.cpp +++ b/src/model.cpp @@ -93,7 +93,6 @@ void Model::Update(const Buffer &buf) { void Model::Draw() const { glBindVertexArray(va); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, handle[ATTRIB_INDEX]); glDrawElements( GL_TRIANGLES, // how count, // count @@ -191,7 +190,6 @@ void BlockModel::Update(const Buffer &buf) { void BlockModel::Draw() const { glBindVertexArray(va); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, handle[ATTRIB_INDEX]); glDrawElements( GL_TRIANGLES, // how count, // count @@ -279,7 +277,6 @@ void OutlineModel::Draw() { glEnable(GL_LINE_SMOOTH); glLineWidth(2.0f); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, handle[ATTRIB_INDEX]); glDrawElements( GL_LINES, // how indices.size(), // count -- 2.39.2 From 4ef32c5a4a5bdb6da8383f66d8265715eb2ed4f9 Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Wed, 27 May 2015 17:22:27 +0200 Subject: [PATCH 13/16] fix dec/rad error in camera FOV --- src/camera.cpp | 4 +++- src/camera.hpp | 1 + src/geometry.hpp | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/camera.cpp b/src/camera.cpp index eeb4dce..7bf15bf 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -1,5 +1,7 @@ #include "camera.hpp" +#include "geometry.hpp" + #include #include @@ -7,7 +9,7 @@ namespace blank { Camera::Camera() -: fov(45.0f) +: fov(PI_0p25) , aspect(1.0f) , near_clip(0.1f) , far_clip(256.0f) diff --git a/src/camera.hpp b/src/camera.hpp index 22e2ba5..1477a47 100644 --- a/src/camera.hpp +++ b/src/camera.hpp @@ -14,6 +14,7 @@ public: void Viewport(int width, int height); void Viewport(int x, int y, int width, int height); + /// FOV in radians void FOV(float f); void Aspect(float r); void Aspect(float w, float h); diff --git a/src/geometry.hpp b/src/geometry.hpp index 16651d8..78fe5f5 100644 --- a/src/geometry.hpp +++ b/src/geometry.hpp @@ -8,6 +8,7 @@ namespace blank { constexpr float PI = 3.141592653589793238462643383279502884; +constexpr float PI_0p25 = PI * 0.25f; constexpr float PI_0p5 = PI * 0.5f; constexpr float PI_1p5 = PI * 1.5f; constexpr float PI_2p0 = PI * 2.0f; -- 2.39.2 From 35c09fc00094a3d390732fd533b2bd03413d90c7 Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Wed, 27 May 2015 18:50:52 +0200 Subject: [PATCH 14/16] added ability to get seperate information about block face obstruction --- src/block.hpp | 37 +++++++++++++++++++++++++++++++++++++ src/chunk.cpp | 11 ++++++----- src/chunk.hpp | 4 ++-- 3 files changed, 45 insertions(+), 7 deletions(-) diff --git a/src/block.hpp b/src/block.hpp index 4fcee4c..3af80a8 100644 --- a/src/block.hpp +++ b/src/block.hpp @@ -87,6 +87,43 @@ struct Block { } } + struct FaceSet { + + explicit FaceSet(unsigned char v = 0) + : value(v) { } + + bool IsSet(Face f) const { + return value & Mask(f); + } + void Set(Face f) { + value |= Mask(f); + } + void Unset(Face f) { + value |= ~Mask(f); + } + + void Clear() { + value = 0; + } + void Fill() { + value = Mask(FACE_COUNT) - 1; + } + + bool Empty() const { + return value == 0; + } + bool All() const { + return value == Mask(FACE_COUNT) - 1; + } + + unsigned char Mask(Face f) const { + return 1 << f; + } + + unsigned char value; + + }; + }; diff --git a/src/chunk.cpp b/src/chunk.cpp index 74ca1bc..23d5a13 100644 --- a/src/chunk.cpp +++ b/src/chunk.cpp @@ -445,7 +445,7 @@ void Chunk::Update() { for (size_t i = 0; i < Size(); ++i) { const BlockType &type = Type(blocks[i]); - if (!type.visible || Obstructed(i)) continue; + if (!type.visible || Obstructed(i).All()) continue; type.FillBlockModel(buf, ToTransform(i), vtx_counter); size_t vtx_begin = vtx_counter; @@ -464,18 +464,19 @@ void Chunk::Update() { dirty = false; } -bool Chunk::Obstructed(int idx) const { +Block::FaceSet Chunk::Obstructed(int idx) const { Chunk::Pos pos(ToPos(idx)); + Block::FaceSet result; for (int f = 0; f < Block::FACE_COUNT; ++f) { Block::Face face = Block::Face(f); BlockLookup next(const_cast(this), pos, face); - if (!next || !next.GetType().FaceFilled(next.GetBlock(), Block::Opposite(face))) { - return false; + if (next && next.GetType().FaceFilled(next.GetBlock(), Block::Opposite(face))) { + result.Set(face); } } - return true; + return result; } glm::mat4 Chunk::ToTransform(int idx) const { diff --git a/src/chunk.hpp b/src/chunk.hpp index 4addb56..06dc98b 100644 --- a/src/chunk.hpp +++ b/src/chunk.hpp @@ -88,8 +88,8 @@ public: void Unlink(); void Relink(); - // check if block at given index is completely enclosed (and therefore invisible) - bool Obstructed(int idx) const; + // check which faces of a block at given index are obstructed (and therefore invisible) + Block::FaceSet Obstructed(int idx) const; void Invalidate() { dirty = true; } -- 2.39.2 From 6e59f3102d6d64355d5a30b708a326327b089aaf Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Fri, 29 May 2015 13:04:38 +0200 Subject: [PATCH 15/16] reorganized block tables --- src/block.cpp | 135 ++++++++++++++++++++++++-------------------------- src/block.hpp | 32 ++++++------ 2 files changed, 78 insertions(+), 89 deletions(-) diff --git a/src/block.cpp b/src/block.cpp index dea5267..b63b82f 100644 --- a/src/block.cpp +++ b/src/block.cpp @@ -8,42 +8,6 @@ namespace blank { -namespace { - -const glm::mat4 block_transforms[Block::FACE_COUNT * Block::TURN_COUNT] = { - { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, }, // face: up, turn: none - { 0, 0, -1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, }, // face: up, turn: left - { -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, }, // face: up, turn: around - { 0, 0, 1, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 1, }, // face: up, turn: right - { 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, }, // face: down, turn: none - { 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 1, }, // face: down, turn: left - { -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, }, // face: down, turn: around - { 0, 0, 1, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, }, // face: down, turn: right - { 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, }, // face: right, turn: none - { 0, -1, 0, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, 0, 1, }, // face: right, turn: left - { 0, -1, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, }, // face: right, turn: around - { 0, -1, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0, 0, 0, 1, }, // face: right, turn: right - { 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, }, // face: left, turn: none - { 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, }, // face: left, turn: left - { 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, }, // face: left, turn: around - { 0, 1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, 0, 0, 1, }, // face: left, turn: right - { 1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, }, // face: front, turn: none - { 0, 0, -1, 0, 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 1, }, // face: front, turn: left - { -1, 0, 0, 0, 0, 0, -1, 0, 0, -1, 0, 0, 0, 0, 0, 1, }, // face: front, turn: around - { 0, 0, 1, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 1, }, // face: front, turn: right - { 1, 0, 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, }, // face: back, turn: none - { 0, 0, -1, 0, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, }, // face: back, turn: left - { -1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, }, // face: back, turn: around - { 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, }, // face: back, turn: right -}; - -} - -const glm::mat4 &Block::Transform() const { - return block_transforms[orient]; -} - - const NullShape BlockType::DEFAULT_SHAPE; BlockType::BlockType(bool v, const glm::vec3 &col, const Shape *s) @@ -58,41 +22,6 @@ BlockType::BlockType(bool v, const glm::vec3 &col, const Shape *s) } -namespace { - -const Block::Face face_map[Block::FACE_COUNT * Block::TURN_COUNT][Block::FACE_COUNT] = { - { Block::FACE_UP, Block::FACE_DOWN, Block::FACE_RIGHT, Block::FACE_LEFT, Block::FACE_FRONT, Block::FACE_BACK, }, // face: up, turn: none - { Block::FACE_UP, Block::FACE_DOWN, Block::FACE_FRONT, Block::FACE_BACK, Block::FACE_LEFT, Block::FACE_RIGHT, }, // face: up, turn: left - { Block::FACE_UP, Block::FACE_DOWN, Block::FACE_LEFT, Block::FACE_RIGHT, Block::FACE_BACK, Block::FACE_FRONT, }, // face: up, turn: around - { Block::FACE_UP, Block::FACE_DOWN, Block::FACE_BACK, Block::FACE_FRONT, Block::FACE_RIGHT, Block::FACE_LEFT, }, // face: up, turn: right - { Block::FACE_DOWN, Block::FACE_UP, Block::FACE_RIGHT, Block::FACE_LEFT, Block::FACE_BACK, Block::FACE_FRONT, }, // face: down, turn: none - { Block::FACE_DOWN, Block::FACE_UP, Block::FACE_BACK, Block::FACE_FRONT, Block::FACE_LEFT, Block::FACE_RIGHT, }, // face: down, turn: left - { Block::FACE_DOWN, Block::FACE_UP, Block::FACE_LEFT, Block::FACE_RIGHT, Block::FACE_FRONT, Block::FACE_BACK, }, // face: down, turn: around - { Block::FACE_DOWN, Block::FACE_UP, Block::FACE_FRONT, Block::FACE_BACK, Block::FACE_RIGHT, Block::FACE_LEFT, }, // face: down, turn: right - { Block::FACE_LEFT, Block::FACE_RIGHT, Block::FACE_UP, Block::FACE_DOWN, Block::FACE_FRONT, Block::FACE_BACK, }, // face: right, turn: none - { Block::FACE_LEFT, Block::FACE_RIGHT, Block::FACE_FRONT, Block::FACE_BACK, Block::FACE_DOWN, Block::FACE_UP, }, // face: right, turn: left - { Block::FACE_LEFT, Block::FACE_RIGHT, Block::FACE_DOWN, Block::FACE_UP, Block::FACE_BACK, Block::FACE_FRONT, }, // face: right, turn: around - { Block::FACE_LEFT, Block::FACE_RIGHT, Block::FACE_BACK, Block::FACE_FRONT, Block::FACE_UP, Block::FACE_DOWN, }, // face: right, turn: right - { Block::FACE_RIGHT, Block::FACE_LEFT, Block::FACE_DOWN, Block::FACE_UP, Block::FACE_FRONT, Block::FACE_BACK, }, // face: left, turn: none - { Block::FACE_RIGHT, Block::FACE_LEFT, Block::FACE_FRONT, Block::FACE_BACK, Block::FACE_UP, Block::FACE_DOWN, }, // face: left, turn: left - { Block::FACE_RIGHT, Block::FACE_LEFT, Block::FACE_UP, Block::FACE_DOWN, Block::FACE_BACK, Block::FACE_FRONT, }, // face: left, turn: around - { Block::FACE_RIGHT, Block::FACE_LEFT, Block::FACE_BACK, Block::FACE_FRONT, Block::FACE_DOWN, Block::FACE_UP, }, // face: left, turn: right - { Block::FACE_BACK, Block::FACE_FRONT, Block::FACE_RIGHT, Block::FACE_LEFT, Block::FACE_UP, Block::FACE_DOWN, }, // face: front, turn: none - { Block::FACE_BACK, Block::FACE_FRONT, Block::FACE_UP, Block::FACE_DOWN, Block::FACE_LEFT, Block::FACE_RIGHT, }, // face: front, turn: left - { Block::FACE_BACK, Block::FACE_FRONT, Block::FACE_LEFT, Block::FACE_RIGHT, Block::FACE_DOWN, Block::FACE_UP, }, // face: front, turn: around - { Block::FACE_BACK, Block::FACE_FRONT, Block::FACE_DOWN, Block::FACE_UP, Block::FACE_RIGHT, Block::FACE_LEFT, }, // face: front, turn: right - { Block::FACE_FRONT, Block::FACE_BACK, Block::FACE_RIGHT, Block::FACE_LEFT, Block::FACE_DOWN, Block::FACE_UP, }, // face: back, turn: none - { Block::FACE_FRONT, Block::FACE_BACK, Block::FACE_DOWN, Block::FACE_UP, Block::FACE_LEFT, Block::FACE_RIGHT, }, // face: back, turn: left - { Block::FACE_FRONT, Block::FACE_BACK, Block::FACE_LEFT, Block::FACE_RIGHT, Block::FACE_UP, Block::FACE_DOWN, }, // face: back, turn: around - { Block::FACE_FRONT, Block::FACE_BACK, Block::FACE_UP, Block::FACE_DOWN, Block::FACE_RIGHT, Block::FACE_LEFT, }, // face: back, turn: right -}; - -} - -bool BlockType::FaceFilled(const Block &block, Block::Face face) const { - return fill[face_map[block.orient][face]]; -} - void BlockType::FillModel( Model::Buffer &buf, const glm::mat4 &transform, @@ -132,4 +61,68 @@ Block::Type BlockTypeRegistry::Add(const BlockType &t) { return id; } + +const glm::mat4 Block::orient2transform[ORIENT_COUNT] = { + { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, }, // face: up, turn: none + { 0, 0, -1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, }, // face: up, turn: left + { -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, }, // face: up, turn: around + { 0, 0, 1, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 1, }, // face: up, turn: right + { 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, }, // face: down, turn: none + { 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 1, }, // face: down, turn: left + { -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, }, // face: down, turn: around + { 0, 0, 1, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, }, // face: down, turn: right + { 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, }, // face: right, turn: none + { 0, -1, 0, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, 0, 1, }, // face: right, turn: left + { 0, -1, 0, 0, -1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, }, // face: right, turn: around + { 0, -1, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0, 0, 0, 1, }, // face: right, turn: right + { 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, }, // face: left, turn: none + { 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, }, // face: left, turn: left + { 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, }, // face: left, turn: around + { 0, 1, 0, 0, 0, 0, -1, 0, -1, 0, 0, 0, 0, 0, 0, 1, }, // face: left, turn: right + { 1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, }, // face: front, turn: none + { 0, 0, -1, 0, 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 1, }, // face: front, turn: left + { -1, 0, 0, 0, 0, 0, -1, 0, 0, -1, 0, 0, 0, 0, 0, 1, }, // face: front, turn: around + { 0, 0, 1, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 1, }, // face: front, turn: right + { 1, 0, 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1, }, // face: back, turn: none + { 0, 0, -1, 0, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, }, // face: back, turn: left + { -1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, }, // face: back, turn: around + { 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, }, // face: back, turn: right +}; + +const glm::tvec3 Block::face2normal[FACE_COUNT] = { + { 0, 1, 0 }, + { 0, -1, 0 }, + { 1, 0, 0 }, + { -1, 0, 0 }, + { 0, 0, 1 }, + { 0, 0, -1 }, +}; + +const Block::Face Block::orient2face[ORIENT_COUNT][FACE_COUNT] = { + { FACE_UP, FACE_DOWN, FACE_RIGHT, FACE_LEFT, FACE_FRONT, FACE_BACK, }, // face: up, turn: none + { FACE_UP, FACE_DOWN, FACE_FRONT, FACE_BACK, FACE_LEFT, FACE_RIGHT, }, // face: up, turn: left + { FACE_UP, FACE_DOWN, FACE_LEFT, FACE_RIGHT, FACE_BACK, FACE_FRONT, }, // face: up, turn: around + { FACE_UP, FACE_DOWN, FACE_BACK, FACE_FRONT, FACE_RIGHT, FACE_LEFT, }, // face: up, turn: right + { FACE_DOWN, FACE_UP, FACE_RIGHT, FACE_LEFT, FACE_BACK, FACE_FRONT, }, // face: down, turn: none + { FACE_DOWN, FACE_UP, FACE_BACK, FACE_FRONT, FACE_LEFT, FACE_RIGHT, }, // face: down, turn: left + { FACE_DOWN, FACE_UP, FACE_LEFT, FACE_RIGHT, FACE_FRONT, FACE_BACK, }, // face: down, turn: around + { FACE_DOWN, FACE_UP, FACE_FRONT, FACE_BACK, FACE_RIGHT, FACE_LEFT, }, // face: down, turn: right + { FACE_LEFT, FACE_RIGHT, FACE_UP, FACE_DOWN, FACE_FRONT, FACE_BACK, }, // face: right, turn: none + { FACE_LEFT, FACE_RIGHT, FACE_FRONT, FACE_BACK, FACE_DOWN, FACE_UP, }, // face: right, turn: left + { FACE_LEFT, FACE_RIGHT, FACE_DOWN, FACE_UP, FACE_BACK, FACE_FRONT, }, // face: right, turn: around + { FACE_LEFT, FACE_RIGHT, FACE_BACK, FACE_FRONT, FACE_UP, FACE_DOWN, }, // face: right, turn: right + { FACE_RIGHT, FACE_LEFT, FACE_DOWN, FACE_UP, FACE_FRONT, FACE_BACK, }, // face: left, turn: none + { FACE_RIGHT, FACE_LEFT, FACE_FRONT, FACE_BACK, FACE_UP, FACE_DOWN, }, // face: left, turn: left + { FACE_RIGHT, FACE_LEFT, FACE_UP, FACE_DOWN, FACE_BACK, FACE_FRONT, }, // face: left, turn: around + { FACE_RIGHT, FACE_LEFT, FACE_BACK, FACE_FRONT, FACE_DOWN, FACE_UP, }, // face: left, turn: right + { FACE_BACK, FACE_FRONT, FACE_RIGHT, FACE_LEFT, FACE_UP, FACE_DOWN, }, // face: front, turn: none + { FACE_BACK, FACE_FRONT, FACE_UP, FACE_DOWN, FACE_LEFT, FACE_RIGHT, }, // face: front, turn: left + { FACE_BACK, FACE_FRONT, FACE_LEFT, FACE_RIGHT, FACE_DOWN, FACE_UP, }, // face: front, turn: around + { FACE_BACK, FACE_FRONT, FACE_DOWN, FACE_UP, FACE_RIGHT, FACE_LEFT, }, // face: front, turn: right + { FACE_FRONT, FACE_BACK, FACE_RIGHT, FACE_LEFT, FACE_DOWN, FACE_UP, }, // face: back, turn: none + { FACE_FRONT, FACE_BACK, FACE_DOWN, FACE_UP, FACE_LEFT, FACE_RIGHT, }, // face: back, turn: left + { FACE_FRONT, FACE_BACK, FACE_LEFT, FACE_RIGHT, FACE_UP, FACE_DOWN, }, // face: back, turn: around + { FACE_FRONT, FACE_BACK, FACE_UP, FACE_DOWN, FACE_RIGHT, FACE_LEFT, }, // face: back, turn: right +}; + } diff --git a/src/block.hpp b/src/block.hpp index 3af80a8..ab34a30 100644 --- a/src/block.hpp +++ b/src/block.hpp @@ -34,40 +34,29 @@ struct Block { TURN_COUNT, }; + static constexpr int ORIENT_COUNT = FACE_COUNT * TURN_COUNT; + Type type; unsigned char orient; constexpr explicit Block(Type type = 0, Face face = FACE_UP, Turn turn = TURN_NONE) : type(type), orient(face * TURN_COUNT + turn) { } - const glm::mat4 &Transform() const; + const glm::mat4 &Transform() const { return orient2transform[orient]; } Face GetFace() const { return Face(orient / TURN_COUNT); } void SetFace(Face face) { orient = face * TURN_COUNT + GetTurn(); } Turn GetTurn() const { return Turn(orient % TURN_COUNT); } void SetTurn(Turn turn) { orient = GetFace() * TURN_COUNT + turn; } + Face OrientedFace(Face f) const { return orient2face[orient][f]; } + static Face Opposite(Face f) { return Face(f ^ 1); } static glm::tvec3 FaceNormal(Face face) { - switch (face) { - case FACE_UP: - return { 0, 1, 0 }; - case FACE_DOWN: - return { 0, -1, 0 }; - case FACE_RIGHT: - return { 1, 0, 0 }; - case FACE_LEFT: - return { -1, 0, 0 }; - case FACE_FRONT: - return { 0, 0, 1 }; - case FACE_BACK: - return { 0, 0, -1 }; - default: - return { 0, 0, 0 }; - } + return face2normal[face]; } static Face NormalFace(const glm::vec3 &norm) { @@ -124,6 +113,11 @@ struct Block { }; +private: + static const glm::tvec3 face2normal[6]; + static const glm::mat4 orient2transform[ORIENT_COUNT]; + static const Face orient2face[ORIENT_COUNT][FACE_COUNT]; + }; @@ -162,7 +156,9 @@ struct BlockType { static const NullShape DEFAULT_SHAPE; - bool FaceFilled(const Block &, Block::Face) const; + bool FaceFilled(const Block &block, Block::Face face) const { + return fill[block.OrientedFace(face)]; + } void FillModel( Model::Buffer &m, -- 2.39.2 From 76b3ec0f6aa0dacf6d4944a2787991f3585299e8 Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Fri, 29 May 2015 15:16:46 +0200 Subject: [PATCH 16/16] noexcept all the things --- src/app.cpp | 2 +- src/block.cpp | 8 +-- src/block.hpp | 40 +++++++-------- src/camera.cpp | 16 +++--- src/camera.hpp | 18 +++---- src/chunk.cpp | 81 +++++++++++++---------------- src/chunk.hpp | 125 +++++++++++++++++++++++---------------------- src/controller.cpp | 16 +++--- src/controller.hpp | 26 +++++----- src/entity.cpp | 24 ++++----- src/entity.hpp | 38 +++++++------- src/generator.cpp | 4 +- src/generator.hpp | 8 +-- src/geometry.cpp | 4 +- src/geometry.hpp | 6 +-- src/glmio.hpp | 27 ---------- src/hud.cpp | 8 +-- src/hud.hpp | 6 +-- src/init.cpp | 8 +-- src/init.hpp | 8 +-- src/interface.cpp | 6 +-- src/interface.hpp | 6 +-- src/model.cpp | 36 ++++++------- src/model.hpp | 40 +++++++-------- src/noise.cpp | 16 +++--- src/noise.hpp | 18 +++---- src/runtime.cpp | 2 +- src/runtime.hpp | 2 +- src/shader.cpp | 52 +++++++++---------- src/shader.hpp | 66 ++++++++++++------------ src/shape.cpp | 6 +-- src/shape.hpp | 16 +++--- 32 files changed, 353 insertions(+), 386 deletions(-) delete mode 100644 src/glmio.hpp diff --git a/src/app.cpp b/src/app.cpp index 6a87042..21f5bcf 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -30,7 +30,7 @@ Application::Application(const Config &config) Entity &Application::MakeTestEntity(World &world) { Entity &e = world.AddEntity(); e.Position({ 0.0f, 0.0f, 0.0f }); - e.SetShape(world.BlockTypes()[1]->shape, { 1.0f, 1.0f, 0.0f }); + e.SetShape(world.BlockTypes()[1].shape, { 1.0f, 1.0f, 0.0f }); e.AngularVelocity(glm::quat(glm::vec3{ 0.00001f, 0.000006f, 0.000013f })); return e; } diff --git a/src/block.cpp b/src/block.cpp index b63b82f..ab090da 100644 --- a/src/block.cpp +++ b/src/block.cpp @@ -10,7 +10,7 @@ namespace blank { const NullShape BlockType::DEFAULT_SHAPE; -BlockType::BlockType(bool v, const glm::vec3 &col, const Shape *s) +BlockType::BlockType(bool v, const glm::vec3 &col, const Shape *s) noexcept : shape(s) , color(col) , outline_color(-1, -1, -1) @@ -26,7 +26,7 @@ void BlockType::FillModel( Model::Buffer &buf, const glm::mat4 &transform, Model::Index idx_offset -) const { +) const noexcept { shape->Vertices(buf.vertices, buf.normals, buf.indices, transform, idx_offset); buf.colors.insert(buf.colors.end(), shape->VertexCount(), color); } @@ -35,7 +35,7 @@ void BlockType::FillBlockModel( BlockModel::Buffer &buf, const glm::mat4 &transform, BlockModel::Index idx_offset -) const { +) const noexcept { shape->Vertices(buf.vertices, buf.indices, transform, idx_offset); buf.colors.insert(buf.colors.end(), shape->VertexCount(), color); } @@ -44,7 +44,7 @@ void BlockType::FillOutlineModel( OutlineModel &model, const glm::vec3 &pos_offset, OutlineModel::Index idx_offset -) const { +) const noexcept { shape->Outline(model.vertices, model.indices, pos_offset, idx_offset); model.colors.insert(model.colors.end(), shape->OutlineCount(), outline_color); } diff --git a/src/block.hpp b/src/block.hpp index ab34a30..2c26ed7 100644 --- a/src/block.hpp +++ b/src/block.hpp @@ -39,27 +39,27 @@ struct Block { Type type; unsigned char orient; - constexpr explicit Block(Type type = 0, Face face = FACE_UP, Turn turn = TURN_NONE) + constexpr explicit Block(Type type = 0, Face face = FACE_UP, Turn turn = TURN_NONE) noexcept : type(type), orient(face * TURN_COUNT + turn) { } - const glm::mat4 &Transform() const { return orient2transform[orient]; } + const glm::mat4 &Transform() const noexcept { return orient2transform[orient]; } - Face GetFace() const { return Face(orient / TURN_COUNT); } - void SetFace(Face face) { orient = face * TURN_COUNT + GetTurn(); } - Turn GetTurn() const { return Turn(orient % TURN_COUNT); } - void SetTurn(Turn turn) { orient = GetFace() * TURN_COUNT + turn; } + Face GetFace() const noexcept { return Face(orient / TURN_COUNT); } + void SetFace(Face face) noexcept { orient = face * TURN_COUNT + GetTurn(); } + Turn GetTurn() const noexcept { return Turn(orient % TURN_COUNT); } + void SetTurn(Turn turn) noexcept { orient = GetFace() * TURN_COUNT + turn; } - Face OrientedFace(Face f) const { return orient2face[orient][f]; } + Face OrientedFace(Face f) const noexcept { return orient2face[orient][f]; } - static Face Opposite(Face f) { + static Face Opposite(Face f) noexcept { return Face(f ^ 1); } - static glm::tvec3 FaceNormal(Face face) { + static glm::tvec3 FaceNormal(Face face) noexcept { return face2normal[face]; } - static Face NormalFace(const glm::vec3 &norm) { + static Face NormalFace(const glm::vec3 &norm) noexcept { const glm::vec3 anorm(abs(norm)); if (anorm.x > anorm.y) { if (anorm.x > anorm.z) { @@ -137,13 +137,13 @@ struct BlockType { struct Faces { bool face[Block::FACE_COUNT]; - Faces &operator =(const Faces &other) { + Faces &operator =(const Faces &other) noexcept { for (int i = 0; i < Block::FACE_COUNT; ++i) { face[i] = other.face[i]; } return *this; } - bool operator [](Block::Face f) const { + bool operator [](Block::Face f) const noexcept { return face[f]; } } fill; @@ -152,11 +152,11 @@ struct BlockType { bool v = false, const glm::vec3 &color = { 1, 1, 1 }, const Shape *shape = &DEFAULT_SHAPE - ); + ) noexcept; static const NullShape DEFAULT_SHAPE; - bool FaceFilled(const Block &block, Block::Face face) const { + bool FaceFilled(const Block &block, Block::Face face) const noexcept { return fill[block.OrientedFace(face)]; } @@ -164,17 +164,17 @@ struct BlockType { Model::Buffer &m, const glm::mat4 &transform = glm::mat4(1.0f), Model::Index idx_offset = 0 - ) const; + ) const noexcept; void FillBlockModel( BlockModel::Buffer &m, const glm::mat4 &transform = glm::mat4(1.0f), BlockModel::Index idx_offset = 0 - ) const; + ) const noexcept; void FillOutlineModel( OutlineModel &m, const glm::vec3 &pos_offset = { 0, 0, 0 }, OutlineModel::Index idx_offset = 0 - ) const; + ) const noexcept; }; @@ -187,10 +187,10 @@ public: public: Block::Type Add(const BlockType &); - size_t Size() const { return types.size(); } + size_t Size() const noexcept { return types.size(); } - BlockType *operator [](Block::Type id) { return &types[id]; } - const BlockType *Get(Block::Type id) const { return &types[id]; } + BlockType &operator [](Block::Type id) { return types[id]; } + const BlockType &Get(Block::Type id) const { return types[id]; } private: std::vector types; diff --git a/src/camera.cpp b/src/camera.cpp index 7bf15bf..f4e3171 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -8,7 +8,7 @@ namespace blank { -Camera::Camera() +Camera::Camera() noexcept : fov(PI_0p25) , aspect(1.0f) , near_clip(0.1f) @@ -18,37 +18,37 @@ Camera::Camera() } -void Camera::Viewport(int width, int height) { +void Camera::Viewport(int width, int height) noexcept { Viewport(0, 0, width, height); } -void Camera::Viewport(int x, int y, int width, int height) { +void Camera::Viewport(int x, int y, int width, int height) noexcept { glViewport(x, y, width, height); Aspect(width, height); } -void Camera::FOV(float f) { +void Camera::FOV(float f) noexcept { fov = f; UpdateProjection(); } -void Camera::Aspect(float r) { +void Camera::Aspect(float r) noexcept { aspect = r; UpdateProjection(); } -void Camera::Aspect(float w, float h) { +void Camera::Aspect(float w, float h) noexcept { Aspect(w / h); } -void Camera::Clip(float near, float far) { +void Camera::Clip(float near, float far) noexcept { near_clip = near; far_clip = far; UpdateProjection(); } -void Camera::UpdateProjection() { +void Camera::UpdateProjection() noexcept { projection = glm::perspective(fov, aspect, near_clip, far_clip); } diff --git a/src/camera.hpp b/src/camera.hpp index 1477a47..717da24 100644 --- a/src/camera.hpp +++ b/src/camera.hpp @@ -9,21 +9,21 @@ namespace blank { class Camera { public: - Camera(); + Camera() noexcept; - void Viewport(int width, int height); - void Viewport(int x, int y, int width, int height); + void Viewport(int width, int height) noexcept; + void Viewport(int x, int y, int width, int height) noexcept; /// FOV in radians - void FOV(float f); - void Aspect(float r); - void Aspect(float w, float h); - void Clip(float near, float far); + void FOV(float f) noexcept; + void Aspect(float r) noexcept; + void Aspect(float w, float h) noexcept; + void Clip(float near, float far) noexcept; - const glm::mat4 &Projection() { return projection; } + const glm::mat4 &Projection() noexcept { return projection; } private: - void UpdateProjection(); + void UpdateProjection() noexcept; private: float fov; diff --git a/src/chunk.cpp b/src/chunk.cpp index 23d5a13..c31926b 100644 --- a/src/chunk.cpp +++ b/src/chunk.cpp @@ -5,12 +5,11 @@ #include #include #include -#include namespace blank { -Chunk::Chunk(const BlockTypeRegistry &types) +Chunk::Chunk(const BlockTypeRegistry &types) noexcept : types(&types) , neighbor{0} , blocks{} @@ -21,7 +20,7 @@ Chunk::Chunk(const BlockTypeRegistry &types) } -Chunk::Chunk(Chunk &&other) +Chunk::Chunk(Chunk &&other) noexcept : types(other.types) , model(std::move(other.model)) , position(other.position) @@ -31,7 +30,7 @@ Chunk::Chunk(Chunk &&other) std::copy(other.light, other.light + sizeof(light), light); } -Chunk &Chunk::operator =(Chunk &&other) { +Chunk &Chunk::operator =(Chunk &&other) noexcept { types = other.types; std::copy(other.neighbor, other.neighbor + sizeof(neighbor), neighbor); std::copy(other.blocks, other.blocks + sizeof(blocks), blocks); @@ -53,14 +52,14 @@ struct SetNode { SetNode(Chunk *chunk, Chunk::Pos pos) : chunk(chunk), pos(pos) { } - int Get() const { return chunk->GetLight(pos); } - void Set(int level) { chunk->SetLight(pos, level); } + int Get() const noexcept { return chunk->GetLight(pos); } + void Set(int level) noexcept { chunk->SetLight(pos, level); } - bool HasNext(Block::Face face) { + bool HasNext(Block::Face face) noexcept { const BlockLookup next(chunk, pos, face); return next && !next.GetType().block_light; } - SetNode GetNext(Block::Face face) { + SetNode GetNext(Block::Face face) noexcept { const BlockLookup next(chunk, pos, face); return SetNode(&next.GetChunk(), next.GetBlockPos()); } @@ -79,18 +78,18 @@ struct UnsetNode : SetNode(set), level(Get()) { } - bool HasNext(Block::Face face) { + bool HasNext(Block::Face face) noexcept { const BlockLookup next(chunk, pos, face); return next; } - UnsetNode GetNext(Block::Face face) { return UnsetNode(SetNode::GetNext(face)); } + UnsetNode GetNext(Block::Face face) noexcept { return UnsetNode(SetNode::GetNext(face)); } }; std::queue light_queue; std::queue dark_queue; -void work_light() { +void work_light() noexcept { while (!light_queue.empty()) { SetNode node = light_queue.front(); light_queue.pop(); @@ -108,7 +107,7 @@ void work_light() { } } -void work_dark() { +void work_dark() noexcept { while (!dark_queue.empty()) { UnsetNode node = dark_queue.front(); dark_queue.pop(); @@ -130,7 +129,7 @@ void work_dark() { } -void Chunk::SetBlock(int index, const Block &block) { +void Chunk::SetBlock(int index, const Block &block) noexcept { const BlockType &old_type = Type(blocks[index]); const BlockType &new_type = Type(block); @@ -176,7 +175,7 @@ void Chunk::SetBlock(int index, const Block &block) { } } -void Chunk::SetNeighbor(Chunk &other) { +void Chunk::SetNeighbor(Chunk &other) noexcept { if (other.position == position + Pos(-1, 0, 0)) { if (neighbor[Block::FACE_LEFT] != &other) { neighbor[Block::FACE_LEFT] = &other; @@ -288,13 +287,13 @@ void Chunk::SetNeighbor(Chunk &other) { } } -void Chunk::ClearNeighbors() { +void Chunk::ClearNeighbors() noexcept { for (int i = 0; i < Block::FACE_COUNT; ++i) { neighbor[i] = nullptr; } } -void Chunk::Unlink() { +void Chunk::Unlink() noexcept { for (int face = 0; face < Block::FACE_COUNT; ++face) { if (neighbor[face]) { neighbor[face]->neighbor[Block::Opposite(Block::Face(face))] = nullptr; @@ -302,7 +301,7 @@ void Chunk::Unlink() { } } -void Chunk::Relink() { +void Chunk::Relink() noexcept { for (int face = 0; face < Block::FACE_COUNT; ++face) { if (neighbor[face]) { neighbor[face]->neighbor[Block::Opposite(Block::Face(face))] = this; @@ -311,18 +310,18 @@ void Chunk::Relink() { } -void Chunk::SetLight(int index, int level) { +void Chunk::SetLight(int index, int level) noexcept { if (light[index] != level) { light[index] = level; Invalidate(); } } -int Chunk::GetLight(int index) const { +int Chunk::GetLight(int index) const noexcept { return light[index]; } -float Chunk::GetVertexLight(int index, const BlockModel::Position &vtx, const Model::Normal &norm) const { +float Chunk::GetVertexLight(int index, const BlockModel::Position &vtx, const Model::Normal &norm) const noexcept { float light = GetLight(index); Chunk::Pos pos(ToPos(index)); @@ -349,7 +348,7 @@ float Chunk::GetVertexLight(int index, const BlockModel::Position &vtx, const Mo } -bool Chunk::IsSurface(const Pos &pos) const { +bool Chunk::IsSurface(const Pos &pos) const noexcept { const Block &block = BlockAt(pos); if (!Type(block).visible) { return false; @@ -364,7 +363,7 @@ bool Chunk::IsSurface(const Pos &pos) const { } -void Chunk::Draw() { +void Chunk::Draw() noexcept { if (dirty) { Update(); } @@ -378,7 +377,7 @@ bool Chunk::Intersection( int &blkid, float &dist, glm::vec3 &normal -) const { +) const noexcept { // TODO: should be possible to heavily optimize this int id = 0; blkid = -1; @@ -410,14 +409,6 @@ bool Chunk::Intersection( } } -void Chunk::Position(const Pos &pos) { - position = pos; -} - -glm::mat4 Chunk::Transform(const Pos &offset) const { - return glm::translate((position - offset) * Extent()); -} - namespace { @@ -425,13 +416,13 @@ BlockModel::Buffer buf; } -void Chunk::CheckUpdate() { +void Chunk::CheckUpdate() noexcept { if (dirty) { Update(); } } -void Chunk::Update() { +void Chunk::Update() noexcept { int vtx_count = 0, idx_count = 0; for (const auto &block : blocks) { const Shape *shape = Type(block).shape; @@ -464,7 +455,7 @@ void Chunk::Update() { dirty = false; } -Block::FaceSet Chunk::Obstructed(int idx) const { +Block::FaceSet Chunk::Obstructed(int idx) const noexcept { Chunk::Pos pos(ToPos(idx)); Block::FaceSet result; @@ -479,12 +470,12 @@ Block::FaceSet Chunk::Obstructed(int idx) const { return result; } -glm::mat4 Chunk::ToTransform(int idx) const { +glm::mat4 Chunk::ToTransform(int idx) const noexcept { return glm::translate(glm::mat4(1.0f), ToCoords(idx)) * blocks[idx].Transform(); } -BlockLookup::BlockLookup(Chunk *c, const Chunk::Pos &p) +BlockLookup::BlockLookup(Chunk *c, const Chunk::Pos &p) noexcept : chunk(c), pos(p) { while (pos.x >= Chunk::Width()) { if (chunk->HasNeighbor(Block::FACE_RIGHT)) { @@ -542,7 +533,7 @@ BlockLookup::BlockLookup(Chunk *c, const Chunk::Pos &p) } } -BlockLookup::BlockLookup(Chunk *c, const Chunk::Pos &p, Block::Face face) +BlockLookup::BlockLookup(Chunk *c, const Chunk::Pos &p, Block::Face face) noexcept : chunk(c), pos(p) { pos += Block::FaceNormal(face); if (!Chunk::InBounds(pos)) { @@ -552,7 +543,7 @@ BlockLookup::BlockLookup(Chunk *c, const Chunk::Pos &p, Block::Face face) } -ChunkLoader::ChunkLoader(const Config &config, const BlockTypeRegistry ®, const Generator &gen) +ChunkLoader::ChunkLoader(const Config &config, const BlockTypeRegistry ®, const Generator &gen) noexcept : base(0, 0, 0) , reg(reg) , gen(gen) @@ -568,10 +559,10 @@ namespace { struct ChunkLess { - explicit ChunkLess(const Chunk::Pos &base) + explicit ChunkLess(const Chunk::Pos &base) noexcept : base(base) { } - bool operator ()(const Chunk::Pos &a, const Chunk::Pos &b) const { + bool operator ()(const Chunk::Pos &a, const Chunk::Pos &b) const noexcept { Chunk::Pos da(base - a); Chunk::Pos db(base - b); return @@ -657,17 +648,17 @@ Chunk &ChunkLoader::Generate(const Chunk::Pos &pos) { return chunk; } -void ChunkLoader::Insert(Chunk &chunk) { +void ChunkLoader::Insert(Chunk &chunk) noexcept { for (Chunk &other : loaded) { chunk.SetNeighbor(other); } } -void ChunkLoader::Remove(Chunk &chunk) { +void ChunkLoader::Remove(Chunk &chunk) noexcept { chunk.Unlink(); } -Chunk *ChunkLoader::Loaded(const Chunk::Pos &pos) { +Chunk *ChunkLoader::Loaded(const Chunk::Pos &pos) noexcept { for (Chunk &chunk : loaded) { if (chunk.Position() == pos) { return &chunk; @@ -676,7 +667,7 @@ Chunk *ChunkLoader::Loaded(const Chunk::Pos &pos) { return nullptr; } -bool ChunkLoader::Queued(const Chunk::Pos &pos) { +bool ChunkLoader::Queued(const Chunk::Pos &pos) noexcept { for (const Chunk::Pos &chunk : to_generate) { if (chunk == pos) { return true; @@ -685,7 +676,7 @@ bool ChunkLoader::Queued(const Chunk::Pos &pos) { return nullptr; } -bool ChunkLoader::Known(const Chunk::Pos &pos) { +bool ChunkLoader::Known(const Chunk::Pos &pos) noexcept { if (Loaded(pos)) return true; return Queued(pos); } diff --git a/src/chunk.hpp b/src/chunk.hpp index 06dc98b..24024f9 100644 --- a/src/chunk.hpp +++ b/src/chunk.hpp @@ -8,6 +8,7 @@ #include #include #include +#include namespace blank { @@ -19,54 +20,54 @@ public: using Pos = glm::tvec3; public: - explicit Chunk(const BlockTypeRegistry &); + explicit Chunk(const BlockTypeRegistry &) noexcept; - Chunk(Chunk &&); - Chunk &operator =(Chunk &&); + Chunk(Chunk &&) noexcept; + Chunk &operator =(Chunk &&) noexcept; static constexpr int Width() { return 16; } static constexpr int Height() { return 16; } static constexpr int Depth() { return 16; } - static Pos Extent() { return { Width(), Height(), Depth() }; } + static Pos Extent() noexcept { return { Width(), Height(), Depth() }; } static constexpr int Size() { return Width() * Height() * Depth(); } - static AABB Bounds() { return AABB{ { 0, 0, 0 }, Extent() }; } + static AABB Bounds() noexcept { return AABB{ { 0, 0, 0 }, Extent() }; } - static constexpr bool InBounds(const Block::Pos &pos) { + static constexpr bool InBounds(const Block::Pos &pos) noexcept { return pos.x >= 0 && pos.x < Width() && pos.y >= 0 && pos.y < Height() && pos.z >= 0 && pos.z < Depth(); } - static constexpr bool InBounds(const Pos &pos) { + static constexpr bool InBounds(const Pos &pos) noexcept { return pos.x >= 0 && pos.x < Width() && pos.y >= 0 && pos.y < Height() && pos.z >= 0 && pos.z < Depth(); } - static constexpr int ToIndex(const Pos &pos) { + static constexpr int ToIndex(const Pos &pos) noexcept { return pos.x + pos.y * Width() + pos.z * Width() * Height(); } - static constexpr bool InBounds(int idx) { + static constexpr bool InBounds(int idx) noexcept { return idx >= 0 && idx < Size(); } - static Block::Pos ToCoords(int idx) { + static Block::Pos ToCoords(int idx) noexcept { return Block::Pos( 0.5f + (idx % Width()), 0.5f + ((idx / Width()) % Height()), 0.5f + (idx / (Width() * Height())) ); } - static Pos ToPos(int idx) { + static Pos ToPos(int idx) noexcept { return Pos( (idx % Width()), ((idx / Width()) % Height()), (idx / (Width() * Height())) ); } - glm::mat4 ToTransform(int idx) const; + glm::mat4 ToTransform(int idx) const noexcept; - static constexpr bool IsBorder(int idx) { + static constexpr bool IsBorder(int idx) noexcept { return idx < Width() * Height() || // low Z plane idx % Width() == 0 || // low X plane @@ -76,48 +77,48 @@ public: (idx / Width()) % Height() == Height() - 1; // high Y plane } - bool IsSurface(int index) const { return IsSurface(ToPos(index)); } - bool IsSurface(const Block::Pos &pos) const { return IsSurface(Pos(pos)); } - bool IsSurface(const Pos &pos) const; + bool IsSurface(int index) const noexcept { return IsSurface(ToPos(index)); } + bool IsSurface(const Block::Pos &pos) const noexcept { return IsSurface(Pos(pos)); } + bool IsSurface(const Pos &pos) const noexcept; - void SetNeighbor(Chunk &); - bool HasNeighbor(Block::Face f) const { return neighbor[f]; } - Chunk &GetNeighbor(Block::Face f) { return *neighbor[f]; } - const Chunk &GetNeighbor(Block::Face f) const { return *neighbor[f]; } - void ClearNeighbors(); - void Unlink(); - void Relink(); + void SetNeighbor(Chunk &) noexcept; + bool HasNeighbor(Block::Face f) const noexcept { return neighbor[f]; } + Chunk &GetNeighbor(Block::Face f) noexcept { return *neighbor[f]; } + const Chunk &GetNeighbor(Block::Face f) const noexcept { return *neighbor[f]; } + void ClearNeighbors() noexcept; + void Unlink() noexcept; + void Relink() noexcept; // check which faces of a block at given index are obstructed (and therefore invisible) - Block::FaceSet Obstructed(int idx) const; + Block::FaceSet Obstructed(int idx) const noexcept; - void Invalidate() { dirty = true; } + void Invalidate() noexcept { dirty = true; } - void SetBlock(int index, const Block &); - void SetBlock(const Block::Pos &pos, const Block &block) { SetBlock(ToIndex(pos), block); } - void SetBlock(const Pos &pos, const Block &block) { SetBlock(ToIndex(pos), block); } + void SetBlock(int index, const Block &) noexcept; + void SetBlock(const Block::Pos &pos, const Block &block) noexcept { SetBlock(ToIndex(pos), block); } + void SetBlock(const Pos &pos, const Block &block) noexcept { SetBlock(ToIndex(pos), block); } - const Block &BlockAt(int index) const { return blocks[index]; } - const Block &BlockAt(const Block::Pos &pos) const { return BlockAt(ToIndex(pos)); } - const Block &BlockAt(const Pos &pos) const { return BlockAt(ToIndex(pos)); } + const Block &BlockAt(int index) const noexcept { return blocks[index]; } + const Block &BlockAt(const Block::Pos &pos) const noexcept { return BlockAt(ToIndex(pos)); } + const Block &BlockAt(const Pos &pos) const noexcept { return BlockAt(ToIndex(pos)); } - const BlockType &Type(const Block &b) const { return *types->Get(b.type); } + const BlockType &Type(const Block &b) const noexcept { return types->Get(b.type); } - void SetLight(int index, int level); - void SetLight(const Pos &pos, int level) { SetLight(ToIndex(pos), level); } - void SetLight(const Block::Pos &pos, int level) { SetLight(ToIndex(pos), level); } + void SetLight(int index, int level) noexcept; + void SetLight(const Pos &pos, int level) noexcept { SetLight(ToIndex(pos), level); } + void SetLight(const Block::Pos &pos, int level) noexcept { SetLight(ToIndex(pos), level); } - int GetLight(int index) const; - int GetLight(const Pos &pos) const { return GetLight(ToIndex(pos)); } - int GetLight(const Block::Pos &pos) const { return GetLight(ToIndex(pos)); } + int GetLight(int index) const noexcept; + int GetLight(const Pos &pos) const noexcept { return GetLight(ToIndex(pos)); } + int GetLight(const Block::Pos &pos) const noexcept { return GetLight(ToIndex(pos)); } - float GetVertexLight(int index, const BlockModel::Position &, const Model::Normal &) const; + float GetVertexLight(int index, const BlockModel::Position &, const Model::Normal &) const noexcept; bool Intersection( const Ray &ray, const glm::mat4 &M, float &dist - ) const { + ) const noexcept { return blank::Intersection(ray, Bounds(), M, &dist); } @@ -126,17 +127,19 @@ public: const glm::mat4 &M, int &blkid, float &dist, - glm::vec3 &normal) const; + glm::vec3 &normal) const noexcept; - void Position(const Pos &); - const Pos &Position() const { return position; } - glm::mat4 Transform(const Pos &offset) const; + void Position(const Pos &pos) noexcept { position = pos; } + const Pos &Position() const noexcept { return position; } + glm::mat4 Transform(const Pos &offset) const noexcept { + return glm::translate((position - offset) * Extent()); + } - void CheckUpdate(); - void Draw(); + void CheckUpdate() noexcept; + void Draw() noexcept; private: - void Update(); + void Update() noexcept; private: const BlockTypeRegistry *types; @@ -154,20 +157,20 @@ class BlockLookup { public: // resolve chunk/position from oob coordinates - BlockLookup(Chunk *c, const Chunk::Pos &p); + BlockLookup(Chunk *c, const Chunk::Pos &p) noexcept; // resolve chunk/position from ib coordinates and direction - BlockLookup(Chunk *c, const Chunk::Pos &p, Block::Face dir); + BlockLookup(Chunk *c, const Chunk::Pos &p, Block::Face dir) noexcept; // check if lookup was successful operator bool() const { return chunk; } // only valid if lookup was successful - Chunk &GetChunk() const { return *chunk; } - const Chunk::Pos &GetBlockPos() const { return pos; } - const Block &GetBlock() const { return GetChunk().BlockAt(GetBlockPos()); } - const BlockType &GetType() const { return GetChunk().Type(GetBlock()); } - int GetLight() const { return GetChunk().GetLight(GetBlockPos()); } + Chunk &GetChunk() const noexcept { return *chunk; } + const Chunk::Pos &GetBlockPos() const noexcept { return pos; } + const Block &GetBlock() const noexcept { return GetChunk().BlockAt(GetBlockPos()); } + const BlockType &GetType() const noexcept { return GetChunk().Type(GetBlock()); } + int GetLight() const noexcept { return GetChunk().GetLight(GetBlockPos()); } private: Chunk *chunk; @@ -186,16 +189,16 @@ public: int unload_dist = 8; }; - ChunkLoader(const Config &, const BlockTypeRegistry &, const Generator &); + ChunkLoader(const Config &, const BlockTypeRegistry &, const Generator &) noexcept; void Generate(const Chunk::Pos &from, const Chunk::Pos &to); void GenerateSurrounding(const Chunk::Pos &); - std::list &Loaded() { return loaded; } + std::list &Loaded() noexcept { return loaded; } - Chunk *Loaded(const Chunk::Pos &); - bool Queued(const Chunk::Pos &); - bool Known(const Chunk::Pos &); + Chunk *Loaded(const Chunk::Pos &) noexcept; + bool Queued(const Chunk::Pos &) noexcept; + bool Known(const Chunk::Pos &) noexcept; Chunk &ForceLoad(const Chunk::Pos &); void Rebase(const Chunk::Pos &); @@ -203,8 +206,8 @@ public: private: Chunk &Generate(const Chunk::Pos &pos); - void Insert(Chunk &); - void Remove(Chunk &); + void Insert(Chunk &) noexcept; + void Remove(Chunk &) noexcept; private: Chunk::Pos base; diff --git a/src/controller.cpp b/src/controller.cpp index fcdb407..e86551f 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -6,7 +6,7 @@ namespace blank { -FPSController::FPSController(Entity &entity) +FPSController::FPSController(Entity &entity) noexcept : entity(entity) , pitch(0) , yaw(0) { @@ -14,7 +14,7 @@ FPSController::FPSController(Entity &entity) } -void FPSController::Pitch(float p) { +void FPSController::Pitch(float p) noexcept { pitch = p; if (pitch > PI / 2) { pitch = PI / 2; @@ -23,11 +23,11 @@ void FPSController::Pitch(float p) { } } -void FPSController::RotatePitch(float delta) { +void FPSController::RotatePitch(float delta) noexcept { Pitch(pitch + delta); } -void FPSController::Yaw(float y) { +void FPSController::Yaw(float y) noexcept { yaw = y; if (yaw > PI) { yaw -= PI * 2; @@ -36,25 +36,25 @@ void FPSController::Yaw(float y) { } } -void FPSController::RotateYaw(float delta) { +void FPSController::RotateYaw(float delta) noexcept { Yaw(yaw + delta); } -void FPSController::Update(int dt) { +void FPSController::Update(int dt) noexcept { entity.Rotation(glm::eulerAngleYX(yaw, pitch)); entity.Velocity(glm::rotateY(velocity, yaw)); } -RandomWalk::RandomWalk(Entity &e) +RandomWalk::RandomWalk(Entity &e) noexcept : entity(e) , time_left(0) { } -void RandomWalk::Update(int dt) { +void RandomWalk::Update(int dt) noexcept { time_left -= dt; if (time_left > 0) return; time_left += 2500 + (rand() % 5000); diff --git a/src/controller.hpp b/src/controller.hpp index 7dd3d11..f674e23 100644 --- a/src/controller.hpp +++ b/src/controller.hpp @@ -12,22 +12,22 @@ namespace blank { class FPSController { public: - explicit FPSController(Entity &); + explicit FPSController(Entity &) noexcept; - Ray Aim() const { return entity.Aim(entity.ChunkCoords()); } + Ray Aim() const noexcept { return entity.Aim(entity.ChunkCoords()); } - const glm::vec3 &Velocity() const { return velocity; } - void Velocity(const glm::vec3 &vel) { velocity = vel; } + const glm::vec3 &Velocity() const noexcept { return velocity; } + void Velocity(const glm::vec3 &vel) noexcept { velocity = vel; } // all angles in radians (full circle = 2π) - float Pitch() const { return pitch; } - void Pitch(float p); - void RotatePitch(float delta); - float Yaw() const { return yaw; } - void Yaw(float y); - void RotateYaw(float delta); + float Pitch() const noexcept { return pitch; } + void Pitch(float p) noexcept; + void RotatePitch(float delta) noexcept; + float Yaw() const noexcept { return yaw; } + void Yaw(float y) noexcept; + void RotateYaw(float delta) noexcept; - void Update(int dt); + void Update(int dt) noexcept; private: Entity &entity; @@ -43,9 +43,9 @@ private: class RandomWalk { public: - explicit RandomWalk(Entity &); + explicit RandomWalk(Entity &) noexcept; - void Update(int dt); + void Update(int dt) noexcept; private: Entity &entity; diff --git a/src/entity.cpp b/src/entity.cpp index 2358601..054af2a 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -14,7 +14,7 @@ blank::Model::Buffer model_buffer; namespace blank { -Entity::Entity() +Entity::Entity() noexcept : shape(nullptr) , model() , velocity(0, 0, 0) @@ -34,16 +34,16 @@ void Entity::SetShape(const Shape *s, const glm::vec3 &color) { model.Update(model_buffer); } -void Entity::SetShapeless() { +void Entity::SetShapeless() noexcept { shape = nullptr; } -void Entity::Velocity(const glm::vec3 &vel) { +void Entity::Velocity(const glm::vec3 &vel) noexcept { velocity = vel; } -void Entity::Position(const Block::Pos &pos) { +void Entity::Position(const Block::Pos &pos) noexcept { position = pos; while (position.x >= Chunk::Width()) { position.x -= Chunk::Width(); @@ -71,28 +71,28 @@ void Entity::Position(const Block::Pos &pos) { } } -void Entity::Move(const glm::vec3 &delta) { +void Entity::Move(const glm::vec3 &delta) noexcept { Position(position + delta); } -void Entity::AngularVelocity(const glm::quat &v) { +void Entity::AngularVelocity(const glm::quat &v) noexcept { angular_velocity = v; } -void Entity::Rotation(const glm::mat4 &rot) { +void Entity::Rotation(const glm::mat4 &rot) noexcept { rotation = rot; } -void Entity::Rotate(const glm::quat &delta) { +void Entity::Rotate(const glm::quat &delta) noexcept { Rotation(rotation * glm::mat4_cast(delta)); } -glm::mat4 Entity::Transform(const Chunk::Pos &chunk_offset) const { +glm::mat4 Entity::Transform(const Chunk::Pos &chunk_offset) const noexcept { const glm::vec3 chunk_pos = (chunk - chunk_offset) * Chunk::Extent(); return glm::translate(position + chunk_pos) * rotation; } -Ray Entity::Aim(const Chunk::Pos &chunk_offset) const { +Ray Entity::Aim(const Chunk::Pos &chunk_offset) const noexcept { glm::mat4 transform = Transform(chunk_offset); glm::vec4 from = transform * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); from /= from.w; @@ -101,13 +101,13 @@ Ray Entity::Aim(const Chunk::Pos &chunk_offset) const { return Ray{ glm::vec3(from), glm::normalize(glm::vec3(to - from)) }; } -void Entity::Update(int dt) { +void Entity::Update(int dt) noexcept { Move(velocity * float(dt)); Rotate(angular_velocity * float(dt)); } -void Entity::Draw() { +void Entity::Draw() noexcept { model.Draw(); } diff --git a/src/entity.hpp b/src/entity.hpp index 5ef8fbe..20c7630 100644 --- a/src/entity.hpp +++ b/src/entity.hpp @@ -17,35 +17,35 @@ class Shape; class Entity { public: - Entity(); + Entity() noexcept; - bool HasShape() const { return shape; } - const Shape *GetShape() const { return shape; } + bool HasShape() const noexcept { return shape; } + const Shape *GetShape() const noexcept { return shape; } void SetShape(const Shape *, const glm::vec3 &color); - void SetShapeless(); + void SetShapeless() noexcept; - const glm::vec3 &Velocity() const { return velocity; } - void Velocity(const glm::vec3 &); + const glm::vec3 &Velocity() const noexcept { return velocity; } + void Velocity(const glm::vec3 &) noexcept; - const Block::Pos &Position() const { return position; } - void Position(const Block::Pos &); - void Move(const glm::vec3 &delta); + const Block::Pos &Position() const noexcept { return position; } + void Position(const Block::Pos &) noexcept; + void Move(const glm::vec3 &delta) noexcept; - const Chunk::Pos ChunkCoords() const { return chunk; } + const Chunk::Pos ChunkCoords() const noexcept { return chunk; } - const glm::quat &AngularVelocity() const { return angular_velocity; } - void AngularVelocity(const glm::quat &); + const glm::quat &AngularVelocity() const noexcept { return angular_velocity; } + void AngularVelocity(const glm::quat &) noexcept; - const glm::mat4 &Rotation() const { return rotation; } - void Rotation(const glm::mat4 &); - void Rotate(const glm::quat &delta); + const glm::mat4 &Rotation() const noexcept { return rotation; } + void Rotation(const glm::mat4 &) noexcept; + void Rotate(const glm::quat &delta) noexcept; - glm::mat4 Transform(const Chunk::Pos &chunk_offset) const; - Ray Aim(const Chunk::Pos &chunk_offset) const; + glm::mat4 Transform(const Chunk::Pos &chunk_offset) const noexcept; + Ray Aim(const Chunk::Pos &chunk_offset) const noexcept; - void Update(int dt); + void Update(int dt) noexcept; - void Draw(); + void Draw() noexcept; private: const Shape *shape; diff --git a/src/generator.cpp b/src/generator.cpp index 373374f..3714065 100644 --- a/src/generator.cpp +++ b/src/generator.cpp @@ -5,7 +5,7 @@ namespace blank { -Generator::Generator(const Config &config) +Generator::Generator(const Config &config) noexcept : solidNoise(config.solid_seed) , typeNoise(config.type_seed) , stretch(1.0f/config.stretch) @@ -17,7 +17,7 @@ Generator::Generator(const Config &config) } -void Generator::operator ()(Chunk &chunk) const { +void Generator::operator ()(Chunk &chunk) const noexcept { Chunk::Pos pos(chunk.Position()); glm::vec3 coords(pos * Chunk::Extent()); for (int z = 0; z < Chunk::Depth(); ++z) { diff --git a/src/generator.hpp b/src/generator.hpp index 70c38f5..dedfb72 100644 --- a/src/generator.hpp +++ b/src/generator.hpp @@ -20,12 +20,12 @@ public: float solid_threshold = 0.5f; }; - explicit Generator(const Config &); + explicit Generator(const Config &) noexcept; - void operator ()(Chunk &) const; + void operator ()(Chunk &) const noexcept; - void Space(Block::Type t) { space = t; } - void Light(Block::Type t) { light = t; } + void Space(Block::Type t) noexcept { space = t; } + void Light(Block::Type t) noexcept { light = t; } void Solids(const std::vector &s) { solids = s; } private: diff --git a/src/geometry.cpp b/src/geometry.cpp index cd28bab..416d930 100644 --- a/src/geometry.cpp +++ b/src/geometry.cpp @@ -11,7 +11,7 @@ bool Intersection( const glm::mat4 &M, float *dist, glm::vec3 *normal -) { +) noexcept { float t_min = 0.0f; float t_max = std::numeric_limits::infinity(); const glm::vec3 aabb_pos(M[3].x, M[3].y, M[3].z); @@ -65,7 +65,7 @@ bool Intersection( return true; } -bool CullTest(const AABB &box, const glm::mat4 &MVP) { +bool CullTest(const AABB &box, const glm::mat4 &MVP) noexcept { // transform corners into clip space glm::vec4 corners[8] = { { box.min.x, box.min.y, box.min.z, 1.0f }, diff --git a/src/geometry.hpp b/src/geometry.hpp index 78fe5f5..df75f22 100644 --- a/src/geometry.hpp +++ b/src/geometry.hpp @@ -17,7 +17,7 @@ struct AABB { glm::vec3 min; glm::vec3 max; - void Adjust() { + void Adjust() noexcept { if (max.x < min.x) std::swap(max.x, min.x); if (max.y < min.y) std::swap(max.y, min.y); if (max.z < min.z) std::swap(max.z, min.z); @@ -34,9 +34,9 @@ bool Intersection( const AABB &, const glm::mat4 &M, float *dist = nullptr, - glm::vec3 *normal = nullptr); + glm::vec3 *normal = nullptr) noexcept; -bool CullTest(const AABB &box, const glm::mat4 &MVP); +bool CullTest(const AABB &box, const glm::mat4 &MVP) noexcept; } diff --git a/src/glmio.hpp b/src/glmio.hpp deleted file mode 100644 index f96d5fd..0000000 --- a/src/glmio.hpp +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef BLANKL_GLMIO_HPP_ -#define BLANKL_GLMIO_HPP_ - -#include -#include - - -namespace blank { - -template -std::ostream &operator <<(std::ostream &out, const glm::tvec3 &v) { - return out << '<' << v.x << ", " << v.y << ", " << v.z << '>'; -} - -template -std::ostream &operator <<(std::ostream &out, const glm::tvec4 &v) { - return out << '<' << v.x << ", " << v.y << ", " << v.z << ", " << v.w << '>'; -} - -template -std::ostream &operator <<(std::ostream &out, const glm::tmat4x4 &m) { - return out << '[' << m[0] << ", " << m[1] << ", " << m[2] << ", " << m[3] << ']'; -} - -} - -#endif diff --git a/src/hud.cpp b/src/hud.cpp index 0747cff..0f496c6 100644 --- a/src/hud.cpp +++ b/src/hud.cpp @@ -39,18 +39,18 @@ HUD::HUD(const BlockTypeRegistry &types) } -void HUD::Viewport(float width, float height) { +void HUD::Viewport(float width, float height) noexcept { Viewport(0, 0, width, height); } -void HUD::Viewport(float x, float y, float width, float height) { +void HUD::Viewport(float x, float y, float width, float height) noexcept { projection = glm::ortho(x, width, height, y, near, far); crosshair_transform = glm::translate(glm::mat4(1.0f), glm::vec3(width * 0.5f, height * 0.5f, 0.0f)); } void HUD::Display(const Block &b) { - const BlockType &type = *types.Get(b.type); + const BlockType &type = types.Get(b.type); block_buf.Clear(); type.FillModel(block_buf, b.Transform()); @@ -59,7 +59,7 @@ void HUD::Display(const Block &b) { } -void HUD::Render(DirectionalLighting &program) { +void HUD::Render(DirectionalLighting &program) noexcept { if (block_visible) { program.SetLightDirection({ 1.0f, 3.0f, 5.0f }); // disable distance fog diff --git a/src/hud.hpp b/src/hud.hpp index 4bfd5fb..984a24d 100644 --- a/src/hud.hpp +++ b/src/hud.hpp @@ -20,12 +20,12 @@ public: HUD(const HUD &) = delete; HUD &operator =(const HUD &) = delete; - void Viewport(float width, float height); - void Viewport(float x, float y, float width, float height); + void Viewport(float width, float height) noexcept; + void Viewport(float x, float y, float width, float height) noexcept; void Display(const Block &); - void Render(DirectionalLighting &); + void Render(DirectionalLighting &) noexcept; private: const BlockTypeRegistry &types; diff --git a/src/init.cpp b/src/init.cpp index 73a7309..a56674c 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -149,20 +149,20 @@ void GLContext::EnableVSync() { } } -void GLContext::EnableDepthTest() { +void GLContext::EnableDepthTest() noexcept { glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); } -void GLContext::EnableBackfaceCulling() { +void GLContext::EnableBackfaceCulling() noexcept { glEnable(GL_CULL_FACE); } -void GLContext::Clear() { +void GLContext::Clear() noexcept { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } -void GLContext::ClearDepthBuffer() { +void GLContext::ClearDepthBuffer() noexcept { glClear(GL_DEPTH_BUFFER_BIT); } diff --git a/src/init.hpp b/src/init.hpp index d08437b..30da3be 100644 --- a/src/init.hpp +++ b/src/init.hpp @@ -82,11 +82,11 @@ public: GLContext &operator =(const GLContext &) = delete; static void EnableVSync(); - static void EnableDepthTest(); - static void EnableBackfaceCulling(); + static void EnableDepthTest() noexcept; + static void EnableBackfaceCulling() noexcept; - static void Clear(); - static void ClearDepthBuffer(); + static void Clear() noexcept; + static void ClearDepthBuffer() noexcept; private: SDL_GLContext handle; diff --git a/src/interface.cpp b/src/interface.cpp index e4888c5..12117f7 100644 --- a/src/interface.cpp +++ b/src/interface.cpp @@ -201,7 +201,7 @@ void Interface::PlaceBlock() { mod_chunk->Invalidate(); } -void Interface::RemoveBlock() { +void Interface::RemoveBlock() noexcept { if (!aim_chunk) return; aim_chunk->SetBlock(aim_block, remove); aim_chunk->Invalidate(); @@ -234,7 +234,7 @@ void Interface::SelectPrevious() { hud.Display(selection); } -void Interface::Handle(const SDL_WindowEvent &event) { +void Interface::Handle(const SDL_WindowEvent &event) noexcept { if (event.event == SDL_WINDOWEVENT_RESIZED) { hud.Viewport(event.data1, event.data2); } @@ -260,7 +260,7 @@ void Interface::Update(int dt) { } -void Interface::Render(DirectionalLighting &program) { +void Interface::Render(DirectionalLighting &program) noexcept { if (config.visual_disabled) return; if (aim_chunk) { diff --git a/src/interface.hpp b/src/interface.hpp index 1f4bb90..16ee89f 100644 --- a/src/interface.hpp +++ b/src/interface.hpp @@ -35,14 +35,14 @@ public: void Handle(const SDL_MouseMotionEvent &); void Handle(const SDL_MouseButtonEvent &); void Handle(const SDL_MouseWheelEvent &); - void Handle(const SDL_WindowEvent &); + void Handle(const SDL_WindowEvent &) noexcept; void FaceBlock(); void TurnBlock(); void PickBlock(); void PlaceBlock(); - void RemoveBlock(); + void RemoveBlock() noexcept; void PrintBlockInfo(); void PrintChunkInfo(); @@ -55,7 +55,7 @@ public: void Update(int dt); - void Render(DirectionalLighting &); + void Render(DirectionalLighting &) noexcept; private: World &world; diff --git a/src/model.cpp b/src/model.cpp index 1d4edef..4e75674 100644 --- a/src/model.cpp +++ b/src/model.cpp @@ -5,20 +5,20 @@ namespace blank { -Model::Model() -: va(0) +Model::Model() noexcept +: va(0) , handle{} , count(0) { glGenVertexArrays(1, &va); glGenBuffers(ATTRIB_COUNT, handle); } -Model::~Model() { +Model::~Model() noexcept { glDeleteBuffers(ATTRIB_COUNT, handle); glDeleteVertexArrays(1, &va); } -Model::Model(Model &&other) +Model::Model(Model &&other) noexcept : va(other.va) , count(other.count) { other.va = 0; @@ -28,7 +28,7 @@ Model::Model(Model &&other) } } -Model &Model::operator =(Model &&other) { +Model &Model::operator =(Model &&other) noexcept { std::swap(va, other.va); for (int i = 0; i < ATTRIB_COUNT; ++i) { std::swap(handle[i], other.handle[i]); @@ -37,7 +37,7 @@ Model &Model::operator =(Model &&other) { return *this; } -void Model::Update(const Buffer &buf) { +void Model::Update(const Buffer &buf) noexcept { glBindVertexArray(va); glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_VERTEX]); glBufferData(GL_ARRAY_BUFFER, buf.vertices.size() * sizeof(glm::vec3), buf.vertices.data(), GL_STATIC_DRAW); @@ -91,7 +91,7 @@ void Model::Update(const Buffer &buf) { } -void Model::Draw() const { +void Model::Draw() const noexcept { glBindVertexArray(va); glDrawElements( GL_TRIANGLES, // how @@ -102,7 +102,7 @@ void Model::Draw() const { } -BlockModel::BlockModel() +BlockModel::BlockModel() noexcept : va(0) , handle{} , count(0) { @@ -110,12 +110,12 @@ BlockModel::BlockModel() glGenBuffers(ATTRIB_COUNT, handle); } -BlockModel::~BlockModel() { +BlockModel::~BlockModel() noexcept { glDeleteBuffers(ATTRIB_COUNT, handle); glDeleteVertexArrays(1, &va); } -BlockModel::BlockModel(BlockModel &&other) +BlockModel::BlockModel(BlockModel &&other) noexcept : va(other.va) , count(other.count) { other.va = 0; @@ -125,7 +125,7 @@ BlockModel::BlockModel(BlockModel &&other) } } -BlockModel &BlockModel::operator =(BlockModel &&other) { +BlockModel &BlockModel::operator =(BlockModel &&other) noexcept { std::swap(va, other.va); for (int i = 0; i < ATTRIB_COUNT; ++i) { std::swap(handle[i], other.handle[i]); @@ -134,7 +134,7 @@ BlockModel &BlockModel::operator =(BlockModel &&other) { return *this; } -void BlockModel::Update(const Buffer &buf) { +void BlockModel::Update(const Buffer &buf) noexcept { glBindVertexArray(va); glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_VERTEX]); glBufferData(GL_ARRAY_BUFFER, buf.vertices.size() * sizeof(glm::vec3), buf.vertices.data(), GL_STATIC_DRAW); @@ -188,7 +188,7 @@ void BlockModel::Update(const Buffer &buf) { } -void BlockModel::Draw() const { +void BlockModel::Draw() const noexcept { glBindVertexArray(va); glDrawElements( GL_TRIANGLES, // how @@ -198,7 +198,7 @@ void BlockModel::Draw() const { ); } -OutlineModel::OutlineModel() +OutlineModel::OutlineModel() noexcept : vertices() , colors() , indices() @@ -209,13 +209,13 @@ OutlineModel::OutlineModel() glGenBuffers(ATTRIB_COUNT, handle); } -OutlineModel::~OutlineModel() { +OutlineModel::~OutlineModel() noexcept { glDeleteBuffers(ATTRIB_COUNT, handle); glDeleteVertexArrays(1, &va); } -void OutlineModel::Clear() { +void OutlineModel::Clear() noexcept { vertices.clear(); colors.clear(); indices.clear(); @@ -229,7 +229,7 @@ void OutlineModel::Reserve(int v, int i) { } -void OutlineModel::Update() { +void OutlineModel::Update() noexcept { glBindBuffer(GL_ARRAY_BUFFER, handle[ATTRIB_VERTEX]); glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), vertices.data(), GL_STATIC_DRAW); glEnableVertexAttribArray(ATTRIB_VERTEX); @@ -267,7 +267,7 @@ void OutlineModel::Update() { } -void OutlineModel::Draw() { +void OutlineModel::Draw() noexcept { glBindVertexArray(va); if (dirty) { diff --git a/src/model.hpp b/src/model.hpp index 557b4ac..096e1cf 100644 --- a/src/model.hpp +++ b/src/model.hpp @@ -29,7 +29,7 @@ public: Normals normals; Indices indices; - void Clear() { + void Clear() noexcept { vertices.clear(); colors.clear(); normals.clear(); @@ -46,18 +46,18 @@ public: }; public: - Model(); - ~Model(); + Model() noexcept; + ~Model() noexcept; Model(const Model &) = delete; Model &operator =(const Model &) = delete; - Model(Model &&); - Model &operator =(Model &&); + Model(Model &&) noexcept; + Model &operator =(Model &&) noexcept; - void Update(const Buffer &); + void Update(const Buffer &) noexcept; - void Draw() const; + void Draw() const noexcept; private: enum Attribute { @@ -96,7 +96,7 @@ public: Lights lights; Indices indices; - void Clear() { + void Clear() noexcept { vertices.clear(); colors.clear(); lights.clear(); @@ -113,18 +113,18 @@ public: }; public: - BlockModel(); - ~BlockModel(); + BlockModel() noexcept; + ~BlockModel() noexcept; BlockModel(const BlockModel &) = delete; BlockModel &operator =(const Model &) = delete; - BlockModel(BlockModel &&); - BlockModel &operator =(BlockModel &&); + BlockModel(BlockModel &&) noexcept; + BlockModel &operator =(BlockModel &&) noexcept; - void Update(const Buffer &); + void Update(const Buffer &) noexcept; - void Draw() const; + void Draw() const noexcept; private: enum Attribute { @@ -159,21 +159,21 @@ public: Indices indices; public: - OutlineModel(); - ~OutlineModel(); + OutlineModel() noexcept; + ~OutlineModel() noexcept; OutlineModel(const OutlineModel &) = delete; OutlineModel &operator =(const OutlineModel &) = delete; - void Invalidate() { dirty = true; } + void Invalidate() noexcept { dirty = true; } - void Clear(); + void Clear() noexcept; void Reserve(int vtx_count, int idx_count); - void Draw(); + void Draw() noexcept; private: - void Update(); + void Update() noexcept; private: enum Attribute { diff --git a/src/noise.cpp b/src/noise.cpp index 8b71614..a5a9a20 100644 --- a/src/noise.cpp +++ b/src/noise.cpp @@ -12,12 +12,12 @@ constexpr float one_sixth = 1.0f/6.0f; namespace blank { -GaloisLFSR::GaloisLFSR(std::uint64_t seed) +GaloisLFSR::GaloisLFSR(std::uint64_t seed) noexcept : state(seed) { } -bool GaloisLFSR::operator ()() { +bool GaloisLFSR::operator ()() noexcept { bool result = state & 1; state >>= 1; if (result) { @@ -30,7 +30,7 @@ bool GaloisLFSR::operator ()() { } -SimplexNoise::SimplexNoise(unsigned int seed) +SimplexNoise::SimplexNoise(unsigned int seed) noexcept : grad({ { 1.0f, 1.0f, 0.0f }, { -1.0f, 1.0f, 0.0f }, @@ -53,7 +53,7 @@ SimplexNoise::SimplexNoise(unsigned int seed) } -float SimplexNoise::operator ()(const glm::vec3 &in) const { +float SimplexNoise::operator ()(const glm::vec3 &in) const noexcept { float skew = (in.x + in.y + in.z) * one_third; glm::vec3 skewed(glm::floor(in + skew)); @@ -118,22 +118,22 @@ float SimplexNoise::operator ()(const glm::vec3 &in) const { } -unsigned char SimplexNoise::Perm(size_t idx) const { +unsigned char SimplexNoise::Perm(size_t idx) const noexcept { return perm[idx]; } -const glm::vec3 &SimplexNoise::Grad(size_t idx) const { +const glm::vec3 &SimplexNoise::Grad(size_t idx) const noexcept { return grad[idx % 12]; } -WorleyNoise::WorleyNoise(unsigned int seed) +WorleyNoise::WorleyNoise(unsigned int seed) noexcept : seed(seed) , num_points(8) { } -float WorleyNoise::operator ()(const glm::vec3 &in) const { +float WorleyNoise::operator ()(const glm::vec3 &in) const noexcept { glm::vec3 center = floor(in); float closest = 1.0f; // cannot be farther away than 1.0 diff --git a/src/noise.hpp b/src/noise.hpp index 26e3766..0f37031 100644 --- a/src/noise.hpp +++ b/src/noise.hpp @@ -12,13 +12,13 @@ class GaloisLFSR { public: // seed should be non-zero - explicit GaloisLFSR(std::uint64_t seed); + explicit GaloisLFSR(std::uint64_t seed) noexcept; // get the next bit - bool operator ()(); + bool operator ()() noexcept; template - void operator ()(T &out) { + void operator ()(T &out) noexcept { constexpr int num_bits = std::numeric_limits::digits + std::numeric_limits::is_signed; @@ -40,13 +40,13 @@ private: class SimplexNoise { public: - explicit SimplexNoise(unsigned int seed); + explicit SimplexNoise(unsigned int seed) noexcept; - float operator ()(const glm::vec3 &) const; + float operator ()(const glm::vec3 &) const noexcept; private: - unsigned char Perm(size_t idx) const; - const glm::vec3 &Grad(size_t idx) const; + unsigned char Perm(size_t idx) const noexcept; + const glm::vec3 &Grad(size_t idx) const noexcept; private: unsigned char perm[512]; @@ -59,9 +59,9 @@ private: class WorleyNoise { public: - explicit WorleyNoise(unsigned int seed); + explicit WorleyNoise(unsigned int seed) noexcept; - float operator ()(const glm::vec3 &) const; + float operator ()(const glm::vec3 &) const noexcept; private: const unsigned int seed; diff --git a/src/runtime.cpp b/src/runtime.cpp index 18a06bf..7475c90 100644 --- a/src/runtime.cpp +++ b/src/runtime.cpp @@ -11,7 +11,7 @@ using namespace std; namespace blank { -Runtime::Runtime() +Runtime::Runtime() noexcept : name("blank") , mode(NORMAL) , n(0) diff --git a/src/runtime.hpp b/src/runtime.hpp index 1fbc4db..014cd32 100644 --- a/src/runtime.hpp +++ b/src/runtime.hpp @@ -19,7 +19,7 @@ public: ERROR, }; - Runtime(); + Runtime() noexcept; void ReadArgs(int argc, const char *const *argv); diff --git a/src/shader.cpp b/src/shader.cpp index 01f7861..b2ccb8b 100644 --- a/src/shader.cpp +++ b/src/shader.cpp @@ -42,27 +42,27 @@ Shader::~Shader() { } } -Shader::Shader(Shader &&other) +Shader::Shader(Shader &&other) noexcept : handle(other.handle) { other.handle = 0; } -Shader &Shader::operator =(Shader &&other) { +Shader &Shader::operator =(Shader &&other) noexcept { std::swap(handle, other.handle); return *this; } -void Shader::Source(const GLchar *src) { +void Shader::Source(const GLchar *src) noexcept { const GLchar* src_arr[] = { src }; glShaderSource(handle, 1, src_arr, nullptr); } -void Shader::Compile() { +void Shader::Compile() noexcept { glCompileShader(handle); } -bool Shader::Compiled() const { +bool Shader::Compiled() const noexcept { GLint compiled = GL_FALSE; glGetShaderiv(handle, GL_COMPILE_STATUS, &compiled); return compiled == GL_TRUE; @@ -77,7 +77,7 @@ void Shader::Log(std::ostream &out) const { } -void Shader::AttachToProgram(GLuint id) const { +void Shader::AttachToProgram(GLuint id) const noexcept { glAttachShader(id, handle); } @@ -109,15 +109,15 @@ const Shader &Program::LoadShader(GLenum type, const GLchar *src) { return shader; } -void Program::Attach(Shader &shader) { +void Program::Attach(Shader &shader) noexcept { shader.AttachToProgram(handle); } -void Program::Link() { +void Program::Link() noexcept { glLinkProgram(handle); } -bool Program::Linked() const { +bool Program::Linked() const noexcept { GLint linked = GL_FALSE; glGetProgramiv(handle, GL_LINK_STATUS, &linked); return linked == GL_TRUE; @@ -132,11 +132,11 @@ void Program::Log(std::ostream &out) const { } -GLint Program::AttributeLocation(const GLchar *name) const { +GLint Program::AttributeLocation(const GLchar *name) const noexcept { return glGetAttribLocation(handle, name); } -GLint Program::UniformLocation(const GLchar *name) const { +GLint Program::UniformLocation(const GLchar *name) const noexcept { return glGetUniformLocation(handle, name); } @@ -209,7 +209,7 @@ DirectionalLighting::DirectionalLighting() } -void DirectionalLighting::Activate() { +void DirectionalLighting::Activate() noexcept { GLContext::EnableDepthTest(); GLContext::EnableBackfaceCulling(); program.Use(); @@ -218,7 +218,7 @@ void DirectionalLighting::Activate() { glUniform3f(light_color_handle, light_color.x, light_color.y, light_color.z); } -void DirectionalLighting::SetM(const glm::mat4 &m) { +void DirectionalLighting::SetM(const glm::mat4 &m) noexcept { glm::mat4 mv(view * m); glm::mat4 mvp(vp * m); glUniformMatrix4fv(m_handle, 1, GL_FALSE, &m[0][0]); @@ -226,33 +226,33 @@ void DirectionalLighting::SetM(const glm::mat4 &m) { glUniformMatrix4fv(mvp_handle, 1, GL_FALSE, &mvp[0][0]); } -void DirectionalLighting::SetLightDirection(const glm::vec3 &dir) { +void DirectionalLighting::SetLightDirection(const glm::vec3 &dir) noexcept { light_direction = -dir; glUniform3f(light_direction_handle, light_direction.x, light_direction.y, light_direction.z); } -void DirectionalLighting::SetFogDensity(float f) { +void DirectionalLighting::SetFogDensity(float f) noexcept { fog_density = f; glUniform1f(fog_density_handle, fog_density); } -void DirectionalLighting::SetProjection(const glm::mat4 &p) { +void DirectionalLighting::SetProjection(const glm::mat4 &p) noexcept { projection = p; vp = p * view; } -void DirectionalLighting::SetView(const glm::mat4 &v) { +void DirectionalLighting::SetView(const glm::mat4 &v) noexcept { view = v; vp = projection * v; } -void DirectionalLighting::SetVP(const glm::mat4 &v, const glm::mat4 &p) { +void DirectionalLighting::SetVP(const glm::mat4 &v, const glm::mat4 &p) noexcept { projection = p; view = v; vp = p * v; } -void DirectionalLighting::SetMVP(const glm::mat4 &m, const glm::mat4 &v, const glm::mat4 &p) { +void DirectionalLighting::SetMVP(const glm::mat4 &m, const glm::mat4 &v, const glm::mat4 &p) noexcept { SetVP(v, p); SetM(m); } @@ -313,41 +313,41 @@ BlockLighting::BlockLighting() } -void BlockLighting::Activate() { +void BlockLighting::Activate() noexcept { GLContext::EnableDepthTest(); GLContext::EnableBackfaceCulling(); program.Use(); } -void BlockLighting::SetM(const glm::mat4 &m) { +void BlockLighting::SetM(const glm::mat4 &m) noexcept { glm::mat4 mv(view * m); glm::mat4 mvp(vp * m); glUniformMatrix4fv(mv_handle, 1, GL_FALSE, &mv[0][0]); glUniformMatrix4fv(mvp_handle, 1, GL_FALSE, &mvp[0][0]); } -void BlockLighting::SetFogDensity(float f) { +void BlockLighting::SetFogDensity(float f) noexcept { fog_density = f; glUniform1f(fog_density_handle, fog_density); } -void BlockLighting::SetProjection(const glm::mat4 &p) { +void BlockLighting::SetProjection(const glm::mat4 &p) noexcept { projection = p; vp = p * view; } -void BlockLighting::SetView(const glm::mat4 &v) { +void BlockLighting::SetView(const glm::mat4 &v) noexcept { view = v; vp = projection * v; } -void BlockLighting::SetVP(const glm::mat4 &v, const glm::mat4 &p) { +void BlockLighting::SetVP(const glm::mat4 &v, const glm::mat4 &p) noexcept { projection = p; view = v; vp = p * v; } -void BlockLighting::SetMVP(const glm::mat4 &m, const glm::mat4 &v, const glm::mat4 &p) { +void BlockLighting::SetMVP(const glm::mat4 &m, const glm::mat4 &v, const glm::mat4 &p) noexcept { SetVP(v, p); SetM(m); } diff --git a/src/shader.hpp b/src/shader.hpp index bb9ad84..df625c6 100644 --- a/src/shader.hpp +++ b/src/shader.hpp @@ -15,18 +15,18 @@ public: explicit Shader(GLenum type); ~Shader(); - Shader(Shader &&); - Shader &operator =(Shader &&); + Shader(Shader &&) noexcept; + Shader &operator =(Shader &&) noexcept; Shader(const Shader &) = delete; Shader &operator =(const Shader &) = delete; - void Source(const GLchar *src); - void Compile(); - bool Compiled() const; + void Source(const GLchar *src) noexcept; + void Compile() noexcept; + bool Compiled() const noexcept; void Log(std::ostream &) const; - void AttachToProgram(GLuint id) const; + void AttachToProgram(GLuint id) const noexcept; private: GLuint handle; @@ -44,15 +44,15 @@ public: Program &operator =(const Program &) = delete; const Shader &LoadShader(GLenum type, const GLchar *src); - void Attach(Shader &); - void Link(); - bool Linked() const; + void Attach(Shader &) noexcept; + void Link() noexcept; + bool Linked() const noexcept; void Log(std::ostream &) const; - GLint AttributeLocation(const GLchar *name) const; - GLint UniformLocation(const GLchar *name) const; + GLint AttributeLocation(const GLchar *name) const noexcept; + GLint UniformLocation(const GLchar *name) const noexcept; - void Use() const { glUseProgram(handle); } + void Use() const noexcept { glUseProgram(handle); } private: GLuint handle; @@ -66,21 +66,21 @@ class DirectionalLighting { public: DirectionalLighting(); - void Activate(); + void Activate() noexcept; - void SetLightDirection(const glm::vec3 &); + void SetLightDirection(const glm::vec3 &) noexcept; - void SetFogDensity(float); + void SetFogDensity(float) noexcept; - void SetM(const glm::mat4 &m); - void SetProjection(const glm::mat4 &p); - void SetView(const glm::mat4 &v); - void SetVP(const glm::mat4 &v, const glm::mat4 &p); - void SetMVP(const glm::mat4 &m, const glm::mat4 &v, const glm::mat4 &p); + void SetM(const glm::mat4 &m) noexcept; + void SetProjection(const glm::mat4 &p) noexcept; + void SetView(const glm::mat4 &v) noexcept; + void SetVP(const glm::mat4 &v, const glm::mat4 &p) noexcept; + void SetMVP(const glm::mat4 &m, const glm::mat4 &v, const glm::mat4 &p) noexcept; - const glm::mat4 &Projection() const { return projection; } - const glm::mat4 &View() const { return view; } - const glm::mat4 &GetVP() const { return vp; } + const glm::mat4 &Projection() const noexcept { return projection; } + const glm::mat4 &View() const noexcept { return view; } + const glm::mat4 &GetVP() const noexcept { return vp; } private: Program program; @@ -108,19 +108,19 @@ class BlockLighting { public: BlockLighting(); - void Activate(); + void Activate() noexcept; - void SetFogDensity(float); + void SetFogDensity(float) noexcept; - void SetM(const glm::mat4 &m); - void SetProjection(const glm::mat4 &p); - void SetView(const glm::mat4 &v); - void SetVP(const glm::mat4 &v, const glm::mat4 &p); - void SetMVP(const glm::mat4 &m, const glm::mat4 &v, const glm::mat4 &p); + void SetM(const glm::mat4 &m) noexcept; + void SetProjection(const glm::mat4 &p) noexcept; + void SetView(const glm::mat4 &v) noexcept; + void SetVP(const glm::mat4 &v, const glm::mat4 &p) noexcept; + void SetMVP(const glm::mat4 &m, const glm::mat4 &v, const glm::mat4 &p) noexcept; - const glm::mat4 &Projection() const { return projection; } - const glm::mat4 &View() const { return view; } - const glm::mat4 &GetVP() const { return vp; } + const glm::mat4 &Projection() const noexcept { return projection; } + const glm::mat4 &View() const noexcept { return view; } + const glm::mat4 &GetVP() const noexcept { return vp; } private: Program program; diff --git a/src/shape.cpp b/src/shape.cpp index 545a8e4..59e4f1f 100644 --- a/src/shape.cpp +++ b/src/shape.cpp @@ -75,7 +75,7 @@ bool NullShape::Intersects( const Ray &, const glm::mat4 &, float &, glm::vec3 & -) const { +) const noexcept { return false; } @@ -162,7 +162,7 @@ bool CuboidShape::Intersects( const Ray &ray, const glm::mat4 &M, float &dist, glm::vec3 &normal -) const { +) const noexcept { return Intersection(ray, bb, M, &dist, &normal); } @@ -294,7 +294,7 @@ bool StairShape::Intersects( const glm::mat4 &M, float &dist, glm::vec3 &norm -) const { +) const noexcept { float top_dist, bot_dist; glm::vec3 top_norm, bot_norm; bool top_hit = Intersection(ray, top, M, &top_dist, &top_norm); diff --git a/src/shape.hpp b/src/shape.hpp index abf8795..4120f76 100644 --- a/src/shape.hpp +++ b/src/shape.hpp @@ -13,14 +13,14 @@ namespace blank { struct Shape { /// the number of vertices (and normals) this shape has - size_t VertexCount() const { return vtx_pos.size(); } + size_t VertexCount() const noexcept { return vtx_pos.size(); } /// the number of vertex indices this shape has - size_t VertexIndexCount() const { return vtx_idx.size(); } + size_t VertexIndexCount() const noexcept { return vtx_idx.size(); } - const Model::Normal &VertexNormal(size_t idx) const { return vtx_nrm[idx]; } + const Model::Normal &VertexNormal(size_t idx) const noexcept { return vtx_nrm[idx]; } Model::Normal VertexNormal( size_t idx, const glm::mat4 &transform - ) const { + ) const noexcept { return Model::Normal(transform * glm::vec4(vtx_nrm[idx], 0.0f)); } @@ -68,7 +68,7 @@ struct Shape { const glm::mat4 &, float &dist, glm::vec3 &normal - ) const = 0; + ) const noexcept = 0; protected: void SetShape(const Model::Positions &pos, const Model::Normals &nrm, const Model::Indices &idx) { @@ -98,7 +98,7 @@ class NullShape public: NullShape(); - bool Intersects(const Ray &, const glm::mat4 &, float &, glm::vec3 &) const override; + bool Intersects(const Ray &, const glm::mat4 &, float &, glm::vec3 &) const noexcept override; }; @@ -109,7 +109,7 @@ class CuboidShape public: CuboidShape(const AABB &bounds); - bool Intersects(const Ray &, const glm::mat4 &, float &, glm::vec3 &) const override; + bool Intersects(const Ray &, const glm::mat4 &, float &, glm::vec3 &) const noexcept override; private: AABB bb; @@ -123,7 +123,7 @@ class StairShape public: StairShape(const AABB &bounds, const glm::vec2 &clip); - bool Intersects(const Ray &, const glm::mat4 &, float &, glm::vec3 &) const override; + bool Intersects(const Ray &, const glm::mat4 &, float &, glm::vec3 &) const noexcept override; private: AABB top, bot; -- 2.39.2