Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 6 additions & 18 deletions src/client/creature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,29 +114,17 @@ void Creature::draw(const Rect& destRect, uint8_t size, bool center)
if (size > 0)
frameSize = std::max<int>(frameSize * (size / 100.f), 2 * g_gameConfig.getSpriteSize() * (size / 100.f));

const auto& draw = [&](const Point& p) {
g_drawPool.bindFrameBuffer(frameSize); {
auto p = Point(frameSize - g_gameConfig.getSpriteSize()) + getDisplacement();
if (center)
p /= 2;

internalDraw(p);
if (isMarked())
internalDraw(p, getMarkedColor());
else if (isHighlighted())
internalDraw(p, getHighlightColor());
};

if (hasShader() && getShader()->useFramebuffer()) {
g_drawPool.setScaleFactor(destRect.size().bigger() / static_cast<float>(frameSize));
auto p = destRect.topLeft();
if (center)
p += (frameSize / 1.25);
draw(p);
g_drawPool.setScaleFactor(1.f);
} else {
g_drawPool.bindFrameBuffer(frameSize); {
auto p = Point(frameSize - g_gameConfig.getSpriteSize()) + getDisplacement();
if (center)
p /= 2;
draw(p);
} g_drawPool.releaseFrameBuffer(destRect);
}
} g_drawPool.releaseFrameBuffer(destRect);
}

void Creature::drawInformation(const MapPosInfo& mapRect, const Point& dest, int drawFlags)
Expand Down
15 changes: 4 additions & 11 deletions src/client/uiitem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,10 @@ void UIItem::drawSelf(DrawPoolType drawPane)
if (m_itemVisible && m_item) {
const int exactSize = std::max<int>(g_gameConfig.getSpriteSize(), m_item->getExactSize());

if (m_item->hasShader() && m_item->getShader()->useFramebuffer()) {
g_drawPool.setScaleFactor(getPaddingRect().size().bigger() / static_cast<float>(exactSize));
m_item->setColor(m_color);
m_item->draw(getPaddingRect().topLeft());
g_drawPool.setScaleFactor(1.f);
} else {
g_drawPool.bindFrameBuffer(exactSize);
m_item->setColor(m_color);
m_item->draw(Point(exactSize - g_gameConfig.getSpriteSize()) + m_item->getDisplacement());
g_drawPool.releaseFrameBuffer(getPaddingRect());
}
g_drawPool.bindFrameBuffer(exactSize);
m_item->setColor(m_color);
m_item->draw(Point(exactSize - g_gameConfig.getSpriteSize()) + m_item->getDisplacement());
g_drawPool.releaseFrameBuffer(getPaddingRect());

if (m_font && (m_alwaysShowCount || m_item->isStackable() || m_item->isChargeable()) && m_item->getCountOrSubType() > 1) {
static const Color STACK_COLOR(231, 231, 231);
Expand Down
103 changes: 50 additions & 53 deletions src/framework/graphics/drawpool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ void DrawPool::add(const Color& color, const TexturePtr& texture, DrawPool::Draw
order = DrawOrder::THIRD;

if (m_alwaysGroupDrawings || conductor.agroup) {
auto& coords = m_coords.try_emplace(m_state.hash, nullptr).first->second;
auto& coords = m_coords.try_emplace(getCurrentState().hash, nullptr).first->second;
if (!coords) {
auto state = getState(texture, color);
coords = m_objects[order].emplace_back(std::move(state), m_lastCoordBufferSize).coords.get();
Expand All @@ -77,7 +77,7 @@ void DrawPool::add(const Color& color, const TexturePtr& texture, DrawPool::Draw
auto& list = m_objects[order];
if (!list.empty()) {
auto& prevObj = list.back();
if (prevObj.state == m_state) {
if (prevObj.state == getCurrentState()) {
if (!prevObj.coords)
prevObj.addMethod(std::move(method));
else if (coordsBuffer)
Expand Down Expand Up @@ -127,39 +127,40 @@ void DrawPool::addCoords(CoordsBuffer* buffer, const DrawMethod& method, DrawMod
}

bool DrawPool::updateHash(const DrawPool::DrawMethod& method, const TexturePtr& texture, const Color& color, const bool hasCoord) {
{ // State Hash
m_state.hash = 0;
auto& state = getCurrentState();
state.hash = 0;

{ // State Hash
if (m_bindedFramebuffers)
stdext::hash_combine(m_state.hash, m_lastFramebufferId);
stdext::hash_combine(state.hash, m_lastFramebufferId);

if (m_state.blendEquation != BlendEquation::ADD)
stdext::hash_combine(m_state.hash, m_state.blendEquation);
if (state.blendEquation != BlendEquation::ADD)
stdext::hash_combine(state.hash, state.blendEquation);

if (m_state.compositionMode != CompositionMode::NORMAL)
stdext::hash_combine(m_state.hash, m_state.compositionMode);
if (state.compositionMode != CompositionMode::NORMAL)
stdext::hash_combine(state.hash, state.compositionMode);

if (m_state.opacity < 1.f)
stdext::hash_combine(m_state.hash, m_state.opacity);
if (state.opacity < 1.f)
stdext::hash_combine(state.hash, state.opacity);

if (m_state.clipRect.isValid())
stdext::hash_union(m_state.hash, m_state.clipRect.hash());
if (state.clipRect.isValid())
stdext::hash_union(state.hash, state.clipRect.hash());

if (m_state.shaderProgram)
stdext::hash_union(m_state.hash, m_state.shaderProgram->hash());
if (state.shaderProgram)
stdext::hash_union(state.hash, state.shaderProgram->hash());

if (m_state.transformMatrix != DEFAULT_MATRIX3)
stdext::hash_union(m_state.hash, m_state.transformMatrix.hash());
if (state.transformMatrix != DEFAULT_MATRIX3)
stdext::hash_union(state.hash, state.transformMatrix.hash());

if (color != Color::white)
stdext::hash_union(m_state.hash, color.hash());
stdext::hash_union(state.hash, color.hash());

if (texture)
stdext::hash_union(m_state.hash, texture->hash());
stdext::hash_union(state.hash, texture->hash());
}

if (hasFrameBuffer()) { // Pool Hash
size_t hash = m_state.hash;
size_t hash = state.hash;

if (method.type == DrawPool::DrawMethodType::TRIANGLE) {
if (!method.a.isNull()) stdext::hash_union(hash, method.a.hash());
Expand All @@ -184,52 +185,51 @@ bool DrawPool::updateHash(const DrawPool::DrawMethod& method, const TexturePtr&

DrawPool::PoolState DrawPool::getState(const TexturePtr& texture, const Color& color)
{
return PoolState{
std::move(m_state.transformMatrix), m_state.opacity,
m_state.compositionMode, m_state.blendEquation,
std::move(m_state.clipRect), m_state.shaderProgram,
std::move(m_state.action), std::move(const_cast<Color&>(color)), texture, m_state.hash
};
PoolState copy = getCurrentState();
copy.texture = texture;
if (copy.color != color)
copy.color = color;
return copy;
}

void DrawPool::setCompositionMode(const CompositionMode mode, bool onlyOnce)
{
m_state.compositionMode = mode;
getCurrentState().compositionMode = mode;
if (onlyOnce) m_onlyOnceStateFlag |= STATE_COMPOSITE_MODE;
}

void DrawPool::setBlendEquation(BlendEquation equation, bool onlyOnce)
{
m_state.blendEquation = equation;
getCurrentState().blendEquation = equation;
if (onlyOnce) m_onlyOnceStateFlag |= STATE_BLEND_EQUATION;
}

void DrawPool::setClipRect(const Rect& clipRect, bool onlyOnce)
{
m_state.clipRect = clipRect;
getCurrentState().clipRect = clipRect;
if (onlyOnce) m_onlyOnceStateFlag |= STATE_CLIP_RECT;
}

void DrawPool::setOpacity(const float opacity, bool onlyOnce)
{
m_state.opacity = opacity;
getCurrentState().opacity = opacity;
if (onlyOnce) m_onlyOnceStateFlag |= STATE_OPACITY;
}

void DrawPool::setShaderProgram(const PainterShaderProgramPtr& shaderProgram, bool onlyOnce, const std::function<void()>& action)
{
if (g_painter->isReplaceColorShader(m_state.shaderProgram))
if (g_painter->isReplaceColorShader(getCurrentState().shaderProgram))
return;

if (shaderProgram) {
if (!g_painter->isReplaceColorShader(shaderProgram.get()))
m_shaderRefreshDelay = FPS20;

m_state.shaderProgram = shaderProgram.get();
m_state.action = action;
getCurrentState().shaderProgram = shaderProgram.get();
getCurrentState().action = action;
} else {
m_state.shaderProgram = nullptr;
m_state.action = nullptr;
getCurrentState().shaderProgram = nullptr;
getCurrentState().action = nullptr;
}

if (onlyOnce) m_onlyOnceStateFlag |= STATE_SHADER_PROGRAM;
Expand All @@ -246,7 +246,7 @@ void DrawPool::resetState()

m_hashCtrl.reset();

m_state = {};
getCurrentState() = {};
m_lastFramebufferId = 0;
m_shaderRefreshDelay = 0;
m_scale = PlatformWindow::DEFAULT_DISPLAY_DENSITY;
Expand All @@ -272,7 +272,7 @@ void DrawPool::scale(float factor)
return;

m_scale = factor;
m_state.transformMatrix = DEFAULT_MATRIX3 * Matrix3{
getCurrentState().transformMatrix = DEFAULT_MATRIX3 * Matrix3{
factor, 0.0f, 0.0f,
0.0f, factor, 0.0f,
0.0f, 0.0f, 1.0f
Expand All @@ -287,7 +287,7 @@ void DrawPool::translate(float x, float y)
0.0f, 0.0f, 1.0f
};

m_state.transformMatrix = m_state.transformMatrix * translateMatrix.transposed();
getCurrentState().transformMatrix = getCurrentState().transformMatrix * translateMatrix.transposed();
}

void DrawPool::rotate(float angle)
Expand All @@ -298,7 +298,7 @@ void DrawPool::rotate(float angle)
0.0f, 0.0f, 1.0f
};

m_state.transformMatrix = m_state.transformMatrix * rotationMatrix.transposed();
getCurrentState().transformMatrix = getCurrentState().transformMatrix * rotationMatrix.transposed();
}

void DrawPool::rotate(float x, float y, float angle)
Expand All @@ -310,14 +310,14 @@ void DrawPool::rotate(float x, float y, float angle)

void DrawPool::pushTransformMatrix()
{
m_transformMatrixStack.emplace_back(m_state.transformMatrix);
m_transformMatrixStack.emplace_back(getCurrentState().transformMatrix);
assert(m_transformMatrixStack.size() < 100);
}

void DrawPool::popTransformMatrix()
{
assert(!m_transformMatrixStack.empty());
m_state.transformMatrix = m_transformMatrixStack.back();
getCurrentState().transformMatrix = m_transformMatrixStack.back();
m_transformMatrixStack.pop_back();
}

Expand Down Expand Up @@ -363,28 +363,25 @@ void DrawPool::bindFrameBuffer(const Size& size, const Color& color)
++m_lastFramebufferId;

if (color != Color::white)
m_state.color = color;
getCurrentState().color = color;

if (m_bindedFramebuffers == 0) {
m_oldState = std::move(m_state);
m_state = {};
}
nextStateAndReset();

addAction([this, size, frameIndex = m_bindedFramebuffers] {
static const PoolState state;

state.execute();

addAction([this, size, frameIndex = m_bindedFramebuffers, drawState = m_state] {
drawState.execute();
const auto& frame = getTemporaryFrameBuffer(frameIndex);
frame->resize(size);
frame->bind();
});
}
void DrawPool::releaseFrameBuffer(const Rect& dest)
{
if (m_bindedFramebuffers == 0) {
m_state = std::move(m_oldState);
m_oldState = {};
}
backState();

addAction([this, dest, frameIndex = m_bindedFramebuffers, drawState = m_state] {
addAction([this, dest, frameIndex = m_bindedFramebuffers, drawState = getCurrentState()] {
const auto& frame = getTemporaryFrameBuffer(frameIndex);
frame->release();
drawState.execute();
Expand Down
30 changes: 21 additions & 9 deletions src/framework/graphics/drawpool.h
Original file line number Diff line number Diff line change
Expand Up @@ -255,21 +255,24 @@ class DrawPool
bool updateHash(const DrawPool::DrawMethod& method, const TexturePtr& texture, const Color& color, const bool hasCoord);
PoolState getState(const TexturePtr& texture, const Color& color);

float getOpacity() const { return m_state.opacity; }
Rect getClipRect() { return m_state.clipRect; }
PoolState& getCurrentState() { return m_states[m_lastStateIndex]; }
const PoolState& getCurrentState() const { return m_states[m_lastStateIndex]; }

float getOpacity() const { return getCurrentState().opacity; }
Rect getClipRect() { return getCurrentState().clipRect; }

void setCompositionMode(CompositionMode mode, bool onlyOnce = false);
void setBlendEquation(BlendEquation equation, bool onlyOnce = false);
void setClipRect(const Rect& clipRect, bool onlyOnce = false);
void setOpacity(float opacity, bool onlyOnce = false);
void setShaderProgram(const PainterShaderProgramPtr& shaderProgram, bool onlyOnce = false, const std::function<void()>& action = nullptr);

void resetOpacity() { m_state.opacity = 1.f; }
void resetClipRect() { m_state.clipRect = {}; }
void resetShaderProgram() { m_state.shaderProgram = nullptr; m_state.action = nullptr; }
void resetCompositionMode() { m_state.compositionMode = CompositionMode::NORMAL; }
void resetBlendEquation() { m_state.blendEquation = BlendEquation::ADD; }
void resetTransformMatrix() { m_state.transformMatrix = DEFAULT_MATRIX3; }
void resetOpacity() { getCurrentState().opacity = 1.f; }
void resetClipRect() { getCurrentState().clipRect = {}; }
void resetShaderProgram() { getCurrentState().shaderProgram = nullptr; getCurrentState().action = nullptr; }
void resetCompositionMode() { getCurrentState().compositionMode = CompositionMode::NORMAL; }
void resetBlendEquation() { getCurrentState().blendEquation = BlendEquation::ADD; }
void resetTransformMatrix() { getCurrentState().transformMatrix = DEFAULT_MATRIX3; }

void pushTransformMatrix();
void popTransformMatrix();
Expand Down Expand Up @@ -346,6 +349,14 @@ class DrawPool
}
}

void nextStateAndReset() {
m_states[++m_lastStateIndex] = {};
}

void backState() {
--m_lastStateIndex;
}

const FrameBufferPtr& getTemporaryFrameBuffer(const uint8_t index);

bool m_enabled{ true };
Expand All @@ -357,7 +368,8 @@ class DrawPool
uint32_t m_onlyOnceStateFlag{ 0 };
uint_fast64_t m_lastFramebufferId{ 0 };

PoolState m_state, m_oldState;
PoolState m_states[10];
uint_fast8_t m_lastStateIndex{ 0 };

DrawPoolType m_type{ DrawPoolType::LAST };

Expand Down
2 changes: 1 addition & 1 deletion src/framework/graphics/drawpoolmanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class DrawPoolManager
void setBlendEquation(BlendEquation equation, bool onlyOnce = false) const { getCurrentPool()->setBlendEquation(equation, onlyOnce); }
void setCompositionMode(const CompositionMode mode, bool onlyOnce = false) const { getCurrentPool()->setCompositionMode(mode, onlyOnce); }

bool shaderNeedFramebuffer() const { return getCurrentPool()->m_state.shaderProgram && getCurrentPool()->m_state.shaderProgram->useFramebuffer(); }
bool shaderNeedFramebuffer() const { return getCurrentPool()->getCurrentState().shaderProgram && getCurrentPool()->getCurrentState().shaderProgram->useFramebuffer(); }
void setShaderProgram(const PainterShaderProgramPtr& shaderProgram, const std::function<void()>& action) const { getCurrentPool()->setShaderProgram(shaderProgram, false, action); }
void setShaderProgram(const PainterShaderProgramPtr& shaderProgram, bool onlyOnce = false, const std::function<void()>& action = nullptr) const { getCurrentPool()->setShaderProgram(shaderProgram, onlyOnce, action); }

Expand Down