From 9e02f1122f58e1b9afd3dd02b27ccd62ea78e29f Mon Sep 17 00:00:00 2001 From: MihailRis Date: Wed, 20 Nov 2024 14:42:53 +0300 Subject: [PATCH] add BlockWrapsRenderer (WIP) --- src/graphics/render/BlockWrapsRenderer.cpp | 103 +++++++++++++++++++++ src/graphics/render/BlockWrapsRenderer.hpp | 38 ++++++++ src/graphics/render/ChunksRenderer.cpp | 1 + src/graphics/render/WorldRenderer.cpp | 5 +- src/graphics/render/WorldRenderer.hpp | 2 + src/maths/UVRegion.hpp | 11 +++ src/world/Level.hpp | 2 +- 7 files changed, 160 insertions(+), 2 deletions(-) create mode 100644 src/graphics/render/BlockWrapsRenderer.cpp create mode 100644 src/graphics/render/BlockWrapsRenderer.hpp diff --git a/src/graphics/render/BlockWrapsRenderer.cpp b/src/graphics/render/BlockWrapsRenderer.cpp new file mode 100644 index 00000000..82ddf951 --- /dev/null +++ b/src/graphics/render/BlockWrapsRenderer.cpp @@ -0,0 +1,103 @@ +#include "BlockWrapsRenderer.hpp" + +#include "assets/Assets.hpp" +#include "assets/assets_util.hpp" +#include "constants.hpp" +#include "content/Content.hpp" +#include "graphics/core/Atlas.hpp" +#include "graphics/core/Shader.hpp" +#include "graphics/core/DrawContext.hpp" +#include "graphics/render/MainBatch.hpp" +#include "objects/Player.hpp" +#include "voxels/Block.hpp" +#include "voxels/Chunks.hpp" +#include "window/Window.hpp" +#include "world/Level.hpp" + +BlockWrapsRenderer::BlockWrapsRenderer(const Assets& assets, const Level& level) + : assets(assets), level(level), batch(std::make_unique(1024)) { +} + +BlockWrapsRenderer::~BlockWrapsRenderer() = default; + +void BlockWrapsRenderer::draw(const BlockWrapper& wrapper) { + const auto& chunks = *level.chunks; + + auto textureRegion = util::get_texture_region(assets, wrapper.texture, ""); + + auto& shader = assets.require("entity"); + shader.use(); + shader.uniform1i("u_alphaClip", false); + + const UVRegion& cracksRegion = textureRegion.region; + UVRegion regions[6] { + cracksRegion, cracksRegion, cracksRegion, + cracksRegion, cracksRegion, cracksRegion + }; + batch->setTexture(textureRegion.texture); + + const voxel* vox = chunks.get(wrapper.position); + if (vox == nullptr) { + return; + } + if (vox->id != BLOCK_VOID) { + const auto& def = + level.content->getIndices()->blocks.require(vox->id); + switch (def.model) { + case BlockModel::block: + batch->cube( + glm::vec3(wrapper.position) + glm::vec3(0.5f), + glm::vec3(1.01f), + regions, + glm::vec4(0), + false + ); + break; + case BlockModel::aabb: { + const auto& aabb = def.rt.hitboxes[vox->state.rotation].at(0); + const auto& size = aabb.size(); + regions[0].scale(size.z, size.y); + regions[1].scale(size.z, size.y); + regions[2].scale(size.x, size.z); + regions[3].scale(size.x, size.z); + regions[4].scale(size.x, size.y); + regions[5].scale(size.x, size.y); + batch->cube( + glm::vec3(wrapper.position) + aabb.center(), + size * glm::vec3(1.01f), + regions, + glm::vec4(0), + false + ); + break; + } + default: + break; + } + } +} + +void BlockWrapsRenderer::draw(const DrawContext& pctx, const Player& player) { + auto ctx = pctx.sub(); + + + batch->flush(); +} + +u64id_t BlockWrapsRenderer::add( + const glm::ivec3& position, const std::string& texture +) { + u64id_t id = nextWrapper++; + wrappers[id] = std::make_unique( + BlockWrapper {position, texture} + ); + return id; +} + +BlockWrapper* BlockWrapsRenderer::get(u64id_t id) const { + const auto& found = wrappers.find(id); + if (found == wrappers.end()) { + return nullptr; + } + return found->second.get(); +} diff --git a/src/graphics/render/BlockWrapsRenderer.hpp b/src/graphics/render/BlockWrapsRenderer.hpp new file mode 100644 index 00000000..3cb21cba --- /dev/null +++ b/src/graphics/render/BlockWrapsRenderer.hpp @@ -0,0 +1,38 @@ +#pragma once + +#include +#include +#include + +#include "MainBatch.hpp" +#include "typedefs.hpp" + +class Assets; +class Player; +class Level; +class DrawContext; + +struct BlockWrapper { + glm::ivec3 position; + std::string texture; +}; + +class BlockWrapsRenderer { + const Assets& assets; + const Level& level; + std::unique_ptr batch; + + std::unordered_map> wrappers; + u64id_t nextWrapper = 1; + + void draw(const BlockWrapper& wrapper); +public: + BlockWrapsRenderer(const Assets& assets, const Level& level); + ~BlockWrapsRenderer(); + + void draw(const DrawContext& ctx, const Player& player); + + u64id_t add(const glm::ivec3& position, const std::string& texture); + + BlockWrapper* get(u64id_t id) const; +}; diff --git a/src/graphics/render/ChunksRenderer.cpp b/src/graphics/render/ChunksRenderer.cpp index d3686a86..78ed45bf 100644 --- a/src/graphics/render/ChunksRenderer.cpp +++ b/src/graphics/render/ChunksRenderer.cpp @@ -236,6 +236,7 @@ void ChunksRenderer::drawSortedMeshes(const Camera& camera, Shader& shader) { const auto& cameraPos = camera.position; const auto& atlas = assets.require("blocks"); + shader.use(); atlas.getTexture()->bind(); shader.uniformMatrix("u_model", glm::mat4(1.0f)); shader.uniform1i("u_alphaClip", false); diff --git a/src/graphics/render/WorldRenderer.cpp b/src/graphics/render/WorldRenderer.cpp index 30284187..7084d2de 100644 --- a/src/graphics/render/WorldRenderer.cpp +++ b/src/graphics/render/WorldRenderer.cpp @@ -41,6 +41,7 @@ #include "graphics/core/Shader.hpp" #include "graphics/core/Texture.hpp" #include "graphics/core/Font.hpp" +#include "BlockWrapsRenderer.hpp" #include "ParticlesRenderer.hpp" #include "TextsRenderer.hpp" #include "ChunksRenderer.hpp" @@ -80,7 +81,8 @@ WorldRenderer::WorldRenderer( *frustumCulling, frontend.getContentGfxCache(), engine->getSettings() - )) { + )), + blockWraps(std::make_unique(assets, level)) { auto& settings = engine->getSettings(); level.events->listen( EVT_CHUNK_HIDDEN, @@ -170,6 +172,7 @@ void WorldRenderer::renderLevel( setupWorldShader(shader, camera, settings, fogFactor); chunks->drawChunks(camera, shader); + blockWraps->draw(ctx, *player); if (hudVisible) { renderLines(camera, linesShader, ctx); diff --git a/src/graphics/render/WorldRenderer.hpp b/src/graphics/render/WorldRenderer.hpp index b94694bd..94105726 100644 --- a/src/graphics/render/WorldRenderer.hpp +++ b/src/graphics/render/WorldRenderer.hpp @@ -17,6 +17,7 @@ class Batch3D; class LineBatch; class ChunksRenderer; class ParticlesRenderer; +class BlockWrapsRenderer; class GuidesRenderer; class TextsRenderer; class Shader; @@ -39,6 +40,7 @@ class WorldRenderer { std::unique_ptr lineBatch; std::unique_ptr batch3d; std::unique_ptr chunks; + std::unique_ptr blockWraps; std::unique_ptr guides; std::unique_ptr skybox; std::unique_ptr modelBatch; diff --git a/src/maths/UVRegion.hpp b/src/maths/UVRegion.hpp index 75b0ab6b..019c8760 100644 --- a/src/maths/UVRegion.hpp +++ b/src/maths/UVRegion.hpp @@ -40,4 +40,15 @@ struct UVRegion { float h = getHeight(); return glm::vec2(u1 + uv.x * w, v1 + uv.y * h); } + + void scale(float x, float y) { + float w = getWidth(); + float h = getHeight(); + float cx = (u1 + u2) * 0.5f; + float cy = (v1 + v2) * 0.5f; + u1 = cx - w * 0.5f * x; + v1 = cy - h * 0.5f * y; + u2 = cx + w * 0.5f * x; + v2 = cy + h * 0.5f * y; + } }; diff --git a/src/world/Level.hpp b/src/world/Level.hpp index c88a1617..767844cf 100644 --- a/src/world/Level.hpp +++ b/src/world/Level.hpp @@ -72,7 +72,7 @@ public: } template - std::shared_ptr getObject(uint64_t id) { + std::shared_ptr getObject(uint64_t id) const { static_assert( std::is_base_of::value, "T must be a derived of Object class"