From c2dd185c0849bd9e1207958caad5c8a06a6c238e Mon Sep 17 00:00:00 2001 From: MihailRis Date: Fri, 5 Jan 2024 18:41:55 +0300 Subject: [PATCH] Hud refactor --- src/frontend/InventoryView.cpp | 104 +++++++++++++++++++++++++++++++++ src/frontend/InventoryView.h | 45 ++++++++++++++ src/frontend/hud.cpp | 100 +++++++------------------------ src/frontend/hud.h | 7 +-- src/frontend/screens.cpp | 10 +++- src/frontend/screens.h | 7 ++- 6 files changed, 183 insertions(+), 90 deletions(-) create mode 100644 src/frontend/InventoryView.cpp create mode 100644 src/frontend/InventoryView.h diff --git a/src/frontend/InventoryView.cpp b/src/frontend/InventoryView.cpp new file mode 100644 index 00000000..6685535f --- /dev/null +++ b/src/frontend/InventoryView.cpp @@ -0,0 +1,104 @@ +#include "InventoryView.h" + +#include + +#include "BlocksPreview.h" +#include "../window/Events.h" +#include "../assets/Assets.h" +#include "../graphics/Shader.h" +#include "../graphics/Batch2D.h" +#include "../graphics/GfxContext.h" +#include "../content/Content.h" +#include "../maths/voxmaths.h" +#include "../objects/Player.h" +#include "../voxels/Block.h" + +InventoryView::InventoryView( + int columns, + Player* player, + const Assets* assets, + const ContentIndices* indices, + const ContentGfxCache* cache, + std::vector blocks) + : player(player), + assets(assets), + indices(indices), + cache(cache), + blocks(blocks), + invColumns(columns) { + blocksPreview = new BlocksPreview(assets->getShader("ui3d"), + assets->getAtlas("blocks"), + cache); +} + +void InventoryView::setPosition(int x, int y) { + this->invX = x; + this->invY = y; +} + +int InventoryView::getWidth() const { + return invColumns * iconSize + (invColumns-1) * interval + padX * 2; +} + +int InventoryView::getHeight() const { + uint inv_rows = ceildiv(blocks.size(), invColumns); + return inv_rows * iconSize + (inv_rows-1) * interval + padY * 2; +} + +void InventoryView::actAndDraw(const GfxContext* ctx) { + Shader* uiShader = assets->getShader("ui"); + + auto viewport = ctx->getViewport(); + uint inv_w = getWidth(); + uint inv_h = getHeight(); + int xs = invX + padX; + int ys = invY + padY; + + glm::vec4 tint (1.0f); + int mx = Events::cursor.x; + int my = Events::cursor.y; + + // background + auto batch = ctx->getBatch2D(); + batch->texture(nullptr); + batch->color = glm::vec4(0.0f, 0.0f, 0.0f, 0.5f); + batch->rect(invX, invY, inv_w, inv_h); + batch->render(); + + // blocks & items + if (Events::scroll) { + inventoryScroll -= Events::scroll * (iconSize+interval); + } + inventoryScroll = std::min(inventoryScroll, int(inv_h-viewport.getHeight())); + inventoryScroll = std::max(inventoryScroll, 0); + blocksPreview->begin(&ctx->getViewport()); + { + Window::clearDepth(); + GfxContext subctx = ctx->sub(); + subctx.depthTest(true); + subctx.cullFace(true); + uint index = 0; + for (uint i = 0; i < blocks.size(); i++) { + Block* cblock = indices->getBlockDef(blocks[i]); + int x = xs + (iconSize+interval) * (index % invColumns); + int y = ys + (iconSize+interval) * (index / invColumns) - inventoryScroll; + if (y < -int(iconSize+interval) || y >= int(viewport.getHeight())) { + index++; + continue; + } + if (mx > x && mx < x + (int)iconSize && my > y && my < y + (int)iconSize) { + tint.r *= 1.2f; + tint.g *= 1.2f; + tint.b *= 1.2f; + if (Events::jclicked(mousecode::BUTTON_1)) { + player->chosenBlock = blocks[i]; + } + } else { + tint = glm::vec4(1.0f); + } + blocksPreview->draw(cblock, x, y, iconSize, tint); + index++; + } + } + uiShader->use(); +} diff --git a/src/frontend/InventoryView.h b/src/frontend/InventoryView.h new file mode 100644 index 00000000..792fec42 --- /dev/null +++ b/src/frontend/InventoryView.h @@ -0,0 +1,45 @@ +#ifndef FRONTEND_INVENTORY_VIEW_H_ +#define FRONTEND_INVENTORY_VIEW_H_ + +#include + +#include "../typedefs.h" + +class Player; +class Assets; +class GfxContext; +class ContentIndices; +class BlocksPreview; +class ContentGfxCache; + +class InventoryView { + Player* player; + const Assets* assets; + const ContentIndices* indices; + const ContentGfxCache* const cache; + std::vector blocks; + BlocksPreview* blocksPreview; + + int inventoryScroll = 0; + int invColumns; + uint iconSize = 48; + uint interval = 4; + int padX = interval; + int padY = interval; + int invX = 0; + int invY = 0; +public: + InventoryView( + int columns, + Player* player, + const Assets* assets, + const ContentIndices* indices, + const ContentGfxCache* cache, + std::vector blocks); + void setPosition(int x, int y); + void actAndDraw(const GfxContext* ctx); + int getWidth() const; + int getHeight() const; +}; + +#endif // FRONTEND_INVENTORY_VIEW_H_ diff --git a/src/frontend/hud.cpp b/src/frontend/hud.cpp index 1572e01f..2e8b7b3c 100644 --- a/src/frontend/hud.cpp +++ b/src/frontend/hud.cpp @@ -38,6 +38,7 @@ #include "screens.h" #include "WorldRenderer.h" #include "BlocksPreview.h" +#include "InventoryView.h" #include "../engine.h" #include "../core_defs.h" @@ -59,13 +60,28 @@ HudRenderer::HudRenderer(Engine* engine, const ContentGfxCache* cache) : level(level), assets(engine->getAssets()), - batch(new Batch2D(1024)), gui(engine->getGUI()), cache(cache) { auto menu = gui->getMenu(); blocksPreview = new BlocksPreview(assets->getShader("ui3d"), assets->getAtlas("blocks"), cache); + auto content = level->content; + auto indices = content->indices; + std::vector blocks; + for (blockid_t id = 1; id < indices->countBlockDefs(); id++) { + const Block* def = indices->getBlockDef(id); + if (def->hidden) + continue; + blocks.push_back(id); + } + contentAccess.reset(new InventoryView( + 8, + level->player, + assets, + indices, + cache, + blocks)); uicamera = new Camera(vec3(), 1); uicamera->perspective = false; @@ -195,7 +211,6 @@ HudRenderer::HudRenderer(Engine* engine, HudRenderer::~HudRenderer() { gui->remove(debugPanel); delete blocksPreview; - delete batch; delete uicamera; } @@ -205,81 +220,6 @@ void HudRenderer::drawDebug(int fps){ fpsMax = max(fps, fpsMax); } -/* Inventory temporary replaced with blocks access panel */ -void HudRenderer::drawContentAccess(const GfxContext& ctx, Player* player) { - const Content* content = level->content; - const ContentIndices* contentIds = content->indices; - - const Viewport& viewport = ctx.getViewport(); - const uint width = viewport.getWidth(); - Shader* uiShader = assets->getShader("ui"); - - uint count = contentIds->countBlockDefs(); - uint icon_size = 48; - uint interval = 4; - uint inv_cols = 8; - uint inv_rows = ceildiv(count-1, inv_cols); - int pad_x = interval; - int pad_y = interval; - uint inv_w = inv_cols * icon_size + (inv_cols-1) * interval + pad_x * 2; - uint inv_h = inv_rows * icon_size + (inv_rows-1) * interval + pad_x * 2; - int inv_x = (width - (inv_w)); - int inv_y = 0; - int xs = inv_x + pad_x; - int ys = inv_y + pad_y; - - vec4 tint = vec4(1.0f); - int mx = Events::cursor.x; - int my = Events::cursor.y; - - // background - 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 - if (Events::scroll) { - inventoryScroll -= Events::scroll * (icon_size+interval); - } - inventoryScroll = std::min(inventoryScroll, int(inv_h-viewport.getHeight())); - inventoryScroll = std::max(inventoryScroll, 0); - blocksPreview->begin(&ctx.getViewport()); - { - Window::clearDepth(); - GfxContext subctx = ctx.sub(); - subctx.depthTest(true); - subctx.cullFace(true); - uint index = 0; - for (uint i = 0; i < count-1; i++) { - Block* cblock = contentIds->getBlockDef(i+1); - if (cblock == nullptr) - break; - if (cblock->hidden) - continue; - int x = xs + (icon_size+interval) * (index % inv_cols); - int y = ys + (icon_size+interval) * (index / inv_cols) - inventoryScroll; - if (y < 0 || y >= int(viewport.getHeight())) { - index++; - continue; - } - 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->chosenBlock = i+1; - } - } else { - tint = vec4(1.0f); - } - blocksPreview->draw(cblock, x, y, icon_size, tint); - index++; - } - } - uiShader->use(); -} - void HudRenderer::update() { auto menu = gui->getMenu(); if (pause && menu->current().panel == nullptr) { @@ -322,6 +262,7 @@ void HudRenderer::draw(const GfxContext& ctx){ uishader->use(); uishader->uniformMatrix("u_projview", uicamera->getProjection()*uicamera->getView()); + auto batch = ctx.getBatch2D(); batch->begin(); // Chosen block preview @@ -361,7 +302,8 @@ void HudRenderer::draw(const GfxContext& ctx){ batch->rect(0, 0, width, height); } if (inventoryOpen) { - drawContentAccess(ctx, player); + contentAccess->setPosition(viewport.getWidth()-contentAccess->getWidth(), 0); + contentAccess->actAndDraw(&ctx); } batch->render(); } @@ -372,4 +314,4 @@ bool HudRenderer::isInventoryOpen() const { bool HudRenderer::isPause() const { return pause; -} \ No newline at end of file +} diff --git a/src/frontend/hud.h b/src/frontend/hud.h index e893d3b3..e2c7e2fa 100644 --- a/src/frontend/hud.h +++ b/src/frontend/hud.h @@ -8,7 +8,6 @@ #include "../graphics/GfxContext.h" -class Batch2D; class Camera; class Level; class Block; @@ -17,8 +16,8 @@ class Player; class Level; class Engine; class ContentGfxCache; -class WorldRenderer; class BlocksPreview; +class InventoryView; namespace gui { class GUI; @@ -28,7 +27,6 @@ namespace gui { class HudRenderer { Level* level; Assets* assets; - Batch2D* batch; Camera* uicamera; BlocksPreview* blocksPreview; @@ -37,9 +35,9 @@ class HudRenderer { int fpsMax = 60; std::wstring fpsString; bool inventoryOpen = false; - int inventoryScroll = 0; bool pause = false; + std::unique_ptr contentAccess; std::shared_ptr debugPanel; gui::GUI* gui; const ContentGfxCache* const cache; @@ -50,7 +48,6 @@ public: ~HudRenderer(); void update(); - void drawContentAccess(const GfxContext& ctx, Player* player); void draw(const GfxContext& context); void drawDebug(int fps); diff --git a/src/frontend/screens.cpp b/src/frontend/screens.cpp index 73edad59..f14e9e25 100644 --- a/src/frontend/screens.cpp +++ b/src/frontend/screens.cpp @@ -41,20 +41,24 @@ using glm::vec3; using glm::vec4; using std::shared_ptr; +Screen::Screen(Engine* engine) : engine(engine), batch(new Batch2D(1024)) { +} + +Screen::~Screen() { +} + MenuScreen::MenuScreen(Engine* engine_) : Screen(engine_) { auto menu = engine->getGUI()->getMenu(); menus::refresh_menus(engine, menu); menu->reset(); menu->set("main"); - batch = new Batch2D(1024); uicamera = new Camera(vec3(), Window::height); uicamera->perspective = false; uicamera->flipped = true; } MenuScreen::~MenuScreen() { - delete batch; delete uicamera; } @@ -155,7 +159,7 @@ void LevelScreen::draw(float delta) { Camera* camera = level->player->currentViewCamera; Viewport viewport(Window::width, Window::height); - GfxContext ctx(nullptr, viewport, nullptr); + GfxContext ctx(nullptr, viewport, batch.get()); worldRenderer->draw(ctx, camera); diff --git a/src/frontend/screens.h b/src/frontend/screens.h index e8b3f963..73991d8d 100644 --- a/src/frontend/screens.h +++ b/src/frontend/screens.h @@ -18,15 +18,15 @@ class LevelController; class Screen { protected: Engine* engine; + std::unique_ptr batch; public: - Screen(Engine* engine) : engine(engine) {}; - virtual ~Screen() {}; + Screen(Engine* engine); + virtual ~Screen(); virtual void update(float delta) = 0; virtual void draw(float delta) = 0; }; class MenuScreen : public Screen { - Batch2D* batch; Camera* uicamera; public: MenuScreen(Engine* engine); @@ -42,6 +42,7 @@ class LevelScreen : public Screen { WorldRenderer* worldRenderer; HudRenderer* hud; ContentGfxCache* cache; + bool hudVisible = true; void updateHotkeys(); public: