From 7bcf7f536eb133984d6a70d73e8f3e3c2d09db0f Mon Sep 17 00:00:00 2001 From: Eduardo Bart Date: Tue, 17 Jan 2012 03:36:25 -0200 Subject: [PATCH] cache rendering of UILabel --- TODO | 107 ++++++++++----------- modules/client/client.lua | 7 +- modules/client_options/options.otmod | 2 +- modules/core_widgets/tooltip/tooltip.lua | 4 +- src/framework/graphics/framebuffer.cpp | 3 + src/framework/graphics/painter.cpp | 4 +- src/framework/graphics/painter.h | 3 +- src/framework/graphics/particleemitter.cpp | 2 +- src/framework/platform/x11window.cpp | 1 + src/framework/ui/uiwidget.h | 8 +- src/framework/ui/uiwidgettext.cpp | 58 +++++++---- src/otclient/core/game.cpp | 2 +- src/otclient/core/localplayer.cpp | 3 + src/otclient/core/localplayer.h | 3 + src/otclient/net/protocolgameparse.cpp | 4 + 15 files changed, 124 insertions(+), 87 deletions(-) diff --git a/TODO b/TODO index 2a637ec0..1f9ff81f 100644 --- a/TODO +++ b/TODO @@ -1,26 +1,20 @@ ==================================================== High priority TODO in order (before first public disclose) -[bart] chat with tabs -[bart] scrollbar -[bart] scrollable widgets -[bart] complete miniwindow (close, minimize, resize) -[bart] move windows -[bart] add top menu buttons -[bart] console scrolling -[bart] modules managment interface -[bart] adjust interface design - -[baxnie] display exit box when exiting from game -[baxnie] auto walk -[baxnie] attack modes -[baxnie] player status icons (poison, etc) -[baxnie] container windows -[baxnie] move items -[baxnie] use with -[baxnie] hotkeys window -[baxnie] trade window -[baxnie] battle list +termiante chat +scrollbar +scrollable widgets +complete miniwindow (close, minimize, resize, move) +move windows +add top menu buttons +modules managment interface +adjust interface design +display exit box when exiting from game +attack modes +player status icons (poison, etc) +container windows +move items +use with @@ -28,25 +22,27 @@ High priority TODO in order (before first public disclose) Low priority TODO == Core -[bart] review directories loading search -[bart] load modules from zip packages -[bart] create a class for reading binary files -[bart] rework lua/c++ logger -[bart] make protocol class compatible with old tibia protocols +review directories loading search +load modules from zip packages +create a class for reading binary files +rework lua/c++ logger +ake protocol class compatible with old tibia protocols == Graphics -[bart] use CoordsBuffer in font -[bart] cache renders into framebuffers -[bart] use hardware buffer -[bart] use indices +use CoordsBuffer in font +cache renders into framebuffers +use hardware buffer +use indices +fix opacity and cached framebuffers conflict == Lua -[bart] make possible to bind non LuaObject derived classes on lua engine (for usage with Point,Rect,Color,Size) -[bart] review usage of x,y/width,height in lua instead of point/size +make possible to bind non LuaObject derived classes on lua engine (for usage with Point,Rect,Color,Size) +review usage of x,y/width,height in lua instead of point/size == Platform -[bart] port to MacOs and iphone +port to MacOs and iphone change win32 mouse cursor icon +rework win32 key input system == UI [bart] fix massive hotkeys when holding down a key @@ -66,26 +62,29 @@ change win32 mouse cursor icon [bart] make api to enable/disable capture of events to avoid massive event processing [bart] review style apply system -== Client modules -[bart] make possible to reload modules - == Client -[bart] implement left panel with dragging windows -[bart] clean sprites cache periodically -[bart] create a shader manager -[bart] find a way to load map rendering styles -[bart] move redering of creatures names, skulls, etc to UI -[bart] cache screen creatures in a list on map -[bart] handle corrupt errors in dat/spr -[bart] remake spr/dat using OTML and image files -[bart] rework map tile rendering (cache visible tiles, etc) -[bart] minimap window -[bart] draw lights using shaders -[bart] limit FPS in options -[bart] resize map, right panel -[baxnie] do lua game event calls from Game instead from GameProtocol -[baxnie] login queue -[baxnie] questlog -[baxnie] edit texts -[baxnie] ignore list -[baxnie] viplist marks +make possible to reload modules +terminal/console scrolling +auto walk +hotkeys window +trade window +battle list +implement left panel with dragging windows +clean sprites cache periodically +create a shader manager +find a way to load map rendering styles +move redering of creatures names, skulls, etc to UI +cache screen creatures in a list on map +handle corrupt errors in dat/spr +remake spr/dat using OTML and image files +rework map tile rendering (cache visible tiles, etc) +minimap window +draw lights using shaders +limit FPS in options +resize map, right panel +do lua game event calls from Game instead from GameProtocol +login queue +questlog +edit texts +ignore list +viplist marks diff --git a/modules/client/client.lua b/modules/client/client.lua index de112f8b..8c9b5492 100644 --- a/modules/client/client.lua +++ b/modules/client/client.lua @@ -1,6 +1,6 @@ Client = {} -local function setupWindow() +function Client.init() g_window.show() g_window.setMinimumSize({ width = 600, height = 480 }) @@ -29,11 +29,8 @@ local function setupWindow() g_window.setIcon(resolvepath('clienticon.png')) end -function Client.init() - setupWindow() -end - function Client.terminate() + -- save window configs Settings.set('window-size', g_window.getUnmaximizedSize()) Settings.set('window-pos', g_window.getUnmaximizedPos()) Settings.set('window-maximized', g_window.isMaximized()) diff --git a/modules/client_options/options.otmod b/modules/client_options/options.otmod index 1a38eb45..fdb94178 100644 --- a/modules/client_options/options.otmod +++ b/modules/client_options/options.otmod @@ -8,5 +8,5 @@ Module require 'options' Options.init() - onUnload: + onUnload: | Options.terminate() \ No newline at end of file diff --git a/modules/core_widgets/tooltip/tooltip.lua b/modules/core_widgets/tooltip/tooltip.lua index 1c672e12..b890e925 100644 --- a/modules/core_widgets/tooltip/tooltip.lua +++ b/modules/core_widgets/tooltip/tooltip.lua @@ -55,8 +55,8 @@ local function onWidgetStyleApply(widget, styleName, styleNode) end end ---connect(UIWidget, { onStyleApply = onWidgetStyleApply, --- onHoverChange = onWidgetHoverChange}) +connect(UIWidget, { onStyleApply = onWidgetStyleApply, + onHoverChange = onWidgetHoverChange}) -- UIWidget extensions function UIWidget:setTooltip(text) diff --git a/src/framework/graphics/framebuffer.cpp b/src/framework/graphics/framebuffer.cpp index 4917bf84..737d8d53 100644 --- a/src/framework/graphics/framebuffer.cpp +++ b/src/framework/graphics/framebuffer.cpp @@ -42,6 +42,9 @@ FrameBuffer::~FrameBuffer() void FrameBuffer::resize(const Size& size) { + if(m_texture && m_texture->getSize() == size) + return; + internalBind(); m_texture = TexturePtr(new Texture(size.width(), size.height(), 4)); m_texture->setSmooth(true); diff --git a/src/framework/graphics/painter.cpp b/src/framework/graphics/painter.cpp index 374d1ba2..1710eaec 100644 --- a/src/framework/graphics/painter.cpp +++ b/src/framework/graphics/painter.cpp @@ -131,8 +131,8 @@ void Painter::setCompositionMode(Painter::CompositionMode compositionMode) case CompositionMode_Multiply: glBlendFunc(GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA); break; - case CompositionMode_Addition: - glBlendFunc(GL_SRC_ALPHA, GL_ONE); + case CompositionMode_Add: + glBlendFunc(GL_ONE, GL_ONE); break; } } diff --git a/src/framework/graphics/painter.h b/src/framework/graphics/painter.h index c53ec16b..78fb6a15 100644 --- a/src/framework/graphics/painter.h +++ b/src/framework/graphics/painter.h @@ -34,7 +34,7 @@ public: enum CompositionMode { CompositionMode_Normal, CompositionMode_Multiply, - CompositionMode_Addition + CompositionMode_Add }; void init(); @@ -57,6 +57,7 @@ public: void setCustomProgram(PainterShaderProgramPtr program); void releaseCustomProgram() { m_customProgram = nullptr; } void setCompositionMode(CompositionMode compositionMode); + void resetCompositionMode() { setCompositionMode(CompositionMode_Normal); } void setProjectionMatrix(const Matrix3& projectionMatrix) { m_projectionMatrix = projectionMatrix; } Matrix3 getProjectionMatrix() { return m_projectionMatrix; } diff --git a/src/framework/graphics/particleemitter.cpp b/src/framework/graphics/particleemitter.cpp index 50e92dd0..2b5c18fd 100644 --- a/src/framework/graphics/particleemitter.cpp +++ b/src/framework/graphics/particleemitter.cpp @@ -163,7 +163,7 @@ bool ParticleEmitter::load(const OTMLNodePtr& node) else if(childNode->value() == "multiply") m_pCompositionMode = Painter::CompositionMode_Multiply; else if(childNode->value() == "addition") - m_pCompositionMode = Painter::CompositionMode_Addition; + m_pCompositionMode = Painter::CompositionMode_Add; } } diff --git a/src/framework/platform/x11window.cpp b/src/framework/platform/x11window.cpp index d528ee32..70fa984b 100644 --- a/src/framework/platform/x11window.cpp +++ b/src/framework/platform/x11window.cpp @@ -704,6 +704,7 @@ void X11Window::poll() break; case UnmapNotify: m_visible = false; + releaseAllKeys(); break; case FocusIn: m_focused = true; diff --git a/src/framework/ui/uiwidget.h b/src/framework/ui/uiwidget.h index 192b2db8..962fb705 100644 --- a/src/framework/ui/uiwidget.h +++ b/src/framework/ui/uiwidget.h @@ -407,6 +407,10 @@ private: void initText(); void parseTextStyle(const OTMLNodePtr& styleNode); + Boolean m_textMustRecache; + FrameBufferPtr m_textFramebuffer; + Size m_textCachedBoxSize; + protected: void drawText(const Rect& screenCoords); @@ -423,8 +427,8 @@ public: void clearText() { setText(""); } void setText(const std::string& text); - void setTextAlign(Fw::AlignmentFlag align) { m_textAlign = align; } - void setTextOffset(const Point& offset) { m_textOffset = offset; } + void setTextAlign(Fw::AlignmentFlag align) { m_textAlign = align; m_textMustRecache = true; } + void setTextOffset(const Point& offset) { m_textOffset = offset; m_textMustRecache = true; } void setFont(const std::string& fontName); std::string getText() { return m_text; } diff --git a/src/framework/ui/uiwidgettext.cpp b/src/framework/ui/uiwidgettext.cpp index 2ed1309f..5c0f75bb 100644 --- a/src/framework/ui/uiwidgettext.cpp +++ b/src/framework/ui/uiwidgettext.cpp @@ -24,6 +24,7 @@ #include "uitranslator.h" #include #include +#include void UIWidget::initText() { @@ -47,12 +48,30 @@ void UIWidget::parseTextStyle(const OTMLNodePtr& styleNode) void UIWidget::drawText(const Rect& screenCoords) { - g_painter.setColor(m_color); - if(m_text.length() > 0 && m_color.a() > 0) { - Rect textRect = screenCoords; - textRect.translate(m_textOffset); - m_font->renderText(m_text, textRect, m_textAlign, m_color); + if(m_text.length() == 0 || m_color.a() == 0) + return; + + Size boxSize = screenCoords.size(); + if(boxSize != m_textCachedBoxSize || m_textMustRecache) { + if(!m_textFramebuffer) + m_textFramebuffer = FrameBufferPtr(new FrameBuffer(boxSize)); + else + m_textFramebuffer->resize(boxSize); + + m_textFramebuffer->bind(); + Rect virtualTextRect(0, 0, boxSize); + virtualTextRect.translate(m_textOffset); + g_painter.setCompositionMode(Painter::CompositionMode_Add); + m_font->renderText(m_text, virtualTextRect, m_textAlign, Fw::white); + g_painter.resetCompositionMode(); + m_textFramebuffer->release(); + + m_textMustRecache = false; + m_textCachedBoxSize = boxSize; } + + g_painter.setColor(m_color); + m_textFramebuffer->draw(screenCoords); } void UIWidget::onTextChange(const std::string& text) @@ -67,26 +86,29 @@ void UIWidget::onFontChange(const std::string& font) void UIWidget::setText(const std::string& text) { - if(m_text != text) { - m_text = text; + if(m_text == text) + return; - // update rect size - if(!m_rect.isValid()) { - Size textSize = m_font->calculateTextRectSize(m_text); - Size newSize = getSize(); - if(newSize.width() <= 0) - newSize.setWidth(textSize.width()); - if(newSize.height() <= 0) - newSize.setHeight(textSize.height()); - setSize(newSize); - } + m_text = text; - onTextChange(text); + // update rect size + if(!m_rect.isValid()) { + Size textSize = m_font->calculateTextRectSize(m_text); + Size newSize = getSize(); + if(newSize.width() <= 0) + newSize.setWidth(textSize.width()); + if(newSize.height() <= 0) + newSize.setHeight(textSize.height()); + setSize(newSize); } + + onTextChange(text); + m_textMustRecache = true; } void UIWidget::setFont(const std::string& fontName) { m_font = g_fonts.getFont(fontName); onFontChange(fontName); + m_textMustRecache = true; } diff --git a/src/otclient/core/game.cpp b/src/otclient/core/game.cpp index 016a1f9c..2321636a 100644 --- a/src/otclient/core/game.cpp +++ b/src/otclient/core/game.cpp @@ -162,7 +162,7 @@ void Game::processWalkCancel(Otc::Direction direction) void Game::walk(Otc::Direction direction) { - if(!isOnline() || isDead() || !checkBotProtection()) + if(!isOnline() || !m_localPlayer->isKnown() || isDead() || !checkBotProtection()) return; if(m_localPlayer->isFollowing()) diff --git a/src/otclient/core/localplayer.cpp b/src/otclient/core/localplayer.cpp index 23313ddb..2156ac46 100644 --- a/src/otclient/core/localplayer.cpp +++ b/src/otclient/core/localplayer.cpp @@ -39,6 +39,9 @@ bool LocalPlayer::canWalk(Otc::Direction direction) // check for blockable tiles in the walk direction TilePtr tile = g_map.getTile(m_pos + Position::getPosFromDirection(direction)); + if(!tile) + return false; + if(!tile->isWalkable()) { g_game.processTextMessage("statusSmall", "Sorry, not possible."); return false; diff --git a/src/otclient/core/localplayer.h b/src/otclient/core/localplayer.h index d2cfdf58..c5742b40 100644 --- a/src/otclient/core/localplayer.h +++ b/src/otclient/core/localplayer.h @@ -34,6 +34,7 @@ public: void setAttackingCreature(const CreaturePtr& creature); void setFollowingCreature(const CreaturePtr& creature); void setIcons(Otc::PlayerIcons icons) { m_icons = icons; } + void setKnown(bool known) { m_known = known; } bool getCanReportBugs() { return m_canReportBugs; } int getSkill(Otc::Skill skill, Otc::SkillType skillType) { return m_skills[skill][skillType]; } @@ -42,6 +43,7 @@ public: CreaturePtr getFollowingCreature() { return m_followingCreature; } Otc::PlayerIcons getIcons() { return m_icons; } + bool isKnown() { return m_known; } bool isAttacking() { return m_attackingCreature != nullptr; } bool isFollowing() { return m_followingCreature != nullptr; } @@ -65,6 +67,7 @@ public: private: bool m_canReportBugs; + bool m_known; CreaturePtr m_attackingCreature, m_followingCreature; Otc::PlayerIcons m_icons; int m_skills[Otc::LastSkill][Otc::LastSkillType]; diff --git a/src/otclient/net/protocolgameparse.cpp b/src/otclient/net/protocolgameparse.cpp index ba0d8a3b..1a25e6e5 100644 --- a/src/otclient/net/protocolgameparse.cpp +++ b/src/otclient/net/protocolgameparse.cpp @@ -1142,6 +1142,10 @@ ThingPtr ProtocolGame::internalGetThing(InputMessage& msg) creature->setEmblem(emblem); creature->setPassable(passable); creature->cancelWalk(direction); + + if(creature == m_localPlayer) { + m_localPlayer->setKnown(true); + } } thing = creature;