From 1fda002e0b74f6bfad8201dc4de331f3621d8c9d Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 1 Dec 2023 13:56:35 +0300 Subject: [PATCH] Actual 3D block icons --- res/shaders/ui3d.glslv | 3 +- src/frontend/hud.cpp | 80 +++++++++++++++++++++++----------------- src/frontend/hud.h | 3 +- src/graphics/Batch3D.cpp | 48 +++++++++++++----------- src/graphics/Batch3D.h | 8 ++-- 5 files changed, 81 insertions(+), 61 deletions(-) diff --git a/res/shaders/ui3d.glslv b/res/shaders/ui3d.glslv index f53b1a1b..65ccf0df 100644 --- a/res/shaders/ui3d.glslv +++ b/res/shaders/ui3d.glslv @@ -6,9 +6,10 @@ out vec2 a_textureCoord; out vec4 a_color; uniform mat4 u_projview; +uniform mat4 u_apply; void main(){ a_textureCoord = v_textureCoord; a_color = v_color; - gl_Position = u_projview * vec4(v_position, 1.0); + gl_Position = u_apply * u_projview * vec4(v_position, 1.0); } diff --git a/src/frontend/hud.cpp b/src/frontend/hud.cpp index 0d2bfa07..ef97acd2 100644 --- a/src/frontend/hud.cpp +++ b/src/frontend/hud.cpp @@ -15,6 +15,7 @@ #include "../assets/Assets.h" #include "../graphics/Shader.h" #include "../graphics/Batch2D.h" +#include "../graphics/Batch3D.h" #include "../graphics/Font.h" #include "../graphics/Atlas.h" #include "../graphics/Mesh.h" @@ -36,6 +37,7 @@ #include "ContentGfxCache.h" #include "screens.h" #include "WorldRenderer.h" +#include "BlocksPreview.h" #include "../engine.h" #include "../core_defs.h" @@ -58,11 +60,15 @@ HudRenderer::HudRenderer(Engine* engine, WorldRenderer* renderer) : level(level), assets(engine->getAssets()), + batch(new Batch2D(1024)), gui(engine->getGUI()), cache(cache), renderer(renderer) { auto menu = gui->getMenu(); - batch = new Batch2D(1024); + blocksPreview = new BlocksPreview(assets->getShader("ui3d"), + assets->getAtlas("blocks"), + cache); + uicamera = new Camera(vec3(), 1); uicamera->perspective = false; uicamera->flipped = true; @@ -180,6 +186,7 @@ HudRenderer::HudRenderer(Engine* engine, HudRenderer::~HudRenderer() { gui->remove(debugPanel); + delete blocksPreview; delete batch; delete uicamera; } @@ -197,7 +204,7 @@ void HudRenderer::drawContentAccess(const GfxContext& ctx, Player* player) { const Viewport& viewport = ctx.getViewport(); const uint width = viewport.getWidth(); - Atlas* atlas = assets->getAtlas("blocks"); + Shader* uiShader = assets->getShader("ui"); uint count = contentIds->countBlockDefs(); uint icon_size = 48; @@ -221,37 +228,35 @@ void HudRenderer::drawContentAccess(const GfxContext& ctx, Player* player) { batch->texture(nullptr); batch->color = vec4(0.0f, 0.0f, 0.0f, 0.5f); batch->rect(inv_x, inv_y, inv_w, inv_h); + batch->render(); // blocks & items - batch->texture(atlas->getTexture()); - for (uint i = 0; i < count-1; i++) { - Block* cblock = contentIds->getBlockDef(i+1); - if (cblock == nullptr) - break; - int x = xs + (icon_size+interval) * (i % inv_cols); - int y = ys + (icon_size+interval) * (i / inv_cols); - if (mx > x && mx < x + (int)icon_size && my > y && my < y + (int)icon_size) { - tint.r *= 1.2f; - tint.g *= 1.2f; - tint.b *= 1.2f; - if (Events::jclicked(mousecode::BUTTON_1)) { - player->choosenBlock = i+1; + blocksPreview->begin(); + { + Window::clearDepth(); + GfxContext subctx = ctx.sub(); + subctx.depthTest(true); + subctx.cullFace(true); + for (uint i = 0; i < count-1; i++) { + Block* cblock = contentIds->getBlockDef(i+1); + if (cblock == nullptr) + break; + int x = xs + (icon_size+interval) * (i % inv_cols); + int y = ys + (icon_size+interval) * (i / inv_cols); + if (mx > x && mx < x + (int)icon_size && my > y && my < y + (int)icon_size) { + tint.r *= 1.2f; + tint.g *= 1.2f; + tint.b *= 1.2f; + if (Events::jclicked(mousecode::BUTTON_1)) { + player->choosenBlock = i+1; + } + } else { + tint = vec4(1.0f); } - } else { - tint = vec4(1.0f); + blocksPreview->draw(cblock, x, y, icon_size, tint); } - drawBlockPreview(cblock, x, y, icon_size, icon_size, tint); - } -} - -void HudRenderer::drawBlockPreview(const Block* def, float x, float y, float w, float h, vec4 tint) { - if (def->model == BlockModel::block){ - batch->blockSprite(x, y, w, h, &cache->getRegion(def->rt.id, 0), tint); - } else if (def->model == BlockModel::aabb) { - batch->blockSprite(x, y, w, h, &cache->getRegion(def->rt.id, 0), tint, def->hitbox.size()); - } else if (def->model == BlockModel::xsprite){ - batch->sprite(x, y, w, h, cache->getRegion(def->rt.id, 3), tint); } + uiShader->use(); } void HudRenderer::update() { @@ -288,8 +293,6 @@ void HudRenderer::draw(const GfxContext& ctx){ const uint width = viewport.getWidth(); const uint height = viewport.getHeight(); - Atlas* atlas = assets->getAtlas("blocks"); - debugPanel->visible(level->player->debug); uicamera->fov = height; @@ -312,16 +315,25 @@ void HudRenderer::draw(const GfxContext& ctx){ Player* player = level->player; - batch->color = vec4(0.0f, 0.0f, 0.0f, 0.5f); + batch->color = vec4(0.0f, 0.0f, 0.0f, 0.75f); batch->rect(width - 68, height - 68, 68, 68); - batch->color = vec4(1.0f); - batch->texture(atlas->getTexture()); + batch->render(); + + blocksPreview->begin(); { + Window::clearDepth(); + GfxContext subctx = ctx.sub(); + subctx.depthTest(true); + subctx.cullFace(true); + Block* cblock = contentIds->getBlockDef(player->choosenBlock); assert(cblock != nullptr); - drawBlockPreview(cblock, width - 56, uicamera->fov - 56, 48, 48, vec4(1.0f)); + blocksPreview->draw(cblock, width - 56, uicamera->fov - 56, 48, vec4(1.0f)); + //drawBlockPreview(cblock, width - 56, uicamera->fov - 56, 48, 48, vec4(1.0f)); } + uishader->use(); + batch->begin(); if (pause) { batch->texture(nullptr); diff --git a/src/frontend/hud.h b/src/frontend/hud.h index 25f595af..9d2e7f2e 100644 --- a/src/frontend/hud.h +++ b/src/frontend/hud.h @@ -18,6 +18,7 @@ class Level; class Engine; class ContentGfxCache; class WorldRenderer; +class BlocksPreview; namespace gui { class GUI; @@ -29,6 +30,7 @@ class HudRenderer { Assets* assets; Batch2D* batch; Camera* uicamera; + BlocksPreview* blocksPreview; int fps = 60; int fpsMin = 60; @@ -42,7 +44,6 @@ class HudRenderer { const ContentGfxCache* const cache; WorldRenderer* renderer; - void drawBlockPreview(const Block* def, float x, float y, float w, float h, glm::vec4 tint); public: HudRenderer(Engine* engine, Level* level, diff --git a/src/graphics/Batch3D.cpp b/src/graphics/Batch3D.cpp index 860c6156..275797b7 100644 --- a/src/graphics/Batch3D.cpp +++ b/src/graphics/Batch3D.cpp @@ -14,8 +14,7 @@ using glm::vec4; Batch3D::Batch3D(size_t capacity) : capacity(capacity), - offset(0), - color(1.0f, 1.0f, 1.0f, 1.0f) { + offset(0) { const vattr attrs[] = { {3}, {2}, {4}, {0} }; @@ -86,7 +85,7 @@ void Batch3D::face(const vec3& coord, float w, float h, const UVRegion& region, const vec4& tint) { if (index + VERTEX_SIZE * 4 > capacity) { - render(); + flush(); } vertex(coord, region.u1, region.v1, tint.r, tint.g, tint.b, tint.a); @@ -106,7 +105,7 @@ void Batch3D::face(const vec3& coord, float w, float h, void Batch3D::texture(Texture* new_texture){ if (_texture == new_texture) return; - render(); + flush(); _texture = new_texture; if (new_texture == nullptr) blank->bind(); @@ -114,48 +113,49 @@ void Batch3D::texture(Texture* new_texture){ new_texture->bind(); } -void Batch3D::sprite(vec3 pos, vec3 up, vec3 right, float w, float h){ +void Batch3D::sprite(vec3 pos, vec3 up, vec3 right, float w, float h, const UVRegion& uv, vec4 color){ const float r = color.r; const float g = color.g; const float b = color.b; const float a = color.a; - if (index + 6*VERTEX_SIZE >= capacity) - render(); + if (index + 6*VERTEX_SIZE >= capacity) { + flush(); + } vertex(pos.x - right.x * w - up.x * h, pos.y - right.y * w - up.y * h, pos.z - right.z * w - up.z * h, - 0, 0, + uv.u1, uv.v1, r,g,b,a); vertex(pos.x + right.x * w + up.x * h, pos.y + right.y * w + up.y * h, pos.z + right.z * w + up.z * h, - 1, 1, + uv.u2, uv.v2, r,g,b,a); vertex(pos.x - right.x * w - up.x * h, pos.y + right.y * w + up.y * h, pos.z - right.z * w - up.z * h, - 0, 1, + uv.u1, uv.v2, r,g,b,a); vertex(pos.x - right.x * w - up.x * h, pos.y - right.y * w - up.y * h, pos.z - right.z * w - up.z * h, - 0, 0, + uv.u1, uv.v1, r,g,b,a); vertex(pos.x + right.x * w + up.x * h, pos.y - right.y * w - up.y * h, pos.z + right.z * w + up.z * h, - 1, 0, + uv.u2, uv.v1, r,g,b,a); vertex(pos.x + right.x * w + up.x * h, pos.y + right.y * w + up.y * h, pos.z + right.z * w + up.z * h, - 1, 1, + uv.u2, uv.v2, r,g,b,a); } @@ -163,16 +163,22 @@ inline vec4 do_tint(float value) { return vec4(value, value, value, 1.0f); } -void Batch3D::blockCube(const vec3& size, const UVRegion(&texfaces)[6], ubyte group) { - face(vec3(0.0f, 0.0f, 0.0f), size.x, size.y, vec3(1, 0, 0), vec3(0, 1, 0), texfaces[5], do_tint(1.0)); - face(vec3(size.x, 0.0f, -size.z), size.x, size.y, vec3(-1, 0, 0), vec3(0, 1, 0), texfaces[4], vec4(1.0f)); - face(vec3(0.0f, size.y, 0.0f), size.x, size.z, vec3(1, 0, 0), vec3(0, 0, -1), texfaces[3], vec4(1.0f)); - face(vec3(0.0f, 0.0f, -size.z), size.x, size.z, vec3(1, 0, 0), vec3(0, 0, 1), texfaces[2], vec4(1.0f)); - face(vec3(0.0f, 0.0f, -size.z), size.z, size.y, vec3(0, 0, 1), vec3(0, 1, 0), texfaces[0], vec4(1.0f)); - face(vec3(size.x, 0.0f, 0.0f), size.z, size.y, vec3(0, 0, -1), vec3(0, 1, 0), texfaces[1], vec4(1.0f)); +void Batch3D::xSprite(float w, float h, const UVRegion& uv, const vec4 tint, bool shading) { + face(vec3(-w *0.25f, 0.0f, 0.0f - w *0.25f), w, h, vec3(1, 0, 0), vec3(0, 1, 0), uv, (shading ? do_tint(1.0f)*tint : tint)); + face(vec3(w * 0.25f, 0.0f, w * 0.5f - w *0.25f), w, h, vec3(0, 0, -1), vec3(0, 1, 0), uv, (shading ? do_tint(0.9f)*tint : tint)); } -void Batch3D::render() { +void Batch3D::blockCube(const vec3 size, const UVRegion(&texfaces)[6], const vec4 tint, bool shading) { + vec3 coord = (1.0f - size) * -0.45f; + face(coord+vec3(0.0f, 0.0f, 0.0f), size.x, size.y, vec3(1, 0, 0), vec3(0, 1, 0), texfaces[5], (shading ? do_tint(0.8)*tint : tint)); + face(coord+vec3(size.x, 0.0f, -size.z), size.x, size.y, vec3(-1, 0, 0), vec3(0, 1, 0), texfaces[4], (shading ? do_tint(0.8f)*tint : tint)); + face(coord+vec3(0.0f, size.y, 0.0f), size.x, size.z, vec3(1, 0, 0), vec3(0, 0, -1), texfaces[3], (shading ? do_tint(1.0f)*tint : tint)); + face(coord+vec3(0.0f, 0.0f, -size.z), size.x, size.z, vec3(1, 0, 0), vec3(0, 0, 1), texfaces[2], (shading ? do_tint(0.7f)*tint : tint)); + face(coord+vec3(0.0f, 0.0f, -size.z), size.z, size.y, vec3(0, 0, 1), vec3(0, 1, 0), texfaces[0], (shading ? do_tint(0.9f)*tint : tint)); + face(coord+vec3(size.x, 0.0f, 0.0f), size.z, size.y, vec3(0, 0, -1), vec3(0, 1, 0), texfaces[1], (shading ? do_tint(0.9f)*tint : tint)); +} + +void Batch3D::flush() { mesh->reload(buffer, index / VERTEX_SIZE); mesh->draw(); index = 0; diff --git a/src/graphics/Batch3D.h b/src/graphics/Batch3D.h index 69a0fceb..5de47c84 100644 --- a/src/graphics/Batch3D.h +++ b/src/graphics/Batch3D.h @@ -13,7 +13,6 @@ class Batch3D { float* buffer; size_t capacity; size_t offset; - glm::vec4 color; Mesh* mesh; size_t index; @@ -41,9 +40,10 @@ public: void begin(); void texture(Texture* texture); - void sprite(glm::vec3 pos, glm::vec3 up, glm::vec3 right, float w, float h); - void blockCube(const glm::vec3& size, const UVRegion(&texfaces)[6], ubyte group); - void render(); + void sprite(glm::vec3 pos, glm::vec3 up, glm::vec3 right, float w, float h, const UVRegion& uv, glm::vec4 tint); + void xSprite(float w, float h, const UVRegion& uv, const glm::vec4 tint, bool shading=true); + void blockCube(const glm::vec3 size, const UVRegion(&texfaces)[6], const glm::vec4 tint, bool shading=true); + void flush(); }; #endif /* GRAPHICS_BATCH3D_H_ */