From 2c46659eb013496ca0ebd00a05851a9ee96f55df Mon Sep 17 00:00:00 2001 From: Renato Date: Sun, 12 Feb 2023 15:36:03 -0300 Subject: [PATCH 1/5] first --- src/framework/graphics/drawpool.cpp | 47 ++++++----------------------- src/framework/graphics/drawpool.h | 2 -- 2 files changed, 9 insertions(+), 40 deletions(-) diff --git a/src/framework/graphics/drawpool.cpp b/src/framework/graphics/drawpool.cpp index 19ff7360f5..9f4d5816dd 100644 --- a/src/framework/graphics/drawpool.cpp +++ b/src/framework/graphics/drawpool.cpp @@ -82,24 +82,12 @@ void DrawPool::add(const Color& color, const TexturePtr& texture, DrawMethod& me const size_t methodHash = updateHash(state, method); - const DrawOrder drawOrder = m_type == DrawPoolType::MAP ? DrawPool::DrawOrder::THIRD : DrawPool::DrawOrder::FIRST; + const uint8_t drawOrder = static_cast(m_type == DrawPoolType::MAP ? drawBuffer ? drawBuffer->m_order : DrawPool::DrawOrder::THIRD : DrawPool::DrawOrder::FIRST); if (m_type != DrawPoolType::FOREGROUND && (m_alwaysGroupDrawings || (drawBuffer && drawBuffer->m_agroup))) { if (const auto it = m_objectsByhash.find(state.hash); it != m_objectsByhash.end()) { const auto& buffer = it->second.buffer; - if (!buffer->isTemporary() && buffer->isValid()) { - auto& hashList = buffer->m_hashs; - if (++buffer->m_i != hashList.size()) { - // checks if the vertex to be added is in the same position, - // otherwise the buffer will be invalidated to recreate the cache. - if (hashList[buffer->m_i] != methodHash) - buffer->invalidate(); - else return; - } - hashList.push_back(methodHash); - } - if (coordsBuffer) buffer->getCoords()->append(coordsBuffer.get()); else @@ -108,36 +96,19 @@ void DrawPool::add(const Color& color, const TexturePtr& texture, DrawMethod& me return; } - const auto& buffer = drawBuffer ? drawBuffer : DrawBuffer::createTemporaryBuffer(drawOrder); - - bool addCoord = buffer->isTemporary(); - if (!addCoord) { // is not temp buffer - if (buffer->m_stateHash != state.hash || !buffer->isValid()) { - buffer->getCoords()->clear(); - buffer->m_stateHash = state.hash; - buffer->m_hashs.clear(); - buffer->m_hashs.push_back(methodHash); - addCoord = true; - } - buffer->m_i = 0; // reset identifier to say it is valid. - } - - if (addCoord) { - auto* coords = buffer->getCoords(); - if (coordsBuffer) - coords->append(coordsBuffer.get()); - else - addCoords(coords, method, DrawMode::TRIANGLES); - } + const auto& buffer = DrawBuffer::createTemporaryBuffer(static_cast(drawOrder)); + auto* coords = buffer->getCoords(); + if (coordsBuffer) + coords->append(coordsBuffer.get()); + else + addCoords(coords, method, DrawMode::TRIANGLES); - m_currentOrder = static_cast(buffer->m_order); - m_objectsByhash.emplace(state.hash, m_objects[m_currentFloor][m_currentOrder].emplace_back(state, buffer)); + m_objectsByhash.emplace(state.hash, m_objects[m_currentFloor][drawOrder].emplace_back(state, buffer)); return; } - m_currentOrder = static_cast(drawBuffer ? drawBuffer->m_order : drawOrder); - auto& list = m_objects[m_currentFloor][m_currentOrder]; + auto& list = m_objects[m_currentFloor][drawOrder]; if (!list.empty()) { auto& prevObj = list.back(); diff --git a/src/framework/graphics/drawpool.h b/src/framework/graphics/drawpool.h index 867b940924..774227544a 100644 --- a/src/framework/graphics/drawpool.h +++ b/src/framework/graphics/drawpool.h @@ -204,7 +204,6 @@ class DrawPool bool m_enabled{ true }; bool m_alwaysGroupDrawings{ false }; - uint8_t m_currentOrder{ 0 }; uint8_t m_currentFloor{ 0 }; uint16_t m_refreshDelay{ 0 }, m_shaderRefreshDelay{ 0 }; @@ -294,7 +293,6 @@ class DrawBuffer size_t m_ref{ 0 }; size_t m_stateHash{ 0 }; - std::vector m_hashs; CoordsBufferPtr m_coords; friend class DrawPool; From b914351ece537b514ebe302356bb9be7dcbf963f Mon Sep 17 00:00:00 2001 From: Renato Date: Sun, 12 Feb 2023 17:30:56 -0300 Subject: [PATCH 2/5] rewritedrawpool --- src/client/creature.cpp | 1 + src/client/effect.cpp | 6 +- src/client/effect.h | 1 + src/client/item.cpp | 30 ++++----- src/client/item.h | 2 +- src/client/mapview.cpp | 4 +- src/client/mapview.h | 2 +- src/client/missile.cpp | 5 +- src/client/missile.h | 1 + src/client/thing.cpp | 5 -- src/client/thing.h | 7 +- src/client/thingtype.cpp | 11 +-- src/client/thingtype.h | 2 +- src/client/tile.cpp | 4 +- src/framework/graphics/declarations.h | 2 - src/framework/graphics/drawpool.cpp | 60 +++++++---------- src/framework/graphics/drawpool.h | 78 ++++++---------------- src/framework/graphics/drawpoolmanager.cpp | 26 ++++---- src/framework/graphics/drawpoolmanager.h | 4 +- src/framework/util/color.h | 7 ++ 20 files changed, 102 insertions(+), 156 deletions(-) diff --git a/src/client/creature.cpp b/src/client/creature.cpp index 07de90bfcc..e69239f079 100644 --- a/src/client/creature.cpp +++ b/src/client/creature.cpp @@ -42,6 +42,7 @@ double Creature::speedC = 0; Creature::Creature() :m_type(Proto::CreatureTypeUnknown) { + m_drawConductor.order = DrawOrder::THIRD; m_name.setFont(g_fonts.getFont("verdana-11px-rounded")); m_name.setAlign(Fw::AlignTopCenter); diff --git a/src/client/effect.cpp b/src/client/effect.cpp index 7510a497b4..31cbeef44e 100644 --- a/src/client/effect.cpp +++ b/src/client/effect.cpp @@ -64,10 +64,10 @@ void Effect::drawEffect(const Point& dest, uint32_t flags, int offsetX, int offs yPattern += getNumPatternY(); } - if (g_app.isDrawingEffectsOnTop() && !m_drawBuffer) - m_drawBuffer = std::make_shared(DrawPool::DrawOrder::FOURTH); + if (g_app.isDrawingEffectsOnTop()) + m_drawConductor.agroup = true; - getThingType()->draw(dest, 0, xPattern, yPattern, 0, animationPhase, flags, TextureType::NONE, Color::white, lightView, m_drawBuffer); + getThingType()->draw(dest, 0, xPattern, yPattern, 0, animationPhase, flags, TextureType::NONE, Color::white, lightView, m_drawConductor); } void Effect::onAppear() diff --git a/src/client/effect.h b/src/client/effect.h index 969f26e047..91d4cbb443 100644 --- a/src/client/effect.h +++ b/src/client/effect.h @@ -30,6 +30,7 @@ class Effect : public Thing { public: + Effect() { m_drawConductor.order = DrawOrder::THIRD; }; void drawEffect(const Point& dest, uint32_t flags, int offsetX, int offsetY, LightView* lightView = nullptr); void setId(uint32_t id) override; diff --git a/src/client/item.cpp b/src/client/item.cpp index 45f636a25a..85fa1f5af6 100644 --- a/src/client/item.cpp +++ b/src/client/item.cpp @@ -56,7 +56,7 @@ void Item::draw(const Point& dest, uint32_t flags, TextureType textureType, bool drawAttachedEffect(dest, lightView, false); // On Bottom if (textureType != TextureType::ALL_BLANK && m_shader) g_drawPool.setShaderProgram(m_shader, true, m_shaderAction); - getThingType()->draw(dest, 0, m_numPatternX, m_numPatternY, m_numPatternZ, animationPhase, flags, textureType, m_color, lightView, m_drawBuffer); + getThingType()->draw(dest, 0, m_numPatternX, m_numPatternY, m_numPatternZ, animationPhase, flags, textureType, m_color, lightView, m_drawConductor); drawAttachedEffect(dest, lightView, true); // On Top if (isMarked) { @@ -64,26 +64,24 @@ void Item::draw(const Point& dest, uint32_t flags, TextureType textureType, bool } } -// Do not change if you do not understand what is being done. -void Item::createBuffer() +void Item::setConductor() { - DrawPool::DrawOrder order = DrawPool::DrawOrder::NONE; - if (isSingleGround()) - order = DrawPool::DrawOrder::FIRST; - else if (isSingleGroundBorder() && !hasElevation()) - order = DrawPool::DrawOrder::SECOND; - - m_drawBuffer = order != DrawPool::DrawOrder::NONE ? std::make_shared(order) : nullptr; + if (isSingleGround()) { + m_drawConductor.agroup = true; + m_drawConductor.order = DrawOrder::FIRST; + } else if (isSingleGroundBorder() && !hasElevation()) { + m_drawConductor.agroup = true; + m_drawConductor.order = DrawOrder::SECOND; + } else + m_drawConductor.order = DrawOrder::THIRD; } void Item::setPosition(const Position& position, uint8_t stackPos, bool hasElevation) { Thing::setPosition(position, stackPos); - if (hasElevation) - m_drawBuffer = nullptr; - else if (m_drawBuffer) - m_drawBuffer->agroup(stackPos == 0); + if (hasElevation || m_drawConductor.agroup && stackPos > 0) + m_drawConductor.agroup = false; } int Item::getSubType() @@ -244,7 +242,7 @@ void Item::setId(uint32_t id) m_clientId = id; m_thingType = g_things.getThingType(m_clientId, ThingCategoryItem).get(); - createBuffer(); + setConductor(); // Shader example on only items that can be marketed. /* @@ -289,7 +287,7 @@ void Item::setOtbId(uint16_t id) m_clientId = id; m_thingType = g_things.getThingType(m_clientId, ThingCategoryItem).get(); - createBuffer(); + setConductor(); } void Item::unserializeItem(const BinaryTreePtr& in) diff --git a/src/client/item.h b/src/client/item.h index 37755fb000..ec7a0b0457 100644 --- a/src/client/item.h +++ b/src/client/item.h @@ -148,7 +148,7 @@ class Item : public Thing #endif private: - void createBuffer(); + void setConductor(); uint8_t m_countOrSubType{ 0 }; diff --git a/src/client/mapview.cpp b/src/client/mapview.cpp index 06d1f47a2d..31ac7e7e17 100644 --- a/src/client/mapview.cpp +++ b/src/client/mapview.cpp @@ -85,8 +85,6 @@ MapView::MapView() : m_pool(g_drawPool.get(DrawPoolType::MAP)) g_painter->resetOpacity(); }); - m_shadowBuffer = std::make_shared(DrawPool::DrawOrder::FIFTH, false); - setVisibleDimension(Size(15, 11)); } @@ -184,7 +182,7 @@ void MapView::drawFloor() if (m_shadowFloorIntensity > 0 && z == cameraPosition.z + 1) { g_drawPool.setOpacity(m_shadowFloorIntensity, true); - g_drawPool.addFilledRect(m_rectDimension, Color::black, m_shadowBuffer); + g_drawPool.addFilledRect(m_rectDimension, Color::black, m_shadowConductor); } if (canFloorFade()) diff --git a/src/client/mapview.h b/src/client/mapview.h index 8a048fd856..e5af005166 100644 --- a/src/client/mapview.h +++ b/src/client/mapview.h @@ -304,6 +304,6 @@ class MapView : public LuaObject TilePtr m_lastHighlightTile; TexturePtr m_crosshairTexture; - DrawBufferPtr m_shadowBuffer; + DrawConductor m_shadowConductor{ false, DrawOrder::FIFTH }; DrawPoolFramed* m_pool; }; diff --git a/src/client/missile.cpp b/src/client/missile.cpp index 9dff05da1c..35a7c62dee 100644 --- a/src/client/missile.cpp +++ b/src/client/missile.cpp @@ -28,12 +28,12 @@ void Missile::drawMissile(const Point& dest, LightView* lightView) { - if (!canDraw() || !m_drawBuffer) + if (!canDraw()) return; const float fraction = m_animationTimer.ticksElapsed() / m_duration; getThingType()->draw(dest + m_delta * fraction * g_drawPool.getScaleFactor(), 0, m_numPatternX, m_numPatternY, 0, 0, - Otc::DrawThings | Otc::DrawLights, TextureType::NONE, Color::white, lightView, m_drawBuffer); + Otc::DrawThings | Otc::DrawLights, TextureType::NONE, Color::white, lightView, m_drawConductor); } void Missile::setPath(const Position& fromPosition, const Position& toPosition) @@ -53,7 +53,6 @@ void Missile::setPath(const Position& fromPosition, const Position& toPosition) m_delta *= SPRITE_SIZE; m_animationTimer.restart(); m_distance = fromPosition.distance(toPosition); - m_drawBuffer = std::make_shared(DrawPool::DrawOrder::FIFTH); { // Update Pattern if (m_direction == Otc::NorthWest) { diff --git a/src/client/missile.h b/src/client/missile.h index c2a883b001..cfe1d03837 100644 --- a/src/client/missile.h +++ b/src/client/missile.h @@ -30,6 +30,7 @@ class Missile : public Thing { public: + Missile() { m_drawConductor = { true, DrawOrder::FIFTH }; }; void drawMissile(const Point& dest, LightView* lightView = nullptr); void setId(uint32_t id) override; diff --git a/src/client/thing.cpp b/src/client/thing.cpp index dde8e903c1..3896657e9e 100644 --- a/src/client/thing.cpp +++ b/src/client/thing.cpp @@ -87,11 +87,6 @@ int Thing::getStackPos() return -1; } -void Thing::onDisappear() { - if (m_drawBuffer) - m_drawBuffer->invalidate(); -} - void Thing::setShader(const std::string_view name) { m_shader = g_shaders.getShader(name); } void Thing::attachEffect(const AttachedEffectPtr& obj) { diff --git a/src/client/thing.h b/src/client/thing.h index 629596f7f7..5ea1f32cf1 100644 --- a/src/client/thing.h +++ b/src/client/thing.h @@ -160,13 +160,12 @@ class Thing : public LuaObject void canDraw(bool canDraw) { m_canDraw = canDraw; } inline bool canDraw() const { return m_canDraw && m_clientId > 0; } - void destroyBuffer() { m_drawBuffer = nullptr; } - void setShader(const std::string_view name); + void ungroup() { m_drawConductor.agroup = false; } virtual void onPositionChange(const Position& /*newPos*/, const Position& /*oldPos*/) {} virtual void onAppear() {} - virtual void onDisappear(); + virtual void onDisappear() {}; const Color& getMarkedColor() { m_markedColor.setAlpha(0.1f + std::abs(500 - g_clock.millis() % 1000) / 1000.0f); return m_markedColor; } void attachEffect(const AttachedEffectPtr& obj); @@ -201,7 +200,7 @@ class Thing : public LuaObject Position m_position; ThingType* m_thingType{ nullptr }; - DrawBufferPtr m_drawBuffer; + DrawConductor m_drawConductor; Color m_markedColor{ Color::yellow }; diff --git a/src/client/thingtype.cpp b/src/client/thingtype.cpp index 5abe7a31e8..b5a58af5ee 100644 --- a/src/client/thingtype.cpp +++ b/src/client/thingtype.cpp @@ -597,7 +597,7 @@ void ThingType::unserializeOtml(const OTMLNodePtr& node) } } -void ThingType::draw(const Point& dest, int layer, int xPattern, int yPattern, int zPattern, int animationPhase, uint32_t flags, TextureType textureType, Color color, LightView* lightView, const DrawBufferPtr& drawBuffer) +void ThingType::draw(const Point& dest, int layer, int xPattern, int yPattern, int zPattern, int animationPhase, uint32_t flags, TextureType textureType, const Color& color, LightView* lightView, const DrawConductor& conductor) { if (m_null) return; @@ -621,13 +621,8 @@ void ThingType::draw(const Point& dest, int layer, int xPattern, int yPattern, i const Rect screenRect(dest + (textureOffset - m_displacement - (m_size.toPoint() - Point(1)) * SPRITE_SIZE) * g_drawPool.getScaleFactor(), textureRect.size() * g_drawPool.getScaleFactor()); if (flags & Otc::DrawThings) { - if (m_opacity < 1.0f) - color.setAlpha(m_opacity); - - if (drawBuffer) - drawBuffer->validate(dest); - - g_drawPool.addTexturedRect(screenRect, texture, textureRect, color, drawBuffer); + const Color& newColor = m_opacity < 1.0f ? Color(color, m_opacity) : color; + g_drawPool.addTexturedRect(screenRect, texture, textureRect, m_opacity < 1.0f ? Color(color) : color, conductor); } if (lightView && hasLight() && flags & Otc::DrawLights) { diff --git a/src/client/thingtype.h b/src/client/thingtype.h index f924a5c88a..4211019169 100644 --- a/src/client/thingtype.h +++ b/src/client/thingtype.h @@ -276,7 +276,7 @@ class ThingType : public LuaObject void exportImage(const std::string& fileName); #endif - void draw(const Point& dest, int layer, int xPattern, int yPattern, int zPattern, int animationPhase, uint32_t flags, TextureType textureType, Color color = Color::white, LightView* lightView = nullptr, const DrawBufferPtr& drawBuffer = nullptr); + void draw(const Point& dest, int layer, int xPattern, int yPattern, int zPattern, int animationPhase, uint32_t flags, TextureType textureType, const Color& color, LightView* lightView = nullptr, const DrawConductor& conductor = DEFAULT_DRAW_CONDUCTOR); uint16_t getId() { return m_id; } ThingCategory getCategory() { return m_category; } diff --git a/src/client/tile.cpp b/src/client/tile.cpp index 38458ea0c7..8ff6ce3e4b 100644 --- a/src/client/tile.cpp +++ b/src/client/tile.cpp @@ -248,8 +248,8 @@ void Tile::addThing(const ThingPtr& thing, int stackPos) if (const auto& ground = getGround()) { --stackPos; if (ground->isTopGround()) { - ground->destroyBuffer(); - thing->destroyBuffer(); + ground->ungroup(); + thing->ungroup(); } } } diff --git a/src/framework/graphics/declarations.h b/src/framework/graphics/declarations.h index ed73605e49..5fadbd343f 100644 --- a/src/framework/graphics/declarations.h +++ b/src/framework/graphics/declarations.h @@ -49,7 +49,6 @@ class SpriteSheet; class DrawPool; class DrawPoolFramed; class DrawPoolManager; -class DrawBuffer; class CoordsBuffer; using ImagePtr = std::shared_ptr; @@ -70,7 +69,6 @@ using ParticleEffectPtr = std::shared_ptr; using SpriteSheetPtr = std::shared_ptr; using ShaderList = std::vector; -using DrawBufferPtr = std::shared_ptr; using CoordsBufferPtr = std::shared_ptr; using ParticleEffectTypePtr = std::shared_ptr; diff --git a/src/framework/graphics/drawpool.cpp b/src/framework/graphics/drawpool.cpp index 9f4d5816dd..478f67ae09 100644 --- a/src/framework/graphics/drawpool.cpp +++ b/src/framework/graphics/drawpool.cpp @@ -52,15 +52,18 @@ DrawPool* DrawPool::create(const DrawPoolType type) return pool; } -void DrawPool::add(const Color& color, const TexturePtr& texture, DrawMethod& method, const DrawMode drawMode, const DrawBufferPtr& drawBuffer, const CoordsBufferPtr& coordsBuffer) +void DrawPool::add(const Color& color, const TexturePtr& texture, DrawPool::DrawMethod& method, + DrawMode drawMode, const DrawConductor& conductor, const CoordsBufferPtr& coordsBuffer) { auto state = PoolState{ - m_state.transformMatrix, m_state.opacity, + std::move(m_state.transformMatrix), m_state.opacity, m_state.compositionMode, m_state.blendEquation, m_state.clipRect, m_state.shaderProgram, - m_state.action, color, texture + m_state.action, std::move(const_cast(color)), texture }; + updateHash(state, method); + if (m_onlyOnceStateFlag > 0) { // Only Once State if (m_onlyOnceStateFlag & STATE_OPACITY) resetOpacity(); @@ -80,59 +83,48 @@ void DrawPool::add(const Color& color, const TexturePtr& texture, DrawMethod& me m_onlyOnceStateFlag = 0; } - const size_t methodHash = updateHash(state, method); - - const uint8_t drawOrder = static_cast(m_type == DrawPoolType::MAP ? drawBuffer ? drawBuffer->m_order : DrawPool::DrawOrder::THIRD : DrawPool::DrawOrder::FIRST); - - if (m_type != DrawPoolType::FOREGROUND && (m_alwaysGroupDrawings || (drawBuffer && drawBuffer->m_agroup))) { - if (const auto it = m_objectsByhash.find(state.hash); it != m_objectsByhash.end()) { - const auto& buffer = it->second.buffer; + if (m_alwaysGroupDrawings || conductor.agroup) { + const auto it = m_objectsByhash.find(state.hash); - if (coordsBuffer) - buffer->getCoords()->append(coordsBuffer.get()); - else - addCoords(buffer->getCoords(), method, DrawMode::TRIANGLES); + const bool bufferFound = it != m_objectsByhash.end(); + const auto& coords = bufferFound ? it->second.coords : std::make_shared(); - return; + if (!bufferFound) { + m_objectsByhash.emplace(state.hash, + m_objects[m_currentFloor][conductor.order].emplace_back(state, coords) + ); } - const auto& buffer = DrawBuffer::createTemporaryBuffer(static_cast(drawOrder)); - auto* coords = buffer->getCoords(); if (coordsBuffer) coords->append(coordsBuffer.get()); else - addCoords(coords, method, DrawMode::TRIANGLES); - - m_objectsByhash.emplace(state.hash, m_objects[m_currentFloor][drawOrder].emplace_back(state, buffer)); + addCoords(coords.get(), method, DrawMode::TRIANGLES); return; } - auto& list = m_objects[m_currentFloor][drawOrder]; + auto& list = m_objects[m_currentFloor][conductor.order]; if (!list.empty()) { auto& prevObj = list.back(); if (prevObj.state == state) { - if (!prevObj.buffer) { + if (!prevObj.coords) { prevObj.addMethod(method); return; } - if (prevObj.buffer->isTemporary()) { - if (coordsBuffer) { - prevObj.buffer->getCoords()->append(coordsBuffer.get()); - } else { - addCoords(prevObj.buffer->getCoords(), method, DrawMode::TRIANGLES); - } + if (coordsBuffer) { + prevObj.coords->append(coordsBuffer.get()); + } else { + addCoords(prevObj.coords.get(), method, DrawMode::TRIANGLES); } } } if (coordsBuffer) { - const auto& buffer = DrawBuffer::createTemporaryBuffer(DrawPool::DrawOrder::FIRST); - buffer->getCoords()->append(coordsBuffer.get()); - list.emplace_back(state, buffer); + list.emplace_back(state, std::make_shared()) + .coords->append(coordsBuffer.get()); } else list.emplace_back(drawMode, state, method); } @@ -158,7 +150,7 @@ void DrawPool::addCoords(CoordsBuffer* buffer, const DrawMethod& method, DrawMod } } -size_t DrawPool::updateHash(PoolState& state, const DrawMethod& method) +void DrawPool::updateHash(PoolState& state, const DrawMethod& method) { { // State Hash if (state.blendEquation != BlendEquation::ADD) @@ -188,8 +180,8 @@ size_t DrawPool::updateHash(PoolState& state, const DrawMethod& method) stdext::hash_union(m_status.second, state.hash); } - size_t methodhash = 0; { // Method Hash + size_t methodhash = 0; if (method.type == DrawPool::DrawMethodType::TRIANGLE) { if (!method.a.isNull()) stdext::hash_union(methodhash, method.a.hash()); if (!method.b.isNull()) stdext::hash_union(methodhash, method.b.hash()); @@ -203,8 +195,6 @@ size_t DrawPool::updateHash(PoolState& state, const DrawMethod& method) stdext::hash_union(m_status.second, methodhash); } - - return methodhash; } void DrawPool::setCompositionMode(const CompositionMode mode, bool onlyOnce) diff --git a/src/framework/graphics/drawpool.h b/src/framework/graphics/drawpool.h index 774227544a..ac15e5419e 100644 --- a/src/framework/graphics/drawpool.h +++ b/src/framework/graphics/drawpool.h @@ -41,19 +41,27 @@ enum class DrawPoolType : uint8_t UNKNOW }; +enum DrawOrder +{ + FIRST, // GROUND + SECOND, // BORDER + THIRD, // BOTTOM & TOP + FOURTH, // TOP ~ TOP + FIFTH, // ABOVE ALL - MISSILE + LAST +}; + +struct DrawConductor +{ + bool agroup{ false }; + uint8_t order{ DrawOrder::FIRST }; +}; + +static const DrawConductor DEFAULT_DRAW_CONDUCTOR; + class DrawPool { public: - enum class DrawOrder - { - NONE = -1, - FIRST, // GROUND - SECOND, // BORDER - THIRD, // BOTTOM & TOP - FOURTH, // TOP ~ TOP - FIFTH, // ABOVE ALL - MISSILE - LAST - }; void setEnable(bool v) { m_enabled = v; } @@ -113,7 +121,7 @@ class DrawPool struct DrawObject { DrawObject(std::function action) : action(std::move(action)) {} - DrawObject(PoolState& state, const DrawBufferPtr& buffer) : buffer(buffer), state(std::move(state)) {} + DrawObject(PoolState& state, const CoordsBufferPtr& coordsBuffer) : coords(coordsBuffer), state(std::move(state)) {} DrawObject(const DrawMode drawMode, PoolState& state, DrawMethod& method) : drawMode(drawMode), state(std::move(state)) { methods.emplace_back(std::move(method)); } @@ -124,7 +132,7 @@ class DrawPool } DrawMode drawMode{ DrawMode::TRIANGLES }; - DrawBufferPtr buffer; + CoordsBufferPtr coords; PoolState state; std::vector methods; std::function action{ nullptr }; @@ -156,12 +164,12 @@ class DrawPool static DrawPool* create(const DrawPoolType type); void add(const Color& color, const TexturePtr& texture, DrawPool::DrawMethod& method, - DrawMode drawMode = DrawMode::TRIANGLES, const DrawBufferPtr& drawBuffer = nullptr, + DrawMode drawMode = DrawMode::TRIANGLES, const DrawConductor& conductor = DEFAULT_DRAW_CONDUCTOR, const CoordsBufferPtr& coordsBuffer = nullptr); void resetState(); - size_t updateHash(PoolState& state, const DrawPool::DrawMethod& method); + void updateHash(PoolState& state, const DrawPool::DrawMethod& method); float getOpacity() const { return m_state.opacity; } Rect getClipRect() { return m_state.clipRect; } @@ -256,45 +264,3 @@ class DrawPoolFramed : public DrawPool }; extern DrawPoolManager g_drawPool; - -class DrawBuffer -{ -public: - DrawBuffer(DrawPool::DrawOrder order, bool agroup = true) : m_agroup(agroup), m_order(order) {} - void agroup(bool v) { m_agroup = v; } - void setOrder(DrawPool::DrawOrder order) { m_order = order; } - - void invalidate() { m_i = -1; } - - bool validate(const Point& p) - { - const size_t hash = p.hash(); - if (m_ref != hash) { m_ref = hash; invalidate(); } - return isValid(); - } - -private: - static DrawBufferPtr createTemporaryBuffer(DrawPool::DrawOrder order) - { - auto buffer = std::make_shared(order); - buffer->m_i = -2; // identifier to say it is a temporary buffer. - return buffer; - } - - inline bool isValid() const { return m_i != -1; } - inline bool isTemporary() const { return m_i == -2; } - - inline CoordsBuffer* getCoords() { return (m_coords ? m_coords : m_coords = std::make_shared()).get(); } - - int m_i{ -1 }; - bool m_agroup{ true }; - - DrawPool::DrawOrder m_order{ DrawPool::DrawOrder::FIRST }; - size_t m_ref{ 0 }; - size_t m_stateHash{ 0 }; - - CoordsBufferPtr m_coords; - - friend class DrawPool; - friend class DrawPoolManager; -}; diff --git a/src/framework/graphics/drawpoolmanager.cpp b/src/framework/graphics/drawpoolmanager.cpp index 1e69eb7103..ab0bea17c8 100644 --- a/src/framework/graphics/drawpoolmanager.cpp +++ b/src/framework/graphics/drawpoolmanager.cpp @@ -89,7 +89,7 @@ void DrawPoolManager::draw() if (pf->m_beforeDraw) pf->m_beforeDraw(); pf->m_framebuffer->draw(); if (pf->m_afterDraw) pf->m_afterDraw(); - } else for (const auto& obj : pool->m_objects[0][static_cast(DrawPool::DrawOrder::FIRST)]) { + } else for (const auto& obj : pool->m_objects[0][DrawOrder::FIRST]) { drawObject(obj); } } @@ -102,26 +102,24 @@ void DrawPoolManager::drawObject(const DrawPool::DrawObject& obj) return; } - const bool useGlobalCoord = !obj.buffer; - auto& buffer = useGlobalCoord ? m_coordsBuffer : *obj.buffer->m_coords; - - if (useGlobalCoord) { - buffer.clear(); + auto& coords = !obj.coords ? m_coordsBuffer : *obj.coords; + if (!obj.coords) { + coords.clear(); for (const auto& method : obj.methods) - DrawPool::addCoords(&buffer, method, obj.drawMode); + DrawPool::addCoords(&coords, method, obj.drawMode); } obj.state.execute(); - g_painter->drawCoords(buffer, obj.drawMode); + g_painter->drawCoords(coords, obj.drawMode); } void DrawPoolManager::addTexturedCoordsBuffer(const TexturePtr& texture, const CoordsBufferPtr& coords, const Color& color) const { DrawPool::DrawMethod method; - getCurrentPool()->add(color, texture, method, DrawMode::TRIANGLE_STRIP, nullptr, coords); + getCurrentPool()->add(color, texture, method, DrawMode::TRIANGLE_STRIP, DEFAULT_DRAW_CONDUCTOR, coords); } -void DrawPoolManager::addTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src, const Color& color, const DrawBufferPtr& buffer) const +void DrawPoolManager::addTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src, const Color& color, const DrawConductor& condutor) const { if (dest.isEmpty() || src.isEmpty()) return; @@ -131,7 +129,7 @@ void DrawPoolManager::addTexturedRect(const Rect& dest, const TexturePtr& textur .dest = dest, .src = src }; - getCurrentPool()->add(color, texture, method, DrawMode::TRIANGLE_STRIP, buffer); + getCurrentPool()->add(color, texture, method, DrawMode::TRIANGLE_STRIP, condutor); } void DrawPoolManager::addUpsideDownTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src, const Color& color) const @@ -154,14 +152,14 @@ void DrawPoolManager::addTexturedRepeatedRect(const Rect& dest, const TexturePtr getCurrentPool()->add(color, texture, method); } -void DrawPoolManager::addFilledRect(const Rect& dest, const Color& color, const DrawBufferPtr& buffer) const +void DrawPoolManager::addFilledRect(const Rect& dest, const Color& color, const DrawConductor& condutor) const { if (dest.isEmpty()) return; DrawPool::DrawMethod method{ DrawPool::DrawMethodType::RECT, dest }; - getCurrentPool()->add(color, nullptr, method, DrawMode::TRIANGLES, buffer); + getCurrentPool()->add(color, nullptr, method, DrawMode::TRIANGLES, condutor); } void DrawPoolManager::addFilledTriangle(const Point& a, const Point& b, const Point& c, const Color& color) const @@ -190,7 +188,7 @@ void DrawPoolManager::addBoundingRect(const Rect& dest, const Color& color, uint void DrawPoolManager::addAction(const std::function& action) const { - getCurrentPool()->m_objects[0][static_cast(DrawPool::DrawOrder::FIRST)].emplace_back(action); + getCurrentPool()->m_objects[0][DrawOrder::FIRST].emplace_back(action); } void DrawPoolManager::bindFrameBuffer(const Size& size) const diff --git a/src/framework/graphics/drawpoolmanager.h b/src/framework/graphics/drawpoolmanager.h index 2867d5291a..163fbd7d75 100644 --- a/src/framework/graphics/drawpoolmanager.h +++ b/src/framework/graphics/drawpoolmanager.h @@ -46,11 +46,11 @@ class DrawPoolManager void addTexturedRect(const Rect& dest, const TexturePtr& texture, const Color& color = Color::white) const { addTexturedRect(dest, texture, Rect(Point(), texture->getSize()), color); } - void addTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src, const Color& color = Color::white, const DrawBufferPtr& buffer = nullptr) const; + void addTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src, const Color& color = Color::white, const DrawConductor& condutor = DEFAULT_DRAW_CONDUCTOR) const; void addTexturedCoordsBuffer(const TexturePtr& texture, const CoordsBufferPtr& coords, const Color& color = Color::white) const; void addUpsideDownTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src, const Color& color = Color::white) const; void addTexturedRepeatedRect(const Rect& dest, const TexturePtr& texture, const Rect& src, const Color& color = Color::white) const; - void addFilledRect(const Rect& dest, const Color& color = Color::white, const DrawBufferPtr& buffer = nullptr) const; + void addFilledRect(const Rect& dest, const Color& color = Color::white, const DrawConductor& condutor = DEFAULT_DRAW_CONDUCTOR) const; void addFilledTriangle(const Point& a, const Point& b, const Point& c, const Color& color = Color::white) const; void addBoundingRect(const Rect& dest, const Color& color = Color::white, uint16_t innerLineWidth = 1) const; void addAction(const std::function& action) const; diff --git a/src/framework/util/color.h b/src/framework/util/color.h index 0374165af3..1f28bb9008 100644 --- a/src/framework/util/color.h +++ b/src/framework/util/color.h @@ -49,6 +49,13 @@ class Color } Color(const Color& color) = default; + Color(const Color& color, float alpha) { + m_r = color.m_r; + m_g = color.m_g; + m_b = color.m_b; + m_a = alpha; + update(); + } uint8_t a() const { return static_cast(m_a * 255.f); } uint8_t b() const { return static_cast(m_b * 255.f); } From d399fa226ed79efe8282667db7d592f458d56a20 Mon Sep 17 00:00:00 2001 From: Renato Date: Sun, 12 Feb 2023 17:31:23 -0300 Subject: [PATCH 3/5] Update drawpool.h --- src/framework/graphics/drawpool.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/framework/graphics/drawpool.h b/src/framework/graphics/drawpool.h index ac15e5419e..08828bd652 100644 --- a/src/framework/graphics/drawpool.h +++ b/src/framework/graphics/drawpool.h @@ -41,7 +41,7 @@ enum class DrawPoolType : uint8_t UNKNOW }; -enum DrawOrder +enum DrawOrder : uint8_t { FIRST, // GROUND SECOND, // BORDER From 490d467c98fc431a68517a6100702fb105249d19 Mon Sep 17 00:00:00 2001 From: Renato Date: Sun, 12 Feb 2023 17:45:09 -0300 Subject: [PATCH 4/5] Update drawpool.cpp --- src/framework/graphics/drawpool.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/framework/graphics/drawpool.cpp b/src/framework/graphics/drawpool.cpp index 478f67ae09..bdadc60b92 100644 --- a/src/framework/graphics/drawpool.cpp +++ b/src/framework/graphics/drawpool.cpp @@ -58,8 +58,8 @@ void DrawPool::add(const Color& color, const TexturePtr& texture, DrawPool::Draw auto state = PoolState{ std::move(m_state.transformMatrix), m_state.opacity, m_state.compositionMode, m_state.blendEquation, - m_state.clipRect, m_state.shaderProgram, - m_state.action, std::move(const_cast(color)), texture + std::move(m_state.clipRect), m_state.shaderProgram, + std::move(m_state.action), std::move(const_cast(color)), texture }; updateHash(state, method); From 0c6c33dd86dda9a81b905d981a29ac23e4b6ad43 Mon Sep 17 00:00:00 2001 From: Renato Date: Sun, 12 Feb 2023 18:44:27 -0300 Subject: [PATCH 5/5] fix order draw --- src/client/creature.cpp | 1 - src/client/effect.h | 1 - src/client/item.cpp | 3 +-- src/client/thing.h | 2 +- src/client/tile.cpp | 2 +- src/framework/graphics/drawpool.cpp | 21 ++++++++++++--------- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/client/creature.cpp b/src/client/creature.cpp index e69239f079..07de90bfcc 100644 --- a/src/client/creature.cpp +++ b/src/client/creature.cpp @@ -42,7 +42,6 @@ double Creature::speedC = 0; Creature::Creature() :m_type(Proto::CreatureTypeUnknown) { - m_drawConductor.order = DrawOrder::THIRD; m_name.setFont(g_fonts.getFont("verdana-11px-rounded")); m_name.setAlign(Fw::AlignTopCenter); diff --git a/src/client/effect.h b/src/client/effect.h index 91d4cbb443..969f26e047 100644 --- a/src/client/effect.h +++ b/src/client/effect.h @@ -30,7 +30,6 @@ class Effect : public Thing { public: - Effect() { m_drawConductor.order = DrawOrder::THIRD; }; void drawEffect(const Point& dest, uint32_t flags, int offsetX, int offsetY, LightView* lightView = nullptr); void setId(uint32_t id) override; diff --git a/src/client/item.cpp b/src/client/item.cpp index 85fa1f5af6..f66c151889 100644 --- a/src/client/item.cpp +++ b/src/client/item.cpp @@ -72,8 +72,7 @@ void Item::setConductor() } else if (isSingleGroundBorder() && !hasElevation()) { m_drawConductor.agroup = true; m_drawConductor.order = DrawOrder::SECOND; - } else - m_drawConductor.order = DrawOrder::THIRD; + } } void Item::setPosition(const Position& position, uint8_t stackPos, bool hasElevation) diff --git a/src/client/thing.h b/src/client/thing.h index 5ea1f32cf1..f36f971f39 100644 --- a/src/client/thing.h +++ b/src/client/thing.h @@ -200,7 +200,7 @@ class Thing : public LuaObject Position m_position; ThingType* m_thingType{ nullptr }; - DrawConductor m_drawConductor; + DrawConductor m_drawConductor{ false, DrawOrder::THIRD }; Color m_markedColor{ Color::yellow }; diff --git a/src/client/tile.cpp b/src/client/tile.cpp index 8ff6ce3e4b..06825f4295 100644 --- a/src/client/tile.cpp +++ b/src/client/tile.cpp @@ -246,7 +246,7 @@ void Tile::addThing(const ThingPtr& thing, int stackPos) // Do not change if you do not understand what is being done. { if (const auto& ground = getGround()) { - --stackPos; + stackPos = std::max(--stackPos, 0); if (ground->isTopGround()) { ground->ungroup(); thing->ungroup(); diff --git a/src/framework/graphics/drawpool.cpp b/src/framework/graphics/drawpool.cpp index bdadc60b92..6ce0365b92 100644 --- a/src/framework/graphics/drawpool.cpp +++ b/src/framework/graphics/drawpool.cpp @@ -83,6 +83,11 @@ void DrawPool::add(const Color& color, const TexturePtr& texture, DrawPool::Draw m_onlyOnceStateFlag = 0; } + uint8_t order = conductor.order; + if (m_type == DrawPoolType::MAP && order == DrawOrder::FIRST && !conductor.agroup) { + order = DrawOrder::THIRD; + } + if (m_alwaysGroupDrawings || conductor.agroup) { const auto it = m_objectsByhash.find(state.hash); @@ -91,7 +96,7 @@ void DrawPool::add(const Color& color, const TexturePtr& texture, DrawPool::Draw if (!bufferFound) { m_objectsByhash.emplace(state.hash, - m_objects[m_currentFloor][conductor.order].emplace_back(state, coords) + m_objects[m_currentFloor][order].emplace_back(state, coords) ); } @@ -103,22 +108,20 @@ void DrawPool::add(const Color& color, const TexturePtr& texture, DrawPool::Draw return; } - auto& list = m_objects[m_currentFloor][conductor.order]; + auto& list = m_objects[m_currentFloor][order]; if (!list.empty()) { auto& prevObj = list.back(); if (prevObj.state == state) { - if (!prevObj.coords) { + if (!prevObj.coords) prevObj.addMethod(method); - return; - } - - if (coordsBuffer) { + else if (coordsBuffer) prevObj.coords->append(coordsBuffer.get()); - } else { + else addCoords(prevObj.coords.get(), method, DrawMode::TRIANGLES); - } + + return; } }