From 5c77e641e9a592787d484fcad1ebb653825ad159 Mon Sep 17 00:00:00 2001 From: Benau Date: Fri, 1 May 2020 09:45:22 +0800 Subject: [PATCH] Add batch drawing for list box widget --- src/font/font_drawer.cpp | 24 ++++++++++++++++++++++++ src/font/font_drawer.hpp | 6 ++++++ src/guiengine/CGUISpriteBank.cpp | 19 ++++++++++++++++--- src/guiengine/widgets/CGUISTKListBox.cpp | 8 +++++--- 4 files changed, 51 insertions(+), 6 deletions(-) diff --git a/src/font/font_drawer.cpp b/src/font/font_drawer.cpp index 9e0fce3bc..5ea260d02 100644 --- a/src/font/font_drawer.cpp +++ b/src/font/font_drawer.cpp @@ -57,6 +57,27 @@ public: std::unique_ptr > g_clip; // ============================================================================ std::map > g_glyphs; +// ============================================================================ +bool g_batching = false; +// ---------------------------------------------------------------------------- +void FontDrawer::startBatching() +{ + g_batching = true; +} // startBatching + +// ---------------------------------------------------------------------------- +bool FontDrawer::isBatching() +{ + return g_batching; +} // isBatching + +// ---------------------------------------------------------------------------- +void FontDrawer::endBatching() +{ + g_batching = false; + draw(); +} // endBatching + // ---------------------------------------------------------------------------- void FontDrawer::addGlyph(video::ITexture* texture, const core::rect& dest_rect, @@ -119,6 +140,9 @@ void FontDrawer::addGlyph(video::ITexture* texture, // ---------------------------------------------------------------------------- void FontDrawer::draw() { + if (g_batching || g_glyphs.empty()) + return; + if (g_clip && !g_clip->isValid()) { for (auto it = g_glyphs.begin(); it != g_glyphs.end();) diff --git a/src/font/font_drawer.hpp b/src/font/font_drawer.hpp index 64cf4d6b7..1900e8a8a 100644 --- a/src/font/font_drawer.hpp +++ b/src/font/font_drawer.hpp @@ -31,6 +31,12 @@ using namespace irr; namespace FontDrawer { + // ------------------------------------------------------------------------ + void startBatching(); + // ------------------------------------------------------------------------ + bool isBatching(); + // ------------------------------------------------------------------------ + void endBatching(); // ------------------------------------------------------------------------ void addGlyph(video::ITexture* texture, const core::rect& dest_rect, diff --git a/src/guiengine/CGUISpriteBank.cpp b/src/guiengine/CGUISpriteBank.cpp index c7cf908ba..1edfe4650 100644 --- a/src/guiengine/CGUISpriteBank.cpp +++ b/src/guiengine/CGUISpriteBank.cpp @@ -9,6 +9,7 @@ #include "IVideoDriver.h" #include "ITexture.h" #include +#include "font/font_drawer.hpp" #include "graphics/2dutils.hpp" namespace irr @@ -202,7 +203,7 @@ void STKModifiedSpriteBank::draw2DSprite(u32 index, ? Sprites[index].Frames.size()-1 : f; } - const video::ITexture* tex = + video::ITexture* tex = Textures[Sprites[index].Frames[frame].textureNumber]; if (!tex) return; @@ -242,8 +243,20 @@ void STKModifiedSpriteBank::draw2DSprite(u32 index, const video::SColor *const colors=0, bool useAlphaChannelOfTexture=false)=0 */ - draw2DImage(tex, dest, r /* source rect */, clip, - NULL /* colors */, true); + if (FontDrawer::isBatching()) + { + // FontDrawing is batching when stk list box widget is drawing text, + // so we combine the images to them to make it faster (for example in + // server list when there are all green tick icons) + FontDrawer::addGlyph(tex, core::rect(dest.UpperLeftCorner.X, + dest.UpperLeftCorner.Y, dest.LowerRightCorner.X, + dest.LowerRightCorner.Y), r, clip, video::SColor(-1)); + } + else + { + draw2DImage(tex, dest, r /* source rect */, clip, NULL /* colors */, + true); + } #endif } // draw2DSprite diff --git a/src/guiengine/widgets/CGUISTKListBox.cpp b/src/guiengine/widgets/CGUISTKListBox.cpp index a4dcbb634..3e795ec57 100644 --- a/src/guiengine/widgets/CGUISTKListBox.cpp +++ b/src/guiengine/widgets/CGUISTKListBox.cpp @@ -5,6 +5,7 @@ #include "guiengine/widgets/CGUISTKListBox.hpp" +#include "font/font_drawer.hpp" #include "graphics/2dutils.hpp" #include "IGUISkin.h" #include "IGUIEnvironment.h" @@ -467,6 +468,7 @@ void CGUISTKListBox::updateAbsolutePosition() //! draws the element and its children void CGUISTKListBox::draw() { +#ifndef SERVER_ONLY if (!IsVisible) return; @@ -505,19 +507,18 @@ void CGUISTKListBox::draw() bool hl = (HighlightWhenNotFocused || Environment->hasFocus(this) || Environment->hasFocus(ScrollBar)); + FontDrawer::startBatching(); for (s32 i=0; i<(s32)Items.size(); ++i) { if (frameRect.LowerRightCorner.Y >= AbsoluteRect.UpperLeftCorner.Y && frameRect.UpperLeftCorner.Y <= AbsoluteRect.LowerRightCorner.Y) { -#ifndef SERVER_ONLY if (m_alternating_darkness && i % 2 != 0) { video::SColor color(0); color.setAlpha(30); GL32_draw2DRectangle(color, frameRect, &clientClip); } -#endif if (i == Selected && hl) skin->draw2DRectangle(this, skin->getColor(EGDC_HIGH_LIGHT), frameRect, &clientClip); @@ -614,7 +615,8 @@ void CGUISTKListBox::draw() frameRect.UpperLeftCorner.Y += ItemHeight; frameRect.LowerRightCorner.Y += ItemHeight; } - + FontDrawer::endBatching(); +#endif IGUIElement::draw(); }