From db2108171cc42175e8661184b1bb6558c8612ab5 Mon Sep 17 00:00:00 2001 From: MihailRis Date: Sun, 21 Jan 2024 23:35:41 +0300 Subject: [PATCH] inventory render optimized --- src/constants.h | 2 + src/frontend/BlocksPreview.cpp | 112 +++++++---- src/frontend/BlocksPreview.h | 24 +-- src/frontend/InventoryView.cpp | 29 +-- src/frontend/InventoryView.h | 3 +- src/frontend/LevelFrontend.cpp | 12 +- src/frontend/LevelFrontend.h | 5 +- src/frontend/hud.cpp | 340 ++++++++++++++++----------------- src/graphics/Framebuffer.cpp | 6 +- src/graphics/Framebuffer.h | 2 +- src/window/Window.cpp | 4 + src/window/Window.h | 1 + 12 files changed, 285 insertions(+), 255 deletions(-) diff --git a/src/constants.h b/src/constants.h index dd5e56e0..f9cc1d4b 100644 --- a/src/constants.h +++ b/src/constants.h @@ -17,6 +17,8 @@ const int CHUNK_D = 16; const uint VOXEL_USER_BITS = 8; constexpr uint VOXEL_USER_BITS_OFFSET = sizeof(blockstate_t)*8-VOXEL_USER_BITS; +const int ITEM_ICON_SIZE = 48; + /* Chunk volume (count of voxels per Chunk) */ constexpr int CHUNK_VOL = (CHUNK_W * CHUNK_H * CHUNK_D); diff --git a/src/frontend/BlocksPreview.cpp b/src/frontend/BlocksPreview.cpp index 846afc4a..723cdc10 100644 --- a/src/frontend/BlocksPreview.cpp +++ b/src/frontend/BlocksPreview.cpp @@ -8,47 +8,23 @@ #include "../graphics/Texture.h" #include "../graphics/Atlas.h" #include "../graphics/Batch3D.h" +#include "../graphics/Framebuffer.h" +#include "../graphics/GfxContext.h" +#include "../window/Window.h" #include "../window/Camera.h" #include "../voxels/Block.h" +#include "../content/Content.h" +#include "../constants.h" #include "ContentGfxCache.h" -BlocksPreview::BlocksPreview(Assets* assets, const ContentGfxCache* cache) - : shader(assets->getShader("ui3d")), - atlas(assets->getAtlas("blocks")), - cache(cache) { - batch = std::make_unique(1024); -} - -BlocksPreview::~BlocksPreview() { -} - -void BlocksPreview::begin(const Viewport* viewport) { - this->viewport = viewport; - shader->use(); - shader->uniformMatrix("u_projview", - glm::ortho(0.0f, float(viewport->getWidth()), - 0.0f, float(viewport->getHeight()), - -100.0f, 100.0f) * - glm::lookAt(glm::vec3(2, 2, 2), glm::vec3(0.0f), glm::vec3(0, 1, 0))); - atlas->getTexture()->bind(); -} - -/* Draw one block preview at given screen position */ -void BlocksPreview::draw(const Block* def, int x, int y, int size, glm::vec4 tint) { - uint width = viewport->getWidth(); - uint height = viewport->getHeight(); - - y = height - y - 1 - 35 /* magic garbage */; - x += 2; - - if (def->model == BlockModel::aabb) { - x += (1.0f - def->hitbox.size()).x * size * 0.5f; - y += (1.0f - def->hitbox.size()).y * size * 0.25f; - } - - glm::vec3 offset (x/float(width) * 2, y/float(height) * 2, 0.0f); - shader->uniformMatrix("u_apply", glm::translate(glm::mat4(1.0f), offset)); - +ImageData* BlocksPreview::draw( + const ContentGfxCache* cache, + Framebuffer* fbo, + Batch3D* batch, + const Block* def, + int size +){ + Window::clear(); blockid_t id = def->rt.id; const UVRegion texfaces[6]{cache->getRegion(id, 0), cache->getRegion(id, 1), cache->getRegion(id, 2), cache->getRegion(id, 3), @@ -59,11 +35,11 @@ void BlocksPreview::draw(const Block* def, int x, int y, int size, glm::vec4 tin // something went wrong... break; case BlockModel::block: - batch->blockCube(glm::vec3(size * 0.63f), texfaces, tint, !def->rt.emissive); + batch->blockCube(glm::vec3(size * 0.63f), texfaces, glm::vec4(1.0f), !def->rt.emissive); break; case BlockModel::aabb: batch->blockCube(def->hitbox.size() * glm::vec3(size * 0.63f), - texfaces, tint, !def->rt.emissive); + texfaces, glm::vec4(1.0f), !def->rt.emissive); break; case BlockModel::custom: case BlockModel::xsprite: { @@ -73,10 +49,64 @@ void BlocksPreview::draw(const Block* def, int x, int y, int size, glm::vec4 tin right, size*0.5f, size*0.6f, texfaces[0], - tint); + glm::vec4(1.0f)); break; } } - batch->flush(); + return fbo->texture->readData(); +} + +std::unique_ptr BlocksPreview::build( + const ContentGfxCache* cache, + Assets* assets, + const Content* content +) { + auto indices = content->getIndices(); + size_t count = indices->countBlockDefs(); + size_t iconSize = ITEM_ICON_SIZE; + + Shader* shader = assets->getShader("ui3d"); + Atlas* atlas = assets->getAtlas("blocks"); + + Viewport viewport(iconSize, iconSize); + GfxContext pctx(nullptr, viewport, nullptr); + GfxContext ctx = pctx.sub(); + ctx.cullFace(true); + ctx.depthTest(true); + + Framebuffer fbo(iconSize, iconSize, true); + Batch3D batch(1024); + batch.begin(); + + shader->use(); + shader->uniformMatrix("u_projview", + + glm::ortho(0.0f, float(iconSize), 0.0f, float(iconSize), + -100.0f, 100.0f) * + glm::lookAt(glm::vec3(2, 2, 2), + glm::vec3(0.0f), + glm::vec3(0, 1, 0))); + + AtlasBuilder builder; + Window::viewport(0, 0, iconSize, iconSize); + Window::setBgColor(glm::vec4(0.0f)); + + fbo.bind(); + for (size_t i = 0; i < count; i++) { + auto def = indices->getBlockDef(i); + + glm::vec3 offset(0.1f, 0.5f, 0.1f); + if (def->model == BlockModel::aabb) { + offset.y += (1.0f - def->hitbox.size()).y * 0.5f; + } + atlas->getTexture()->bind(); + shader->uniformMatrix("u_apply", glm::translate(glm::mat4(1.0f), offset)); + + builder.add(def->name, draw(cache, &fbo, &batch, def, iconSize)); + } + fbo.unbind(); + + Window::viewport(0, 0, Window::width, Window::height); + return std::unique_ptr(builder.build(2)); } diff --git a/src/frontend/BlocksPreview.h b/src/frontend/BlocksPreview.h index 0a1a03f3..5c4ab4c1 100644 --- a/src/frontend/BlocksPreview.h +++ b/src/frontend/BlocksPreview.h @@ -6,25 +6,27 @@ #include class Assets; -class Viewport; -class Shader; +class ImageData; class Atlas; +class Framebuffer; class Batch3D; class Block; +class Content; class ContentGfxCache; class BlocksPreview { - Shader* shader; - Atlas* atlas; - std::unique_ptr batch; - const ContentGfxCache* const cache; - const Viewport* viewport; public: - BlocksPreview(Assets* assets, const ContentGfxCache* cache); - ~BlocksPreview(); + static ImageData* draw( + const ContentGfxCache* cache, + Framebuffer* framebuffer, + Batch3D* batch, + const Block* block, + int size); - void begin(const Viewport* viewport); - void draw(const Block* block, int x, int y, int size, glm::vec4 tint); + static std::unique_ptr build( + const ContentGfxCache* cache, + Assets* assets, + const Content* content); }; #endif // FRONTEND_BLOCKS_PREVIEW_H_ diff --git a/src/frontend/InventoryView.cpp b/src/frontend/InventoryView.cpp index e10f2032..93c2f0bc 100644 --- a/src/frontend/InventoryView.cpp +++ b/src/frontend/InventoryView.cpp @@ -153,31 +153,26 @@ void SlotView::draw(Batch2D* batch, Assets* assets) { batch->color = glm::vec4(1.0f); - Shader* uiShader = assets->getShader("ui"); Viewport viewport(Window::width, Window::height); GfxContext ctx(nullptr, viewport, batch); - auto preview = frontend->getBlocksPreview(); + auto previews = frontend->getBlocksAtlas(); auto indices = content->getIndices(); ItemDef* item = indices->getItemDef(stack.getItemId()); switch (item->iconType) { case item_icon_type::none: break; - case item_icon_type::block: - batch->render(); - { - GfxContext subctx = ctx.sub(); - subctx.depthTest(true); - subctx.cullFace(true); + case item_icon_type::block: { + Block* cblock = content->requireBlock(item->icon); + batch->texture(previews->getTexture()); - Block* cblock = content->requireBlock(item->icon); - preview->begin(&subctx.getViewport()); - preview->draw(cblock, coord.x, coord.y, slotSize, tint); - } - uiShader->use(); - batch->begin(); + UVRegion region = previews->get(cblock->name); + batch->rect( + coord.x, coord.y, slotSize, slotSize, + 0, 0, 0, region, false, true, tint); break; + } case item_icon_type::sprite: { size_t index = item->icon.find(':'); std::string name = item->icon.substr(index+1); @@ -327,12 +322,6 @@ InventoryLayout* InventoryView::getLayout() const { return layout.get(); } -// performance disaster x2 -void InventoryView::draw(Batch2D* batch, Assets* assets) { - Container::draw(batch, assets); - Window::clearDepth(); -} - void InventoryView::drawBackground(Batch2D* batch, Assets* assets) { glm::vec2 coord = calcCoord(); batch->texture(nullptr); diff --git a/src/frontend/InventoryView.h b/src/frontend/InventoryView.h index 5c7df130..c8c4801d 100644 --- a/src/frontend/InventoryView.h +++ b/src/frontend/InventoryView.h @@ -126,7 +126,6 @@ public: void build(); - virtual void draw(Batch2D* batch, Assets* assets) override; virtual void drawBackground(Batch2D* batch, Assets* assets) override; void setInventory(std::shared_ptr inventory); @@ -138,7 +137,7 @@ public: void setSelected(int index); static const int SLOT_INTERVAL = 4; - static const int SLOT_SIZE = 48; + static const int SLOT_SIZE = ITEM_ICON_SIZE; }; class InventoryInteraction { diff --git a/src/frontend/LevelFrontend.cpp b/src/frontend/LevelFrontend.cpp index 4b1c6542..9561dfb2 100644 --- a/src/frontend/LevelFrontend.cpp +++ b/src/frontend/LevelFrontend.cpp @@ -2,6 +2,7 @@ #include "../world/Level.h" #include "../assets/Assets.h" +#include "../graphics/Atlas.h" #include "BlocksPreview.h" #include "ContentGfxCache.h" @@ -9,8 +10,7 @@ LevelFrontend::LevelFrontend(Level* level, Assets* assets) : level(level), assets(assets), contentCache(std::make_unique(level->content, assets)), - blocksPreview(std::make_unique(assets, contentCache.get())) { - + blocksAtlas(BlocksPreview::build(contentCache.get(), assets, level->content)) { } LevelFrontend::~LevelFrontend() { @@ -24,10 +24,10 @@ Assets* LevelFrontend::getAssets() const { return assets; } -BlocksPreview* LevelFrontend::getBlocksPreview() const { - return blocksPreview.get(); -} - ContentGfxCache* LevelFrontend::getContentGfxCache() const { return contentCache.get(); } + +Atlas* LevelFrontend::getBlocksAtlas() const { + return blocksAtlas.get(); +} diff --git a/src/frontend/LevelFrontend.h b/src/frontend/LevelFrontend.h index 095f5535..98a8a111 100644 --- a/src/frontend/LevelFrontend.h +++ b/src/frontend/LevelFrontend.h @@ -3,6 +3,7 @@ #include +class Atlas; class Level; class Assets; class BlocksPreview; @@ -12,15 +13,15 @@ class LevelFrontend { Level* level; Assets* assets; std::unique_ptr contentCache; - std::unique_ptr blocksPreview; + std::unique_ptr blocksAtlas; public: LevelFrontend(Level* level, Assets* assets); ~LevelFrontend(); Level* getLevel() const; Assets* getAssets() const; - BlocksPreview* getBlocksPreview() const; ContentGfxCache* getContentGfxCache() const; + Atlas* getBlocksAtlas() const; }; diff --git a/src/frontend/hud.cpp b/src/frontend/hud.cpp index ea82473e..4d0a5493 100644 --- a/src/frontend/hud.cpp +++ b/src/frontend/hud.cpp @@ -52,106 +52,106 @@ using glm::vec4; using namespace gui; inline std::shared_ptr