diff --git a/res/content/base/blocks/leaves.json b/res/content/base/blocks/leaves.json index 91182bc8..e3ddae22 100644 --- a/res/content/base/blocks/leaves.json +++ b/res/content/base/blocks/leaves.json @@ -1,7 +1,7 @@ { "texture": "leaves", "material": "base:grass", - "base:durability": 0.7, + "draw-group": 5, "culling": "optional", - "model": "aabb" + "base:durability": 0.7 } diff --git a/res/content/base/textures/blocks/leaves_culled.png b/res/content/base/textures/blocks/leaves_opaque.png similarity index 100% rename from res/content/base/textures/blocks/leaves_culled.png rename to res/content/base/textures/blocks/leaves_opaque.png diff --git a/src/content/ContentLoader.cpp b/src/content/ContentLoader.cpp index fee559e4..1dc676ea 100644 --- a/src/content/ContentLoader.cpp +++ b/src/content/ContentLoader.cpp @@ -239,10 +239,18 @@ void ContentLoader::loadBlock( } def.model = *model; } else if (!modelTypeName.empty()) { - logger.error() << "unknown model " << modelTypeName; + logger.error() << "unknown model: " << modelTypeName; def.model = BlockModel::none; } + std::string cullingModeName = to_string(def.culling); + root.at("culling").get(cullingModeName); + if (auto mode = CullingMode_from(cullingModeName)) { + def.culling = *mode; + } else { + logger.error() << "unknown culling mode: " << cullingModeName; + } + root.at("material").get(def.material); // rotation profile diff --git a/src/graphics/render/BlocksRenderer.cpp b/src/graphics/render/BlocksRenderer.cpp index cb590bcb..f1e8001f 100644 --- a/src/graphics/render/BlocksRenderer.cpp +++ b/src/graphics/render/BlocksRenderer.cpp @@ -342,41 +342,41 @@ void BlocksRenderer::blockCube( } if (ao) { - if (isOpen(coord + Z, group)) { + if (isOpen(coord + Z, block)) { faceAO(coord, X, Y, Z, texfaces[5], lights); } - if (isOpen(coord - Z, group)) { + if (isOpen(coord - Z, block)) { faceAO(coord, -X, Y, -Z, texfaces[4], lights); } - if (isOpen(coord + Y, group)) { + if (isOpen(coord + Y, block)) { faceAO(coord, X, -Z, Y, texfaces[3], lights); } - if (isOpen(coord - Y, group)) { + if (isOpen(coord - Y, block)) { faceAO(coord, X, Z, -Y, texfaces[2], lights); } - if (isOpen(coord + X, group)) { + if (isOpen(coord + X, block)) { faceAO(coord, -Z, Y, X, texfaces[1], lights); } - if (isOpen(coord - X, group)) { + if (isOpen(coord - X, block)) { faceAO(coord, Z, Y, -X, texfaces[0], lights); } } else { - if (isOpen(coord + Z, group)) { + if (isOpen(coord + Z, block)) { face(coord, X, Y, Z, texfaces[5], pickLight(coord + Z), lights); } - if (isOpen(coord - Z, group)) { + if (isOpen(coord - Z, block)) { face(coord, -X, Y, -Z, texfaces[4], pickLight(coord - Z), lights); } - if (isOpen(coord + Y, group)) { + if (isOpen(coord + Y, block)) { face(coord, X, -Z, Y, texfaces[3], pickLight(coord + Y), lights); } - if (isOpen(coord - Y, group)) { + if (isOpen(coord - Y, block)) { face(coord, X, Z, -Y, texfaces[2], pickLight(coord - Y), lights); } - if (isOpen(coord + X, group)) { + if (isOpen(coord + X, block)) { face(coord, -Z, Y, X, texfaces[1], pickLight(coord + X), lights); } - if (isOpen(coord - X, group)) { + if (isOpen(coord - X, block)) { face(coord, Z, Y, -X, texfaces[0], pickLight(coord - X), lights); } } diff --git a/src/graphics/render/BlocksRenderer.hpp b/src/graphics/render/BlocksRenderer.hpp index c0e0086e..d27f681b 100644 --- a/src/graphics/render/BlocksRenderer.hpp +++ b/src/graphics/render/BlocksRenderer.hpp @@ -118,7 +118,7 @@ class BlocksRenderer { bool isOpenForLight(int x, int y, int z) const; // Does block allow to see other blocks sides (is it transparent) - inline bool isOpen(const glm::ivec3& pos, ubyte group) const { + inline bool isOpen(const glm::ivec3& pos, const Block& def) const { auto id = voxelsBuffer->pickBlockId( chunk->x * CHUNK_W + pos.x, pos.y, chunk->z * CHUNK_D + pos.z ); @@ -126,7 +126,11 @@ class BlocksRenderer { return false; } const auto& block = *blockDefsCache[id]; - if ((block.drawGroup != group && block.lightPassing) || !block.rt.solid) { + if (((block.drawGroup != def.drawGroup) && block.drawGroup) || !block.rt.solid) { + return true; + } + if (def.culling == CullingMode::DISABLED || + (def.culling == CullingMode::OPTIONAL && id == def.rt.id)) { return true; } return !id; diff --git a/src/voxels/Block.cpp b/src/voxels/Block.cpp index 520f9f99..96bca245 100644 --- a/src/voxels/Block.cpp +++ b/src/voxels/Block.cpp @@ -49,6 +49,30 @@ std::optional BlockModel_from(std::string_view str) { return std::nullopt; } +std::string to_string(CullingMode mode) { + switch (mode) { + case CullingMode::DEFAULT: + return "default"; + case CullingMode::OPTIONAL: + return "optional"; + case CullingMode::DISABLED: + return "disabled"; + default: + return "unknown"; + } +} + +std::optional CullingMode_from(std::string_view str) { + if (str == "default") { + return CullingMode::DEFAULT; + } else if (str == "optional") { + return CullingMode::OPTIONAL; + } else if (str == "disabled") { + return CullingMode::DISABLED; + } + return std::nullopt; +} + CoordSystem::CoordSystem(glm::ivec3 axisX, glm::ivec3 axisY, glm::ivec3 axisZ) : axisX(axisX), axisY(axisY), axisZ(axisZ) { fix = glm::ivec3(0); diff --git a/src/voxels/Block.hpp b/src/voxels/Block.hpp index 557bf04c..eb232e8d 100644 --- a/src/voxels/Block.hpp +++ b/src/voxels/Block.hpp @@ -97,6 +97,15 @@ enum class BlockModel { std::string to_string(BlockModel model); std::optional BlockModel_from(std::string_view str); +enum class CullingMode { + DEFAULT, + OPTIONAL, + DISABLED, +}; + +std::string to_string(CullingMode mode); +std::optional CullingMode_from(std::string_view str); + using BoxModel = AABB; /// @brief Common kit of block properties applied to groups of blocks @@ -142,6 +151,9 @@ public: std::string modelName = ""; + /// @brief Culling mode + CullingMode culling = CullingMode::DEFAULT; + /// @brief Does the block passing lights into itself bool lightPassing = false;