add BlockWrapsRenderer (WIP)

This commit is contained in:
MihailRis 2024-11-20 14:42:53 +03:00
parent 14b596140d
commit 9e02f1122f
7 changed files with 160 additions and 2 deletions

View File

@ -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<MainBatch>(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<Shader>("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>(
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();
}

View File

@ -0,0 +1,38 @@
#pragma once
#include <string>
#include <memory>
#include <unordered_map>
#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<MainBatch> batch;
std::unordered_map<u64id_t, std::unique_ptr<BlockWrapper>> 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;
};

View File

@ -236,6 +236,7 @@ void ChunksRenderer::drawSortedMeshes(const Camera& camera, Shader& shader) {
const auto& cameraPos = camera.position;
const auto& atlas = assets.require<Atlas>("blocks");
shader.use();
atlas.getTexture()->bind();
shader.uniformMatrix("u_model", glm::mat4(1.0f));
shader.uniform1i("u_alphaClip", false);

View File

@ -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<BlockWrapsRenderer>(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);

View File

@ -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> lineBatch;
std::unique_ptr<Batch3D> batch3d;
std::unique_ptr<ChunksRenderer> chunks;
std::unique_ptr<BlockWrapsRenderer> blockWraps;
std::unique_ptr<GuidesRenderer> guides;
std::unique_ptr<Skybox> skybox;
std::unique_ptr<ModelBatch> modelBatch;

View File

@ -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;
}
};

View File

@ -72,7 +72,7 @@ public:
}
template <class T>
std::shared_ptr<T> getObject(uint64_t id) {
std::shared_ptr<T> getObject(uint64_t id) const {
static_assert(
std::is_base_of<Object, T>::value,
"T must be a derived of Object class"