graphics fixes and improvements
This commit is contained in:
parent
4f9ca15ef0
commit
1a7f2a44fc
|
@ -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",
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -41,6 +41,7 @@ end
|
|||
|
||||
function UIItem:onHoverChange(hovered)
|
||||
UIWidget.onHoverChange(self, hovered)
|
||||
|
||||
if self:isVirtual() then return end
|
||||
|
||||
local draggingWidget = g_ui.getDraggingWidget()
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 })
|
||||
|
|
|
@ -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,29 +211,35 @@ 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) {
|
||||
// draw the foreground into a texture
|
||||
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();
|
||||
|
||||
// draw foreground
|
||||
g_painter->clear(Color::black);
|
||||
g_ui.render(true);
|
||||
|
||||
// copy the foreground to a texture
|
||||
m_foreground->copyFromScreen(viewportRect);
|
||||
m_backgroundFrameCounter.processNextFrame();
|
||||
g_ui.render(Fw::BothPanes);
|
||||
}
|
||||
|
||||
// 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();
|
||||
|
||||
// update screen pixels
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -262,6 +262,12 @@ namespace Fw
|
|||
DraggingState = 2048,
|
||||
LastWidgetState = 4096
|
||||
};
|
||||
|
||||
enum DrawPane {
|
||||
ForegroundPane = 1,
|
||||
BackgroundPane = 2,
|
||||
BothPanes = 3
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include "graphics.h"
|
||||
|
||||
#include <framework/core/eventdispatcher.h>
|
||||
|
||||
/*
|
||||
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]);
|
||||
}
|
||||
*/
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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<true> m_backuping;
|
||||
|
||||
static uint boundFbo;
|
||||
};
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -70,6 +70,7 @@ public:
|
|||
bool canUseHardwareMipmaps();
|
||||
bool canUseClampToEdge();
|
||||
bool canUseBlendFuncSeparate();
|
||||
bool canCacheBackbuffer();
|
||||
|
||||
private:
|
||||
Size m_viewportSize;
|
||||
|
@ -84,6 +85,7 @@ private:
|
|||
Boolean<true> m_useMipmaps;
|
||||
Boolean<true> m_useHardwareMipmaps;
|
||||
Boolean<true> m_useClampToEdge;
|
||||
Boolean<true> m_cacheBackbuffer;
|
||||
PainterEngine m_prefferedPainterEngine;
|
||||
PainterEngine m_selectedPainterEngine;
|
||||
};
|
||||
|
|
|
@ -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<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);
|
||||
|
||||
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; }
|
||||
uint8* getPixelData() { return &m_pixels[0]; }
|
||||
|
|
|
@ -27,104 +27,68 @@
|
|||
|
||||
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
|
||||
internalLoadGLTexture(pixels, channels, width, height);
|
||||
m_id = 0;
|
||||
|
||||
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()
|
||||
{
|
||||
// free texture from gl memory
|
||||
if(m_textureId > 0)
|
||||
glDeleteTextures(1, &m_textureId);
|
||||
if(m_id > 0)
|
||||
glDeleteTextures(1, &m_id);
|
||||
}
|
||||
|
||||
uint Texture::internalLoadGLTexture(uchar *pixels, int channels, int width, int height)
|
||||
void Texture::bind()
|
||||
{
|
||||
m_size.resize(width, height);
|
||||
|
||||
// convert texture pixel data to power of two size, only required for OpenGL 1.5 or older
|
||||
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;
|
||||
// must reset painter texture state
|
||||
g_painter->setTexture(this);
|
||||
glBindTexture(GL_TEXTURE_2D, m_id);
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
void Texture::bind()
|
||||
{
|
||||
// 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()
|
||||
bool Texture::buildHardwareMipmaps()
|
||||
{
|
||||
if(!g_graphics.canUseHardwareMipmaps())
|
||||
return false;
|
||||
|
@ -188,69 +134,43 @@ void Texture::setUpsideDown(bool upsideDown)
|
|||
setupTranformMatrix();
|
||||
}
|
||||
|
||||
void Texture::generateSoftwareMipmaps(std::vector<uint8> 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<uint8> outPixels;
|
||||
m_size = size;
|
||||
m_glSize = glSize;
|
||||
setupTranformMatrix();
|
||||
return true;
|
||||
}
|
||||
|
||||
int mipmap = 1;
|
||||
while(true) {
|
||||
outPixels.resize(outSize.area()*4);
|
||||
void Texture::setupWrap()
|
||||
{
|
||||
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
|
||||
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;
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -29,41 +29,35 @@ class Texture : public std::enable_shared_from_this<Texture>
|
|||
{
|
||||
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<uint8> 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;
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "texturemanager.h"
|
||||
#include "animatedtexture.h"
|
||||
#include "graphics.h"
|
||||
#include "image.h"
|
||||
|
||||
#include <framework/core/resourcemanager.h>
|
||||
#include <framework/thirdparty/apngloader.h>
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -30,7 +30,7 @@ class UITextEdit : public UIWidget
|
|||
public:
|
||||
UITextEdit();
|
||||
|
||||
void drawSelf(bool foregroundPane);
|
||||
void drawSelf(Fw::DrawPane drawPane);
|
||||
|
||||
private:
|
||||
void update();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -51,20 +51,45 @@ void OTClient::init(const std::vector<std::string>& 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");
|
||||
|
|
|
@ -24,12 +24,12 @@
|
|||
#include <framework/otml/otml.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;
|
||||
|
||||
UIWidget::drawSelf(foregroundPane);
|
||||
UIWidget::drawSelf(drawPane);
|
||||
|
||||
if(m_creature) {
|
||||
Rect drawRect = getPaddingRect();
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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); }
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ public:
|
|||
UIMap();
|
||||
~UIMap();
|
||||
|
||||
void drawSelf(bool foregroundPane);
|
||||
void drawSelf(Fw::DrawPane drawPane);
|
||||
|
||||
bool setZoom(int zoom);
|
||||
bool zoomIn();
|
||||
|
|
Loading…
Reference in New Issue