diff --git a/modules/client_locales/locales/pt.lua b/modules/client_locales/locales/pt.lua index e0bebdd8..3292788a 100644 --- a/modules/client_locales/locales/pt.lua +++ b/modules/client_locales/locales/pt.lua @@ -43,7 +43,6 @@ locale = { ["Auto login"] = "Entrar automaticamente", ["Auto login selected character on next charlist load"] = "Entrar automaticamente com o personagem quando reabrir a lista de personagens", ["Axe Fighting"] = "Combate com Machado", - ["Background pane framerate limit: %s"] = "Limite da taxa de quadros no segundo plano: %s", ["Banishment"] = "Banimento", ["Banishment + Final Warning"] = "Banimento + Aviso final", ["Battle"] = "Batalha", @@ -88,9 +87,8 @@ locale = { ["Fishing"] = "Pesca", ["Fist Fighting"] = "Porrada", ["Follow"] = "Seguir", - ["Foreground pane framerate limit: %s"] = "Limite da taxa de quadros no primeiro plano: %s", - ["Frame rate limit"] = "Limite de FPS", ["Fullscreen"] = "Tela cheia", + ["Game framerate limit: %s"] = "Limite da taxa de quadros do jogo: %s", ["General"] = "Geral", ["Graphics"] = "Gráficos", ["Graphics Engine:"] = "Motor Gráfico:", @@ -106,6 +104,7 @@ locale = { ["Hotkeys"] = "Atalhos", ["Ignore capacity"] = "Ignorar capacidade", ["Ignore equipped"] = "Ignorar equipado", + ["Interface framerate limit: %s"] = "Limite da taxa de quadros da interface: %s", ["Inventory"] = "Inventário", ["Invite to Party"] = "Convidar para o grupo", ["Invite to private chat"] = "Convidar para o canal privado", diff --git a/modules/client_options/graphics.otui b/modules/client_options/graphics.otui index 9df0c815..7402cdaa 100644 --- a/modules/client_options/graphics.otui +++ b/modules/client_options/graphics.otui @@ -35,7 +35,7 @@ Panel Label id: backgroundFrameRateLimitLabel - !text: tr('Background pane framerate limit: %s', 'max') + !text: tr('Game framerate limit: %s', 'max') anchors.left: parent.left anchors.right: parent.right anchors.top: prev.bottom @@ -59,12 +59,12 @@ Panel value = 0 end - self:getParent():getChildById('backgroundFrameRateLimitLabel'):setText(tr('Background pane framerate limit: %s', text)) + self:getParent():getChildById('backgroundFrameRateLimitLabel'):setText(tr('Game framerate limit: %s', text)) g_app.setBackgroundPaneMaxFps(value) Label id: foregroundFrameRateLimitLabel - !text: tr('Foreground pane framerate limit: %s', '8') + !text: tr('Interface framerate limit: %s', '24') anchors.left: parent.left anchors.right: parent.right anchors.top: prev.bottom @@ -78,7 +78,7 @@ Panel margin-top: 3 minimum: 1 maximum: 61 - value: 8 + value: 61 step: 1 @onValueChange: | local value = self:getValue() @@ -88,6 +88,6 @@ Panel value = 0 end - self:getParent():getChildById('foregroundFrameRateLimitLabel'):setText(tr('Foreground pane framerate limit: %s', text)) + self:getParent():getChildById('foregroundFrameRateLimitLabel'):setText(tr('Interface framerate limit: %s', text)) g_app.setForegroundPaneMaxFps(value) diff --git a/modules/client_options/options.lua b/modules/client_options/options.lua index 1b5dfbec..6984e3f3 100644 --- a/modules/client_options/options.lua +++ b/modules/client_options/options.lua @@ -39,6 +39,14 @@ local function setupGraphicsEngines() g_graphics.selectPainterEngine(2) end end + + local foregroundFrameRateScrollBar = graphicsPanel:getChildById('foregroundFrameRateScrollBar') + local foregroundFrameRateLimitLabel = graphicsPanel:getChildById('foregroundFrameRateLimitLabel') + if not g_graphics.canCacheBackbuffer() then + foregroundFrameRateScrollBar:setValue(61) + foregroundFrameRateScrollBar:disable() + foregroundFrameRateLimitLabel:disable() + end end function Options.init() @@ -50,12 +58,12 @@ function Options.init() end end - Keyboard.bindKeyDown('Ctrl+P', Options.toggle) + Keyboard.bindKeyDown('Ctrl+D', Options.toggle) Keyboard.bindKeyDown('Ctrl+F', function() Options.toggleOption('fullscreen') end) optionsWindow = displayUI('options.otui') optionsWindow:hide() - optionsButton = TopMenu.addLeftButton('optionsButton', tr('Options') .. ' (Ctrl+P)', 'options.png', Options.toggle) + optionsButton = TopMenu.addLeftButton('optionsButton', tr('Options') .. ' (Ctrl+D)', 'options.png', Options.toggle) optionsTabBar = optionsWindow:getChildById('optionsTabBar') optionsTabBar:setContentWidget(optionsWindow:getChildById('optionsTabContent')) @@ -69,7 +77,7 @@ function Options.init() end function Options.terminate() - Keyboard.unbindKeyDown('Ctrl+P') + Keyboard.unbindKeyDown('Ctrl+D') Keyboard.unbindKeyDown('Ctrl+F') optionsWindow:destroy() optionsWindow = nil diff --git a/modules/client_topmenu/topmenu.otui b/modules/client_topmenu/topmenu.otui index 65750cf6..03178c67 100644 --- a/modules/client_topmenu/topmenu.otui +++ b/modules/client_topmenu/topmenu.otui @@ -83,6 +83,8 @@ TopPanel cycleEvent(function() local frameCounter = rootWidget:recursiveGetChildById('frameCounter') if frameCounter then - frameCounter:setText('FPS: ' .. g_app.getBackgroundPaneFps()) + local text = 'FPS: ' .. g_app.getBackgroundPaneFps() + frameCounter:setText(text) + --print(text) end end, 250) diff --git a/modules/core_lib/widgets/uiscrollbar.lua b/modules/core_lib/widgets/uiscrollbar.lua index eed4a662..9cebe3e6 100644 --- a/modules/core_lib/widgets/uiscrollbar.lua +++ b/modules/core_lib/widgets/uiscrollbar.lua @@ -63,10 +63,11 @@ local function updateSlider(self) slider:setMarginLeft(offset) end - if self.maximum == self.minimum then - self:disable() - else - self:enable() + local status = (self.maximum ~= self.minimum) + + self:setOn(status) + for _i,child in pairs(self:getChildren()) do + child:setEnabled(status) end end @@ -100,12 +101,10 @@ end function UIScrollBar:onSetup() self.setupDone = true signalcall(self.onValueChange, self, self.value) - addEvent(function() - Mouse.bindAutoPress(self:getChildById('decrementButton'), function() self:decrement() end) - Mouse.bindAutoPress(self:getChildById('incrementButton'), function() self:increment() end) - Mouse.bindPressMove(self:getChildById('sliderButton'), function(mousePos, mouseMoved) parseSliderPos(self, mousePos) end) - updateSlider(self) - end) + Mouse.bindAutoPress(self:getChildById('decrementButton'), function() self:decrement() end) + Mouse.bindAutoPress(self:getChildById('incrementButton'), function() self:increment() end) + Mouse.bindPressMove(self:getChildById('sliderButton'), function(mousePos, mouseMoved) parseSliderPos(self, mousePos) end) + updateSlider(self) end function UIScrollBar:onStyleApply(styleName, styleNode) diff --git a/modules/game/widgets/uiitem.lua b/modules/game/widgets/uiitem.lua index 3578aaec..fdbd593c 100644 --- a/modules/game/widgets/uiitem.lua +++ b/modules/game/widgets/uiitem.lua @@ -41,6 +41,7 @@ end function UIItem:onHoverChange(hovered) UIWidget.onHoverChange(self, hovered) + if self:isVirtual() then return end local draggingWidget = g_ui.getDraggingWidget() diff --git a/modules/game/widgets/uiminiwindow.lua b/modules/game/widgets/uiminiwindow.lua index 172a33fc..fc71607b 100644 --- a/modules/game/widgets/uiminiwindow.lua +++ b/modules/game/widgets/uiminiwindow.lua @@ -6,10 +6,8 @@ function UIMiniWindow.create() end function UIMiniWindow:onSetup() - addEvent(function() - self:getChildById('closeButton').onClick = function() signalcall(self.onClose, self) end - self:getChildById('minimizeButton').onClick = function() signalcall(self.onMinimize, self) end - end) + self:getChildById('closeButton').onClick = function() signalcall(self.onClose, self) end + self:getChildById('minimizeButton').onClick = function() signalcall(self.onMinimize, self) end end function UIMiniWindow:onDragEnter(mousePos) diff --git a/modules/game_console/console.lua b/modules/game_console/console.lua index aba1db2e..479fb928 100644 --- a/modules/game_console/console.lua +++ b/modules/game_console/console.lua @@ -44,6 +44,7 @@ local SayModes = { local MAX_HISTORY = 1000 local MAX_LINES = 100 +local HELP_CHANNEL = 9 local consolePanel local consoleContentPanel @@ -221,6 +222,7 @@ function Console.init() -- tibia like hotkeys Keyboard.bindKeyDown('Ctrl+O', g_game.requestChannels) Keyboard.bindKeyDown('Ctrl+E', Console.removeCurrentTab) + Keyboard.bindKeyDown('Ctrl+H', Console.openHelp) end function Console.terminate() @@ -242,6 +244,7 @@ function Console.terminate() Keyboard.unbindKeyDown('Ctrl+O') Keyboard.unbindKeyDown('Ctrl+E') + Keyboard.unbindKeyDown('Ctrl+H') if channelsWindow then channelsWindow:destroy() @@ -287,6 +290,10 @@ function Console.setTextEditText(text) consoleTextEdit:setText(text) end +function Console.openHelp() + g_game.joinChannel(HELP_CHANNEL) +end + function Console.addTab(name, focus) local tab = consoleTabBar:addTab(name) if focus then diff --git a/modules/game_viplist/viplist.lua b/modules/game_viplist/viplist.lua index 55714d86..c69c3b0e 100644 --- a/modules/game_viplist/viplist.lua +++ b/modules/game_viplist/viplist.lua @@ -12,14 +12,17 @@ function VipList.init() onVipStateChange = VipList.onVipStateChange }) + Keyboard.bindKeyDown('Ctrl+P', VipList.toggle) + vipWindow = displayUI('viplist.otui', GameInterface.getLeftPanel()) - vipButton = TopMenu.addGameToggleButton('vipListButton', tr('VIP list'), 'viplist.png', VipList.toggle) + vipButton = TopMenu.addGameToggleButton('vipListButton', tr('VIP list') .. ' (Ctrl+P)', 'viplist.png', VipList.toggle) vipButton:setOn(true) VipList.refresh() end function VipList.terminate() + Keyboard.unbindKeyDown('Ctrl+P') disconnect(g_game, { onGameEnd = VipList.clear, onAddVip = VipList.onAddVip, onVipStateChange = VipList.onVipStateChange }) diff --git a/src/framework/application.cpp b/src/framework/application.cpp index 8ff344c3..0e84b170 100644 --- a/src/framework/application.cpp +++ b/src/framework/application.cpp @@ -167,6 +167,7 @@ void Application::run() if(!m_initialized) return; + bool cacheForeground = true; m_stopping = false; m_running = true; @@ -189,6 +190,15 @@ void Application::run() bool redraw = false; bool updateForeground = false; + bool canCacheForeground = g_graphics.canCacheBackbuffer() && m_foregroundFrameCounter.getMaxFps() != 0; + if(cacheForeground != canCacheForeground) { + cacheForeground = canCacheForeground; + if(cacheForeground) + glColorMask(1,1,1,1); + else + glColorMask(1,1,1,0); + } + if(m_backgroundFrameCounter.shouldProcessNextFrame()) { redraw = true; @@ -201,28 +211,34 @@ void Application::run() if(redraw) { g_graphics.beginRender(); - Rect viewportRect(0, 0, g_graphics.getViewportSize()); + if(cacheForeground) { + Rect viewportRect(0, 0, g_graphics.getViewportSize()); - // draw the foreground into a texture - if(updateForeground) { - m_foregroundFrameCounter.processNextFrame(); + // draw the foreground into a texture + if(updateForeground) { + m_foregroundFrameCounter.processNextFrame(); - // draw foreground - g_painter->clear(Color::black); - g_ui.render(true); + // draw foreground + g_painter->clear(Color::black); + g_ui.render(Fw::ForegroundPane); - // copy the foreground to a texture - m_foreground->copyFromScreen(viewportRect); - } + // copy the foreground to a texture + m_foreground->copyFromScreen(viewportRect); + } - // draw background (animated stuff) - m_backgroundFrameCounter.processNextFrame(); - g_ui.render(false); + // draw background (animated stuff) + m_backgroundFrameCounter.processNextFrame(); + g_ui.render(Fw::BackgroundPane); - // draw the foreground (steady stuff) - g_painter->setColor(Color::white); - g_painter->setOpacity(1.0); - g_painter->drawTexturedRect(viewportRect, m_foreground, viewportRect); + // draw the foreground (steady stuff) + g_painter->setColor(Color::white); + g_painter->setOpacity(1.0); + g_painter->drawTexturedRect(viewportRect, m_foreground, viewportRect); + } else { + m_foregroundFrameCounter.processNextFrame(); + m_backgroundFrameCounter.processNextFrame(); + g_ui.render(Fw::BothPanes); + } g_graphics.endRender(); @@ -237,9 +253,8 @@ void Application::run() m_foregroundFrameCounter.update(); int sleepMicros = std::min(m_backgroundFrameCounter.getMaximumSleepMicros(), m_foregroundFrameCounter.getMaximumSleepMicros()); - if(sleepMicros >= AdaptativeFrameCounter::MINIMUM_MICROS_SLEEP) { + if(sleepMicros >= AdaptativeFrameCounter::MINIMUM_MICROS_SLEEP) stdext::microsleep(AdaptativeFrameCounter::MINIMUM_MICROS_SLEEP); - } } else { // sleeps until next poll to avoid massive cpu usage @@ -285,8 +300,10 @@ void Application::resize(const Size& size) g_ui.resize(size); m_onInputEvent = false; - m_foreground = TexturePtr(new Texture(size.width(), size.height())); - m_foreground->setUpsideDown(true); + if(g_graphics.canCacheBackbuffer()) { + m_foreground = TexturePtr(new Texture(size)); + m_foreground->setUpsideDown(true); + } m_mustRepaint = true; } diff --git a/src/framework/const.h b/src/framework/const.h index e97fd7b8..0263a644 100644 --- a/src/framework/const.h +++ b/src/framework/const.h @@ -262,6 +262,12 @@ namespace Fw DraggingState = 2048, LastWidgetState = 4096 }; + + enum DrawPane { + ForegroundPane = 1, + BackgroundPane = 2, + BothPanes = 3 + }; } #endif diff --git a/src/framework/graphics/animatedtexture.cpp b/src/framework/graphics/animatedtexture.cpp index 2f27d96b..fa724329 100644 --- a/src/framework/graphics/animatedtexture.cpp +++ b/src/framework/graphics/animatedtexture.cpp @@ -24,7 +24,7 @@ #include "graphics.h" #include - +/* AnimatedTexture::AnimatedTexture(int width, int height, int channels, int numFrames, uchar *framesPixels, int *framesDelay) : Texture(), m_numFrames(numFrames) @@ -48,7 +48,7 @@ AnimatedTexture::AnimatedTexture(int width, int height, int channels, int numFra AnimatedTexture::~AnimatedTexture() { glDeleteTextures(m_numFrames, &m_framesTextureId[0]); - m_textureId = 0; + m_id = 0; } void AnimatedTexture::enableBilinearFilter() @@ -65,7 +65,7 @@ void AnimatedTexture::processAnimation() m_currentFrame++; if(m_currentFrame >= m_numFrames) m_currentFrame = 0; - m_textureId = m_framesTextureId[m_currentFrame]; + m_id = m_framesTextureId[m_currentFrame]; AnimatedTexturePtr self = asAnimatedTexture(); @@ -73,3 +73,4 @@ void AnimatedTexture::processAnimation() if(self.use_count() > 1) g_eventDispatcher.scheduleEvent(std::bind(&AnimatedTexture::processAnimation, self), m_framesDelay[m_currentFrame]); } +*/ \ No newline at end of file diff --git a/src/framework/graphics/animatedtexture.h b/src/framework/graphics/animatedtexture.h index a1110f8e..23b7acf0 100644 --- a/src/framework/graphics/animatedtexture.h +++ b/src/framework/graphics/animatedtexture.h @@ -24,7 +24,7 @@ #define ANIMATEDTEXTURE_H #include "texture.h" - +/* class AnimatedTexture : public Texture { public: @@ -43,5 +43,5 @@ private: int m_currentFrame; ticks_t m_lastAnimCheckTicks; }; - +*/ #endif diff --git a/src/framework/graphics/framebuffer.cpp b/src/framework/graphics/framebuffer.cpp index 5824f0c3..15d10a1c 100644 --- a/src/framework/graphics/framebuffer.cpp +++ b/src/framework/graphics/framebuffer.cpp @@ -63,7 +63,7 @@ void FrameBuffer::resize(const Size& size) if(m_texture && m_texture->getSize() == size) return; - m_texture = TexturePtr(new Texture(size.width(), size.height(), 4)); + m_texture = TexturePtr(new Texture(size)); m_texture->setSmooth(true); m_texture->setUpsideDown(true); @@ -76,8 +76,10 @@ void FrameBuffer::resize(const Size& size) g_logger.fatal("Unable to setup framebuffer object"); internalRelease(); } else { - m_screenBackup = TexturePtr(new Texture(size.width(), size.height())); - m_screenBackup->setUpsideDown(true); + if(m_backuping) { + m_screenBackup = TexturePtr(new Texture(size)); + m_screenBackup->setUpsideDown(true); + } } } @@ -126,7 +128,7 @@ void FrameBuffer::internalBind() glBindFramebuffer(GL_FRAMEBUFFER, m_fbo); m_prevBoundFbo = boundFbo; boundFbo = m_fbo; - } else { + } else if(m_backuping) { // backup screen color buffer into a texture m_screenBackup->copyFromScreen(Rect(0, 0, getSize())); } @@ -145,10 +147,12 @@ void FrameBuffer::internalRelease() m_texture->copyFromScreen(screenRect); // restore screen original content - Painter::CompositionMode oldComposition = g_painter->getCompositionMode(); - g_painter->setCompositionMode(Painter::CompositionMode_Replace); - g_painter->drawTexturedRect(screenRect, m_screenBackup, screenRect); - g_painter->setCompositionMode(oldComposition); + if(m_backuping) { + Painter::CompositionMode oldComposition = g_painter->getCompositionMode(); + g_painter->setCompositionMode(Painter::CompositionMode_Replace); + g_painter->drawTexturedRect(screenRect, m_screenBackup, screenRect); + g_painter->setCompositionMode(oldComposition); + } } } diff --git a/src/framework/graphics/framebuffer.h b/src/framework/graphics/framebuffer.h index 68f26709..6e79a5a6 100644 --- a/src/framework/graphics/framebuffer.h +++ b/src/framework/graphics/framebuffer.h @@ -40,8 +40,11 @@ public: void draw(const Rect& dest); void draw(const Rect& dest, const Rect& src); + void setBackuping(bool enabled) { m_backuping = enabled; } + TexturePtr getTexture() { return m_texture; } Size getSize(); + bool isBackuping() { return m_backuping; } private: void internalCreate(); @@ -53,6 +56,7 @@ private: Size m_oldViewportSize; uint m_fbo; uint m_prevBoundFbo; + Boolean m_backuping; static uint boundFbo; }; diff --git a/src/framework/graphics/graphics.cpp b/src/framework/graphics/graphics.cpp index 32a6c6cd..d476d5a9 100644 --- a/src/framework/graphics/graphics.cpp +++ b/src/framework/graphics/graphics.cpp @@ -92,12 +92,6 @@ void Graphics::init() if(m_maxTextureSize == -1 || m_maxTextureSize > maxTextureSize) m_maxTextureSize = maxTextureSize; - // check if we have alpha channel in the color buffer, because we need alpha channel for glCopyTexSubImage2D - GLint alphaBits = 0; - glGetIntegerv(GL_ALPHA_BITS, &alphaBits); - if(alphaBits <= 0) - g_logger.fatal("OpenGL visual doesn't have an alpha buffer"); - selectPainterEngine(m_prefferedPainterEngine); m_emptyTexture = TexturePtr(new Texture); } @@ -143,6 +137,8 @@ bool Graphics::parseOption(const std::string& option) m_useNonPowerOfTwoTextures = false; else if(option == "-no-clamp-to-edge") m_useClampToEdge = false; + else if(option == "-no-backbuffer-cache") + m_cacheBackbuffer = false; else if(option == "-opengl1") m_prefferedPainterEngine = Painter_OpenGL1; else if(option == "-opengl2") @@ -368,3 +364,16 @@ bool Graphics::canUseBlendFuncSeparate() return true; #endif } + +bool Graphics::canCacheBackbuffer() +{ +#if OPENGL_ES==2 + return m_cacheBackbuffer; +#elif OPENGL_ES==1 + return false; +#else + if(!GLEW_VERSION_1_4) + return false; + return m_cacheBackbuffer; +#endif +} diff --git a/src/framework/graphics/graphics.h b/src/framework/graphics/graphics.h index ab81df21..dc63b5c4 100644 --- a/src/framework/graphics/graphics.h +++ b/src/framework/graphics/graphics.h @@ -70,6 +70,7 @@ public: bool canUseHardwareMipmaps(); bool canUseClampToEdge(); bool canUseBlendFuncSeparate(); + bool canCacheBackbuffer(); private: Size m_viewportSize; @@ -84,6 +85,7 @@ private: Boolean m_useMipmaps; Boolean m_useHardwareMipmaps; Boolean m_useClampToEdge; + Boolean m_cacheBackbuffer; PainterEngine m_prefferedPainterEngine; PainterEngine m_selectedPainterEngine; }; diff --git a/src/framework/graphics/image.cpp b/src/framework/graphics/image.cpp index 31bf49b0..580478f1 100644 --- a/src/framework/graphics/image.cpp +++ b/src/framework/graphics/image.cpp @@ -30,7 +30,7 @@ Image::Image(const Size& size, int bpp, uint8 *pixels) { m_size = size; m_bpp = bpp; - m_pixels.resize(size.area() * bpp); + m_pixels.resize(size.area() * bpp, 0); if(pixels) memcpy(&m_pixels[0], pixels, m_pixels.size()); } @@ -84,8 +84,10 @@ void Image::overwriteMask(const Color& maskedColor, const Color& insideColor, co } } -void Image::append(const Point& dest, const ImagePtr& other) +void Image::blit(const Point& dest, const ImagePtr& other) { + assert(m_bpp == 4); + if(!other) return; @@ -103,3 +105,109 @@ void Image::append(const Point& dest, const ImagePtr& other) } } } + +void Image::paste(const ImagePtr& other) +{ + assert(m_bpp == 4); + + if(!other) + return; + + uint8* otherPixels = other->getPixelData(); + for(int p = 0; p < other->getPixelCount(); ++p) { + int x = p % other->getWidth(); + int y = p / other->getWidth(); + int pos = (y * m_size.width() + x) * 4; + + m_pixels[pos+0] = otherPixels[p*4+0]; + m_pixels[pos+1] = otherPixels[p*4+1]; + m_pixels[pos+2] = otherPixels[p*4+2]; + m_pixels[pos+3] = otherPixels[p*4+3]; + } +} + +bool Image::nextMipmap() +{ + assert(m_bpp == 4); + assert(stdext::is_power_of_two(m_size.width()) && stdext::is_power_of_two(m_size.height())); + + if(m_size.width() == 1 || m_size.height() == 1) + return false; + + Size size = m_size / 2; + std::vector pixels(size.area()*4, 0xFF); + m_pixels = pixels; + m_size = size; + return true; +} + +/* + * + +void Texture::generateSoftwareMipmaps(std::vector inPixels) +{ + bind(); + + assert(stdext::is_power_of_two(m_glSize.width()) && stdext::is_power_of_two(m_glSize.height())); + + Size inSize = m_glSize; + Size outSize = inSize / 2; + std::vector outPixels; + + int mipmap = 1; + while(true) { + outPixels.resize(outSize.area()*4, 0); + + // this is a simple bilinear filtering algorithm, it combines every 4 pixels in one pixel + for(int x=0;x 0) + outPixel[i] = pixelsSum[i] / usedPixels; + else + outPixel[i] = 0; + } + outPixel[3] = pixelsSum[3]/4; + } + } + + glTexImage2D(GL_TEXTURE_2D, mipmap++, GL_RGBA, outSize.width(), outSize.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, &outPixels[0]); + + if(inSize.width() == 1 || inSize.height() == 1) + break; + + inPixels = std::move(outPixels); + inSize /= 2; + outSize /= 2; + } + + if(!m_hasMipmaps) { + m_hasMipmaps = true; + setupFilters(); + } +} +*/ \ No newline at end of file diff --git a/src/framework/graphics/image.h b/src/framework/graphics/image.h index 33a0655f..6d00139b 100644 --- a/src/framework/graphics/image.h +++ b/src/framework/graphics/image.h @@ -35,7 +35,9 @@ public: static ImagePtr loadPNG(const std::string& file); void overwriteMask(const Color& maskedColor, const Color& insideColor = Color::white, const Color& outsideColor = Color::alpha); - void append(const Point& dest, const ImagePtr &other); + void blit(const Point& dest, const ImagePtr& other); + void paste(const ImagePtr& other); + bool nextMipmap(); std::vector& getPixels() { return m_pixels; } uint8* getPixelData() { return &m_pixels[0]; } diff --git a/src/framework/graphics/texture.cpp b/src/framework/graphics/texture.cpp index ea320903..932280cf 100644 --- a/src/framework/graphics/texture.cpp +++ b/src/framework/graphics/texture.cpp @@ -27,131 +27,77 @@ Texture::Texture() { - m_textureId = 0; + m_id = 0; } -Texture::Texture(const ImagePtr& image) +Texture::Texture(const Size& size) { - internalLoadGLTexture(image->getPixelData(), image->getBpp(), image->getWidth(), image->getHeight()); -} + m_id = 0; -Texture::Texture(int width, int height, int channels, uchar *pixels) -{ - // generate opengl texture - internalLoadGLTexture(pixels, channels, width, height); -} + if(!setupSize(size)) + return; -Texture::~Texture() -{ - // free texture from gl memory - if(m_textureId > 0) - glDeleteTextures(1, &m_textureId); + createTexture(); + bind(); + setupPixels(0, m_glSize, nullptr, 4); + setupWrap(); + setupFilters(); } -uint Texture::internalLoadGLTexture(uchar *pixels, int channels, int width, int height) +Texture::Texture(const ImagePtr& image, bool buildMipmaps) { - m_size.resize(width, height); - - // convert texture pixel data to power of two size, only required for OpenGL 1.5 or older - std::vector tmp; - if(!g_graphics.canUseNonPowerOfTwoTextures()) { - int glWidth = 1; - while(glWidth < width) - glWidth = glWidth << 1; - - int glHeight = 1; - while(glHeight < height) - glHeight = glHeight << 1; - - if(m_size != m_glSize && pixels) { - tmp.resize(glHeight*glWidth*channels, 0); - for(int y=0; y g_graphics.getMaxTextureSize()) { - g_logger.error(stdext::format("loading texture with size %dx%d failed, " - "the maximum size allowed by the graphics card is %dx%d," - "to prevent crashes the texture will be displayed as a blank texture", - width, height, g_graphics.getMaxTextureSize(), g_graphics.getMaxTextureSize())); - //TODO: make a workaround, could be bilinear scaling the texture - return 0; - } + if(!setupSize(image->getSize(), buildMipmaps)) + return; - // generate gl texture - GLuint id; - glGenTextures(1, &id); - assert(id != 0); - m_textureId = id; - bind(); + createTexture(); - // detect pixels GL format - GLenum format = 0; - switch(channels) { - case 4: - format = GL_RGBA; - break; - case 3: - format = GL_RGB; - break; - case 2: - format = GL_LUMINANCE_ALPHA; - break; - case 1: - format = GL_LUMINANCE; - break; - } - - // load pixels into gl memory - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_glSize.width(), m_glSize.height(), 0, format, GL_UNSIGNED_BYTE, pixels); + ImagePtr glImage = image; + if(m_size != m_glSize) { + glImage = ImagePtr(new Image(m_glSize, image->getBpp())); + glImage->paste(image); + } else + glImage = image; - GLint texParam = GL_REPEAT; - if(g_graphics.canUseClampToEdge()) - texParam = GL_CLAMP_TO_EDGE; // disable texture borders by default + bind(); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, texParam); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, texParam); + /* + if(buildMipmaps) { + int level = 0; + do { + setupPixels(level++, glImage->getSize(), glImage->getPixelData(), glImage->getBpp()); + } while(glImage->nextMipmap()); + m_hasMipmaps = true; + } else + */ + setupPixels(0, glImage->getSize(), glImage->getPixelData(), glImage->getBpp()); + setupWrap(); setupFilters(); - - return id; } -void Texture::copyFromScreen(const Rect& screenRect) +Texture::~Texture() { - bind(); - glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, screenRect.x(), screenRect.y(), screenRect.width(), screenRect.height()); + // free texture from gl memory + if(m_id > 0) + glDeleteTextures(1, &m_id); } void Texture::bind() { // must reset painter texture state g_painter->setTexture(this); - glBindTexture(GL_TEXTURE_2D, m_textureId); + glBindTexture(GL_TEXTURE_2D, m_id); } -void Texture::generateMipmaps() +void Texture::copyFromScreen(const Rect& screenRect) { - if(!generateHardwareMipmaps()) { - // fallback to software mipmaps generation, this can be slow - //FIXME: disabled because mipmaps size needs to be in base of 2, - // and the current algorithmn does not support that - //generateSoftwareMipmaps(getPixels()); - g_logger.traceError("non power of 2."); - } + bind(); + glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, screenRect.x(), screenRect.y(), screenRect.width(), screenRect.height()); } -bool Texture::generateHardwareMipmaps() +bool Texture::buildHardwareMipmaps() { if(!g_graphics.canUseHardwareMipmaps()) return false; @@ -188,69 +134,43 @@ void Texture::setUpsideDown(bool upsideDown) setupTranformMatrix(); } -void Texture::generateSoftwareMipmaps(std::vector inPixels) +void Texture::createTexture() { - bind(); + glGenTextures(1, &m_id); + assert(m_id != 0); +} - if(!m_hasMipmaps) { - m_hasMipmaps = true; - setupFilters(); +bool Texture::setupSize(const Size& size, bool forcePowerOfTwo) +{ + Size glSize; + if(!g_graphics.canUseNonPowerOfTwoTextures() || forcePowerOfTwo) + glSize.resize(stdext::to_power_of_two(size.width()), stdext::to_power_of_two(size.height())); + else + glSize = size; + + // checks texture max size + if(std::max(glSize.width(), glSize.height()) > g_graphics.getMaxTextureSize()) { + g_logger.error(stdext::format("loading texture with size %dx%d failed, " + "the maximum size allowed by the graphics card is %dx%d," + "to prevent crashes the texture will be displayed as a blank texture", + size.width(), size.height(), g_graphics.getMaxTextureSize(), g_graphics.getMaxTextureSize())); + return false; } - Size inSize = getSize(); - Size outSize = inSize / 2; - std::vector outPixels; - - int mipmap = 1; - while(true) { - outPixels.resize(outSize.area()*4); - - // this is a simple bilinear filtering algorithm, it combines every 4 pixels in one pixel - for(int x=0;x 0) - outPixel[i] = pixelsSum[i] / usedPixels; - else - outPixel[i] = 0; - } - outPixel[3] = pixelsSum[3]/4; - } - } - - glTexImage2D(GL_TEXTURE_2D, mipmap++, GL_RGBA, outSize.width(), outSize.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, &outPixels[0]); - - if(inSize.width() == 1 || inSize.height() == 1) - break; + m_size = size; + m_glSize = glSize; + setupTranformMatrix(); + return true; +} - inPixels = std::move(outPixels); - inSize /= 2; - outSize /= 2; - } +void Texture::setupWrap() +{ + GLint texParam = GL_REPEAT; + if(g_graphics.canUseClampToEdge()) + texParam = GL_CLAMP_TO_EDGE; // disable texture borders by default + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, texParam); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, texParam); } void Texture::setupFilters() @@ -280,3 +200,24 @@ void Texture::setupTranformMatrix() 0.0f, 0.0f, 1.0f }; } } + +void Texture::setupPixels(int level, const Size& size, uchar* pixels, int channels) +{ + GLenum format = 0; + switch(channels) { + case 4: + format = GL_RGBA; + break; + case 3: + format = GL_RGB; + break; + case 2: + format = GL_LUMINANCE_ALPHA; + break; + case 1: + format = GL_LUMINANCE; + break; + } + + glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, size.width(), size.height(), 0, format, GL_UNSIGNED_BYTE, pixels); +} diff --git a/src/framework/graphics/texture.h b/src/framework/graphics/texture.h index d49a09ed..bc5bcc90 100644 --- a/src/framework/graphics/texture.h +++ b/src/framework/graphics/texture.h @@ -29,41 +29,35 @@ class Texture : public std::enable_shared_from_this { public: Texture(); - Texture(const ImagePtr& image); - Texture(int width, int height, int channels = 4, uchar* pixels = NULL); + Texture(const Size& size); + Texture(const ImagePtr& image, bool buildMipmaps = false); virtual ~Texture(); - void copyFromScreen(const Rect& screenRect); - void bind(); + void copyFromScreen(const Rect& screenRect); + bool buildHardwareMipmaps(); - /// Tries to generate mipmaps via hardware, otherwise fallback to software implementation - void generateMipmaps(); - /// Generate mipmaps via hardware if supported - bool generateHardwareMipmaps(); - /// Generate mipmaps via software, which has a special algorithm for combining alpha pixels - void generateSoftwareMipmaps(std::vector inPixels); - - /// Activate texture anti-aliasing giving a better look when they are resized void setSmooth(bool smooth); void setUpsideDown(bool upsideDown); - GLuint getId() { return m_textureId; } - + GLuint getId() { return m_id; } int getWidth() { return m_size.width(); } int getHeight() { return m_size.height(); } const Size& getSize() { return m_size; } + const Size& getGlSize() { return m_glSize; } const Matrix3& getTransformMatrix() { return m_transformMatrix; } - - bool isEmpty() { return m_textureId == 0; } + bool isEmpty() { return m_id == 0; } bool hasMipmaps() { return m_hasMipmaps; } protected: + void createTexture(); + bool setupSize(const Size& size, bool forcePowerOfTwo = false); + void setupWrap(); void setupFilters(); void setupTranformMatrix(); - GLuint internalLoadGLTexture(uchar* pixels, int channels, int w, int h); + void setupPixels(int level, const Size& size, uchar *pixels, int channels = 4); - GLuint m_textureId; + GLuint m_id; Size m_size; Size m_glSize; Matrix3 m_transformMatrix; diff --git a/src/framework/graphics/texturemanager.cpp b/src/framework/graphics/texturemanager.cpp index ff4128c9..631461c5 100644 --- a/src/framework/graphics/texturemanager.cpp +++ b/src/framework/graphics/texturemanager.cpp @@ -23,6 +23,7 @@ #include "texturemanager.h" #include "animatedtexture.h" #include "graphics.h" +#include "image.h" #include #include @@ -75,10 +76,13 @@ TexturePtr TextureManager::loadPNG(std::stringstream& file) apng_data apng; if(load_apng(file, &apng) == 0) { if(apng.num_frames > 1) { // animated texture - uchar *framesdata = apng.pdata + (apng.first_frame * apng.width * apng.height * apng.bpp); - texture = TexturePtr(new AnimatedTexture(apng.width, apng.height, apng.bpp, apng.num_frames, framesdata, (int*)apng.frames_delay)); - } else - texture = TexturePtr(new Texture(apng.width, apng.height, apng.bpp, apng.pdata)); + //uchar *framesdata = apng.pdata + (apng.first_frame * apng.width * apng.height * apng.bpp); + //texture = TexturePtr(new AnimatedTexture(apng.width, apng.height, apng.bpp, apng.num_frames, framesdata, (int*)apng.frames_delay)); + g_logger.error("animated textures is disabled for a while"); + } else { + ImagePtr image = ImagePtr(new Image(Size(apng.width, apng.height), apng.bpp, apng.pdata)); + texture = TexturePtr(new Texture(image)); + } free_apng(&apng); } diff --git a/src/framework/luafunctions.cpp b/src/framework/luafunctions.cpp index 2bb1e4cc..39d7e4ba 100644 --- a/src/framework/luafunctions.cpp +++ b/src/framework/luafunctions.cpp @@ -554,6 +554,7 @@ void Application::registerLuaFunctions() g_lua.registerStaticClass("g_graphics"); g_lua.bindClassStaticFunction("g_graphics", "isPainterEngineAvailable", std::bind(&Graphics::isPainterEngineAvailable, &g_graphics, std::placeholders::_1)); g_lua.bindClassStaticFunction("g_graphics", "selectPainterEngine", std::bind(&Graphics::selectPainterEngine, &g_graphics, std::placeholders::_1)); + g_lua.bindClassStaticFunction("g_graphics", "canCacheBackbuffer", std::bind(&Graphics::canCacheBackbuffer, &g_graphics)); g_lua.bindClassStaticFunction("g_graphics", "getPainterEngine", std::bind(&Graphics::getPainterEngine, &g_graphics)); g_lua.bindClassStaticFunction("g_graphics", "getViewportSize", std::bind(&Graphics::getViewportSize, &g_graphics)); g_lua.bindClassStaticFunction("g_graphics", "getVendor", std::bind(&Graphics::getVendor, &g_graphics)); diff --git a/src/framework/platform/win32window.cpp b/src/framework/platform/win32window.cpp index af8eb458..e1a9695c 100644 --- a/src/framework/platform/win32window.cpp +++ b/src/framework/platform/win32window.cpp @@ -319,7 +319,6 @@ void WIN32Window::internalChooseGLVisual() if(!pixelFormat) g_logger.fatal("Could not find a suitable pixel format"); - pfd.cStencilBits = 8; if(!SetPixelFormat(m_deviceContext, pixelFormat, &pfd)) g_logger.fatal("Could not set the pixel format"); } diff --git a/src/framework/platform/x11window.cpp b/src/framework/platform/x11window.cpp index c986c487..ca13f06f 100644 --- a/src/framework/platform/x11window.cpp +++ b/src/framework/platform/x11window.cpp @@ -370,10 +370,10 @@ void X11Window::internalChooseGLVisual() #else EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT, #endif - EGL_RED_SIZE, 4, - EGL_GREEN_SIZE, 4, - EGL_BLUE_SIZE, 4, - EGL_ALPHA_SIZE, 4, + EGL_RED_SIZE, 5, + EGL_GREEN_SIZE, 6, + EGL_BLUE_SIZE, 5, + EGL_ALPHA_SIZE, 0, EGL_NONE }; diff --git a/src/framework/ui/uimanager.cpp b/src/framework/ui/uimanager.cpp index a7ed64bf..78d4eac4 100644 --- a/src/framework/ui/uimanager.cpp +++ b/src/framework/ui/uimanager.cpp @@ -52,9 +52,9 @@ void UIManager::terminate() m_pressedWidget = nullptr; } -void UIManager::render(bool foregroundPane) +void UIManager::render(Fw::DrawPane drawPane) { - m_rootWidget->draw(m_rootWidget->getRect(), foregroundPane); + m_rootWidget->draw(m_rootWidget->getRect(), drawPane); } void UIManager::resize(const Size& size) diff --git a/src/framework/ui/uimanager.h b/src/framework/ui/uimanager.h index 820e2445..2869fd01 100644 --- a/src/framework/ui/uimanager.h +++ b/src/framework/ui/uimanager.h @@ -33,7 +33,7 @@ public: void init(); void terminate(); - void render(bool foregroundPane); + void render(Fw::DrawPane drawPane); void resize(const Size& size); void inputEvent(const InputEvent& event); diff --git a/src/framework/ui/uitextedit.cpp b/src/framework/ui/uitextedit.cpp index d19e4aa1..8889dcdf 100644 --- a/src/framework/ui/uitextedit.cpp +++ b/src/framework/ui/uitextedit.cpp @@ -41,9 +41,9 @@ UITextEdit::UITextEdit() blinkCursor(); } -void UITextEdit::drawSelf(bool foregroundPane) +void UITextEdit::drawSelf(Fw::DrawPane drawPane) { - if(!foregroundPane) + if((drawPane & Fw::ForegroundPane) == 0) return; drawBackground(m_rect); diff --git a/src/framework/ui/uitextedit.h b/src/framework/ui/uitextedit.h index 58c5582a..731eaca0 100644 --- a/src/framework/ui/uitextedit.h +++ b/src/framework/ui/uitextedit.h @@ -30,7 +30,7 @@ class UITextEdit : public UIWidget public: UITextEdit(); - void drawSelf(bool foregroundPane); + void drawSelf(Fw::DrawPane drawPane); private: void update(); diff --git a/src/framework/ui/uiwidget.cpp b/src/framework/ui/uiwidget.cpp index 36d9b8fe..e0401a10 100644 --- a/src/framework/ui/uiwidget.cpp +++ b/src/framework/ui/uiwidget.cpp @@ -52,27 +52,27 @@ UIWidget::~UIWidget() #endif } -void UIWidget::draw(const Rect& visibleRect, bool foregroundPane) +void UIWidget::draw(const Rect& visibleRect, Fw::DrawPane drawPane) { if(m_clipping) g_painter->setClipRect(visibleRect); - drawSelf(foregroundPane); + drawSelf(drawPane); if(m_children.size() > 0) { if(m_clipping) g_painter->setClipRect(visibleRect.intersection(getPaddingRect())); - drawChildren(visibleRect, foregroundPane); + drawChildren(visibleRect, drawPane); } if(m_clipping) g_painter->resetClipRect(); } -void UIWidget::drawSelf(bool foregroundPane) +void UIWidget::drawSelf(Fw::DrawPane drawPane) { - if(!foregroundPane) + if((drawPane & Fw::ForegroundPane) == 0) return; // draw style components in order @@ -88,7 +88,7 @@ void UIWidget::drawSelf(bool foregroundPane) drawText(m_rect); } -void UIWidget::drawChildren(const Rect& visibleRect, bool foregroundPane) +void UIWidget::drawChildren(const Rect& visibleRect, Fw::DrawPane drawPane) { // draw children for(const UIWidgetPtr& child : m_children) { @@ -107,10 +107,10 @@ void UIWidget::drawChildren(const Rect& visibleRect, bool foregroundPane) if(child->getOpacity() < oldOpacity) g_painter->setOpacity(child->getOpacity()); - child->draw(childVisibleRect, foregroundPane); + child->draw(childVisibleRect, drawPane); // debug draw box - if(foregroundPane && g_ui.isDrawingDebugBoxes()) { + if(g_ui.isDrawingDebugBoxes() && drawPane & Fw::ForegroundPane) { g_painter->setColor(Color::green); g_painter->drawBoundingRect(child->getRect()); } @@ -497,7 +497,10 @@ void UIWidget::applyStyle(const OTMLNodePtr& styleNode) callLuaField("onStyleApply", styleNode->tag(), styleNode); if(m_firstOnStyle) { - callLuaField("onSetup"); + auto self = asUIWidget(); + g_eventDispatcher.addEvent([self] { + self->callLuaField("onSetup"); + }); // always focus new child if(isFocusable() && isExplicitlyVisible() && isExplicitlyEnabled()) focus(); diff --git a/src/framework/ui/uiwidget.h b/src/framework/ui/uiwidget.h index 316dd04c..3908aa0f 100644 --- a/src/framework/ui/uiwidget.h +++ b/src/framework/ui/uiwidget.h @@ -52,9 +52,9 @@ public: virtual ~UIWidget(); protected: - virtual void draw(const Rect& visibleRect, bool foregroundPane); - virtual void drawSelf(bool foregroundPane); - virtual void drawChildren(const Rect& visibleRect, bool foregroundPane); + virtual void draw(const Rect& visibleRect, Fw::DrawPane drawPane); + virtual void drawSelf(Fw::DrawPane drawPane); + virtual void drawChildren(const Rect& visibleRect, Fw::DrawPane drawPane); friend class UIManager; diff --git a/src/otclient/core/thingtype.cpp b/src/otclient/core/thingtype.cpp index a26b3455..83046ade 100644 --- a/src/otclient/core/thingtype.cpp +++ b/src/otclient/core/thingtype.cpp @@ -76,11 +76,7 @@ TexturePtr& ThingType::getSpriteMask(int w, int h, int l, int x, int y, int z, i static Color maskColors[LastMask] = { Color::yellow, Color::red, Color::green, Color::blue }; maskImage->overwriteMask(maskColors[mask]); - maskTexture = TexturePtr(new Texture(maskImage)); - maskTexture->setSmooth(true); - - if(g_graphics.canUseMipmaps()) - maskTexture->generateSoftwareMipmaps(maskImage->getPixels()); + maskTexture = TexturePtr(new Texture(maskImage, true)); } } @@ -120,7 +116,7 @@ TexturePtr& ThingType::getTexture(int animationPhase) Point spritePos = Point(m_dimensions[Width] - w - 1, m_dimensions[Height] - h - 1) * Otc::TILE_PIXELS; - fullImage->append(framePos + spritePos, spriteImage); + fullImage->blit(framePos + spritePos, spriteImage); } } } @@ -139,16 +135,12 @@ TexturePtr& ThingType::getTexture(int animationPhase) } m_texturesFramesRects[animationPhase][frameIndex] = drawRect; - m_texturesFramesOffsets[animationPhase][frameIndex] = drawRect.topLeft() - framePos; + m_texturesFramesOffsets[animationPhase][frameIndex] = drawRect.topLeft() - framePos + Point(1,1); } } } } - animationPhaseTexture = TexturePtr(new Texture(fullImage)); - animationPhaseTexture->setSmooth(true); - - //if(g_graphics.canUseMipmaps()) - //animationPhaseTexture->generateSoftwareMipmaps(fullImage->getPixels()); + animationPhaseTexture = TexturePtr(new Texture(fullImage, true)); } return animationPhaseTexture; } diff --git a/src/otclient/otclient.cpp b/src/otclient/otclient.cpp index ebe2536a..66330e24 100644 --- a/src/otclient/otclient.cpp +++ b/src/otclient/otclient.cpp @@ -51,20 +51,45 @@ void OTClient::init(const std::vector& args) "Compiled by: ", BUILD_COMPILER, "\n", "Build type: ", BUILD_TYPE, "\n"); return; - } else if(arg == "-help" || arg == "--help" || arg == "-h") { + /* + * if(option == "-no-draw-arrays") + m_useDrawArrays = false; + else if(option == "-no-fbos") + m_useFBO = false; + else if(option == "-no-mipmaps") + m_useMipmaps = false; + else if(option == "-no-hardware-mipmaps") + m_useHardwareMipmaps = false; + else if(option == "-no-smooth") + m_useBilinearFiltering = false; + else if(option == "-hardware-buffers") + m_useHardwareBuffers = true; + else if(option == "-no-non-power-of-two-textures") + m_useNonPowerOfTwoTextures = false; + else if(option == "-no-clamp-to-edge") + m_useClampToEdge = false; + else if(option == "-no-backbuffer-cache") + m_cacheBackbuffer = false; + else if(option == "-opengl1") + m_prefferedPainterEngine = Painter_OpenGL1; + else if(option == "-opengl2") + */ + } else if(arg == "-help" || arg == "--help" || arg == "-h" || arg == "-?" || arg == "/?") { stdext::print( "Usage: ", args[0], " [options]\n" "Options:\n" - " -help Display this information and exit\n" - " -version Display version and exit\n" - "\n" - " -no-fbos Disable usage of opengl framebuffer objects\n" - " -no-mipmapping Disable texture mipmaping\n" - " -no-smoothing Disable texture smoothing (bilinear filter)\n" - " -no-hardware-buffering Disable buffering vertex arrays in hardware\n" - " -realtime-mipmapping Improve framebuffer smoothing quality by\n" - " generating mipmaps in realtime when hardware\n" - " mipmap generation implementation is available\n"); + " -help Display this information and exit\n" + " -version Display version and exit\n" + " \n" + " -no-fbos Disable usage of opengl framebuffer objects\n" + " -no-mipmaps Disable texture mipmaping\n" + " -no-smooth Disable texture smoothing (bilinear filter)\n" + " -no-non-power-of-two-textures Use only power of two textures\n" + " -no-clamp-to-edge Don't use GL_CLAMP_TO_EDGE\n" + " -no-backbuffer-cache Don't allow backbuffer caching\n" + " -hardware-buffers Cache vertex arrays in hardware\n" + " -opengl1 Use OpenGL 1.x painter\n" + " -opengl2 Use OpenGL 2.0 painter\n"); return; } else { stdext::println("Unrecognized option '", arg, "', please see -help for available options list"); diff --git a/src/otclient/ui/uicreature.cpp b/src/otclient/ui/uicreature.cpp index d0ce16ca..405c054b 100644 --- a/src/otclient/ui/uicreature.cpp +++ b/src/otclient/ui/uicreature.cpp @@ -24,12 +24,12 @@ #include #include -void UICreature::drawSelf(bool foregroundPane) +void UICreature::drawSelf(Fw::DrawPane drawPane) { - if(!foregroundPane) + if((drawPane & Fw::ForegroundPane) == 0) return; - UIWidget::drawSelf(foregroundPane); + UIWidget::drawSelf(drawPane); if(m_creature) { Rect drawRect = getPaddingRect(); diff --git a/src/otclient/ui/uicreature.h b/src/otclient/ui/uicreature.h index 1cfd0c86..34ba739a 100644 --- a/src/otclient/ui/uicreature.h +++ b/src/otclient/ui/uicreature.h @@ -30,7 +30,7 @@ class UICreature : public UIWidget { public: - void drawSelf(bool foregroundPane); + void drawSelf(Fw::DrawPane drawPane); void setCreature(const CreaturePtr& creature) { m_creature = creature; } void setFixedCreatureSize(bool fixed) { m_fixedCreatureSize = fixed; } diff --git a/src/otclient/ui/uiitem.cpp b/src/otclient/ui/uiitem.cpp index a76ff050..1c5fbb8b 100644 --- a/src/otclient/ui/uiitem.cpp +++ b/src/otclient/ui/uiitem.cpp @@ -30,9 +30,9 @@ UIItem::UIItem() m_dragable = true; } -void UIItem::drawSelf(bool foregroundPane) +void UIItem::drawSelf(Fw::DrawPane drawPane) { - if(!foregroundPane) + if((drawPane & Fw::ForegroundPane) == 0) return; // draw style components in order diff --git a/src/otclient/ui/uiitem.h b/src/otclient/ui/uiitem.h index 975f59a3..ed709eb1 100644 --- a/src/otclient/ui/uiitem.h +++ b/src/otclient/ui/uiitem.h @@ -31,7 +31,7 @@ class UIItem : public UIWidget { public: UIItem(); - void drawSelf(bool foregroundPane); + void drawSelf(Fw::DrawPane drawPane); void setItemId(int id); void setItemCount(int count) { if(m_item) m_item->setCount(count); } diff --git a/src/otclient/ui/uimap.cpp b/src/otclient/ui/uimap.cpp index 3684c663..2be6f2e2 100644 --- a/src/otclient/ui/uimap.cpp +++ b/src/otclient/ui/uimap.cpp @@ -45,21 +45,25 @@ UIMap::~UIMap() g_map.removeMapView(m_mapView); } -void UIMap::drawSelf(bool foregroundPane) +void UIMap::drawSelf(Fw::DrawPane drawPane) { - if(foregroundPane) { - UIWidget::drawSelf(foregroundPane); + UIWidget::drawSelf(drawPane); + if(drawPane & Fw::ForegroundPane) { // draw map border g_painter->setColor(Color::black); g_painter->drawBoundingRect(m_mapRect.expanded(1)); - g_painter->saveState(); - g_painter->setCompositionMode(Painter::CompositionMode_Replace); - g_painter->setColor(Color::alpha); - g_painter->drawFilledRect(m_mapRect); - g_painter->restoreSavedState(); - } else { + if(drawPane != Fw::BothPanes) { + g_painter->saveState(); + g_painter->setCompositionMode(Painter::CompositionMode_Replace); + g_painter->setColor(Color::alpha); + g_painter->drawFilledRect(m_mapRect); + g_painter->restoreSavedState(); + } + } + + if(drawPane & Fw::BackgroundPane) { g_painter->setColor(Color::white); m_mapView->draw(m_mapRect); } diff --git a/src/otclient/ui/uimap.h b/src/otclient/ui/uimap.h index 00ff08df..3c021b17 100644 --- a/src/otclient/ui/uimap.h +++ b/src/otclient/ui/uimap.h @@ -35,7 +35,7 @@ public: UIMap(); ~UIMap(); - void drawSelf(bool foregroundPane); + void drawSelf(Fw::DrawPane drawPane); bool setZoom(int zoom); bool zoomIn();