graphics fixes and improvements
This commit is contained in:
parent
4f9ca15ef0
commit
1a7f2a44fc
|
@ -43,7 +43,6 @@ locale = {
|
||||||
["Auto login"] = "Entrar automaticamente",
|
["Auto login"] = "Entrar automaticamente",
|
||||||
["Auto login selected character on next charlist load"] = "Entrar automaticamente com o personagem quando reabrir a lista de personagens",
|
["Auto login selected character on next charlist load"] = "Entrar automaticamente com o personagem quando reabrir a lista de personagens",
|
||||||
["Axe Fighting"] = "Combate com Machado",
|
["Axe Fighting"] = "Combate com Machado",
|
||||||
["Background pane framerate limit: %s"] = "Limite da taxa de quadros no segundo plano: %s",
|
|
||||||
["Banishment"] = "Banimento",
|
["Banishment"] = "Banimento",
|
||||||
["Banishment + Final Warning"] = "Banimento + Aviso final",
|
["Banishment + Final Warning"] = "Banimento + Aviso final",
|
||||||
["Battle"] = "Batalha",
|
["Battle"] = "Batalha",
|
||||||
|
@ -88,9 +87,8 @@ locale = {
|
||||||
["Fishing"] = "Pesca",
|
["Fishing"] = "Pesca",
|
||||||
["Fist Fighting"] = "Porrada",
|
["Fist Fighting"] = "Porrada",
|
||||||
["Follow"] = "Seguir",
|
["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",
|
["Fullscreen"] = "Tela cheia",
|
||||||
|
["Game framerate limit: %s"] = "Limite da taxa de quadros do jogo: %s",
|
||||||
["General"] = "Geral",
|
["General"] = "Geral",
|
||||||
["Graphics"] = "Gráficos",
|
["Graphics"] = "Gráficos",
|
||||||
["Graphics Engine:"] = "Motor Gráfico:",
|
["Graphics Engine:"] = "Motor Gráfico:",
|
||||||
|
@ -106,6 +104,7 @@ locale = {
|
||||||
["Hotkeys"] = "Atalhos",
|
["Hotkeys"] = "Atalhos",
|
||||||
["Ignore capacity"] = "Ignorar capacidade",
|
["Ignore capacity"] = "Ignorar capacidade",
|
||||||
["Ignore equipped"] = "Ignorar equipado",
|
["Ignore equipped"] = "Ignorar equipado",
|
||||||
|
["Interface framerate limit: %s"] = "Limite da taxa de quadros da interface: %s",
|
||||||
["Inventory"] = "Inventário",
|
["Inventory"] = "Inventário",
|
||||||
["Invite to Party"] = "Convidar para o grupo",
|
["Invite to Party"] = "Convidar para o grupo",
|
||||||
["Invite to private chat"] = "Convidar para o canal privado",
|
["Invite to private chat"] = "Convidar para o canal privado",
|
||||||
|
|
|
@ -35,7 +35,7 @@ Panel
|
||||||
|
|
||||||
Label
|
Label
|
||||||
id: backgroundFrameRateLimitLabel
|
id: backgroundFrameRateLimitLabel
|
||||||
!text: tr('Background pane framerate limit: %s', 'max')
|
!text: tr('Game framerate limit: %s', 'max')
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.top: prev.bottom
|
anchors.top: prev.bottom
|
||||||
|
@ -59,12 +59,12 @@ Panel
|
||||||
value = 0
|
value = 0
|
||||||
end
|
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)
|
g_app.setBackgroundPaneMaxFps(value)
|
||||||
|
|
||||||
Label
|
Label
|
||||||
id: foregroundFrameRateLimitLabel
|
id: foregroundFrameRateLimitLabel
|
||||||
!text: tr('Foreground pane framerate limit: %s', '8')
|
!text: tr('Interface framerate limit: %s', '24')
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.top: prev.bottom
|
anchors.top: prev.bottom
|
||||||
|
@ -78,7 +78,7 @@ Panel
|
||||||
margin-top: 3
|
margin-top: 3
|
||||||
minimum: 1
|
minimum: 1
|
||||||
maximum: 61
|
maximum: 61
|
||||||
value: 8
|
value: 61
|
||||||
step: 1
|
step: 1
|
||||||
@onValueChange: |
|
@onValueChange: |
|
||||||
local value = self:getValue()
|
local value = self:getValue()
|
||||||
|
@ -88,6 +88,6 @@ Panel
|
||||||
value = 0
|
value = 0
|
||||||
end
|
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)
|
g_app.setForegroundPaneMaxFps(value)
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,14 @@ local function setupGraphicsEngines()
|
||||||
g_graphics.selectPainterEngine(2)
|
g_graphics.selectPainterEngine(2)
|
||||||
end
|
end
|
||||||
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
|
end
|
||||||
|
|
||||||
function Options.init()
|
function Options.init()
|
||||||
|
@ -50,12 +58,12 @@ function Options.init()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
Keyboard.bindKeyDown('Ctrl+P', Options.toggle)
|
Keyboard.bindKeyDown('Ctrl+D', Options.toggle)
|
||||||
Keyboard.bindKeyDown('Ctrl+F', function() Options.toggleOption('fullscreen') end)
|
Keyboard.bindKeyDown('Ctrl+F', function() Options.toggleOption('fullscreen') end)
|
||||||
|
|
||||||
optionsWindow = displayUI('options.otui')
|
optionsWindow = displayUI('options.otui')
|
||||||
optionsWindow:hide()
|
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 = optionsWindow:getChildById('optionsTabBar')
|
||||||
optionsTabBar:setContentWidget(optionsWindow:getChildById('optionsTabContent'))
|
optionsTabBar:setContentWidget(optionsWindow:getChildById('optionsTabContent'))
|
||||||
|
|
||||||
|
@ -69,7 +77,7 @@ function Options.init()
|
||||||
end
|
end
|
||||||
|
|
||||||
function Options.terminate()
|
function Options.terminate()
|
||||||
Keyboard.unbindKeyDown('Ctrl+P')
|
Keyboard.unbindKeyDown('Ctrl+D')
|
||||||
Keyboard.unbindKeyDown('Ctrl+F')
|
Keyboard.unbindKeyDown('Ctrl+F')
|
||||||
optionsWindow:destroy()
|
optionsWindow:destroy()
|
||||||
optionsWindow = nil
|
optionsWindow = nil
|
||||||
|
|
|
@ -83,6 +83,8 @@ TopPanel
|
||||||
cycleEvent(function()
|
cycleEvent(function()
|
||||||
local frameCounter = rootWidget:recursiveGetChildById('frameCounter')
|
local frameCounter = rootWidget:recursiveGetChildById('frameCounter')
|
||||||
if frameCounter then
|
if frameCounter then
|
||||||
frameCounter:setText('FPS: ' .. g_app.getBackgroundPaneFps())
|
local text = 'FPS: ' .. g_app.getBackgroundPaneFps()
|
||||||
|
frameCounter:setText(text)
|
||||||
|
--print(text)
|
||||||
end
|
end
|
||||||
end, 250)
|
end, 250)
|
||||||
|
|
|
@ -63,10 +63,11 @@ local function updateSlider(self)
|
||||||
slider:setMarginLeft(offset)
|
slider:setMarginLeft(offset)
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.maximum == self.minimum then
|
local status = (self.maximum ~= self.minimum)
|
||||||
self:disable()
|
|
||||||
else
|
self:setOn(status)
|
||||||
self:enable()
|
for _i,child in pairs(self:getChildren()) do
|
||||||
|
child:setEnabled(status)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -100,12 +101,10 @@ end
|
||||||
function UIScrollBar:onSetup()
|
function UIScrollBar:onSetup()
|
||||||
self.setupDone = true
|
self.setupDone = true
|
||||||
signalcall(self.onValueChange, self, self.value)
|
signalcall(self.onValueChange, self, self.value)
|
||||||
addEvent(function()
|
Mouse.bindAutoPress(self:getChildById('decrementButton'), function() self:decrement() end)
|
||||||
Mouse.bindAutoPress(self:getChildById('decrementButton'), function() self:decrement() end)
|
Mouse.bindAutoPress(self:getChildById('incrementButton'), function() self:increment() end)
|
||||||
Mouse.bindAutoPress(self:getChildById('incrementButton'), function() self:increment() end)
|
Mouse.bindPressMove(self:getChildById('sliderButton'), function(mousePos, mouseMoved) parseSliderPos(self, mousePos) end)
|
||||||
Mouse.bindPressMove(self:getChildById('sliderButton'), function(mousePos, mouseMoved) parseSliderPos(self, mousePos) end)
|
updateSlider(self)
|
||||||
updateSlider(self)
|
|
||||||
end)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function UIScrollBar:onStyleApply(styleName, styleNode)
|
function UIScrollBar:onStyleApply(styleName, styleNode)
|
||||||
|
|
|
@ -41,6 +41,7 @@ end
|
||||||
|
|
||||||
function UIItem:onHoverChange(hovered)
|
function UIItem:onHoverChange(hovered)
|
||||||
UIWidget.onHoverChange(self, hovered)
|
UIWidget.onHoverChange(self, hovered)
|
||||||
|
|
||||||
if self:isVirtual() then return end
|
if self:isVirtual() then return end
|
||||||
|
|
||||||
local draggingWidget = g_ui.getDraggingWidget()
|
local draggingWidget = g_ui.getDraggingWidget()
|
||||||
|
|
|
@ -6,10 +6,8 @@ function UIMiniWindow.create()
|
||||||
end
|
end
|
||||||
|
|
||||||
function UIMiniWindow:onSetup()
|
function UIMiniWindow:onSetup()
|
||||||
addEvent(function()
|
self:getChildById('closeButton').onClick = function() signalcall(self.onClose, self) end
|
||||||
self:getChildById('closeButton').onClick = function() signalcall(self.onClose, self) end
|
self:getChildById('minimizeButton').onClick = function() signalcall(self.onMinimize, self) end
|
||||||
self:getChildById('minimizeButton').onClick = function() signalcall(self.onMinimize, self) end
|
|
||||||
end)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function UIMiniWindow:onDragEnter(mousePos)
|
function UIMiniWindow:onDragEnter(mousePos)
|
||||||
|
|
|
@ -44,6 +44,7 @@ local SayModes = {
|
||||||
|
|
||||||
local MAX_HISTORY = 1000
|
local MAX_HISTORY = 1000
|
||||||
local MAX_LINES = 100
|
local MAX_LINES = 100
|
||||||
|
local HELP_CHANNEL = 9
|
||||||
|
|
||||||
local consolePanel
|
local consolePanel
|
||||||
local consoleContentPanel
|
local consoleContentPanel
|
||||||
|
@ -221,6 +222,7 @@ function Console.init()
|
||||||
-- tibia like hotkeys
|
-- tibia like hotkeys
|
||||||
Keyboard.bindKeyDown('Ctrl+O', g_game.requestChannels)
|
Keyboard.bindKeyDown('Ctrl+O', g_game.requestChannels)
|
||||||
Keyboard.bindKeyDown('Ctrl+E', Console.removeCurrentTab)
|
Keyboard.bindKeyDown('Ctrl+E', Console.removeCurrentTab)
|
||||||
|
Keyboard.bindKeyDown('Ctrl+H', Console.openHelp)
|
||||||
end
|
end
|
||||||
|
|
||||||
function Console.terminate()
|
function Console.terminate()
|
||||||
|
@ -242,6 +244,7 @@ function Console.terminate()
|
||||||
|
|
||||||
Keyboard.unbindKeyDown('Ctrl+O')
|
Keyboard.unbindKeyDown('Ctrl+O')
|
||||||
Keyboard.unbindKeyDown('Ctrl+E')
|
Keyboard.unbindKeyDown('Ctrl+E')
|
||||||
|
Keyboard.unbindKeyDown('Ctrl+H')
|
||||||
|
|
||||||
if channelsWindow then
|
if channelsWindow then
|
||||||
channelsWindow:destroy()
|
channelsWindow:destroy()
|
||||||
|
@ -287,6 +290,10 @@ function Console.setTextEditText(text)
|
||||||
consoleTextEdit:setText(text)
|
consoleTextEdit:setText(text)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function Console.openHelp()
|
||||||
|
g_game.joinChannel(HELP_CHANNEL)
|
||||||
|
end
|
||||||
|
|
||||||
function Console.addTab(name, focus)
|
function Console.addTab(name, focus)
|
||||||
local tab = consoleTabBar:addTab(name)
|
local tab = consoleTabBar:addTab(name)
|
||||||
if focus then
|
if focus then
|
||||||
|
|
|
@ -12,14 +12,17 @@ function VipList.init()
|
||||||
onVipStateChange = VipList.onVipStateChange })
|
onVipStateChange = VipList.onVipStateChange })
|
||||||
|
|
||||||
|
|
||||||
|
Keyboard.bindKeyDown('Ctrl+P', VipList.toggle)
|
||||||
|
|
||||||
vipWindow = displayUI('viplist.otui', GameInterface.getLeftPanel())
|
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)
|
vipButton:setOn(true)
|
||||||
|
|
||||||
VipList.refresh()
|
VipList.refresh()
|
||||||
end
|
end
|
||||||
|
|
||||||
function VipList.terminate()
|
function VipList.terminate()
|
||||||
|
Keyboard.unbindKeyDown('Ctrl+P')
|
||||||
disconnect(g_game, { onGameEnd = VipList.clear,
|
disconnect(g_game, { onGameEnd = VipList.clear,
|
||||||
onAddVip = VipList.onAddVip,
|
onAddVip = VipList.onAddVip,
|
||||||
onVipStateChange = VipList.onVipStateChange })
|
onVipStateChange = VipList.onVipStateChange })
|
||||||
|
|
|
@ -167,6 +167,7 @@ void Application::run()
|
||||||
if(!m_initialized)
|
if(!m_initialized)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
bool cacheForeground = true;
|
||||||
m_stopping = false;
|
m_stopping = false;
|
||||||
m_running = true;
|
m_running = true;
|
||||||
|
|
||||||
|
@ -189,6 +190,15 @@ void Application::run()
|
||||||
bool redraw = false;
|
bool redraw = false;
|
||||||
bool updateForeground = 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()) {
|
if(m_backgroundFrameCounter.shouldProcessNextFrame()) {
|
||||||
redraw = true;
|
redraw = true;
|
||||||
|
|
||||||
|
@ -201,29 +211,35 @@ void Application::run()
|
||||||
if(redraw) {
|
if(redraw) {
|
||||||
g_graphics.beginRender();
|
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
|
// draw the foreground into a texture
|
||||||
if(updateForeground) {
|
if(updateForeground) {
|
||||||
|
m_foregroundFrameCounter.processNextFrame();
|
||||||
|
|
||||||
|
// draw foreground
|
||||||
|
g_painter->clear(Color::black);
|
||||||
|
g_ui.render(Fw::ForegroundPane);
|
||||||
|
|
||||||
|
// copy the foreground to a texture
|
||||||
|
m_foreground->copyFromScreen(viewportRect);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
} else {
|
||||||
m_foregroundFrameCounter.processNextFrame();
|
m_foregroundFrameCounter.processNextFrame();
|
||||||
|
m_backgroundFrameCounter.processNextFrame();
|
||||||
// draw foreground
|
g_ui.render(Fw::BothPanes);
|
||||||
g_painter->clear(Color::black);
|
|
||||||
g_ui.render(true);
|
|
||||||
|
|
||||||
// copy the foreground to a texture
|
|
||||||
m_foreground->copyFromScreen(viewportRect);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// draw background (animated stuff)
|
|
||||||
m_backgroundFrameCounter.processNextFrame();
|
|
||||||
g_ui.render(false);
|
|
||||||
|
|
||||||
// draw the foreground (steady stuff)
|
|
||||||
g_painter->setColor(Color::white);
|
|
||||||
g_painter->setOpacity(1.0);
|
|
||||||
g_painter->drawTexturedRect(viewportRect, m_foreground, viewportRect);
|
|
||||||
|
|
||||||
g_graphics.endRender();
|
g_graphics.endRender();
|
||||||
|
|
||||||
// update screen pixels
|
// update screen pixels
|
||||||
|
@ -237,9 +253,8 @@ void Application::run()
|
||||||
m_foregroundFrameCounter.update();
|
m_foregroundFrameCounter.update();
|
||||||
|
|
||||||
int sleepMicros = std::min(m_backgroundFrameCounter.getMaximumSleepMicros(), m_foregroundFrameCounter.getMaximumSleepMicros());
|
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);
|
stdext::microsleep(AdaptativeFrameCounter::MINIMUM_MICROS_SLEEP);
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// sleeps until next poll to avoid massive cpu usage
|
// sleeps until next poll to avoid massive cpu usage
|
||||||
|
@ -285,8 +300,10 @@ void Application::resize(const Size& size)
|
||||||
g_ui.resize(size);
|
g_ui.resize(size);
|
||||||
m_onInputEvent = false;
|
m_onInputEvent = false;
|
||||||
|
|
||||||
m_foreground = TexturePtr(new Texture(size.width(), size.height()));
|
if(g_graphics.canCacheBackbuffer()) {
|
||||||
m_foreground->setUpsideDown(true);
|
m_foreground = TexturePtr(new Texture(size));
|
||||||
|
m_foreground->setUpsideDown(true);
|
||||||
|
}
|
||||||
m_mustRepaint = true;
|
m_mustRepaint = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -262,6 +262,12 @@ namespace Fw
|
||||||
DraggingState = 2048,
|
DraggingState = 2048,
|
||||||
LastWidgetState = 4096
|
LastWidgetState = 4096
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum DrawPane {
|
||||||
|
ForegroundPane = 1,
|
||||||
|
BackgroundPane = 2,
|
||||||
|
BothPanes = 3
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
#include "graphics.h"
|
#include "graphics.h"
|
||||||
|
|
||||||
#include <framework/core/eventdispatcher.h>
|
#include <framework/core/eventdispatcher.h>
|
||||||
|
/*
|
||||||
AnimatedTexture::AnimatedTexture(int width, int height, int channels, int numFrames, uchar *framesPixels, int *framesDelay) :
|
AnimatedTexture::AnimatedTexture(int width, int height, int channels, int numFrames, uchar *framesPixels, int *framesDelay) :
|
||||||
Texture(),
|
Texture(),
|
||||||
m_numFrames(numFrames)
|
m_numFrames(numFrames)
|
||||||
|
@ -48,7 +48,7 @@ AnimatedTexture::AnimatedTexture(int width, int height, int channels, int numFra
|
||||||
AnimatedTexture::~AnimatedTexture()
|
AnimatedTexture::~AnimatedTexture()
|
||||||
{
|
{
|
||||||
glDeleteTextures(m_numFrames, &m_framesTextureId[0]);
|
glDeleteTextures(m_numFrames, &m_framesTextureId[0]);
|
||||||
m_textureId = 0;
|
m_id = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnimatedTexture::enableBilinearFilter()
|
void AnimatedTexture::enableBilinearFilter()
|
||||||
|
@ -65,7 +65,7 @@ void AnimatedTexture::processAnimation()
|
||||||
m_currentFrame++;
|
m_currentFrame++;
|
||||||
if(m_currentFrame >= m_numFrames)
|
if(m_currentFrame >= m_numFrames)
|
||||||
m_currentFrame = 0;
|
m_currentFrame = 0;
|
||||||
m_textureId = m_framesTextureId[m_currentFrame];
|
m_id = m_framesTextureId[m_currentFrame];
|
||||||
|
|
||||||
AnimatedTexturePtr self = asAnimatedTexture();
|
AnimatedTexturePtr self = asAnimatedTexture();
|
||||||
|
|
||||||
|
@ -73,3 +73,4 @@ void AnimatedTexture::processAnimation()
|
||||||
if(self.use_count() > 1)
|
if(self.use_count() > 1)
|
||||||
g_eventDispatcher.scheduleEvent(std::bind(&AnimatedTexture::processAnimation, self), m_framesDelay[m_currentFrame]);
|
g_eventDispatcher.scheduleEvent(std::bind(&AnimatedTexture::processAnimation, self), m_framesDelay[m_currentFrame]);
|
||||||
}
|
}
|
||||||
|
*/
|
|
@ -24,7 +24,7 @@
|
||||||
#define ANIMATEDTEXTURE_H
|
#define ANIMATEDTEXTURE_H
|
||||||
|
|
||||||
#include "texture.h"
|
#include "texture.h"
|
||||||
|
/*
|
||||||
class AnimatedTexture : public Texture
|
class AnimatedTexture : public Texture
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -43,5 +43,5 @@ private:
|
||||||
int m_currentFrame;
|
int m_currentFrame;
|
||||||
ticks_t m_lastAnimCheckTicks;
|
ticks_t m_lastAnimCheckTicks;
|
||||||
};
|
};
|
||||||
|
*/
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -63,7 +63,7 @@ void FrameBuffer::resize(const Size& size)
|
||||||
if(m_texture && m_texture->getSize() == size)
|
if(m_texture && m_texture->getSize() == size)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_texture = TexturePtr(new Texture(size.width(), size.height(), 4));
|
m_texture = TexturePtr(new Texture(size));
|
||||||
m_texture->setSmooth(true);
|
m_texture->setSmooth(true);
|
||||||
m_texture->setUpsideDown(true);
|
m_texture->setUpsideDown(true);
|
||||||
|
|
||||||
|
@ -76,8 +76,10 @@ void FrameBuffer::resize(const Size& size)
|
||||||
g_logger.fatal("Unable to setup framebuffer object");
|
g_logger.fatal("Unable to setup framebuffer object");
|
||||||
internalRelease();
|
internalRelease();
|
||||||
} else {
|
} else {
|
||||||
m_screenBackup = TexturePtr(new Texture(size.width(), size.height()));
|
if(m_backuping) {
|
||||||
m_screenBackup->setUpsideDown(true);
|
m_screenBackup = TexturePtr(new Texture(size));
|
||||||
|
m_screenBackup->setUpsideDown(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,7 +128,7 @@ void FrameBuffer::internalBind()
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
|
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
|
||||||
m_prevBoundFbo = boundFbo;
|
m_prevBoundFbo = boundFbo;
|
||||||
boundFbo = m_fbo;
|
boundFbo = m_fbo;
|
||||||
} else {
|
} else if(m_backuping) {
|
||||||
// backup screen color buffer into a texture
|
// backup screen color buffer into a texture
|
||||||
m_screenBackup->copyFromScreen(Rect(0, 0, getSize()));
|
m_screenBackup->copyFromScreen(Rect(0, 0, getSize()));
|
||||||
}
|
}
|
||||||
|
@ -145,10 +147,12 @@ void FrameBuffer::internalRelease()
|
||||||
m_texture->copyFromScreen(screenRect);
|
m_texture->copyFromScreen(screenRect);
|
||||||
|
|
||||||
// restore screen original content
|
// restore screen original content
|
||||||
Painter::CompositionMode oldComposition = g_painter->getCompositionMode();
|
if(m_backuping) {
|
||||||
g_painter->setCompositionMode(Painter::CompositionMode_Replace);
|
Painter::CompositionMode oldComposition = g_painter->getCompositionMode();
|
||||||
g_painter->drawTexturedRect(screenRect, m_screenBackup, screenRect);
|
g_painter->setCompositionMode(Painter::CompositionMode_Replace);
|
||||||
g_painter->setCompositionMode(oldComposition);
|
g_painter->drawTexturedRect(screenRect, m_screenBackup, screenRect);
|
||||||
|
g_painter->setCompositionMode(oldComposition);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,8 +40,11 @@ public:
|
||||||
void draw(const Rect& dest);
|
void draw(const Rect& dest);
|
||||||
void draw(const Rect& dest, const Rect& src);
|
void draw(const Rect& dest, const Rect& src);
|
||||||
|
|
||||||
|
void setBackuping(bool enabled) { m_backuping = enabled; }
|
||||||
|
|
||||||
TexturePtr getTexture() { return m_texture; }
|
TexturePtr getTexture() { return m_texture; }
|
||||||
Size getSize();
|
Size getSize();
|
||||||
|
bool isBackuping() { return m_backuping; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void internalCreate();
|
void internalCreate();
|
||||||
|
@ -53,6 +56,7 @@ private:
|
||||||
Size m_oldViewportSize;
|
Size m_oldViewportSize;
|
||||||
uint m_fbo;
|
uint m_fbo;
|
||||||
uint m_prevBoundFbo;
|
uint m_prevBoundFbo;
|
||||||
|
Boolean<true> m_backuping;
|
||||||
|
|
||||||
static uint boundFbo;
|
static uint boundFbo;
|
||||||
};
|
};
|
||||||
|
|
|
@ -92,12 +92,6 @@ void Graphics::init()
|
||||||
if(m_maxTextureSize == -1 || m_maxTextureSize > maxTextureSize)
|
if(m_maxTextureSize == -1 || m_maxTextureSize > maxTextureSize)
|
||||||
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);
|
selectPainterEngine(m_prefferedPainterEngine);
|
||||||
m_emptyTexture = TexturePtr(new Texture);
|
m_emptyTexture = TexturePtr(new Texture);
|
||||||
}
|
}
|
||||||
|
@ -143,6 +137,8 @@ bool Graphics::parseOption(const std::string& option)
|
||||||
m_useNonPowerOfTwoTextures = false;
|
m_useNonPowerOfTwoTextures = false;
|
||||||
else if(option == "-no-clamp-to-edge")
|
else if(option == "-no-clamp-to-edge")
|
||||||
m_useClampToEdge = false;
|
m_useClampToEdge = false;
|
||||||
|
else if(option == "-no-backbuffer-cache")
|
||||||
|
m_cacheBackbuffer = false;
|
||||||
else if(option == "-opengl1")
|
else if(option == "-opengl1")
|
||||||
m_prefferedPainterEngine = Painter_OpenGL1;
|
m_prefferedPainterEngine = Painter_OpenGL1;
|
||||||
else if(option == "-opengl2")
|
else if(option == "-opengl2")
|
||||||
|
@ -368,3 +364,16 @@ bool Graphics::canUseBlendFuncSeparate()
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#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
|
||||||
|
}
|
||||||
|
|
|
@ -70,6 +70,7 @@ public:
|
||||||
bool canUseHardwareMipmaps();
|
bool canUseHardwareMipmaps();
|
||||||
bool canUseClampToEdge();
|
bool canUseClampToEdge();
|
||||||
bool canUseBlendFuncSeparate();
|
bool canUseBlendFuncSeparate();
|
||||||
|
bool canCacheBackbuffer();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Size m_viewportSize;
|
Size m_viewportSize;
|
||||||
|
@ -84,6 +85,7 @@ private:
|
||||||
Boolean<true> m_useMipmaps;
|
Boolean<true> m_useMipmaps;
|
||||||
Boolean<true> m_useHardwareMipmaps;
|
Boolean<true> m_useHardwareMipmaps;
|
||||||
Boolean<true> m_useClampToEdge;
|
Boolean<true> m_useClampToEdge;
|
||||||
|
Boolean<true> m_cacheBackbuffer;
|
||||||
PainterEngine m_prefferedPainterEngine;
|
PainterEngine m_prefferedPainterEngine;
|
||||||
PainterEngine m_selectedPainterEngine;
|
PainterEngine m_selectedPainterEngine;
|
||||||
};
|
};
|
||||||
|
|
|
@ -30,7 +30,7 @@ Image::Image(const Size& size, int bpp, uint8 *pixels)
|
||||||
{
|
{
|
||||||
m_size = size;
|
m_size = size;
|
||||||
m_bpp = bpp;
|
m_bpp = bpp;
|
||||||
m_pixels.resize(size.area() * bpp);
|
m_pixels.resize(size.area() * bpp, 0);
|
||||||
if(pixels)
|
if(pixels)
|
||||||
memcpy(&m_pixels[0], pixels, m_pixels.size());
|
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)
|
if(!other)
|
||||||
return;
|
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<uint8> pixels(size.area()*4, 0xFF);
|
||||||
|
m_pixels = pixels;
|
||||||
|
m_size = size;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
|
||||||
|
void Texture::generateSoftwareMipmaps(std::vector<uint8> 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<uint8> 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<outSize.width();++x) {
|
||||||
|
for(int y=0;y<outSize.height();++y) {
|
||||||
|
uint8 *inPixel[4];
|
||||||
|
inPixel[0] = &inPixels[((y*2)*inSize.width() + (x*2))*4];
|
||||||
|
inPixel[1] = &inPixels[((y*2)*inSize.width() + (x*2)+1)*4];
|
||||||
|
inPixel[2] = &inPixels[((y*2+1)*inSize.width() + (x*2))*4];
|
||||||
|
inPixel[3] = &inPixels[((y*2+1)*inSize.width() + (x*2)+1)*4];
|
||||||
|
uint8 *outPixel = &outPixels[(y*outSize.width() + x)*4];
|
||||||
|
|
||||||
|
int pixelsSum[4];
|
||||||
|
for(int i=0;i<4;++i)
|
||||||
|
pixelsSum[i] = 0;
|
||||||
|
|
||||||
|
int usedPixels = 0;
|
||||||
|
for(int j=0;j<4;++j) {
|
||||||
|
// ignore colors of complete alpha pixels
|
||||||
|
if(inPixel[j][3] < 16)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for(int i=0;i<4;++i)
|
||||||
|
pixelsSum[i] += inPixel[j][i];
|
||||||
|
|
||||||
|
usedPixels++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// try to guess the alpha pixel more accurately
|
||||||
|
for(int i=0;i<4;++i) {
|
||||||
|
if(usedPixels > 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
|
@ -35,7 +35,9 @@ public:
|
||||||
static ImagePtr loadPNG(const std::string& file);
|
static ImagePtr loadPNG(const std::string& file);
|
||||||
|
|
||||||
void overwriteMask(const Color& maskedColor, const Color& insideColor = Color::white, const Color& outsideColor = Color::alpha);
|
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<uint8>& getPixels() { return m_pixels; }
|
std::vector<uint8>& getPixels() { return m_pixels; }
|
||||||
uint8* getPixelData() { return &m_pixels[0]; }
|
uint8* getPixelData() { return &m_pixels[0]; }
|
||||||
|
|
|
@ -27,104 +27,68 @@
|
||||||
|
|
||||||
Texture::Texture()
|
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;
|
||||||
|
|
||||||
|
if(!setupSize(size))
|
||||||
|
return;
|
||||||
|
|
||||||
|
createTexture();
|
||||||
|
bind();
|
||||||
|
setupPixels(0, m_glSize, nullptr, 4);
|
||||||
|
setupWrap();
|
||||||
|
setupFilters();
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture::Texture(int width, int height, int channels, uchar *pixels)
|
Texture::Texture(const ImagePtr& image, bool buildMipmaps)
|
||||||
{
|
{
|
||||||
// generate opengl texture
|
m_id = 0;
|
||||||
internalLoadGLTexture(pixels, channels, width, height);
|
|
||||||
|
if(!setupSize(image->getSize(), buildMipmaps))
|
||||||
|
return;
|
||||||
|
|
||||||
|
createTexture();
|
||||||
|
|
||||||
|
ImagePtr glImage = image;
|
||||||
|
if(m_size != m_glSize) {
|
||||||
|
glImage = ImagePtr(new Image(m_glSize, image->getBpp()));
|
||||||
|
glImage->paste(image);
|
||||||
|
} else
|
||||||
|
glImage = image;
|
||||||
|
|
||||||
|
bind();
|
||||||
|
|
||||||
|
/*
|
||||||
|
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture::~Texture()
|
Texture::~Texture()
|
||||||
{
|
{
|
||||||
// free texture from gl memory
|
// free texture from gl memory
|
||||||
if(m_textureId > 0)
|
if(m_id > 0)
|
||||||
glDeleteTextures(1, &m_textureId);
|
glDeleteTextures(1, &m_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint Texture::internalLoadGLTexture(uchar *pixels, int channels, int width, int height)
|
void Texture::bind()
|
||||||
{
|
{
|
||||||
m_size.resize(width, height);
|
// must reset painter texture state
|
||||||
|
g_painter->setTexture(this);
|
||||||
// convert texture pixel data to power of two size, only required for OpenGL 1.5 or older
|
glBindTexture(GL_TEXTURE_2D, m_id);
|
||||||
std::vector<uint8> 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<height; ++y)
|
|
||||||
for(int x=0; x<width; ++x)
|
|
||||||
for(int i=0; i<channels; ++i)
|
|
||||||
tmp[y*glWidth*channels+x*channels+i] = pixels[y*width*channels+x*channels+i];
|
|
||||||
pixels = &tmp[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
m_glSize.resize(glWidth, glHeight);
|
|
||||||
} else
|
|
||||||
m_glSize = m_size;
|
|
||||||
|
|
||||||
setupTranformMatrix();
|
|
||||||
|
|
||||||
// checks texture max size
|
|
||||||
if(std::max(m_glSize.width(), m_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",
|
|
||||||
width, height, g_graphics.getMaxTextureSize(), g_graphics.getMaxTextureSize()));
|
|
||||||
//TODO: make a workaround, could be bilinear scaling the texture
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// generate gl texture
|
|
||||||
GLuint id;
|
|
||||||
glGenTextures(1, &id);
|
|
||||||
assert(id != 0);
|
|
||||||
m_textureId = id;
|
|
||||||
bind();
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
setupFilters();
|
|
||||||
|
|
||||||
return id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Texture::copyFromScreen(const Rect& screenRect)
|
void Texture::copyFromScreen(const Rect& screenRect)
|
||||||
|
@ -133,25 +97,7 @@ void Texture::copyFromScreen(const Rect& screenRect)
|
||||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, screenRect.x(), screenRect.y(), screenRect.width(), screenRect.height());
|
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, screenRect.x(), screenRect.y(), screenRect.width(), screenRect.height());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Texture::bind()
|
bool Texture::buildHardwareMipmaps()
|
||||||
{
|
|
||||||
// must reset painter texture state
|
|
||||||
g_painter->setTexture(this);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, m_textureId);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Texture::generateMipmaps()
|
|
||||||
{
|
|
||||||
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.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Texture::generateHardwareMipmaps()
|
|
||||||
{
|
{
|
||||||
if(!g_graphics.canUseHardwareMipmaps())
|
if(!g_graphics.canUseHardwareMipmaps())
|
||||||
return false;
|
return false;
|
||||||
|
@ -188,69 +134,43 @@ void Texture::setUpsideDown(bool upsideDown)
|
||||||
setupTranformMatrix();
|
setupTranformMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Texture::generateSoftwareMipmaps(std::vector<uint8> inPixels)
|
void Texture::createTexture()
|
||||||
{
|
{
|
||||||
bind();
|
glGenTextures(1, &m_id);
|
||||||
|
assert(m_id != 0);
|
||||||
|
}
|
||||||
|
|
||||||
if(!m_hasMipmaps) {
|
bool Texture::setupSize(const Size& size, bool forcePowerOfTwo)
|
||||||
m_hasMipmaps = true;
|
{
|
||||||
setupFilters();
|
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();
|
m_size = size;
|
||||||
Size outSize = inSize / 2;
|
m_glSize = glSize;
|
||||||
std::vector<uint8> outPixels;
|
setupTranformMatrix();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
int mipmap = 1;
|
void Texture::setupWrap()
|
||||||
while(true) {
|
{
|
||||||
outPixels.resize(outSize.area()*4);
|
GLint texParam = GL_REPEAT;
|
||||||
|
if(g_graphics.canUseClampToEdge())
|
||||||
|
texParam = GL_CLAMP_TO_EDGE; // disable texture borders by default
|
||||||
|
|
||||||
// this is a simple bilinear filtering algorithm, it combines every 4 pixels in one pixel
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, texParam);
|
||||||
for(int x=0;x<outSize.width();++x) {
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, texParam);
|
||||||
for(int y=0;y<outSize.height();++y) {
|
|
||||||
uint8 *inPixel[4];
|
|
||||||
inPixel[0] = &inPixels[((y*2)*inSize.width() + (x*2))*4];
|
|
||||||
inPixel[1] = &inPixels[((y*2)*inSize.width() + (x*2)+1)*4];
|
|
||||||
inPixel[2] = &inPixels[((y*2+1)*inSize.width() + (x*2))*4];
|
|
||||||
inPixel[3] = &inPixels[((y*2+1)*inSize.width() + (x*2)+1)*4];
|
|
||||||
uint8 *outPixel = &outPixels[(y*outSize.width() + x)*4];
|
|
||||||
|
|
||||||
int pixelsSum[4];
|
|
||||||
for(int i=0;i<4;++i)
|
|
||||||
pixelsSum[i] = 0;
|
|
||||||
|
|
||||||
int usedPixels = 0;
|
|
||||||
for(int j=0;j<4;++j) {
|
|
||||||
// ignore colors of complete alpha pixels
|
|
||||||
if(inPixel[j][3] < 16)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
for(int i=0;i<4;++i)
|
|
||||||
pixelsSum[i] += inPixel[j][i];
|
|
||||||
|
|
||||||
usedPixels++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// try to guess the alpha pixel more accurately
|
|
||||||
for(int i=0;i<4;++i) {
|
|
||||||
if(usedPixels > 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Texture::setupFilters()
|
void Texture::setupFilters()
|
||||||
|
@ -280,3 +200,24 @@ void Texture::setupTranformMatrix()
|
||||||
0.0f, 0.0f, 1.0f };
|
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);
|
||||||
|
}
|
||||||
|
|
|
@ -29,41 +29,35 @@ class Texture : public std::enable_shared_from_this<Texture>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Texture();
|
Texture();
|
||||||
Texture(const ImagePtr& image);
|
Texture(const Size& size);
|
||||||
Texture(int width, int height, int channels = 4, uchar* pixels = NULL);
|
Texture(const ImagePtr& image, bool buildMipmaps = false);
|
||||||
virtual ~Texture();
|
virtual ~Texture();
|
||||||
|
|
||||||
void copyFromScreen(const Rect& screenRect);
|
|
||||||
|
|
||||||
void bind();
|
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<uint8> inPixels);
|
|
||||||
|
|
||||||
/// Activate texture anti-aliasing giving a better look when they are resized
|
|
||||||
void setSmooth(bool smooth);
|
void setSmooth(bool smooth);
|
||||||
void setUpsideDown(bool upsideDown);
|
void setUpsideDown(bool upsideDown);
|
||||||
|
|
||||||
GLuint getId() { return m_textureId; }
|
GLuint getId() { return m_id; }
|
||||||
|
|
||||||
int getWidth() { return m_size.width(); }
|
int getWidth() { return m_size.width(); }
|
||||||
int getHeight() { return m_size.height(); }
|
int getHeight() { return m_size.height(); }
|
||||||
const Size& getSize() { return m_size; }
|
const Size& getSize() { return m_size; }
|
||||||
|
const Size& getGlSize() { return m_glSize; }
|
||||||
const Matrix3& getTransformMatrix() { return m_transformMatrix; }
|
const Matrix3& getTransformMatrix() { return m_transformMatrix; }
|
||||||
|
bool isEmpty() { return m_id == 0; }
|
||||||
bool isEmpty() { return m_textureId == 0; }
|
|
||||||
bool hasMipmaps() { return m_hasMipmaps; }
|
bool hasMipmaps() { return m_hasMipmaps; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
void createTexture();
|
||||||
|
bool setupSize(const Size& size, bool forcePowerOfTwo = false);
|
||||||
|
void setupWrap();
|
||||||
void setupFilters();
|
void setupFilters();
|
||||||
void setupTranformMatrix();
|
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_size;
|
||||||
Size m_glSize;
|
Size m_glSize;
|
||||||
Matrix3 m_transformMatrix;
|
Matrix3 m_transformMatrix;
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "texturemanager.h"
|
#include "texturemanager.h"
|
||||||
#include "animatedtexture.h"
|
#include "animatedtexture.h"
|
||||||
#include "graphics.h"
|
#include "graphics.h"
|
||||||
|
#include "image.h"
|
||||||
|
|
||||||
#include <framework/core/resourcemanager.h>
|
#include <framework/core/resourcemanager.h>
|
||||||
#include <framework/thirdparty/apngloader.h>
|
#include <framework/thirdparty/apngloader.h>
|
||||||
|
@ -75,10 +76,13 @@ TexturePtr TextureManager::loadPNG(std::stringstream& file)
|
||||||
apng_data apng;
|
apng_data apng;
|
||||||
if(load_apng(file, &apng) == 0) {
|
if(load_apng(file, &apng) == 0) {
|
||||||
if(apng.num_frames > 1) { // animated texture
|
if(apng.num_frames > 1) { // animated texture
|
||||||
uchar *framesdata = apng.pdata + (apng.first_frame * apng.width * apng.height * apng.bpp);
|
//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));
|
//texture = TexturePtr(new AnimatedTexture(apng.width, apng.height, apng.bpp, apng.num_frames, framesdata, (int*)apng.frames_delay));
|
||||||
} else
|
g_logger.error("animated textures is disabled for a while");
|
||||||
texture = TexturePtr(new Texture(apng.width, apng.height, apng.bpp, apng.pdata));
|
} else {
|
||||||
|
ImagePtr image = ImagePtr(new Image(Size(apng.width, apng.height), apng.bpp, apng.pdata));
|
||||||
|
texture = TexturePtr(new Texture(image));
|
||||||
|
}
|
||||||
free_apng(&apng);
|
free_apng(&apng);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -554,6 +554,7 @@ void Application::registerLuaFunctions()
|
||||||
g_lua.registerStaticClass("g_graphics");
|
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", "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", "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", "getPainterEngine", std::bind(&Graphics::getPainterEngine, &g_graphics));
|
||||||
g_lua.bindClassStaticFunction("g_graphics", "getViewportSize", std::bind(&Graphics::getViewportSize, &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));
|
g_lua.bindClassStaticFunction("g_graphics", "getVendor", std::bind(&Graphics::getVendor, &g_graphics));
|
||||||
|
|
|
@ -319,7 +319,6 @@ void WIN32Window::internalChooseGLVisual()
|
||||||
if(!pixelFormat)
|
if(!pixelFormat)
|
||||||
g_logger.fatal("Could not find a suitable pixel format");
|
g_logger.fatal("Could not find a suitable pixel format");
|
||||||
|
|
||||||
pfd.cStencilBits = 8;
|
|
||||||
if(!SetPixelFormat(m_deviceContext, pixelFormat, &pfd))
|
if(!SetPixelFormat(m_deviceContext, pixelFormat, &pfd))
|
||||||
g_logger.fatal("Could not set the pixel format");
|
g_logger.fatal("Could not set the pixel format");
|
||||||
}
|
}
|
||||||
|
|
|
@ -370,10 +370,10 @@ void X11Window::internalChooseGLVisual()
|
||||||
#else
|
#else
|
||||||
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT,
|
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT,
|
||||||
#endif
|
#endif
|
||||||
EGL_RED_SIZE, 4,
|
EGL_RED_SIZE, 5,
|
||||||
EGL_GREEN_SIZE, 4,
|
EGL_GREEN_SIZE, 6,
|
||||||
EGL_BLUE_SIZE, 4,
|
EGL_BLUE_SIZE, 5,
|
||||||
EGL_ALPHA_SIZE, 4,
|
EGL_ALPHA_SIZE, 0,
|
||||||
EGL_NONE
|
EGL_NONE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -52,9 +52,9 @@ void UIManager::terminate()
|
||||||
m_pressedWidget = nullptr;
|
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)
|
void UIManager::resize(const Size& size)
|
||||||
|
|
|
@ -33,7 +33,7 @@ public:
|
||||||
void init();
|
void init();
|
||||||
void terminate();
|
void terminate();
|
||||||
|
|
||||||
void render(bool foregroundPane);
|
void render(Fw::DrawPane drawPane);
|
||||||
void resize(const Size& size);
|
void resize(const Size& size);
|
||||||
void inputEvent(const InputEvent& event);
|
void inputEvent(const InputEvent& event);
|
||||||
|
|
||||||
|
|
|
@ -41,9 +41,9 @@ UITextEdit::UITextEdit()
|
||||||
blinkCursor();
|
blinkCursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
void UITextEdit::drawSelf(bool foregroundPane)
|
void UITextEdit::drawSelf(Fw::DrawPane drawPane)
|
||||||
{
|
{
|
||||||
if(!foregroundPane)
|
if((drawPane & Fw::ForegroundPane) == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
drawBackground(m_rect);
|
drawBackground(m_rect);
|
||||||
|
|
|
@ -30,7 +30,7 @@ class UITextEdit : public UIWidget
|
||||||
public:
|
public:
|
||||||
UITextEdit();
|
UITextEdit();
|
||||||
|
|
||||||
void drawSelf(bool foregroundPane);
|
void drawSelf(Fw::DrawPane drawPane);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void update();
|
void update();
|
||||||
|
|
|
@ -52,27 +52,27 @@ UIWidget::~UIWidget()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void UIWidget::draw(const Rect& visibleRect, bool foregroundPane)
|
void UIWidget::draw(const Rect& visibleRect, Fw::DrawPane drawPane)
|
||||||
{
|
{
|
||||||
if(m_clipping)
|
if(m_clipping)
|
||||||
g_painter->setClipRect(visibleRect);
|
g_painter->setClipRect(visibleRect);
|
||||||
|
|
||||||
drawSelf(foregroundPane);
|
drawSelf(drawPane);
|
||||||
|
|
||||||
if(m_children.size() > 0) {
|
if(m_children.size() > 0) {
|
||||||
if(m_clipping)
|
if(m_clipping)
|
||||||
g_painter->setClipRect(visibleRect.intersection(getPaddingRect()));
|
g_painter->setClipRect(visibleRect.intersection(getPaddingRect()));
|
||||||
|
|
||||||
drawChildren(visibleRect, foregroundPane);
|
drawChildren(visibleRect, drawPane);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_clipping)
|
if(m_clipping)
|
||||||
g_painter->resetClipRect();
|
g_painter->resetClipRect();
|
||||||
}
|
}
|
||||||
|
|
||||||
void UIWidget::drawSelf(bool foregroundPane)
|
void UIWidget::drawSelf(Fw::DrawPane drawPane)
|
||||||
{
|
{
|
||||||
if(!foregroundPane)
|
if((drawPane & Fw::ForegroundPane) == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// draw style components in order
|
// draw style components in order
|
||||||
|
@ -88,7 +88,7 @@ void UIWidget::drawSelf(bool foregroundPane)
|
||||||
drawText(m_rect);
|
drawText(m_rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UIWidget::drawChildren(const Rect& visibleRect, bool foregroundPane)
|
void UIWidget::drawChildren(const Rect& visibleRect, Fw::DrawPane drawPane)
|
||||||
{
|
{
|
||||||
// draw children
|
// draw children
|
||||||
for(const UIWidgetPtr& child : m_children) {
|
for(const UIWidgetPtr& child : m_children) {
|
||||||
|
@ -107,10 +107,10 @@ void UIWidget::drawChildren(const Rect& visibleRect, bool foregroundPane)
|
||||||
if(child->getOpacity() < oldOpacity)
|
if(child->getOpacity() < oldOpacity)
|
||||||
g_painter->setOpacity(child->getOpacity());
|
g_painter->setOpacity(child->getOpacity());
|
||||||
|
|
||||||
child->draw(childVisibleRect, foregroundPane);
|
child->draw(childVisibleRect, drawPane);
|
||||||
|
|
||||||
// debug draw box
|
// debug draw box
|
||||||
if(foregroundPane && g_ui.isDrawingDebugBoxes()) {
|
if(g_ui.isDrawingDebugBoxes() && drawPane & Fw::ForegroundPane) {
|
||||||
g_painter->setColor(Color::green);
|
g_painter->setColor(Color::green);
|
||||||
g_painter->drawBoundingRect(child->getRect());
|
g_painter->drawBoundingRect(child->getRect());
|
||||||
}
|
}
|
||||||
|
@ -497,7 +497,10 @@ void UIWidget::applyStyle(const OTMLNodePtr& styleNode)
|
||||||
callLuaField("onStyleApply", styleNode->tag(), styleNode);
|
callLuaField("onStyleApply", styleNode->tag(), styleNode);
|
||||||
|
|
||||||
if(m_firstOnStyle) {
|
if(m_firstOnStyle) {
|
||||||
callLuaField("onSetup");
|
auto self = asUIWidget();
|
||||||
|
g_eventDispatcher.addEvent([self] {
|
||||||
|
self->callLuaField("onSetup");
|
||||||
|
});
|
||||||
// always focus new child
|
// always focus new child
|
||||||
if(isFocusable() && isExplicitlyVisible() && isExplicitlyEnabled())
|
if(isFocusable() && isExplicitlyVisible() && isExplicitlyEnabled())
|
||||||
focus();
|
focus();
|
||||||
|
|
|
@ -52,9 +52,9 @@ public:
|
||||||
virtual ~UIWidget();
|
virtual ~UIWidget();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void draw(const Rect& visibleRect, bool foregroundPane);
|
virtual void draw(const Rect& visibleRect, Fw::DrawPane drawPane);
|
||||||
virtual void drawSelf(bool foregroundPane);
|
virtual void drawSelf(Fw::DrawPane drawPane);
|
||||||
virtual void drawChildren(const Rect& visibleRect, bool foregroundPane);
|
virtual void drawChildren(const Rect& visibleRect, Fw::DrawPane drawPane);
|
||||||
|
|
||||||
friend class UIManager;
|
friend class UIManager;
|
||||||
|
|
||||||
|
|
|
@ -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 };
|
static Color maskColors[LastMask] = { Color::yellow, Color::red, Color::green, Color::blue };
|
||||||
maskImage->overwriteMask(maskColors[mask]);
|
maskImage->overwriteMask(maskColors[mask]);
|
||||||
|
|
||||||
maskTexture = TexturePtr(new Texture(maskImage));
|
maskTexture = TexturePtr(new Texture(maskImage, true));
|
||||||
maskTexture->setSmooth(true);
|
|
||||||
|
|
||||||
if(g_graphics.canUseMipmaps())
|
|
||||||
maskTexture->generateSoftwareMipmaps(maskImage->getPixels());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,7 +116,7 @@ TexturePtr& ThingType::getTexture(int animationPhase)
|
||||||
Point spritePos = Point(m_dimensions[Width] - w - 1,
|
Point spritePos = Point(m_dimensions[Width] - w - 1,
|
||||||
m_dimensions[Height] - h - 1) * Otc::TILE_PIXELS;
|
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_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 = TexturePtr(new Texture(fullImage, true));
|
||||||
animationPhaseTexture->setSmooth(true);
|
|
||||||
|
|
||||||
//if(g_graphics.canUseMipmaps())
|
|
||||||
//animationPhaseTexture->generateSoftwareMipmaps(fullImage->getPixels());
|
|
||||||
}
|
}
|
||||||
return animationPhaseTexture;
|
return animationPhaseTexture;
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,20 +51,45 @@ void OTClient::init(const std::vector<std::string>& args)
|
||||||
"Compiled by: ", BUILD_COMPILER, "\n",
|
"Compiled by: ", BUILD_COMPILER, "\n",
|
||||||
"Build type: ", BUILD_TYPE, "\n");
|
"Build type: ", BUILD_TYPE, "\n");
|
||||||
return;
|
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(
|
stdext::print(
|
||||||
"Usage: ", args[0], " [options]\n"
|
"Usage: ", args[0], " [options]\n"
|
||||||
"Options:\n"
|
"Options:\n"
|
||||||
" -help Display this information and exit\n"
|
" -help Display this information and exit\n"
|
||||||
" -version Display version and exit\n"
|
" -version Display version and exit\n"
|
||||||
"\n"
|
" \n"
|
||||||
" -no-fbos Disable usage of opengl framebuffer objects\n"
|
" -no-fbos Disable usage of opengl framebuffer objects\n"
|
||||||
" -no-mipmapping Disable texture mipmaping\n"
|
" -no-mipmaps Disable texture mipmaping\n"
|
||||||
" -no-smoothing Disable texture smoothing (bilinear filter)\n"
|
" -no-smooth Disable texture smoothing (bilinear filter)\n"
|
||||||
" -no-hardware-buffering Disable buffering vertex arrays in hardware\n"
|
" -no-non-power-of-two-textures Use only power of two textures\n"
|
||||||
" -realtime-mipmapping Improve framebuffer smoothing quality by\n"
|
" -no-clamp-to-edge Don't use GL_CLAMP_TO_EDGE\n"
|
||||||
" generating mipmaps in realtime when hardware\n"
|
" -no-backbuffer-cache Don't allow backbuffer caching\n"
|
||||||
" mipmap generation implementation is available\n");
|
" -hardware-buffers Cache vertex arrays in hardware\n"
|
||||||
|
" -opengl1 Use OpenGL 1.x painter\n"
|
||||||
|
" -opengl2 Use OpenGL 2.0 painter\n");
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
stdext::println("Unrecognized option '", arg, "', please see -help for available options list");
|
stdext::println("Unrecognized option '", arg, "', please see -help for available options list");
|
||||||
|
|
|
@ -24,12 +24,12 @@
|
||||||
#include <framework/otml/otml.h>
|
#include <framework/otml/otml.h>
|
||||||
#include <framework/graphics/graphics.h>
|
#include <framework/graphics/graphics.h>
|
||||||
|
|
||||||
void UICreature::drawSelf(bool foregroundPane)
|
void UICreature::drawSelf(Fw::DrawPane drawPane)
|
||||||
{
|
{
|
||||||
if(!foregroundPane)
|
if((drawPane & Fw::ForegroundPane) == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
UIWidget::drawSelf(foregroundPane);
|
UIWidget::drawSelf(drawPane);
|
||||||
|
|
||||||
if(m_creature) {
|
if(m_creature) {
|
||||||
Rect drawRect = getPaddingRect();
|
Rect drawRect = getPaddingRect();
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
class UICreature : public UIWidget
|
class UICreature : public UIWidget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void drawSelf(bool foregroundPane);
|
void drawSelf(Fw::DrawPane drawPane);
|
||||||
|
|
||||||
void setCreature(const CreaturePtr& creature) { m_creature = creature; }
|
void setCreature(const CreaturePtr& creature) { m_creature = creature; }
|
||||||
void setFixedCreatureSize(bool fixed) { m_fixedCreatureSize = fixed; }
|
void setFixedCreatureSize(bool fixed) { m_fixedCreatureSize = fixed; }
|
||||||
|
|
|
@ -30,9 +30,9 @@ UIItem::UIItem()
|
||||||
m_dragable = true;
|
m_dragable = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UIItem::drawSelf(bool foregroundPane)
|
void UIItem::drawSelf(Fw::DrawPane drawPane)
|
||||||
{
|
{
|
||||||
if(!foregroundPane)
|
if((drawPane & Fw::ForegroundPane) == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// draw style components in order
|
// draw style components in order
|
||||||
|
|
|
@ -31,7 +31,7 @@ class UIItem : public UIWidget
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
UIItem();
|
UIItem();
|
||||||
void drawSelf(bool foregroundPane);
|
void drawSelf(Fw::DrawPane drawPane);
|
||||||
|
|
||||||
void setItemId(int id);
|
void setItemId(int id);
|
||||||
void setItemCount(int count) { if(m_item) m_item->setCount(count); }
|
void setItemCount(int count) { if(m_item) m_item->setCount(count); }
|
||||||
|
|
|
@ -45,21 +45,25 @@ UIMap::~UIMap()
|
||||||
g_map.removeMapView(m_mapView);
|
g_map.removeMapView(m_mapView);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UIMap::drawSelf(bool foregroundPane)
|
void UIMap::drawSelf(Fw::DrawPane drawPane)
|
||||||
{
|
{
|
||||||
if(foregroundPane) {
|
UIWidget::drawSelf(drawPane);
|
||||||
UIWidget::drawSelf(foregroundPane);
|
|
||||||
|
|
||||||
|
if(drawPane & Fw::ForegroundPane) {
|
||||||
// draw map border
|
// draw map border
|
||||||
g_painter->setColor(Color::black);
|
g_painter->setColor(Color::black);
|
||||||
g_painter->drawBoundingRect(m_mapRect.expanded(1));
|
g_painter->drawBoundingRect(m_mapRect.expanded(1));
|
||||||
|
|
||||||
g_painter->saveState();
|
if(drawPane != Fw::BothPanes) {
|
||||||
g_painter->setCompositionMode(Painter::CompositionMode_Replace);
|
g_painter->saveState();
|
||||||
g_painter->setColor(Color::alpha);
|
g_painter->setCompositionMode(Painter::CompositionMode_Replace);
|
||||||
g_painter->drawFilledRect(m_mapRect);
|
g_painter->setColor(Color::alpha);
|
||||||
g_painter->restoreSavedState();
|
g_painter->drawFilledRect(m_mapRect);
|
||||||
} else {
|
g_painter->restoreSavedState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(drawPane & Fw::BackgroundPane) {
|
||||||
g_painter->setColor(Color::white);
|
g_painter->setColor(Color::white);
|
||||||
m_mapView->draw(m_mapRect);
|
m_mapView->draw(m_mapRect);
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ public:
|
||||||
UIMap();
|
UIMap();
|
||||||
~UIMap();
|
~UIMap();
|
||||||
|
|
||||||
void drawSelf(bool foregroundPane);
|
void drawSelf(Fw::DrawPane drawPane);
|
||||||
|
|
||||||
bool setZoom(int zoom);
|
bool setZoom(int zoom);
|
||||||
bool zoomIn();
|
bool zoomIn();
|
||||||
|
|
Loading…
Reference in New Issue