use GLSL shaders
This commit is contained in:
parent
cf0aab6d4d
commit
7eead50806
6
TODO
6
TODO
|
@ -14,11 +14,10 @@ fix moving windows and tooltips conflicts
|
||||||
todo display otclient icon in window bar
|
todo display otclient icon in window bar
|
||||||
remake otui styles states system
|
remake otui styles states system
|
||||||
padding
|
padding
|
||||||
|
break UILabel lines
|
||||||
|
|
||||||
rename Game to g_game, etc
|
rename Game to g_game, etc
|
||||||
implement Console key binding
|
implement Console key binding
|
||||||
fatal error if sprite load fails
|
|
||||||
impl vertical sync, clipboard
|
impl vertical sync, clipboard
|
||||||
crash handler
|
crash handler
|
||||||
modify COnnection::poll()
|
modify COnnection::poll()
|
||||||
|
@ -30,3 +29,6 @@ use metatable for Point,Rect,Color,Size lua classes
|
||||||
lua binder generator
|
lua binder generator
|
||||||
restore win32 platform
|
restore win32 platform
|
||||||
set special types for g_configs like lists/point/size
|
set special types for g_configs like lists/point/size
|
||||||
|
restore ctrl+g and keybindings
|
||||||
|
create a class for reading binary files
|
||||||
|
handle corrupt errors in dat/spr
|
|
@ -0,0 +1,5 @@
|
||||||
|
function dumpWidgets()
|
||||||
|
for i=1,UI.root:getChildCount() do
|
||||||
|
print(UI.root:getChildByIndex(i):getId())
|
||||||
|
end
|
||||||
|
end
|
|
@ -34,7 +34,7 @@ local function completeCommand()
|
||||||
local cursorPos = commandLineEdit:getCursorPos()
|
local cursorPos = commandLineEdit:getCursorPos()
|
||||||
if cursorPos == 0 then return end
|
if cursorPos == 0 then return end
|
||||||
|
|
||||||
local commandBegin = string.sub(commandLineEdit:getText(), 1, cursorPos)
|
local commandBegin = commandLineEdit:getText():sub(1, cursorPos)
|
||||||
local possibleCommands = {}
|
local possibleCommands = {}
|
||||||
|
|
||||||
-- create a list containing all globals
|
-- create a list containing all globals
|
||||||
|
@ -43,7 +43,7 @@ local function completeCommand()
|
||||||
|
|
||||||
-- match commands
|
-- match commands
|
||||||
for k,v in pairs(allVars) do
|
for k,v in pairs(allVars) do
|
||||||
if string.sub(k, 1, cursorPos) == commandBegin then
|
if k:sub(1, cursorPos) == commandBegin then
|
||||||
table.insert(possibleCommands, k)
|
table.insert(possibleCommands, k)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -63,9 +63,9 @@ local function completeCommand()
|
||||||
if #possibleCommands[1] < cursorPos then
|
if #possibleCommands[1] < cursorPos then
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
expandedComplete = commandBegin .. string.sub(possibleCommands[1], cursorPos, cursorPos)
|
expandedComplete = commandBegin .. possibleCommands[1]:sub(cursorPos, cursorPos)
|
||||||
for i,v in ipairs(possibleCommands) do
|
for i,v in ipairs(possibleCommands) do
|
||||||
if string.sub(v, 1, #expandedComplete) ~= expandedComplete then
|
if v:sub(1, #expandedComplete) ~= expandedComplete then
|
||||||
done = true
|
done = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -8,11 +8,9 @@ Module
|
||||||
autoLoad: true
|
autoLoad: true
|
||||||
autoLoadPriority: 20
|
autoLoadPriority: 20
|
||||||
|
|
||||||
dependencies:
|
|
||||||
- core
|
|
||||||
|
|
||||||
onLoad: |
|
onLoad: |
|
||||||
require 'console'
|
require 'console'
|
||||||
|
require 'commands'
|
||||||
Console.init()
|
Console.init()
|
||||||
return true
|
return true
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ Client = { }
|
||||||
-- TODO: load and save configurations
|
-- TODO: load and save configurations
|
||||||
function Client.init()
|
function Client.init()
|
||||||
g_window.move({ x=220, y=220 })
|
g_window.move({ x=220, y=220 })
|
||||||
g_window.resize({ width=800, height=600 })
|
g_window.resize({ width=800, height=480 })
|
||||||
g_window.setTitle('OTClient')
|
g_window.setTitle('OTClient')
|
||||||
g_window.setIcon('clienticon.png')
|
g_window.setIcon('clienticon.png')
|
||||||
return true
|
return true
|
||||||
|
|
|
@ -23,8 +23,8 @@ local function onError(protocol, error)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function onMotd(protocol, motd)
|
local function onMotd(protocol, motd)
|
||||||
motdNumber = tonumber(string.sub(motd, 0, string.find(motd, "\n")))
|
motdNumber = tonumber(motd:sub(0, motd:find("\n")))
|
||||||
motdMessage = string.sub(motd, string.find(motd, "\n") + 1, string.len(motd))
|
motdMessage = motd:sub(motd:find("\n") + 1, #motd)
|
||||||
TopMenu.getButton('motdButton'):show()
|
TopMenu.getButton('motdButton'):show()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ local vsyncEnabled = false
|
||||||
|
|
||||||
function getConfig(name, default)
|
function getConfig(name, default)
|
||||||
if g_configs.exists(name) then
|
if g_configs.exists(name) then
|
||||||
local val = string.trim(g_configs.get(name))
|
local val = g_configs.get(name):trim()
|
||||||
if val == 'true' or val == 'false' then
|
if val == 'true' or val == 'false' then
|
||||||
return toboolean(val)
|
return toboolean(val)
|
||||||
else
|
else
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
-- AnchorEdge
|
|
||||||
AnchorNone = 0
|
AnchorNone = 0
|
||||||
AnchorTop = 1
|
AnchorTop = 1
|
||||||
AnchorBottom = 2
|
AnchorBottom = 2
|
||||||
|
@ -15,9 +14,6 @@ LogFatal = 4
|
||||||
|
|
||||||
ActiveFocusReason = 2
|
ActiveFocusReason = 2
|
||||||
|
|
||||||
EmptyFunction = function() end
|
|
||||||
|
|
||||||
-- KeyCodes
|
|
||||||
KeyUnknown = 0
|
KeyUnknown = 0
|
||||||
KeyEscape = 1
|
KeyEscape = 1
|
||||||
KeyTab = 2
|
KeyTab = 2
|
||||||
|
@ -57,7 +53,7 @@ KeyLeftParen = 40 -- (
|
||||||
KeyRightParen = 41 -- )
|
KeyRightParen = 41 -- )
|
||||||
KeyAsterisk = 42 -- *
|
KeyAsterisk = 42 -- *
|
||||||
KeyPlus = 43 -- +
|
KeyPlus = 43 -- +
|
||||||
KeyComma = 44 --
|
KeyComma = 44 -- ,
|
||||||
KeyMinus = 45 -- -
|
KeyMinus = 45 -- -
|
||||||
KeyPeriod = 46 -- .
|
KeyPeriod = 46 -- .
|
||||||
KeySlash = 47 -- /
|
KeySlash = 47 -- /
|
|
@ -7,10 +7,14 @@ Module
|
||||||
onLoad: |
|
onLoad: |
|
||||||
require 'ext/table'
|
require 'ext/table'
|
||||||
require 'ext/string'
|
require 'ext/string'
|
||||||
require 'constants'
|
require 'util/point'
|
||||||
|
require 'util/size'
|
||||||
|
require 'util/color'
|
||||||
|
require 'util/rect'
|
||||||
|
require 'const'
|
||||||
require 'util'
|
require 'util'
|
||||||
require 'dispatcher'
|
require 'dispatcher'
|
||||||
require 'widget'
|
require 'widget'
|
||||||
require 'ui'
|
require 'ui'
|
||||||
require 'gfx'
|
require 'effects'
|
||||||
return true
|
return true
|
||||||
|
|
|
@ -1,43 +1,33 @@
|
||||||
local eventId = 0
|
local eventId = 0
|
||||||
local eventsTable = { }
|
local eventList = {}
|
||||||
local orig = { scheduleEvent = scheduleEvent,
|
|
||||||
addEvent = addEvent }
|
|
||||||
|
|
||||||
-- fix original scheduleEvent
|
|
||||||
function scheduleEvent(func, delay)
|
function scheduleEvent(func, delay)
|
||||||
eventId = eventId + 1
|
eventId = eventId + 1
|
||||||
local id = eventId
|
local id = eventId
|
||||||
local function proxyFunc()
|
local function proxyFunc()
|
||||||
if eventsTable[id] then
|
if eventList[id] then
|
||||||
func()
|
if eventList[id].active then
|
||||||
eventsTable[id] = nil
|
func()
|
||||||
|
end
|
||||||
|
eventList[id] = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
eventsTable[id] = proxyFunc
|
eventList[id] = { func = proxyFunc, active = true }
|
||||||
orig.scheduleEvent(proxyFunc, delay)
|
if delay and delay > 0 then
|
||||||
|
g_dispatcher.scheduleEvent(proxyFunc, delay)
|
||||||
|
else
|
||||||
|
g_dispatcher.addEvent(proxyFunc, false)
|
||||||
|
end
|
||||||
return id
|
return id
|
||||||
end
|
end
|
||||||
|
|
||||||
-- FIXME: the event function can be collected
|
function addEvent(func)
|
||||||
-- and the dispatcher would call an invalid function, generating an warning
|
return scheduleEvent(func, 0)
|
||||||
|
end
|
||||||
|
|
||||||
function removeEvent(id)
|
function removeEvent(id)
|
||||||
if id and eventsTable[id] then
|
if id and eventList[id] then
|
||||||
eventsTable[id] = nil
|
eventList[id].active = false
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- fix original addEvent
|
|
||||||
function addEvent(func)
|
|
||||||
eventId = eventId + 1
|
|
||||||
local id = eventId
|
|
||||||
local function proxyFunc()
|
|
||||||
if eventsTable[id] then
|
|
||||||
func()
|
|
||||||
eventsTable[id] = nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
eventsTable[id] = proxyFunc
|
|
||||||
orig.addEvent(proxyFunc)
|
|
||||||
return id
|
|
||||||
end
|
|
|
@ -1,6 +1,6 @@
|
||||||
GFX = { }
|
Effects = {}
|
||||||
|
|
||||||
function GFX.fadeIn(widget, time, elapsed)
|
function Effects.fadeIn(widget, time, elapsed)
|
||||||
if not elapsed then elapsed = 0 end
|
if not elapsed then elapsed = 0 end
|
||||||
if not time then time = 250 end
|
if not time then time = 250 end
|
||||||
widget:setOpacity(math.min((255*elapsed)/time, 255))
|
widget:setOpacity(math.min((255*elapsed)/time, 255))
|
||||||
|
@ -11,7 +11,7 @@ function GFX.fadeIn(widget, time, elapsed)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function GFX.fadeOut(widget, time, elapsed)
|
function Effects.fadeOut(widget, time, elapsed)
|
||||||
if not elapsed then elapsed = 0 end
|
if not elapsed then elapsed = 0 end
|
||||||
if not time then time = 250 end
|
if not time then time = 250 end
|
||||||
widget:setOpacity((255*(time - elapsed))/time)
|
widget:setOpacity((255*(time - elapsed))/time)
|
|
@ -13,12 +13,12 @@ function string:starts(start)
|
||||||
return self:sub(1, #start) == start
|
return self:sub(1, #start) == start
|
||||||
end
|
end
|
||||||
|
|
||||||
function string.trim(str)
|
function string:trim()
|
||||||
return str:match'^%s*(.*%S)' or ''
|
return self:match('^%s*(.*%S)') or ''
|
||||||
end
|
end
|
||||||
|
|
||||||
function toboolean(str)
|
function toboolean(str)
|
||||||
str = string.trim(str)
|
str = str:trim()
|
||||||
if str == '1' or str == 'true' then
|
if str == '1' or str == 'true' then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
function table.dump(t, depth)
|
function table.dump(t, depth)
|
||||||
if not depth then depth = 0 end
|
if not depth then depth = 0 end
|
||||||
for k,v in pairs(t) do
|
for k,v in pairs(t) do
|
||||||
str = string.rep(' ', depth * 2) .. k .. ': '
|
str = (' '):rep(depth * 2) .. k .. ': '
|
||||||
if type(v) ~= "table" then
|
if type(v) ~= "table" then
|
||||||
print(str .. tostring(v))
|
print(str .. tostring(v))
|
||||||
else
|
else
|
||||||
|
|
|
@ -6,10 +6,8 @@ function print(...)
|
||||||
Logger.log(LogInfo, msg)
|
Logger.log(LogInfo, msg)
|
||||||
end
|
end
|
||||||
|
|
||||||
function createEnvironment()
|
function fatal(msg)
|
||||||
local env = { }
|
Logger.log(LogFatal, msg)
|
||||||
setmetatable(env, { __index = _G} )
|
|
||||||
return env
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function connect(object, signalsAndSlots, pushFront)
|
function connect(object, signalsAndSlots, pushFront)
|
||||||
|
@ -28,10 +26,10 @@ function connect(object, signalsAndSlots, pushFront)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function dumpWidgets()
|
function createEnvironment()
|
||||||
for i=1,UI.root:getChildCount() do
|
local env = { }
|
||||||
print(UI.root:getChildByIndex(i):getId())
|
setmetatable(env, { __index = _G} )
|
||||||
end
|
return env
|
||||||
end
|
end
|
||||||
|
|
||||||
function getCallingScriptSourcePath(depth)
|
function getCallingScriptSourcePath(depth)
|
||||||
|
|
|
@ -28,7 +28,7 @@ function MessageBox.create(title, text, flags)
|
||||||
|
|
||||||
if flags == MessageBoxOk then
|
if flags == MessageBoxOk then
|
||||||
buttonRight:setText("Ok")
|
buttonRight:setText("Ok")
|
||||||
box.onOk = EmptyFunction
|
box.onOk = function() end
|
||||||
buttonRight.onClick = function()
|
buttonRight.onClick = function()
|
||||||
box.onOk()
|
box.onOk()
|
||||||
box:destroy()
|
box:destroy()
|
||||||
|
@ -37,7 +37,7 @@ function MessageBox.create(title, text, flags)
|
||||||
window.onEscape = buttonRight.onClick
|
window.onEscape = buttonRight.onClick
|
||||||
elseif flags == MessageBoxCancel then
|
elseif flags == MessageBoxCancel then
|
||||||
buttonRight:setText("Cancel")
|
buttonRight:setText("Cancel")
|
||||||
box.onCancel = EmptyFunction
|
box.onCancel = function() end
|
||||||
buttonRight.onClick = function()
|
buttonRight.onClick = function()
|
||||||
box.onCancel()
|
box.onCancel()
|
||||||
box:destroy()
|
box:destroy()
|
||||||
|
|
|
@ -28,7 +28,7 @@ function ToolTip.display(text)
|
||||||
local size = label:getSize()
|
local size = label:getSize()
|
||||||
size.width = size.width + 4
|
size.width = size.width + 4
|
||||||
size.height = size.height + 4
|
size.height = size.height + 4
|
||||||
currentToolTip:setSize(size)
|
currentToolTip:resize(size)
|
||||||
moveToolTip(currentToolTip)
|
moveToolTip(currentToolTip)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -135,6 +135,7 @@ SET(framework_SOURCES ${framework_SOURCES}
|
||||||
${CMAKE_CURRENT_LIST_DIR}/graphics/font.cpp
|
${CMAKE_CURRENT_LIST_DIR}/graphics/font.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/graphics/fontmanager.cpp
|
${CMAKE_CURRENT_LIST_DIR}/graphics/fontmanager.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/graphics/graphics.cpp
|
${CMAKE_CURRENT_LIST_DIR}/graphics/graphics.cpp
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/graphics/painter.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/graphics/texture.cpp
|
${CMAKE_CURRENT_LIST_DIR}/graphics/texture.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/graphics/framebuffer.cpp
|
${CMAKE_CURRENT_LIST_DIR}/graphics/framebuffer.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/graphics/animatedtexture.cpp
|
${CMAKE_CURRENT_LIST_DIR}/graphics/animatedtexture.cpp
|
||||||
|
@ -142,6 +143,9 @@ SET(framework_SOURCES ${framework_SOURCES}
|
||||||
${CMAKE_CURRENT_LIST_DIR}/graphics/texturemanager.cpp
|
${CMAKE_CURRENT_LIST_DIR}/graphics/texturemanager.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/graphics/borderimage.cpp
|
${CMAKE_CURRENT_LIST_DIR}/graphics/borderimage.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/graphics/image.cpp
|
${CMAKE_CURRENT_LIST_DIR}/graphics/image.cpp
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/graphics/shader.cpp
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/graphics/shaderprogram.cpp
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/graphics/paintershaderprogram.cpp
|
||||||
|
|
||||||
# framework otml
|
# framework otml
|
||||||
${CMAKE_CURRENT_LIST_DIR}/otml/otmldocument.cpp
|
${CMAKE_CURRENT_LIST_DIR}/otml/otmldocument.cpp
|
||||||
|
|
|
@ -31,7 +31,9 @@
|
||||||
#include <framework/ui/uimanager.h>
|
#include <framework/ui/uimanager.h>
|
||||||
#include <framework/ui/uiwidget.h>
|
#include <framework/ui/uiwidget.h>
|
||||||
#include <framework/graphics/graphics.h>
|
#include <framework/graphics/graphics.h>
|
||||||
|
#include <framework/graphics/painter.h>
|
||||||
#include <framework/luascript/luainterface.h>
|
#include <framework/luascript/luainterface.h>
|
||||||
|
#include <../../oglrenderer/graphics/painter.h>
|
||||||
|
|
||||||
Application *g_app = nullptr;
|
Application *g_app = nullptr;
|
||||||
|
|
||||||
|
@ -134,7 +136,6 @@ void Application::terminate()
|
||||||
// terminate graphics
|
// terminate graphics
|
||||||
if(m_appFlags & Fw::AppEnableGraphics) {
|
if(m_appFlags & Fw::AppEnableGraphics) {
|
||||||
g_ui.terminate();
|
g_ui.terminate();
|
||||||
g_graphics.terminate();
|
|
||||||
g_window.terminate();
|
g_window.terminate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,8 +218,8 @@ void Application::render()
|
||||||
|
|
||||||
void Application::resize(const Size& size)
|
void Application::resize(const Size& size)
|
||||||
{
|
{
|
||||||
g_graphics.resize(size);
|
|
||||||
g_ui.resize(size);
|
g_ui.resize(size);
|
||||||
|
g_graphics.resize(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::inputEvent(const InputEvent& event)
|
void Application::inputEvent(const InputEvent& event)
|
||||||
|
|
|
@ -79,15 +79,13 @@ bool Module::load()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_loadCallback) {
|
if(m_loadCallback && !m_loadCallback()) {
|
||||||
m_loaded = m_loadCallback();
|
logError("Unable to load module '", m_name, "' because its onLoad event returned false");
|
||||||
if(!m_loaded) {
|
return false;
|
||||||
logError("Unable to load module '", m_name, "' because its onLoad event returned false");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
logInfo("Loaded module '", m_name, "'");
|
logInfo("Loaded module '", m_name, "'");
|
||||||
|
m_loaded = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ AnimatedTexture::AnimatedTexture(int width, int height, int channels, int numFra
|
||||||
Texture(),
|
Texture(),
|
||||||
m_numFrames(numFrames)
|
m_numFrames(numFrames)
|
||||||
{
|
{
|
||||||
m_size.setSize(width, height);
|
m_size.resize(width, height);
|
||||||
|
|
||||||
m_framesTextureId.resize(numFrames);
|
m_framesTextureId.resize(numFrames);
|
||||||
m_framesDelay.resize(numFrames);
|
m_framesDelay.resize(numFrames);
|
||||||
|
|
|
@ -137,68 +137,63 @@ void BorderImage::draw(const Rect& screenCoords)
|
||||||
Rect rectCoords;
|
Rect rectCoords;
|
||||||
Size centerSize = screenCoords.size() - m_bordersSize;
|
Size centerSize = screenCoords.size() - m_bordersSize;
|
||||||
|
|
||||||
g_graphics.bindTexture(m_texture);
|
|
||||||
g_graphics.startDrawing();
|
|
||||||
|
|
||||||
// first the center
|
// first the center
|
||||||
if(centerSize.area() > 0) {
|
if(centerSize.area() > 0) {
|
||||||
rectCoords = Rect(screenCoords.left() + m_leftBorderTexCoords.width(),
|
rectCoords = Rect(screenCoords.left() + m_leftBorderTexCoords.width(),
|
||||||
screenCoords.top() + m_topBorderTexCoords.height(),
|
screenCoords.top() + m_topBorderTexCoords.height(),
|
||||||
centerSize);
|
centerSize);
|
||||||
g_graphics.drawRepeatedTexturedRect(rectCoords, m_texture, m_centerTexCoords);
|
g_painter.drawRepeatedTexturedRect(rectCoords, m_texture, m_centerTexCoords);
|
||||||
}
|
}
|
||||||
|
|
||||||
// top left corner
|
// top left corner
|
||||||
rectCoords = Rect(screenCoords.topLeft(),
|
rectCoords = Rect(screenCoords.topLeft(),
|
||||||
m_topLeftCornerTexCoords.size());
|
m_topLeftCornerTexCoords.size());
|
||||||
g_graphics.drawTexturedRect(rectCoords, m_texture, m_topLeftCornerTexCoords);
|
g_painter.drawTexturedRect(rectCoords, m_texture, m_topLeftCornerTexCoords);
|
||||||
|
|
||||||
// top
|
// top
|
||||||
rectCoords = Rect(screenCoords.left() + m_topLeftCornerTexCoords.width(),
|
rectCoords = Rect(screenCoords.left() + m_topLeftCornerTexCoords.width(),
|
||||||
screenCoords.topLeft().y,
|
screenCoords.topLeft().y,
|
||||||
centerSize.width(),
|
centerSize.width(),
|
||||||
m_topBorderTexCoords.height());
|
m_topBorderTexCoords.height());
|
||||||
g_graphics.drawRepeatedTexturedRect(rectCoords, m_texture, m_topBorderTexCoords);
|
g_painter.drawRepeatedTexturedRect(rectCoords, m_texture, m_topBorderTexCoords);
|
||||||
|
|
||||||
|
|
||||||
// top right corner
|
// top right corner
|
||||||
rectCoords = Rect(screenCoords.left() + m_topLeftCornerTexCoords.width() + centerSize.width(),
|
rectCoords = Rect(screenCoords.left() + m_topLeftCornerTexCoords.width() + centerSize.width(),
|
||||||
screenCoords.top(),
|
screenCoords.top(),
|
||||||
m_topRightCornerTexCoords.size());
|
m_topRightCornerTexCoords.size());
|
||||||
g_graphics.drawTexturedRect(rectCoords, m_texture, m_topRightCornerTexCoords);
|
g_painter.drawTexturedRect(rectCoords, m_texture, m_topRightCornerTexCoords);
|
||||||
|
|
||||||
// left
|
// left
|
||||||
rectCoords = Rect(screenCoords.left(),
|
rectCoords = Rect(screenCoords.left(),
|
||||||
screenCoords.top() + m_topLeftCornerTexCoords.height(),
|
screenCoords.top() + m_topLeftCornerTexCoords.height(),
|
||||||
m_leftBorderTexCoords.width(),
|
m_leftBorderTexCoords.width(),
|
||||||
centerSize.height());
|
centerSize.height());
|
||||||
g_graphics.drawRepeatedTexturedRect(rectCoords, m_texture, m_leftBorderTexCoords);
|
g_painter.drawRepeatedTexturedRect(rectCoords, m_texture, m_leftBorderTexCoords);
|
||||||
|
|
||||||
// right
|
// right
|
||||||
rectCoords = Rect(screenCoords.left() + m_leftBorderTexCoords.width() + centerSize.width(),
|
rectCoords = Rect(screenCoords.left() + m_leftBorderTexCoords.width() + centerSize.width(),
|
||||||
screenCoords.top() + m_topRightCornerTexCoords.height(),
|
screenCoords.top() + m_topRightCornerTexCoords.height(),
|
||||||
m_rightBorderTexCoords.width(),
|
m_rightBorderTexCoords.width(),
|
||||||
centerSize.height());
|
centerSize.height());
|
||||||
g_graphics.drawRepeatedTexturedRect(rectCoords, m_texture, m_rightBorderTexCoords);
|
g_painter.drawRepeatedTexturedRect(rectCoords, m_texture, m_rightBorderTexCoords);
|
||||||
|
|
||||||
// bottom left corner
|
// bottom left corner
|
||||||
rectCoords = Rect(screenCoords.left(),
|
rectCoords = Rect(screenCoords.left(),
|
||||||
screenCoords.top() + m_topLeftCornerTexCoords.height() + centerSize.height(),
|
screenCoords.top() + m_topLeftCornerTexCoords.height() + centerSize.height(),
|
||||||
m_bottomLeftCornerTexCoords.size());
|
m_bottomLeftCornerTexCoords.size());
|
||||||
g_graphics.drawTexturedRect(rectCoords, m_texture, m_bottomLeftCornerTexCoords);
|
g_painter.drawTexturedRect(rectCoords, m_texture, m_bottomLeftCornerTexCoords);
|
||||||
|
|
||||||
// bottom
|
// bottom
|
||||||
rectCoords = Rect(screenCoords.left() + m_bottomLeftCornerTexCoords.width(),
|
rectCoords = Rect(screenCoords.left() + m_bottomLeftCornerTexCoords.width(),
|
||||||
screenCoords.top() + m_topBorderTexCoords.height() + centerSize.height(),
|
screenCoords.top() + m_topBorderTexCoords.height() + centerSize.height(),
|
||||||
centerSize.width(),
|
centerSize.width(),
|
||||||
m_bottomBorderTexCoords.height());
|
m_bottomBorderTexCoords.height());
|
||||||
g_graphics.drawRepeatedTexturedRect(rectCoords, m_texture, m_bottomBorderTexCoords);
|
g_painter.drawRepeatedTexturedRect(rectCoords, m_texture, m_bottomBorderTexCoords);
|
||||||
|
|
||||||
// bottom right corner
|
// bottom right corner
|
||||||
rectCoords = Rect(screenCoords.left() + m_bottomLeftCornerTexCoords.width() + centerSize.width(),
|
rectCoords = Rect(screenCoords.left() + m_bottomLeftCornerTexCoords.width() + centerSize.width(),
|
||||||
screenCoords.top() + m_topRightCornerTexCoords.height() + centerSize.height(),
|
screenCoords.top() + m_topRightCornerTexCoords.height() + centerSize.height(),
|
||||||
m_bottomRightCornerTexCoords.size());
|
m_bottomRightCornerTexCoords.size());
|
||||||
g_graphics.drawTexturedRect(rectCoords, m_texture, m_bottomRightCornerTexCoords);
|
g_painter.drawTexturedRect(rectCoords, m_texture, m_bottomRightCornerTexCoords);
|
||||||
|
|
||||||
g_graphics.stopDrawing();
|
|
||||||
}
|
}
|
|
@ -32,6 +32,9 @@ class Font;
|
||||||
class Image;
|
class Image;
|
||||||
class BorderImage;
|
class BorderImage;
|
||||||
class FrameBuffer;
|
class FrameBuffer;
|
||||||
|
class Shader;
|
||||||
|
class ShaderProgram;
|
||||||
|
class PainterShaderProgram;
|
||||||
|
|
||||||
typedef std::weak_ptr<Texture> TextureWeakPtr;
|
typedef std::weak_ptr<Texture> TextureWeakPtr;
|
||||||
|
|
||||||
|
@ -41,5 +44,9 @@ typedef std::shared_ptr<Font> FontPtr;
|
||||||
typedef std::shared_ptr<Image> ImagePtr;
|
typedef std::shared_ptr<Image> ImagePtr;
|
||||||
typedef std::shared_ptr<BorderImage> BorderImagePtr;
|
typedef std::shared_ptr<BorderImage> BorderImagePtr;
|
||||||
typedef std::shared_ptr<FrameBuffer> FrameBufferPtr;
|
typedef std::shared_ptr<FrameBuffer> FrameBufferPtr;
|
||||||
|
typedef std::shared_ptr<Shader> ShaderPtr;
|
||||||
|
typedef std::shared_ptr<ShaderProgram> ShaderProgramPtr;
|
||||||
|
typedef std::shared_ptr<PainterShaderProgram> PainterShaderProgramPtr;
|
||||||
|
typedef std::vector<ShaderPtr> ShaderList;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -64,7 +64,7 @@ void Font::renderText(const std::string& text,
|
||||||
const Point& startPos,
|
const Point& startPos,
|
||||||
const Color& color)
|
const Color& color)
|
||||||
{
|
{
|
||||||
Size boxSize = g_graphics.getScreenSize() - startPos.toSize();
|
Size boxSize = g_graphics.getViewportSize() - startPos.toSize();
|
||||||
Rect screenCoords(startPos, boxSize);
|
Rect screenCoords(startPos, boxSize);
|
||||||
renderText(text, screenCoords, Fw::AlignTopLeft, color);
|
renderText(text, screenCoords, Fw::AlignTopLeft, color);
|
||||||
}
|
}
|
||||||
|
@ -85,9 +85,7 @@ void Font::renderText(const std::string& text,
|
||||||
Size textBoxSize;
|
Size textBoxSize;
|
||||||
const std::vector<Point>& glyphsPositions = calculateGlyphsPositions(text, align, &textBoxSize);
|
const std::vector<Point>& glyphsPositions = calculateGlyphsPositions(text, align, &textBoxSize);
|
||||||
|
|
||||||
g_graphics.bindColor(color);
|
g_painter.setColor(color);
|
||||||
g_graphics.bindTexture(m_texture);
|
|
||||||
g_graphics.startDrawing();
|
|
||||||
|
|
||||||
for(int i = 0; i < textLenght; ++i) {
|
for(int i = 0; i < textLenght; ++i) {
|
||||||
int glyph = (uchar)text[i];
|
int glyph = (uchar)text[i];
|
||||||
|
@ -149,10 +147,8 @@ void Font::renderText(const std::string& text,
|
||||||
}
|
}
|
||||||
|
|
||||||
// render glyph
|
// render glyph
|
||||||
g_graphics.drawTexturedRect(glyphScreenCoords, m_texture, glyphTextureCoords);
|
g_painter.drawTexturedRect(glyphScreenCoords, m_texture, glyphTextureCoords);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_graphics.stopDrawing();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<Point>& Font::calculateGlyphsPositions(const std::string& text,
|
const std::vector<Point>& Font::calculateGlyphsPositions(const std::string& text,
|
||||||
|
@ -172,7 +168,7 @@ const std::vector<Point>& Font::calculateGlyphsPositions(const std::string& text
|
||||||
// return if there is no text
|
// return if there is no text
|
||||||
if(textLength == 0) {
|
if(textLength == 0) {
|
||||||
if(textBoxSize)
|
if(textBoxSize)
|
||||||
textBoxSize->setSize(0,m_glyphHeight);
|
textBoxSize->resize(0,m_glyphHeight);
|
||||||
return glyphsPositions;
|
return glyphsPositions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,6 +276,6 @@ void Font::calculateGlyphsWidthsAutomatically(const Size& glyphSize)
|
||||||
lastColumnFilledPixels = columnFilledPixels;
|
lastColumnFilledPixels = columnFilledPixels;
|
||||||
}
|
}
|
||||||
// store glyph size
|
// store glyph size
|
||||||
m_glyphsSize[glyph].setSize(width, m_glyphHeight);
|
m_glyphsSize[glyph].resize(width, m_glyphHeight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,110 +26,52 @@
|
||||||
|
|
||||||
FrameBuffer::FrameBuffer(int width, int height)
|
FrameBuffer::FrameBuffer(int width, int height)
|
||||||
{
|
{
|
||||||
m_fbo = 0;
|
|
||||||
|
|
||||||
// create FBO texture
|
// create FBO texture
|
||||||
m_texture = TexturePtr(new Texture(width, height, 4));
|
m_texture = TexturePtr(new Texture(width, height, 4));
|
||||||
m_texture->enableBilinearFilter();
|
m_texture->enableBilinearFilter();
|
||||||
|
|
||||||
// use FBO ext only if supported
|
// generate FBO
|
||||||
if(g_graphics.isExtensionSupported("GL_ARB_framebuffer_object")) {
|
glGenFramebuffers(1, &m_fbo);
|
||||||
m_fallbackOldImp = false;
|
if(!m_fbo)
|
||||||
|
logFatal("Unable to create framebuffer object");
|
||||||
|
|
||||||
// generate FBO
|
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
|
||||||
glGenFramebuffers(1, &m_fbo);
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER_EXT, m_fbo);
|
|
||||||
|
|
||||||
// attach 2D texture to this FBO
|
// attach 2D texture to this FBO
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_texture->getId(), 0);
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture->getId(), 0);
|
||||||
|
|
||||||
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER_EXT);
|
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||||
switch(status) {
|
if(status != GL_FRAMEBUFFER_COMPLETE)
|
||||||
case GL_FRAMEBUFFER_COMPLETE_EXT:
|
logFatal("Unable to create framebuffer object");
|
||||||
//ok
|
|
||||||
break;
|
|
||||||
default: // fallback to old implementation
|
|
||||||
m_fallbackOldImp = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// restore back buffer
|
// restore back buffer
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
glDrawBuffer(GL_BACK);
|
|
||||||
glReadBuffer(GL_BACK);
|
|
||||||
} else {
|
|
||||||
// otherwise fallback to copy texture from screen implementation
|
|
||||||
m_fallbackOldImp = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(m_fallbackOldImp)
|
|
||||||
logInfo("Framebuffers not supported, falling back to old implementation.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FrameBuffer::~FrameBuffer()
|
FrameBuffer::~FrameBuffer()
|
||||||
{
|
{
|
||||||
if(m_fbo)
|
glDeleteFramebuffers(1, &m_fbo);
|
||||||
glDeleteFramebuffers(1, &m_fbo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FrameBuffer::bind()
|
void FrameBuffer::bind()
|
||||||
{
|
{
|
||||||
if(!m_fallbackOldImp) {
|
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
|
||||||
// bind framebuffer
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER_EXT, m_fbo);
|
|
||||||
} else {
|
|
||||||
int screenWidth = g_graphics.getScreenSize().width();
|
|
||||||
int screenHeight = g_graphics.getScreenSize().height();
|
|
||||||
|
|
||||||
if(!m_screenBackup || m_screenBackup->getSize() != g_graphics.getScreenSize())
|
|
||||||
m_screenBackup = TexturePtr(new Texture(screenWidth, screenHeight, 4));
|
|
||||||
|
|
||||||
// save screen state
|
|
||||||
glBindTexture(GL_TEXTURE_2D, m_screenBackup->getId());
|
|
||||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, screenWidth, screenHeight);
|
|
||||||
}
|
|
||||||
|
|
||||||
// setup framebuffer viewport
|
|
||||||
glViewport(0, 0, m_texture->getWidth(), m_texture->getHeight());
|
|
||||||
glMatrixMode(GL_PROJECTION);
|
|
||||||
glLoadIdentity();
|
|
||||||
glOrtho(0.0f, m_texture->getWidth(), m_texture->getHeight(), 0, -1, 1);
|
|
||||||
|
|
||||||
// back to model view
|
|
||||||
glMatrixMode(GL_MODELVIEW);
|
|
||||||
glLoadIdentity();
|
|
||||||
|
|
||||||
// clear framebuffer
|
|
||||||
glClearColor(0.0, 0.0, 0.0, 1.0);
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
glViewport(0, 0, m_texture->getWidth(), m_texture->getHeight());
|
||||||
|
g_painter.updateProjectionMatrix(m_texture->getSize(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FrameBuffer::unbind()
|
void FrameBuffer::release()
|
||||||
{
|
{
|
||||||
if(!m_fallbackOldImp) {
|
// bind back buffer again
|
||||||
// bind back buffer again
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
|
|
||||||
glDrawBuffer(GL_BACK);
|
|
||||||
glReadBuffer(GL_BACK);
|
|
||||||
|
|
||||||
// restore graphics viewport
|
// restore graphics viewport
|
||||||
g_graphics.restoreViewport();
|
glViewport(0, 0, g_graphics.getViewportSize().width(), g_graphics.getViewportSize().height());
|
||||||
} else {
|
g_painter.updateProjectionMatrix(g_graphics.getViewportSize());
|
||||||
// copy screen to texture
|
|
||||||
glBindTexture(GL_TEXTURE_2D, m_texture->getId());
|
|
||||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, m_texture->getWidth(), m_texture->getHeight());
|
|
||||||
|
|
||||||
// restore graphics viewport
|
|
||||||
g_graphics.restoreViewport();
|
|
||||||
|
|
||||||
// restore screen
|
|
||||||
glClearColor(0.0, 0.0, 0.0, 1.0);
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
|
||||||
g_graphics.drawTexturedRect(Rect(Point(0,0), g_graphics.getScreenSize()), m_screenBackup, Rect(), true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FrameBuffer::draw(const Rect& screenCoords, const Rect& framebufferCoords)
|
void FrameBuffer::draw(const Rect& dest)
|
||||||
{
|
{
|
||||||
g_graphics.drawTexturedRect(screenCoords, m_texture, framebufferCoords, true);
|
g_painter.drawTexturedRect(dest, m_texture);
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,8 +32,8 @@ public:
|
||||||
virtual ~FrameBuffer();
|
virtual ~FrameBuffer();
|
||||||
|
|
||||||
void bind();
|
void bind();
|
||||||
void unbind();
|
void release();
|
||||||
void draw(const Rect& screenCoords, const Rect& framebufferCoords = Rect());
|
void draw(const Rect& dest);
|
||||||
|
|
||||||
TexturePtr getTexture() { return m_texture; }
|
TexturePtr getTexture() { return m_texture; }
|
||||||
|
|
||||||
|
|
|
@ -30,307 +30,48 @@ Graphics g_graphics;
|
||||||
void Graphics::init()
|
void Graphics::init()
|
||||||
{
|
{
|
||||||
// setup opengl
|
// setup opengl
|
||||||
glEnable(GL_ALPHA_TEST); // enable alpha by default
|
|
||||||
glAlphaFunc(GL_GREATER, 0.0f); // default alpha func
|
|
||||||
glDisable(GL_DEPTH_TEST); // we are rendering 2D only, we don't need depth buffer
|
|
||||||
glEnable(GL_TEXTURE_2D); // enable textures by default
|
|
||||||
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
|
|
||||||
glShadeModel(GL_SMOOTH);
|
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||||
|
|
||||||
logInfo("GPU ", glGetString(GL_RENDERER));
|
logInfo("GPU ", glGetString(GL_RENDERER));
|
||||||
logInfo("OpenGL ", glGetString(GL_VERSION));
|
logInfo("OpenGL ", glGetString(GL_VERSION));
|
||||||
|
|
||||||
m_drawing = false;
|
//if(!isExtensionSupported("GL_ARB_framebuffer_object"))
|
||||||
m_opacity = 255;
|
// logFatal("Your graphics card is not supported.");
|
||||||
|
|
||||||
m_emptyTexture = TexturePtr(new Texture);
|
m_emptyTexture = TexturePtr(new Texture);
|
||||||
|
|
||||||
bindColor(Fw::white);
|
g_painter.init();
|
||||||
bindBlendFunc(Fw::BlendDefault);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::terminate()
|
void Graphics::terminate()
|
||||||
{
|
{
|
||||||
g_fonts.releaseFonts();
|
g_fonts.releaseFonts();
|
||||||
|
g_painter.terminate();
|
||||||
m_emptyTexture.reset();
|
m_emptyTexture.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Graphics::isExtensionSupported(const char *extension)
|
bool Graphics::isExtensionSupported(const char *extension)
|
||||||
{
|
{
|
||||||
const GLubyte *extensions = NULL;
|
std::string extensionsString = (const char*)glGetString(GL_EXTENSIONS);
|
||||||
const GLubyte *start;
|
auto extensions = Fw::split(extensionsString);
|
||||||
GLubyte *where, *terminator;
|
return std::find(extensions.begin(), extensions.end(), extension) != extensions.end();
|
||||||
where = (GLubyte *)strchr(extension, ' ');
|
|
||||||
|
|
||||||
if(where || *extension == '\0')
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
extensions = glGetString(GL_EXTENSIONS);
|
|
||||||
|
|
||||||
start = extensions;
|
|
||||||
while(true) {
|
|
||||||
where = (GLubyte *) strstr((const char *)start, extension);
|
|
||||||
if(!where)
|
|
||||||
break;
|
|
||||||
|
|
||||||
terminator = where + strlen(extension);
|
|
||||||
|
|
||||||
if(where == start || *(where - 1) == ' ')
|
|
||||||
if(*terminator == ' ' || *terminator == '\0')
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
start = terminator;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::resize(const Size& size)
|
void Graphics::resize(const Size& size)
|
||||||
{
|
{
|
||||||
m_screenSize = size;
|
glViewport(0, 0, size.width(), size.height());
|
||||||
restoreViewport();
|
g_painter.updateProjectionMatrix(size);
|
||||||
}
|
m_viewportSize = size;
|
||||||
|
|
||||||
void Graphics::restoreViewport()
|
|
||||||
{
|
|
||||||
const int& width = m_screenSize.width();
|
|
||||||
const int& height = m_screenSize.height();
|
|
||||||
|
|
||||||
// resize gl viewport
|
|
||||||
glViewport(0, 0, width, height);
|
|
||||||
|
|
||||||
/*
|
|
||||||
0,0---------0,w
|
|
||||||
| |
|
|
||||||
| |
|
|
||||||
| |
|
|
||||||
h,0---------h,w
|
|
||||||
*/
|
|
||||||
// setup view region like above
|
|
||||||
glMatrixMode(GL_PROJECTION);
|
|
||||||
glLoadIdentity();
|
|
||||||
glOrtho(0.0f, width, height, 0.0f, -1, 1);
|
|
||||||
|
|
||||||
// back to model view
|
|
||||||
glMatrixMode(GL_MODELVIEW);
|
|
||||||
glLoadIdentity();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::beginRender()
|
void Graphics::beginRender()
|
||||||
{
|
{
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
glLoadIdentity();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::endRender()
|
void Graphics::endRender()
|
||||||
{
|
{
|
||||||
assert(!m_drawing);
|
glFlush();
|
||||||
}
|
|
||||||
|
|
||||||
void Graphics::drawTexturedRect(const Rect& screenCoords,
|
|
||||||
const TexturePtr& texture,
|
|
||||||
const Rect& textureCoords,
|
|
||||||
bool upsideDown)
|
|
||||||
{
|
|
||||||
if(screenCoords.isEmpty() || texture->getId() == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// rect correction for opengl
|
|
||||||
int right = screenCoords.right() + 1;
|
|
||||||
int bottom = screenCoords.bottom() + 1;
|
|
||||||
int top = screenCoords.top();
|
|
||||||
int left = screenCoords.left();
|
|
||||||
|
|
||||||
float textureRight;
|
|
||||||
float textureBottom;
|
|
||||||
float textureTop;
|
|
||||||
float textureLeft;
|
|
||||||
const Size& textureSize = texture->getGlSize();
|
|
||||||
|
|
||||||
if(textureCoords.isEmpty()) {
|
|
||||||
textureRight = texture->getWidth() / (float)textureSize.width();
|
|
||||||
if(upsideDown) {
|
|
||||||
textureBottom = 0.0f;
|
|
||||||
textureTop = texture->getHeight() / (float)textureSize.height();
|
|
||||||
} else {
|
|
||||||
textureBottom = texture->getHeight() / (float)textureSize.height();
|
|
||||||
textureTop = 0.0f;
|
|
||||||
}
|
|
||||||
textureLeft = 0.0f;
|
|
||||||
} else {
|
|
||||||
textureRight = (textureCoords.right() + 1) / (float)textureSize.width();
|
|
||||||
if(upsideDown) {
|
|
||||||
textureTop = (textureCoords.bottom() + 1) / (float)textureSize.height();
|
|
||||||
textureBottom = textureCoords.top() / (float)textureSize.height();
|
|
||||||
} else {
|
|
||||||
textureBottom = (textureCoords.bottom() + 1) / (float)textureSize.height();
|
|
||||||
textureTop = textureCoords.top() / (float)textureSize.height();
|
|
||||||
}
|
|
||||||
textureLeft = textureCoords.left() / (float)textureSize.width();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!m_drawing) {
|
|
||||||
bindTexture(texture);
|
|
||||||
glBegin(GL_QUADS);
|
|
||||||
}
|
|
||||||
|
|
||||||
glTexCoord2f(textureLeft, textureTop); glVertex2i(left, top);
|
|
||||||
glTexCoord2f(textureLeft, textureBottom); glVertex2i(left, bottom);
|
|
||||||
glTexCoord2f(textureRight, textureBottom); glVertex2i(right, bottom);
|
|
||||||
glTexCoord2f(textureRight, textureTop); glVertex2i(right, top);
|
|
||||||
|
|
||||||
if(!m_drawing)
|
|
||||||
glEnd();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Graphics::drawRepeatedTexturedRect(const Rect& screenCoords,
|
|
||||||
const TexturePtr& texture,
|
|
||||||
const Rect& textureCoords)
|
|
||||||
{
|
|
||||||
if(screenCoords.isEmpty() || texture->getId() == 0 || textureCoords.isEmpty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
bool mustStopDrawing = false;
|
|
||||||
if(!m_drawing) {
|
|
||||||
bindTexture(texture);
|
|
||||||
startDrawing();
|
|
||||||
mustStopDrawing = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// render many repeated texture rects
|
|
||||||
Rect virtualScreenCoords(0,0,screenCoords.size());
|
|
||||||
for(int y = 0; y <= virtualScreenCoords.height(); y += textureCoords.height()) {
|
|
||||||
for(int x = 0; x <= virtualScreenCoords.width(); x += textureCoords.width()) {
|
|
||||||
Rect partialCoords(x, y, textureCoords.size());
|
|
||||||
Rect partialTextureCoords = textureCoords;
|
|
||||||
|
|
||||||
// partialCoords to screenCoords bottomRight
|
|
||||||
if(partialCoords.bottom() > virtualScreenCoords.bottom()) {
|
|
||||||
partialTextureCoords.setBottom(partialTextureCoords.bottom() +
|
|
||||||
(virtualScreenCoords.bottom() - partialCoords.bottom()));
|
|
||||||
partialCoords.setBottom(virtualScreenCoords.bottom());
|
|
||||||
}
|
|
||||||
if(partialCoords.right() > virtualScreenCoords.right()) {
|
|
||||||
partialTextureCoords.setRight(partialTextureCoords.right() +
|
|
||||||
(virtualScreenCoords.right() - partialCoords.right()));
|
|
||||||
partialCoords.setRight(virtualScreenCoords.right());
|
|
||||||
}
|
|
||||||
|
|
||||||
partialCoords.translate(screenCoords.topLeft());
|
|
||||||
drawTexturedRect(partialCoords, texture, partialTextureCoords);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(mustStopDrawing)
|
|
||||||
stopDrawing();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Graphics::drawFilledRect(const Rect& screenCoords)
|
|
||||||
{
|
|
||||||
assert(!m_drawing);
|
|
||||||
|
|
||||||
if(screenCoords.isEmpty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
// rect correction for opengl
|
|
||||||
int right = screenCoords.right() + 1;
|
|
||||||
int bottom = screenCoords.bottom() + 1;
|
|
||||||
int top = screenCoords.top();
|
|
||||||
int left = screenCoords.left();
|
|
||||||
|
|
||||||
glDisable(GL_TEXTURE_2D);
|
|
||||||
glBegin(GL_QUADS);
|
|
||||||
|
|
||||||
glVertex2i(left, top);
|
|
||||||
glVertex2i(left, bottom);
|
|
||||||
glVertex2i(right, bottom);
|
|
||||||
glVertex2i(right, top);
|
|
||||||
|
|
||||||
glEnd();
|
|
||||||
glEnable(GL_TEXTURE_2D);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Graphics::drawBoundingRect(const Rect& screenCoords,
|
|
||||||
int innerLineWidth)
|
|
||||||
{
|
|
||||||
assert(!m_drawing);
|
|
||||||
|
|
||||||
if(screenCoords.isEmpty() || 2 * innerLineWidth > screenCoords.height())
|
|
||||||
return;
|
|
||||||
|
|
||||||
// rect correction for opengl
|
|
||||||
int right = screenCoords.right()+1;
|
|
||||||
int bottom = screenCoords.bottom()+1;
|
|
||||||
int top = screenCoords.top();
|
|
||||||
int left = screenCoords.left();
|
|
||||||
|
|
||||||
glDisable(GL_TEXTURE_2D);
|
|
||||||
glBegin(GL_QUADS);
|
|
||||||
|
|
||||||
// top line
|
|
||||||
glVertex2i(left, top);
|
|
||||||
glVertex2i(left, top + innerLineWidth);
|
|
||||||
glVertex2i(right, top + innerLineWidth);
|
|
||||||
glVertex2i(right, top);
|
|
||||||
|
|
||||||
// left
|
|
||||||
glVertex2i(left, screenCoords.top() + innerLineWidth);
|
|
||||||
glVertex2i(left, bottom - innerLineWidth);
|
|
||||||
glVertex2i(left + innerLineWidth, bottom - innerLineWidth);
|
|
||||||
glVertex2i(left + innerLineWidth, screenCoords.top() + innerLineWidth);
|
|
||||||
|
|
||||||
// bottom line
|
|
||||||
glVertex2i(left, bottom);
|
|
||||||
glVertex2i(left, bottom - innerLineWidth);
|
|
||||||
glVertex2i(right, bottom - innerLineWidth);
|
|
||||||
glVertex2i(right, bottom);
|
|
||||||
|
|
||||||
// right line
|
|
||||||
glVertex2i(right , top + innerLineWidth);
|
|
||||||
glVertex2i(right , bottom - innerLineWidth);
|
|
||||||
glVertex2i(right - innerLineWidth, bottom - innerLineWidth);
|
|
||||||
glVertex2i(right - innerLineWidth, top + innerLineWidth);
|
|
||||||
|
|
||||||
glEnd();
|
|
||||||
glEnable(GL_TEXTURE_2D);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Graphics::bindColor(const Color& color)
|
|
||||||
{
|
|
||||||
Color tmp = color;
|
|
||||||
tmp.setAlpha(std::min((uint8)m_opacity, color.a()));
|
|
||||||
glColor4ubv(tmp.rgbaPtr());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Graphics::bindTexture(const TexturePtr& texture)
|
|
||||||
{
|
|
||||||
glBindTexture(GL_TEXTURE_2D, texture->getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Graphics::bindBlendFunc(Fw::BlendFunc blendType)
|
|
||||||
{
|
|
||||||
switch(blendType) {
|
|
||||||
case Fw::BlendDefault:
|
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
||||||
break;
|
|
||||||
case Fw::BlendColorzing:
|
|
||||||
glBlendFunc(GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Graphics::startDrawing()
|
|
||||||
{
|
|
||||||
assert(!m_drawing);
|
|
||||||
glBegin(GL_QUADS);
|
|
||||||
m_drawing = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Graphics::stopDrawing()
|
|
||||||
{
|
|
||||||
assert(m_drawing);
|
|
||||||
glEnd();
|
|
||||||
m_drawing = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,64 +24,25 @@
|
||||||
#define GRAPHICS_H
|
#define GRAPHICS_H
|
||||||
|
|
||||||
#include "declarations.h"
|
#include "declarations.h"
|
||||||
|
#include "painter.h"
|
||||||
|
|
||||||
class Graphics
|
class Graphics
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// Initialize default OpenGL states
|
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
/// Termiante graphics
|
|
||||||
void terminate();
|
void terminate();
|
||||||
|
|
||||||
/// Check if a GL extension is supported
|
|
||||||
bool isExtensionSupported(const char *extension);
|
bool isExtensionSupported(const char *extension);
|
||||||
|
|
||||||
/// Resizes OpenGL viewport
|
|
||||||
void resize(const Size& size);
|
void resize(const Size& size);
|
||||||
|
|
||||||
/// Restore original viewport
|
|
||||||
void restoreViewport();
|
|
||||||
|
|
||||||
/// Called before every render
|
|
||||||
void beginRender();
|
void beginRender();
|
||||||
|
|
||||||
/// Called after every render
|
|
||||||
void endRender();
|
void endRender();
|
||||||
|
|
||||||
void bindColor(const Color& color);
|
const Size& getViewportSize() const { return m_viewportSize; }
|
||||||
void bindTexture(const TexturePtr& texture);
|
|
||||||
void bindBlendFunc(Fw::BlendFunc blendType);
|
|
||||||
|
|
||||||
// drawing API
|
|
||||||
void drawTexturedRect(const Rect& screenCoords,
|
|
||||||
const TexturePtr& texture,
|
|
||||||
const Rect& textureCoords = Rect(),
|
|
||||||
bool upsideDown = false);
|
|
||||||
|
|
||||||
void drawRepeatedTexturedRect(const Rect& screenCoords,
|
|
||||||
const TexturePtr& texture,
|
|
||||||
const Rect& textureCoords);
|
|
||||||
|
|
||||||
void drawFilledRect(const Rect& screenCoords);
|
|
||||||
|
|
||||||
void drawBoundingRect(const Rect& screenCoords,
|
|
||||||
int innerLineWidth = 1);
|
|
||||||
|
|
||||||
const Size& getScreenSize() const { return m_screenSize; }
|
|
||||||
|
|
||||||
void startDrawing();
|
|
||||||
void stopDrawing();
|
|
||||||
bool isDrawing() const { return m_drawing; }
|
|
||||||
|
|
||||||
int getOpacity() const { return m_opacity; }
|
|
||||||
void setOpacity(int opacity) { m_opacity = opacity; }
|
|
||||||
TexturePtr getEmptyTexture() { return m_emptyTexture; }
|
TexturePtr getEmptyTexture() { return m_emptyTexture; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_drawing;
|
Size m_viewportSize;
|
||||||
int m_opacity;
|
|
||||||
Size m_screenSize;
|
|
||||||
TexturePtr m_emptyTexture;
|
TexturePtr m_emptyTexture;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -63,12 +63,12 @@ void Image::draw(const Rect& screenCoords)
|
||||||
else if(texSize.width() > texCoordsSize.width())
|
else if(texSize.width() > texCoordsSize.width())
|
||||||
texCoordsOffset.x = (texSize.width() - texCoordsSize.width())/2;
|
texCoordsOffset.x = (texSize.width() - texCoordsSize.width())/2;
|
||||||
|
|
||||||
g_graphics.drawTexturedRect(screenCoords, m_texture, Rect(texCoordsOffset, texCoordsSize));
|
g_painter.drawTexturedRect(screenCoords, m_texture, Rect(texCoordsOffset, texCoordsSize));
|
||||||
} else {
|
} else {
|
||||||
if(m_repeated)
|
if(m_repeated)
|
||||||
g_graphics.drawRepeatedTexturedRect(screenCoords, m_texture, m_textureCoords);
|
g_painter.drawRepeatedTexturedRect(screenCoords, m_texture, m_textureCoords);
|
||||||
else
|
else
|
||||||
g_graphics.drawTexturedRect(screenCoords, m_texture, m_textureCoords);
|
g_painter.drawTexturedRect(screenCoords, m_texture, m_textureCoords);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,228 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010-2011 OTClient <https://github.com/edubart/otclient>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "painter.h"
|
||||||
|
#include "texture.h"
|
||||||
|
#include "paintershadersources.h"
|
||||||
|
#include "paintershaderprogram.h"
|
||||||
|
#include "shaderprogram.h"
|
||||||
|
#include "graphics.h"
|
||||||
|
|
||||||
|
Painter g_painter;
|
||||||
|
|
||||||
|
void Painter::init()
|
||||||
|
{
|
||||||
|
setColor(Fw::white);
|
||||||
|
setOpacity(255);
|
||||||
|
setCompositionMode(CompositionMode_SourceOver);
|
||||||
|
|
||||||
|
PainterShaderProgramPtr program = PainterShaderProgramPtr(new PainterShaderProgram);
|
||||||
|
program->addShaderFromSourceCode(Shader::Vertex, glslMainWithTexCoordsVertexShader);
|
||||||
|
program->addShaderFromSourceCode(Shader::Vertex, glslPositionOnlyVertexShader);
|
||||||
|
program->addShaderFromSourceCode(Shader::Fragment, glslMainFragmentShader);
|
||||||
|
program->addShaderFromSourceCode(Shader::Fragment, glslTextureSrcFragmentShader);
|
||||||
|
program->bindAttributeLocation(VERTEX_COORDS_ATTR, "vertexCoord");
|
||||||
|
program->bindAttributeLocation(TEXTURE_COORDS_ATTR, "textureCoord");
|
||||||
|
assert(program->link());
|
||||||
|
program->bindUniformLocation(PainterShaderProgram::PROJECTION_MATRIX_UNIFORM, "projectionMatrix");
|
||||||
|
program->bindUniformLocation(PainterShaderProgram::TEXTURE_TRANSFORM_MATRIX_UNIFORM, "textureTransformMatrix");
|
||||||
|
program->bindUniformLocation(PainterShaderProgram::COLOR_UNIFORM, "color");
|
||||||
|
program->bindUniformLocation(PainterShaderProgram::OPACITY_UNIFORM, "opacity");
|
||||||
|
program->bindUniformLocation(PainterShaderProgram::TEXTURE_UNIFORM, "texture");
|
||||||
|
m_drawTexturedProgram = program;
|
||||||
|
|
||||||
|
program = PainterShaderProgramPtr(new PainterShaderProgram);
|
||||||
|
program->addShaderFromSourceCode(Shader::Vertex, glslMainVertexShader);
|
||||||
|
program->addShaderFromSourceCode(Shader::Vertex, glslPositionOnlyVertexShader);
|
||||||
|
program->addShaderFromSourceCode(Shader::Fragment, glslMainFragmentShader);
|
||||||
|
program->addShaderFromSourceCode(Shader::Fragment, glslSolidColorFragmentShader);
|
||||||
|
program->bindAttributeLocation(VERTEX_COORDS_ATTR, "vertexCoord");
|
||||||
|
assert(program->link());
|
||||||
|
program->bindUniformLocation(PainterShaderProgram::PROJECTION_MATRIX_UNIFORM, "projectionMatrix");
|
||||||
|
program->bindUniformLocation(PainterShaderProgram::COLOR_UNIFORM, "color");
|
||||||
|
program->bindUniformLocation(PainterShaderProgram::OPACITY_UNIFORM, "opacity");
|
||||||
|
m_drawSolidColorProgram = program;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Painter::terminate()
|
||||||
|
{
|
||||||
|
m_drawTexturedProgram.reset();
|
||||||
|
m_drawSolidColorProgram.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Painter::updateProjectionMatrix(const Size& viewportSize, bool inverseYAxis)
|
||||||
|
{
|
||||||
|
// The projection matrix converts from Painter's coordinate system to GL's coordinate system
|
||||||
|
// * GL's viewport is 2x2, Painter's is width x height
|
||||||
|
// * GL has +y -> -y going from bottom -> top, Painter is the other way round
|
||||||
|
// * GL has [0,0] in the center, Painter has it in the top-left
|
||||||
|
//
|
||||||
|
// This results in the Projection matrix below, which is multiplied by the painter's
|
||||||
|
// transformation matrix, as shown below:
|
||||||
|
//
|
||||||
|
// Projection Matrix Painter Coord GL Coord
|
||||||
|
// ------------------------------------------------ --------- ---------
|
||||||
|
// | 2.0 / width | 0.0 | -1.0 | | x | | y' |
|
||||||
|
// | 0.0 | -2.0 / height | 1.0 | * | y | = | x' |
|
||||||
|
// | 0.0 | 0.0 | 0.0 | | 1 | | 0 |
|
||||||
|
// ------------------------------------------------ --------- ---------
|
||||||
|
float w = viewportSize.width();
|
||||||
|
float h = viewportSize.height();
|
||||||
|
if(inverseYAxis) {
|
||||||
|
m_projectionMatrix[0][0] = 2.0f/w; m_projectionMatrix[0][1] = 0.0f; m_projectionMatrix[0][2] =-1.0f;
|
||||||
|
m_projectionMatrix[1][0] = 0.0f; m_projectionMatrix[1][1] = 2.0f/h; m_projectionMatrix[1][2] =-1.0f;
|
||||||
|
m_projectionMatrix[2][0] = 0.0f; m_projectionMatrix[2][1] = 0.0f; m_projectionMatrix[2][2] = 0.0f;
|
||||||
|
} else {
|
||||||
|
m_projectionMatrix[0][0] = 2.0f/w; m_projectionMatrix[0][1] = 0.0f; m_projectionMatrix[0][2] =-1.0f;
|
||||||
|
m_projectionMatrix[1][0] = 0.0f; m_projectionMatrix[1][1] =-2.0f/h; m_projectionMatrix[1][2] = 1.0f;
|
||||||
|
m_projectionMatrix[2][0] = 0.0f; m_projectionMatrix[2][1] = 0.0f; m_projectionMatrix[2][2] = 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Painter::drawTexturedRect(const Rect& dest, const TexturePtr& texture)
|
||||||
|
{
|
||||||
|
drawTexturedRect(dest, texture, Rect(Point(0,0), texture->getSize()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Painter::drawTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src)
|
||||||
|
{
|
||||||
|
if(dest.isEmpty() || src.isEmpty() || !texture->getId())
|
||||||
|
return;
|
||||||
|
|
||||||
|
GLfloat vertexCoords[] = { (float)dest.left(), (float)dest.top(),
|
||||||
|
(float)dest.right()+1, (float)dest.top(),
|
||||||
|
(float)dest.left(), (float)dest.bottom()+1,
|
||||||
|
(float)dest.right()+1, (float)dest.bottom()+1 };
|
||||||
|
|
||||||
|
GLfloat textureCoords[] = { (float)src.left(), (float)src.top(),
|
||||||
|
(float)src.right()+1, (float)src.top(),
|
||||||
|
(float)src.left(), (float)src.bottom()+1,
|
||||||
|
(float)src.right()+1, (float)src.bottom()+1 };
|
||||||
|
|
||||||
|
m_drawTexturedProgram->prepareForDraw();
|
||||||
|
m_drawTexturedProgram->setProjectionMatrix(m_projectionMatrix);
|
||||||
|
m_drawTexturedProgram->setOpacity(m_currentOpacity);
|
||||||
|
m_drawTexturedProgram->setColor(m_currentColor);
|
||||||
|
m_drawTexturedProgram->setTexture(texture);
|
||||||
|
m_drawTexturedProgram->setVertexCoords(vertexCoords);
|
||||||
|
m_drawTexturedProgram->setTextureCoords(textureCoords);
|
||||||
|
m_drawTexturedProgram->drawTriangleStrip(4);
|
||||||
|
m_drawTexturedProgram->releaseFromDraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Painter::drawRepeatedTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src)
|
||||||
|
{
|
||||||
|
if(dest.isEmpty() || src.isEmpty() || !texture->getId())
|
||||||
|
return;
|
||||||
|
|
||||||
|
//TODO: use vertex arrays..
|
||||||
|
Rect virtualDest(0, 0, dest.size());
|
||||||
|
for(int y = 0; y <= virtualDest.height(); y += src.height()) {
|
||||||
|
for(int x = 0; x <= virtualDest.width(); x += src.width()) {
|
||||||
|
Rect partialDest(x, y, src.size());
|
||||||
|
Rect partialSrc = src;
|
||||||
|
|
||||||
|
// partialCoords to screenCoords bottomRight
|
||||||
|
if(partialDest.bottom() > virtualDest.bottom()) {
|
||||||
|
partialSrc.setBottom(partialSrc.bottom() + (virtualDest.bottom() - partialDest.bottom()));
|
||||||
|
partialDest.setBottom(virtualDest.bottom());
|
||||||
|
}
|
||||||
|
if(partialDest.right() > virtualDest.right()) {
|
||||||
|
partialSrc.setRight(partialSrc.right() + (virtualDest.right() - partialDest.right()));
|
||||||
|
partialDest.setRight(virtualDest.right());
|
||||||
|
}
|
||||||
|
|
||||||
|
partialDest.translate(dest.topLeft());
|
||||||
|
drawTexturedRect(partialDest, texture, partialSrc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Painter::drawFilledRect(const Rect& dest)
|
||||||
|
{
|
||||||
|
if(dest.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
GLfloat right = dest.right()+1;
|
||||||
|
GLfloat bottom = dest.bottom()+1;
|
||||||
|
GLfloat top = dest.top();
|
||||||
|
GLfloat left = dest.left();
|
||||||
|
|
||||||
|
GLfloat vertexCoords[] = { left, top,
|
||||||
|
right, top,
|
||||||
|
left, bottom,
|
||||||
|
right, bottom };
|
||||||
|
|
||||||
|
m_drawSolidColorProgram->prepareForDraw();
|
||||||
|
m_drawSolidColorProgram->setProjectionMatrix(m_projectionMatrix);
|
||||||
|
m_drawSolidColorProgram->setOpacity(m_currentOpacity);
|
||||||
|
m_drawSolidColorProgram->setColor(m_currentColor);
|
||||||
|
m_drawSolidColorProgram->setVertexCoords(vertexCoords);
|
||||||
|
m_drawSolidColorProgram->drawTriangleStrip(4);
|
||||||
|
m_drawSolidColorProgram->releaseFromDraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Painter::drawBoundingRect(const Rect& dest, int innerLineWidth)
|
||||||
|
{
|
||||||
|
if(dest.isEmpty() || innerLineWidth == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
GLfloat right = dest.right()+1;
|
||||||
|
GLfloat bottom = dest.bottom()+1;
|
||||||
|
GLfloat top = dest.top();
|
||||||
|
GLfloat left = dest.left();
|
||||||
|
GLfloat w = innerLineWidth;
|
||||||
|
|
||||||
|
GLfloat vertexCoords[] = { left, top,
|
||||||
|
right, top,
|
||||||
|
left, top+w,
|
||||||
|
right, top+w,
|
||||||
|
right-w, top+w,
|
||||||
|
right, bottom,
|
||||||
|
right-w, bottom,
|
||||||
|
right-w, bottom-w,
|
||||||
|
left, bottom,
|
||||||
|
left, bottom-w,
|
||||||
|
left+w, bottom-w,
|
||||||
|
left, top+w,
|
||||||
|
left+w, top+w };
|
||||||
|
|
||||||
|
m_drawSolidColorProgram->prepareForDraw();
|
||||||
|
m_drawSolidColorProgram->setProjectionMatrix(m_projectionMatrix);
|
||||||
|
m_drawSolidColorProgram->setOpacity(m_currentOpacity);
|
||||||
|
m_drawSolidColorProgram->setColor(m_currentColor);
|
||||||
|
m_drawSolidColorProgram->setVertexCoords(vertexCoords);
|
||||||
|
m_drawSolidColorProgram->drawTriangleStrip(13);
|
||||||
|
m_drawSolidColorProgram->releaseFromDraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Painter::setCompositionMode(Painter::CompositionMode compositionMode)
|
||||||
|
{
|
||||||
|
switch(compositionMode) {
|
||||||
|
case CompositionMode_SourceOver:
|
||||||
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
break;
|
||||||
|
case CompositionMode_ColorizeDest:
|
||||||
|
glBlendFunc(GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010-2011 OTClient <https://github.com/edubart/otclient>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PAINTER_H
|
||||||
|
#define PAINTER_H
|
||||||
|
|
||||||
|
#include "declarations.h"
|
||||||
|
|
||||||
|
class Painter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum CompositionMode {
|
||||||
|
CompositionMode_SourceOver,
|
||||||
|
CompositionMode_ColorizeDest
|
||||||
|
};
|
||||||
|
|
||||||
|
void init();
|
||||||
|
void terminate();
|
||||||
|
|
||||||
|
void updateProjectionMatrix(const Size& viewportSize, bool inverseYAxis = false);
|
||||||
|
void drawTexturedRect(const Rect& dest, const TexturePtr& texture);
|
||||||
|
void drawTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src);
|
||||||
|
void drawRepeatedTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src);
|
||||||
|
void drawFilledRect(const Rect& dest);
|
||||||
|
void drawBoundingRect(const Rect& dest, int innerLineWidth = 1);
|
||||||
|
|
||||||
|
void setColor(const Color& color) { m_currentColor = color; }
|
||||||
|
Color getColor() { return m_currentColor; }
|
||||||
|
|
||||||
|
void setOpacity(int opacity) { m_currentOpacity = opacity / 255.0f; }
|
||||||
|
int getOpacity() { return m_currentOpacity * 255.0f; }
|
||||||
|
|
||||||
|
void setCompositionMode(CompositionMode compositionMode);
|
||||||
|
|
||||||
|
private:
|
||||||
|
PainterShaderProgramPtr m_drawTexturedProgram;
|
||||||
|
PainterShaderProgramPtr m_drawSolidColorProgram;
|
||||||
|
GLfloat m_projectionMatrix[3][3];
|
||||||
|
Color m_currentColor;
|
||||||
|
GLfloat m_currentOpacity;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern Painter g_painter;
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,99 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010-2011 OTClient <https://github.com/edubart/otclient>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "paintershaderprogram.h"
|
||||||
|
#include "painter.h"
|
||||||
|
#include "texture.h"
|
||||||
|
#include "texturemanager.h"
|
||||||
|
|
||||||
|
void PainterShaderProgram::setProjectionMatrix(float projectionMatrix[3][3])
|
||||||
|
{
|
||||||
|
setUniformValue(PROJECTION_MATRIX_UNIFORM, projectionMatrix, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PainterShaderProgram::setColor(const Color& color)
|
||||||
|
{
|
||||||
|
setUniformValue(COLOR_UNIFORM,
|
||||||
|
color.r() / 255.0f,
|
||||||
|
color.g() / 255.0f,
|
||||||
|
color.b() / 255.0f,
|
||||||
|
color.a() / 255.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PainterShaderProgram::setOpacity(GLfloat opacity)
|
||||||
|
{
|
||||||
|
setUniformValue(OPACITY_UNIFORM, opacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PainterShaderProgram::setTexture(const TexturePtr& texture)
|
||||||
|
{
|
||||||
|
float w = texture->getGlSize().width();
|
||||||
|
float h = texture->getGlSize().height();
|
||||||
|
|
||||||
|
GLfloat textureTransformMatrix[2][2] = {
|
||||||
|
{ 1.0f/w, 0.0f },
|
||||||
|
{ 0.0f, 1.0f/h }
|
||||||
|
};
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, texture->getId());
|
||||||
|
setUniformValue(TEXTURE_UNIFORM, 0);
|
||||||
|
setUniformValue(TEXTURE_TRANSFORM_MATRIX_UNIFORM, textureTransformMatrix, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PainterShaderProgram::setVertexCoords(const GLfloat *vertices)
|
||||||
|
{
|
||||||
|
enableAttributeArray(PainterShaderProgram::VERTEX_COORDS_ATTR);
|
||||||
|
setAttributeArray(PainterShaderProgram::VERTEX_COORDS_ATTR, vertices, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PainterShaderProgram::setTextureCoords(const GLfloat *textureCoords)
|
||||||
|
{
|
||||||
|
enableAttributeArray(PainterShaderProgram::TEXTURE_COORDS_ATTR);
|
||||||
|
setAttributeArray(PainterShaderProgram::TEXTURE_COORDS_ATTR, textureCoords, 2);
|
||||||
|
m_mustDisableTexCoordsArray = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PainterShaderProgram::prepareForDraw()
|
||||||
|
{
|
||||||
|
assert(bind());
|
||||||
|
}
|
||||||
|
|
||||||
|
void PainterShaderProgram::drawTriangleStrip(int numVertices)
|
||||||
|
{
|
||||||
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, numVertices);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PainterShaderProgram::releaseFromDraw()
|
||||||
|
{
|
||||||
|
if(m_mustDisableTexCoordsArray) {
|
||||||
|
disableAttributeArray(PainterShaderProgram::TEXTURE_COORDS_ATTR);
|
||||||
|
m_mustDisableTexCoordsArray = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(m_mustDisableVertexArray) {
|
||||||
|
disableAttributeArray(PainterShaderProgram::VERTEX_COORDS_ATTR);
|
||||||
|
m_mustDisableVertexArray = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//release();
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010-2011 OTClient <https://github.com/edubart/otclient>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PAINTERSHADER_H
|
||||||
|
#define PAINTERSHADER_H
|
||||||
|
|
||||||
|
#include "shaderprogram.h"
|
||||||
|
|
||||||
|
class PainterShaderProgram : public ShaderProgram
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
VERTEX_COORDS_ATTR = 0,
|
||||||
|
TEXTURE_COORDS_ATTR = 1,
|
||||||
|
PROJECTION_MATRIX_UNIFORM = 0,
|
||||||
|
TEXTURE_TRANSFORM_MATRIX_UNIFORM = 1,
|
||||||
|
COLOR_UNIFORM = 2,
|
||||||
|
OPACITY_UNIFORM = 3,
|
||||||
|
TEXTURE_UNIFORM = 4
|
||||||
|
};
|
||||||
|
|
||||||
|
void setProjectionMatrix(GLfloat projectionMatrix[3][3]);
|
||||||
|
void setColor(const Color& color);
|
||||||
|
void setOpacity(GLfloat opacity);
|
||||||
|
void setTexture(const TexturePtr& texture);
|
||||||
|
void setVertexCoords(const GLfloat *vertices);
|
||||||
|
void setTextureCoords(const GLfloat *textureCoords);
|
||||||
|
|
||||||
|
void prepareForDraw();
|
||||||
|
void drawTriangleStrip(int numVertices);
|
||||||
|
void releaseFromDraw();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Boolean<false> m_mustDisableVertexArray;
|
||||||
|
Boolean<false> m_mustDisableTexCoordsArray;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,76 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010-2011 OTClient <https://github.com/edubart/otclient>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int VERTEX_COORDS_ATTR = 0;
|
||||||
|
static int TEXTURE_COORDS_ATTR = 1;
|
||||||
|
|
||||||
|
static int PROJECTION_MATRIX_UNIFORM = 0;
|
||||||
|
static int TEXTURE_TRANSFORM_MATRIX_UNIFORM = 1;
|
||||||
|
static int COLOR_UNIFORM = 2;
|
||||||
|
static int OPACITY_UNIFORM = 3;
|
||||||
|
static int TEXTURE_UNIFORM = 4;
|
||||||
|
|
||||||
|
static const char *glslMainVertexShader = "\n\
|
||||||
|
vec4 calculatePosition();\n\
|
||||||
|
void main() {\n\
|
||||||
|
gl_Position = calculatePosition();\n\
|
||||||
|
}\n";
|
||||||
|
|
||||||
|
static const char *glslMainWithTexCoordsVertexShader = "\n\
|
||||||
|
attribute vec2 textureCoord;\n\
|
||||||
|
uniform mat2 textureTransformMatrix;\n\
|
||||||
|
varying vec2 textureCoords;\n\
|
||||||
|
vec4 calculatePosition();\n\
|
||||||
|
void main()\n\
|
||||||
|
{\n\
|
||||||
|
gl_Position = calculatePosition();\n\
|
||||||
|
textureCoords = textureTransformMatrix * textureCoord;\n\
|
||||||
|
}\n";
|
||||||
|
|
||||||
|
static const char *glslPositionOnlyVertexShader = "\n\
|
||||||
|
attribute vec2 vertexCoord;\n\
|
||||||
|
uniform mat3 projectionMatrix;\n\
|
||||||
|
vec4 calculatePosition() {\n\
|
||||||
|
return vec4(projectionMatrix * vec3(vertexCoord.xy, 1), 1);\n\
|
||||||
|
}\n";
|
||||||
|
|
||||||
|
static const char *glslMainFragmentShader = "\n\
|
||||||
|
uniform float opacity;\n\
|
||||||
|
vec4 calculatePixel();\n\
|
||||||
|
void main()\n\
|
||||||
|
{\n\
|
||||||
|
gl_FragColor = calculatePixel() * opacity;\n\
|
||||||
|
}\n";
|
||||||
|
|
||||||
|
static const char *glslTextureSrcFragmentShader = "\n\
|
||||||
|
varying vec2 textureCoords;\n\
|
||||||
|
uniform vec4 color;\n\
|
||||||
|
uniform sampler2D texture;\n\
|
||||||
|
vec4 calculatePixel() {\n\
|
||||||
|
return texture2D(texture, textureCoords) * color;\n\
|
||||||
|
}\n";
|
||||||
|
|
||||||
|
static const char *glslSolidColorFragmentShader = "\n\
|
||||||
|
uniform vec4 color;\n\
|
||||||
|
vec4 calculatePixel() {\n\
|
||||||
|
return color;\n\
|
||||||
|
}\n";
|
|
@ -0,0 +1,75 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010-2011 OTClient <https://github.com/edubart/otclient>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "shader.h"
|
||||||
|
|
||||||
|
Shader::Shader(Shader::ShaderType shaderType)
|
||||||
|
{
|
||||||
|
m_shaderType = shaderType;
|
||||||
|
switch(shaderType) {
|
||||||
|
case Vertex:
|
||||||
|
m_shaderId = glCreateShader(GL_VERTEX_SHADER);
|
||||||
|
break;
|
||||||
|
case Fragment:
|
||||||
|
m_shaderId = glCreateShader(GL_FRAGMENT_SHADER);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!m_shaderId)
|
||||||
|
logFatal("Unable to create GL shader");
|
||||||
|
}
|
||||||
|
|
||||||
|
Shader::~Shader()
|
||||||
|
{
|
||||||
|
glDeleteShader(m_shaderId);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Shader::compileSourceCode(const std::string& sourceCode)
|
||||||
|
{
|
||||||
|
const char *c_source = sourceCode.c_str();
|
||||||
|
glShaderSource(m_shaderId, 1, &c_source, NULL);
|
||||||
|
glCompileShader(m_shaderId);
|
||||||
|
|
||||||
|
int res;
|
||||||
|
glGetShaderiv(m_shaderId, GL_COMPILE_STATUS, &res);
|
||||||
|
return (res == GL_TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Shader::compileSourceFile(const std::string& sourceFile)
|
||||||
|
{
|
||||||
|
std::ifstream fin(sourceFile);
|
||||||
|
std::string sourceCode((std::istreambuf_iterator<char>(fin)), std::istreambuf_iterator<char>());
|
||||||
|
return compileSourceCode(sourceCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Shader::log()
|
||||||
|
{
|
||||||
|
std::string infoLog;
|
||||||
|
GLint infoLogLength;
|
||||||
|
glGetShaderiv(m_shaderId, GL_INFO_LOG_LENGTH, &infoLogLength);
|
||||||
|
if(infoLogLength > 1) {
|
||||||
|
std::vector<char> buf(infoLogLength);
|
||||||
|
glGetShaderInfoLog(m_shaderId, infoLogLength-1, NULL, &buf[0]);
|
||||||
|
infoLog = &buf[0];
|
||||||
|
}
|
||||||
|
return infoLog;
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010-2011 OTClient <https://github.com/edubart/otclient>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SHADER_H
|
||||||
|
#define SHADER_H
|
||||||
|
|
||||||
|
#include "declarations.h"
|
||||||
|
|
||||||
|
class Shader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum ShaderType {
|
||||||
|
Vertex,
|
||||||
|
Fragment
|
||||||
|
};
|
||||||
|
|
||||||
|
Shader(ShaderType shaderType);
|
||||||
|
~Shader();
|
||||||
|
|
||||||
|
bool compileSourceCode(const std::string& sourceCode);
|
||||||
|
bool compileSourceFile(const std::string& sourceFile);
|
||||||
|
std::string log();
|
||||||
|
|
||||||
|
GLuint getShaderId() { return m_shaderId; }
|
||||||
|
ShaderType getShaderType() { return m_shaderType; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
GLuint m_shaderId;
|
||||||
|
ShaderType m_shaderType;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,144 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010-2011 OTClient <https://github.com/edubart/otclient>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "shaderprogram.h"
|
||||||
|
|
||||||
|
GLuint ShaderProgram::m_currentProgram = 0;
|
||||||
|
|
||||||
|
ShaderProgram::ShaderProgram()
|
||||||
|
{
|
||||||
|
m_linked = false;
|
||||||
|
m_programId = glCreateProgram();
|
||||||
|
m_uniformLocations.fill(-1);
|
||||||
|
if(!m_programId)
|
||||||
|
logFatal("Unable to create GL shader program");
|
||||||
|
}
|
||||||
|
|
||||||
|
ShaderProgram::~ShaderProgram()
|
||||||
|
{
|
||||||
|
glDeleteProgram(m_programId);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ShaderProgram::addShader(const ShaderPtr& shader) {
|
||||||
|
glAttachShader(m_programId, shader->getShaderId());
|
||||||
|
m_linked = false;
|
||||||
|
m_shaders.push_back(shader);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ShaderProgram::addShaderFromSourceCode(Shader::ShaderType shaderType, const std::string& sourceCode) {
|
||||||
|
ShaderPtr shader(new Shader(shaderType));
|
||||||
|
if(!shader->compileSourceCode(sourceCode)) {
|
||||||
|
logError("failed to compile shader: ", shader->log());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return addShader(shader);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ShaderProgram::addShaderFromSourceFile(Shader::ShaderType shaderType, const std::string& sourceFile) {
|
||||||
|
ShaderPtr shader(new Shader(shaderType));
|
||||||
|
if(!shader->compileSourceFile(sourceFile)) {
|
||||||
|
logError("failed to compile shader: ", shader->log());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return addShader(shader);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShaderProgram::removeShader(const ShaderPtr& shader)
|
||||||
|
{
|
||||||
|
auto it = std::find(m_shaders.begin(), m_shaders.end(), shader);
|
||||||
|
if(it == m_shaders.end())
|
||||||
|
return;
|
||||||
|
|
||||||
|
glDetachShader(m_programId, shader->getShaderId());
|
||||||
|
m_shaders.erase(it);
|
||||||
|
m_linked = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShaderProgram::removeAllShaders()
|
||||||
|
{
|
||||||
|
while(!m_shaders.empty())
|
||||||
|
removeShader(m_shaders.front());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ShaderProgram::link()
|
||||||
|
{
|
||||||
|
if(m_linked)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
glLinkProgram(m_programId);
|
||||||
|
|
||||||
|
GLint value;
|
||||||
|
glGetProgramiv(m_programId, GL_LINK_STATUS, &value);
|
||||||
|
m_linked = (value != GL_FALSE);
|
||||||
|
|
||||||
|
if(!m_linked)
|
||||||
|
logTraceWarning(log());
|
||||||
|
return m_linked;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ShaderProgram::bind()
|
||||||
|
{
|
||||||
|
if(m_currentProgram != m_programId) {
|
||||||
|
if(!m_linked && !link())
|
||||||
|
return false;
|
||||||
|
glUseProgram(m_programId);
|
||||||
|
m_currentProgram = m_programId;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShaderProgram::release()
|
||||||
|
{
|
||||||
|
m_currentProgram = 0;
|
||||||
|
glUseProgram(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ShaderProgram::log()
|
||||||
|
{
|
||||||
|
std::string infoLog;
|
||||||
|
GLint infoLogLength;
|
||||||
|
glGetProgramiv(m_programId, GL_INFO_LOG_LENGTH, &infoLogLength);
|
||||||
|
if(infoLogLength > 1) {
|
||||||
|
std::vector<char> buf(infoLogLength);
|
||||||
|
glGetShaderInfoLog(m_programId, infoLogLength-1, NULL, &buf[0]);
|
||||||
|
infoLog = &buf[0];
|
||||||
|
}
|
||||||
|
return infoLog;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ShaderProgram::getAttributeLocation(const char* name)
|
||||||
|
{
|
||||||
|
return glGetAttribLocation(m_programId, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShaderProgram::bindAttributeLocation(int location, const char* name)
|
||||||
|
{
|
||||||
|
return glBindAttribLocation(m_programId, location, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShaderProgram::bindUniformLocation(int location, const char* name)
|
||||||
|
{
|
||||||
|
assert(m_linked);
|
||||||
|
assert(location >= 0 && location < 10);
|
||||||
|
m_uniformLocations[location] = glGetUniformLocation(m_programId, name);
|
||||||
|
}
|
|
@ -0,0 +1,93 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010-2011 OTClient <https://github.com/edubart/otclient>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SHADERPROGRAM_H
|
||||||
|
#define SHADERPROGRAM_H
|
||||||
|
|
||||||
|
#include "shader.h"
|
||||||
|
|
||||||
|
class ShaderProgram
|
||||||
|
{
|
||||||
|
enum {
|
||||||
|
MAX_UNIFORM_LOCATIONS = 10
|
||||||
|
};
|
||||||
|
public:
|
||||||
|
ShaderProgram();
|
||||||
|
~ShaderProgram();
|
||||||
|
|
||||||
|
bool addShader(const ShaderPtr& shader);
|
||||||
|
bool addShaderFromSourceCode(Shader::ShaderType shaderType, const std::string& sourceCode);
|
||||||
|
bool addShaderFromSourceFile(Shader::ShaderType shaderType, const std::string& sourceFile);
|
||||||
|
void removeShader(const ShaderPtr& shader);
|
||||||
|
void removeAllShaders();
|
||||||
|
bool link();
|
||||||
|
bool bind();
|
||||||
|
void release();
|
||||||
|
std::string log();
|
||||||
|
|
||||||
|
void disableAttributeArray(int location) { glDisableVertexAttribArray(location); }
|
||||||
|
void enableAttributeArray(int location) { glEnableVertexAttribArray(location); }
|
||||||
|
void disableAttributeArray(const char *name) { glDisableVertexAttribArray(getAttributeLocation(name)); }
|
||||||
|
void enableAttributeArray(const char *name) { glEnableVertexAttribArray(getAttributeLocation(name)); }
|
||||||
|
|
||||||
|
int getAttributeLocation(const char *name);
|
||||||
|
void bindAttributeLocation(int location, const char *name);
|
||||||
|
void bindUniformLocation(int location, const char *name);
|
||||||
|
|
||||||
|
void setAttributeArray(int location, const GLfloat *values, int size, int stride = 0) { glVertexAttribPointer(location, size, GL_FLOAT, GL_FALSE, stride, values); }
|
||||||
|
void setAttributeValue(int location, GLfloat value) { glVertexAttrib1f(location, value); }
|
||||||
|
void setAttributeValue(int location, GLfloat x, GLfloat y) { glVertexAttrib2f(location, x, y); }
|
||||||
|
void setAttributeValue(int location, GLfloat x, GLfloat y, GLfloat z) { glVertexAttrib3f(location, x, y, z); }
|
||||||
|
void setAttributeArray(const char *name, const GLfloat *values, int size, int stride = 0) { glVertexAttribPointer(getAttributeLocation(name), size, GL_FLOAT, GL_FALSE, stride, values); }
|
||||||
|
void setAttributeValue(const char *name, GLfloat value) { glVertexAttrib1f(getAttributeLocation(name), value); }
|
||||||
|
void setAttributeValue(const char *name, GLfloat x, GLfloat y) { glVertexAttrib2f(getAttributeLocation(name), x, y); }
|
||||||
|
void setAttributeValue(const char *name, GLfloat x, GLfloat y, GLfloat z) { glVertexAttrib3f(getAttributeLocation(name), x, y, z); }
|
||||||
|
|
||||||
|
void setUniformValue(int location, GLint value) { glUniform1i(m_uniformLocations[location], value); }
|
||||||
|
void setUniformValue(int location, GLfloat value) { glUniform1f(m_uniformLocations[location], value); }
|
||||||
|
void setUniformValue(int location, GLfloat x, GLfloat y) { glUniform2f(m_uniformLocations[location], x, y); }
|
||||||
|
void setUniformValue(int location, GLfloat x, GLfloat y, GLfloat z) { glUniform3f(m_uniformLocations[location], x, y, z); }
|
||||||
|
void setUniformValue(int location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { glUniform4f(m_uniformLocations[location], x, y, z, w); }
|
||||||
|
void setUniformValue(int location, GLfloat mat2[2][2], bool transpose) { glUniformMatrix2fv(m_uniformLocations[location], 1, transpose ? GL_TRUE : GL_FALSE, (GLfloat *)mat2); }
|
||||||
|
void setUniformValue(int location, GLfloat mat3[3][3], bool transpose) { glUniformMatrix3fv(m_uniformLocations[location], 1, transpose ? GL_TRUE : GL_FALSE, (GLfloat *)mat3); }
|
||||||
|
void setUniformValue(const char *name, GLint value) { glUniform1i(glGetUniformLocation(m_programId, name), value); }
|
||||||
|
void setUniformValue(const char *name, GLfloat value) { glUniform1f(glGetUniformLocation(m_programId, name), value); }
|
||||||
|
void setUniformValue(const char *name, GLfloat x, GLfloat y) { glUniform2f(glGetUniformLocation(m_programId, name), x, y); }
|
||||||
|
void setUniformValue(const char *name, GLfloat x, GLfloat y, GLfloat z) { glUniform3f(glGetUniformLocation(m_programId, name), x, y, z); }
|
||||||
|
void setUniformValue(const char *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { glUniform4f(glGetUniformLocation(m_programId, name), x, y, z, w); }
|
||||||
|
void setUniformValue(const char *name, GLfloat mat2[2][2], bool transpose = false) { glUniformMatrix2fv(glGetUniformLocation(m_programId, name), 1, transpose ? GL_TRUE : GL_FALSE, (GLfloat *)mat2); }
|
||||||
|
void setUniformValue(const char *name, GLfloat mat3[3][3], bool transpose = false) { glUniformMatrix3fv(glGetUniformLocation(m_programId, name), 1, transpose ? GL_TRUE : GL_FALSE, (GLfloat *)mat3); }
|
||||||
|
|
||||||
|
// Point, PointF, Color, Size, SizeF,
|
||||||
|
bool isLinked() { return m_linked; }
|
||||||
|
GLuint getProgramId() { return m_programId; }
|
||||||
|
ShaderList getShaders() { return m_shaders; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_linked;
|
||||||
|
GLuint m_programId;
|
||||||
|
static GLuint m_currentProgram;
|
||||||
|
ShaderList m_shaders;
|
||||||
|
std::array<GLint, MAX_UNIFORM_LOCATIONS> m_uniformLocations;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -36,7 +36,6 @@ Texture::Texture(int width, int height, int channels, uchar *pixels)
|
||||||
|
|
||||||
Texture::~Texture()
|
Texture::~Texture()
|
||||||
{
|
{
|
||||||
assert(!g_graphics.isDrawing());
|
|
||||||
// free texture from gl memory
|
// free texture from gl memory
|
||||||
if(m_textureId > 0)
|
if(m_textureId > 0)
|
||||||
glDeleteTextures(1, &m_textureId);
|
glDeleteTextures(1, &m_textureId);
|
||||||
|
@ -44,9 +43,7 @@ Texture::~Texture()
|
||||||
|
|
||||||
uint Texture::internalLoadGLTexture(uchar *pixels, int channels, int width, int height)
|
uint Texture::internalLoadGLTexture(uchar *pixels, int channels, int width, int height)
|
||||||
{
|
{
|
||||||
assert(!g_graphics.isDrawing());
|
m_size.resize(width, height);
|
||||||
|
|
||||||
m_size.setSize(width, height);
|
|
||||||
|
|
||||||
// gets max texture size supported by the driver
|
// gets max texture size supported by the driver
|
||||||
static GLint maxTexSize = -1;
|
static GLint maxTexSize = -1;
|
||||||
|
@ -70,7 +67,7 @@ uint Texture::internalLoadGLTexture(uchar *pixels, int channels, int width, int
|
||||||
std::vector<uint8> tmp;
|
std::vector<uint8> tmp;
|
||||||
|
|
||||||
// old opengl drivers only accept power of two dimensions
|
// old opengl drivers only accept power of two dimensions
|
||||||
//if(!g_graphics.isExtensionSupported("GL_ARB_texture_non_power_of_two")) {
|
//if(!g_painter.isExtensionSupported("GL_ARB_texture_non_power_of_two")) {
|
||||||
int glWidth = 1;
|
int glWidth = 1;
|
||||||
while(glWidth < width)
|
while(glWidth < width)
|
||||||
glWidth = glWidth << 1;
|
glWidth = glWidth << 1;
|
||||||
|
@ -88,7 +85,7 @@ uint Texture::internalLoadGLTexture(uchar *pixels, int channels, int width, int
|
||||||
pixels = &tmp[0];
|
pixels = &tmp[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
m_glSize.setSize(glWidth, glHeight);
|
m_glSize.resize(glWidth, glHeight);
|
||||||
//} else
|
//} else
|
||||||
// m_glSize = m_size;
|
// m_glSize = m_size;
|
||||||
|
|
||||||
|
@ -110,7 +107,7 @@ uint Texture::internalLoadGLTexture(uchar *pixels, int channels, int width, int
|
||||||
}
|
}
|
||||||
|
|
||||||
// load pixels into gl memory
|
// load pixels into gl memory
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, channels, m_glSize.width(), m_glSize.height(), 0, format, GL_UNSIGNED_BYTE, pixels);
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_glSize.width(), m_glSize.height(), 0, format, GL_UNSIGNED_BYTE, pixels);
|
||||||
|
|
||||||
// disable texture border
|
// disable texture border
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
|
@ -119,7 +116,6 @@ uint Texture::internalLoadGLTexture(uchar *pixels, int channels, int width, int
|
||||||
// nearest filtering (non smooth)
|
// nearest filtering (non smooth)
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,22 +37,22 @@ public:
|
||||||
virtual void enableBilinearFilter();
|
virtual void enableBilinearFilter();
|
||||||
|
|
||||||
/// Get OpenGL texture id
|
/// Get OpenGL texture id
|
||||||
uint getId() const { return m_textureId; }
|
GLuint getId() { return m_textureId; }
|
||||||
|
|
||||||
/// Copy pixels from OpenGL texture
|
/// Copy pixels from OpenGL texture
|
||||||
std::vector<uint8> getPixels();
|
std::vector<uint8> getPixels();
|
||||||
|
|
||||||
int getWidth() const { return m_size.width(); }
|
int getWidth() { return m_size.width(); }
|
||||||
int getHeight() const { return m_size.height(); }
|
int getHeight() { return m_size.height(); }
|
||||||
const Size& getSize() const { return m_size; }
|
const Size& getSize() { return m_size; }
|
||||||
const Size& getGlSize() const { return m_glSize; }
|
const Size& getGlSize() { return m_glSize; }
|
||||||
|
|
||||||
bool isEmpty() const { return m_textureId == 0; }
|
bool isEmpty() const { return m_textureId == 0; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
uint internalLoadGLTexture(uchar* pixels, int channels, int w, int h);
|
GLuint internalLoadGLTexture(uchar* pixels, int channels, int w, int h);
|
||||||
|
|
||||||
uint m_textureId;
|
GLuint m_textureId;
|
||||||
Size m_size;
|
Size m_size;
|
||||||
Size m_glSize;
|
Size m_glSize;
|
||||||
};
|
};
|
||||||
|
|
|
@ -36,73 +36,110 @@ void Application::registerLuaFunctions()
|
||||||
// UIWidget
|
// UIWidget
|
||||||
g_lua.registerClass<UIWidget>();
|
g_lua.registerClass<UIWidget>();
|
||||||
g_lua.bindClassStaticFunction<UIWidget>("create", &UIWidget::create<UIWidget>);
|
g_lua.bindClassStaticFunction<UIWidget>("create", &UIWidget::create<UIWidget>);
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("getId", &UIWidget::getId);
|
g_lua.bindClassMemberFunction<UIWidget>("destroy", &UIWidget::destroy);
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("setId", &UIWidget::setId);
|
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("isEnabled", &UIWidget::isEnabled);
|
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("setEnabled", &UIWidget::setEnabled);
|
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("isExplicitlyVisible", &UIWidget::isExplicitlyVisible);
|
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("setVisible", &UIWidget::setVisible);
|
g_lua.bindClassMemberFunction<UIWidget>("setVisible", &UIWidget::setVisible);
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("getWidth", &UIWidget::getWidth);
|
g_lua.bindClassMemberFunction<UIWidget>("setEnabled", &UIWidget::setEnabled);
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("setWidth", &UIWidget::setWidth);
|
g_lua.bindClassMemberFunction<UIWidget>("setPressed", &UIWidget::setPressed);
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("getHeight", &UIWidget::getHeight);
|
g_lua.bindClassMemberFunction<UIWidget>("setId", &UIWidget::setId);
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("setHeight", &UIWidget::setHeight);
|
g_lua.bindClassMemberFunction<UIWidget>("setFocusable", &UIWidget::setFocusable);
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("getSize", &UIWidget::getSize);
|
g_lua.bindClassMemberFunction<UIWidget>("setPhantom", &UIWidget::setPhantom);
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("setSize", &UIWidget::resize);
|
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("getPosition", &UIWidget::getPosition);
|
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("getX", &UIWidget::getX);
|
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("getY", &UIWidget::getY);
|
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("moveTo", &UIWidget::moveTo);
|
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("moveChildToIndex", &UIWidget::moveChildToIndex);
|
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("getParent", &UIWidget::getParent);
|
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("setParent", &UIWidget::setParent);
|
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("getBackgroundColor", &UIWidget::getBackgroundColor);
|
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("setBackgroundColor", &UIWidget::setBackgroundColor);
|
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("getForegroundColor", &UIWidget::getForegroundColor);
|
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("setForegroundColor", &UIWidget::setForegroundColor);
|
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("getOpacity", &UIWidget::getOpacity);
|
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("setOpacity", &UIWidget::setOpacity);
|
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("setStyle", &UIWidget::setStyle);
|
g_lua.bindClassMemberFunction<UIWidget>("setStyle", &UIWidget::setStyle);
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("applyStyle", &UIWidget::applyStyle);
|
g_lua.bindClassMemberFunction<UIWidget>("setStyleFromNode", &UIWidget::setStyleFromNode);
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("getStyle", &UIWidget::getStyle);
|
//g_lua.bindClassMemberFunction<UIWidget>("setLayout", &UIWidget::setLayout);
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("getMarginTop", &UIWidget::getMarginTop);
|
g_lua.bindClassMemberFunction<UIWidget>("setParent", &UIWidget::setParent);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("setRect", &UIWidget::setRect);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("setX", &UIWidget::setX);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("setY", &UIWidget::setY);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("setWidth", &UIWidget::setWidth);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("setHeight", &UIWidget::setHeight);
|
||||||
|
//g_lua.bindClassMemberFunction<UIWidget>("setImage", &UIWidget::setImage);
|
||||||
|
//g_lua.bindClassMemberFunction<UIWidget>("setFont", &UIWidget::setFont);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("setOpacity", &UIWidget::setOpacity);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("setBackgroundColor", &UIWidget::setBackgroundColor);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("setForegroundColor", &UIWidget::setForegroundColor);
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("setMarginTop", &UIWidget::setMarginTop);
|
g_lua.bindClassMemberFunction<UIWidget>("setMarginTop", &UIWidget::setMarginTop);
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("getMarginBottom", &UIWidget::getMarginBottom);
|
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("setMarginBottom", &UIWidget::setMarginBottom);
|
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("getMarginLeft", &UIWidget::getMarginLeft);
|
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("setMarginLeft", &UIWidget::setMarginLeft);
|
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("getMarginRight", &UIWidget::getMarginRight);
|
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("setMarginRight", &UIWidget::setMarginRight);
|
g_lua.bindClassMemberFunction<UIWidget>("setMarginRight", &UIWidget::setMarginRight);
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("isVisible", &UIWidget::isVisible);
|
g_lua.bindClassMemberFunction<UIWidget>("setMarginBottom", &UIWidget::setMarginBottom);
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("isHidden", &UIWidget::isHidden);
|
g_lua.bindClassMemberFunction<UIWidget>("setMarginLeft", &UIWidget::setMarginLeft);
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("isHovered", &UIWidget::isHovered);
|
g_lua.bindClassMemberFunction<UIWidget>("setSizeFixed", &UIWidget::setSizeFixed);
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("isFocused", &UIWidget::isFocused);
|
g_lua.bindClassMemberFunction<UIWidget>("setLastFocusReason", &UIWidget::setLastFocusReason);
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("isPressed", &UIWidget::isPressed);
|
g_lua.bindClassMemberFunction<UIWidget>("resize", &UIWidget::resize);
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("isEnabled", &UIWidget::isEnabled);
|
g_lua.bindClassMemberFunction<UIWidget>("moveTo", &UIWidget::moveTo);
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("isDisabled", &UIWidget::isDisabled);
|
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("isActive", &UIWidget::isActive);
|
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("hide", &UIWidget::hide);
|
g_lua.bindClassMemberFunction<UIWidget>("hide", &UIWidget::hide);
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("show", &UIWidget::show);
|
g_lua.bindClassMemberFunction<UIWidget>("show", &UIWidget::show);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("disable", &UIWidget::disable);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("enable", &UIWidget::enable);
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("lock", &UIWidget::lock);
|
g_lua.bindClassMemberFunction<UIWidget>("lock", &UIWidget::lock);
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("unlock", &UIWidget::unlock);
|
g_lua.bindClassMemberFunction<UIWidget>("unlock", &UIWidget::unlock);
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("focus", &UIWidget::focus);
|
g_lua.bindClassMemberFunction<UIWidget>("focus", &UIWidget::focus);
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("getChildren", &UIWidget::getChildren);
|
g_lua.bindClassMemberFunction<UIWidget>("isActive", &UIWidget::isActive);
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("recursiveGetChildById", &UIWidget::recursiveGetChildById);
|
g_lua.bindClassMemberFunction<UIWidget>("isEnabled", &UIWidget::isEnabled);
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("getChildById", &UIWidget::getChildById);
|
g_lua.bindClassMemberFunction<UIWidget>("isDisabled", &UIWidget::isDisabled);
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("getChildByIndex", &UIWidget::getChildByIndex);
|
g_lua.bindClassMemberFunction<UIWidget>("isFocused", &UIWidget::isFocused);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("isHovered", &UIWidget::isHovered);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("isPressed", &UIWidget::isPressed);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("isVisible", &UIWidget::isVisible);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("isHidden", &UIWidget::isHidden);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("isExplicitlyEnabled", &UIWidget::isExplicitlyEnabled);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("isExplicitlyVisible", &UIWidget::isExplicitlyVisible);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("isFocusable", &UIWidget::isFocusable);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("isPhantom", &UIWidget::isPhantom);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("isSizeFixed", &UIWidget::isSizeFixed);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("hasChildren", &UIWidget::hasChildren);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("hasChild", &UIWidget::hasChild);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("getId", &UIWidget::getId);
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("getChildCount", &UIWidget::getChildCount);
|
g_lua.bindClassMemberFunction<UIWidget>("getChildCount", &UIWidget::getChildCount);
|
||||||
|
//g_lua.bindClassMemberFunction<UIWidget>("getLayout", &UIWidget::getLayout);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("getParent", &UIWidget::getParent);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("getRootParent", &UIWidget::getRootParent);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("getPosition", &UIWidget::getPosition);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("getSize", &UIWidget::getSize);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("getRect", &UIWidget::getRect);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("getX", &UIWidget::getX);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("getY", &UIWidget::getY);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("getWidth", &UIWidget::getWidth);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("getHeight", &UIWidget::getHeight);
|
||||||
|
//g_lua.bindClassMemberFunction<UIWidget>("getImage", &UIWidget::getImage);
|
||||||
|
//g_lua.bindClassMemberFunction<UIWidget>("getFont", &UIWidget::getFont);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("getForegroundColor", &UIWidget::getForegroundColor);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("getBackgroundColor", &UIWidget::getBackgroundColor);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("getOpacity", &UIWidget::getOpacity);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("getMarginTop", &UIWidget::getMarginTop);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("getMarginRight", &UIWidget::getMarginRight);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("getMarginBottom", &UIWidget::getMarginBottom);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("getMarginLeft", &UIWidget::getMarginLeft);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("getLastFocusReason", &UIWidget::getLastFocusReason);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("getStyle", &UIWidget::getStyle);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("getChildren", &UIWidget::getChildren);
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("getFocusedChild", &UIWidget::getFocusedChild);
|
g_lua.bindClassMemberFunction<UIWidget>("getFocusedChild", &UIWidget::getFocusedChild);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("getChildAfter", &UIWidget::getChildAfter);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("getChildBefore", &UIWidget::getChildBefore);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("getChildById", &UIWidget::getChildById);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("getChildByPos", &UIWidget::getChildByPos);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("getChildByIndex", &UIWidget::getChildByIndex);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("recursiveGetChildById", &UIWidget::recursiveGetChildById);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("recursiveGetChildByPos", &UIWidget::recursiveGetChildByPos);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("backwardsGetWidgetById", &UIWidget::backwardsGetWidgetById);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("addChild", &UIWidget::addChild);
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("insertChild", &UIWidget::insertChild);
|
g_lua.bindClassMemberFunction<UIWidget>("insertChild", &UIWidget::insertChild);
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("removeChild", &UIWidget::removeChild);
|
g_lua.bindClassMemberFunction<UIWidget>("removeChild", &UIWidget::removeChild);
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("hasChild", &UIWidget::hasChild);
|
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("addChild", &UIWidget::addChild);
|
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("focusChild", &UIWidget::focusChild);
|
g_lua.bindClassMemberFunction<UIWidget>("focusChild", &UIWidget::focusChild);
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("focusNextChild", &UIWidget::focusNextChild);
|
g_lua.bindClassMemberFunction<UIWidget>("focusNextChild", &UIWidget::focusNextChild);
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("focusPreviousChild", &UIWidget::focusPreviousChild);
|
g_lua.bindClassMemberFunction<UIWidget>("focusPreviousChild", &UIWidget::focusPreviousChild);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("moveChildToTop", &UIWidget::moveChildToTop);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("moveChildToIndex", &UIWidget::moveChildToIndex);
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("lockChild", &UIWidget::lockChild);
|
g_lua.bindClassMemberFunction<UIWidget>("lockChild", &UIWidget::lockChild);
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("unlockChild", &UIWidget::unlockChild);
|
g_lua.bindClassMemberFunction<UIWidget>("unlockChild", &UIWidget::unlockChild);
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("updateLayout", &UIWidget::updateLayout);
|
g_lua.bindClassMemberFunction<UIWidget>("isChildLocked", &UIWidget::isChildLocked);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("getChildIndex", &UIWidget::getChildIndex);
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("updateParentLayout", &UIWidget::updateParentLayout);
|
g_lua.bindClassMemberFunction<UIWidget>("updateParentLayout", &UIWidget::updateParentLayout);
|
||||||
g_lua.bindClassMemberFunction<UIWidget>("destroy", &UIWidget::destroy);
|
g_lua.bindClassMemberFunction<UIWidget>("updateLayout", &UIWidget::updateLayout);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("updateStates", &UIWidget::updateStates);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("updateState", &UIWidget::updateState);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("setState", &UIWidget::setState);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("hasState", &UIWidget::hasState);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("updateStyle", &UIWidget::updateStyle);
|
||||||
|
g_lua.bindClassMemberFunction<UIWidget>("applyStyle", &UIWidget::applyStyle);
|
||||||
|
|
||||||
// UILabel
|
// UILabel
|
||||||
g_lua.registerClass<UILabel, UIWidget>();
|
g_lua.registerClass<UILabel, UIWidget>();
|
||||||
|
@ -175,12 +212,27 @@ void Application::registerLuaFunctions()
|
||||||
g_lua.bindClassStaticFunction<Logger>("fireOldMessages", std::bind(&Logger::fireOldMessages, &g_logger));
|
g_lua.bindClassStaticFunction<Logger>("fireOldMessages", std::bind(&Logger::fireOldMessages, &g_logger));
|
||||||
g_lua.bindClassStaticFunction<Logger>("setOnLog", std::bind(&Logger::setOnLog, &g_logger, _1));
|
g_lua.bindClassStaticFunction<Logger>("setOnLog", std::bind(&Logger::setOnLog, &g_logger, _1));
|
||||||
|
|
||||||
|
// Font
|
||||||
|
|
||||||
|
/*
|
||||||
|
// FontManager
|
||||||
|
g_lua.registerStaticClass("g_fonts");
|
||||||
|
g_lua.bindClassStaticFunction("g_fonts", "releaseFonts", std::bind(&FontManager::releaseFonts, &g_fonts));
|
||||||
|
g_lua.bindClassStaticFunction("g_fonts", "importFont", std::bind(&FontManager::importFont, &g_fonts, _1));
|
||||||
|
g_lua.bindClassStaticFunction("g_fonts", "fontExists", std::bind(&FontManager::fontExists, &g_fonts, _1));
|
||||||
|
g_lua.bindClassStaticFunction("g_fonts", "getFont", std::bind(&FontManager::getFont, &g_fonts, _1));
|
||||||
|
g_lua.bindClassStaticFunction("g_fonts", "getDefaultFont", std::bind(&FontManager::getDefaultFont, &g_fonts));
|
||||||
|
g_lua.bindClassStaticFunction("g_fonts", "setDefaultFont", std::bind(&FontManager::setDefaultFont, &g_fonts, _1));
|
||||||
|
*/
|
||||||
|
|
||||||
|
g_lua.registerStaticClass("g_dispatcher");
|
||||||
|
g_lua.bindClassStaticFunction("g_dispatcher", "addEvent", std::bind(&EventDispatcher::addEvent, &g_dispatcher, _1, _2));
|
||||||
|
g_lua.bindClassStaticFunction("g_dispatcher", "scheduleEvent", std::bind(&EventDispatcher::scheduleEvent, &g_dispatcher, _1, _2));
|
||||||
|
|
||||||
// global functions
|
// global functions
|
||||||
g_lua.bindGlobalFunction("importFont", std::bind(&FontManager::importFont, &g_fonts, _1));
|
g_lua.bindGlobalFunction("importFont", std::bind(&FontManager::importFont, &g_fonts, _1));
|
||||||
g_lua.bindGlobalFunction("importStyles", std::bind(&UIManager::importStyles, &g_ui, _1));
|
g_lua.bindGlobalFunction("importStyles", std::bind(&UIManager::importStyles, &g_ui, _1));
|
||||||
g_lua.bindGlobalFunction("setDefaultFont", std::bind(&FontManager::setDefaultFont, &g_fonts, _1));
|
g_lua.bindGlobalFunction("setDefaultFont", std::bind(&FontManager::setDefaultFont, &g_fonts, _1));
|
||||||
g_lua.bindGlobalFunction("loadUI", std::bind(&UIManager::loadUI, &g_ui, _1, _2));
|
g_lua.bindGlobalFunction("loadUI", std::bind(&UIManager::loadUI, &g_ui, _1, _2));
|
||||||
g_lua.bindGlobalFunction("getRootWidget", std::bind(&UIManager::getRootWidget, &g_ui));
|
g_lua.bindGlobalFunction("getRootWidget", std::bind(&UIManager::getRootWidget, &g_ui));
|
||||||
g_lua.bindGlobalFunction("addEvent", std::bind(&EventDispatcher::addEvent, &g_dispatcher, _1, false));
|
|
||||||
g_lua.bindGlobalFunction("scheduleEvent", std::bind(&EventDispatcher::scheduleEvent, &g_dispatcher, _1, _2));
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -340,7 +340,7 @@ void X11Window::internalChooseGLVisual()
|
||||||
m_rootWindow = RootWindow(m_display, m_visual->screen);
|
m_rootWindow = RootWindow(m_display, m_visual->screen);
|
||||||
#else
|
#else
|
||||||
static int attrList[] = {
|
static int attrList[] = {
|
||||||
EGL_BUFFER_SIZE, 16,
|
EGL_BUFFER_SIZE, 24,
|
||||||
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
|
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
|
||||||
EGL_NONE
|
EGL_NONE
|
||||||
};
|
};
|
||||||
|
|
|
@ -40,9 +40,9 @@ void UIButton::render()
|
||||||
|
|
||||||
if(m_icon) {
|
if(m_icon) {
|
||||||
Rect iconRect;
|
Rect iconRect;
|
||||||
iconRect.setSize(m_icon->getSize());
|
iconRect.resize(m_icon->getSize());
|
||||||
iconRect.moveCenter(m_rect.center());
|
iconRect.moveCenter(m_rect.center());
|
||||||
g_graphics.drawTexturedRect(iconRect, m_icon);
|
g_painter.drawTexturedRect(iconRect, m_icon);
|
||||||
}
|
}
|
||||||
|
|
||||||
Rect textRect = m_rect;
|
Rect textRect = m_rect;
|
||||||
|
|
|
@ -38,10 +38,10 @@ void UICheckBox::render()
|
||||||
{
|
{
|
||||||
if(m_image) {
|
if(m_image) {
|
||||||
Rect boxRect;
|
Rect boxRect;
|
||||||
boxRect.setSize(m_boxSize);
|
boxRect.resize(m_boxSize);
|
||||||
boxRect.moveLeft(m_rect.left());
|
boxRect.moveLeft(m_rect.left());
|
||||||
boxRect.moveVerticalCenter(m_rect.verticalCenter());
|
boxRect.moveVerticalCenter(m_rect.verticalCenter());
|
||||||
g_graphics.bindColor(m_backgroundColor);
|
g_painter.setColor(m_backgroundColor);
|
||||||
m_image->draw(boxRect);
|
m_image->draw(boxRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,9 +47,9 @@ void UILineEdit::render()
|
||||||
int textLength = m_text.length();
|
int textLength = m_text.length();
|
||||||
const TexturePtr& texture = m_font->getTexture();
|
const TexturePtr& texture = m_font->getTexture();
|
||||||
|
|
||||||
g_graphics.bindColor(m_foregroundColor);
|
g_painter.setColor(m_foregroundColor);
|
||||||
for(int i=0;i<textLength;++i)
|
for(int i=0;i<textLength;++i)
|
||||||
g_graphics.drawTexturedRect(m_glyphsCoords[i], texture, m_glyphsTexCoords[i]);
|
g_painter.drawTexturedRect(m_glyphsCoords[i], texture, m_glyphsTexCoords[i]);
|
||||||
|
|
||||||
// render cursor
|
// render cursor
|
||||||
if(isExplicitlyEnabled() && (isActive() || m_alwaysActive) && m_cursorPos >= 0) {
|
if(isExplicitlyEnabled() && (isActive() || m_alwaysActive) && m_cursorPos >= 0) {
|
||||||
|
@ -63,7 +63,7 @@ void UILineEdit::render()
|
||||||
cursorRect = Rect(m_drawArea.left()-1, m_drawArea.top(), 1, m_font->getGlyphHeight());
|
cursorRect = Rect(m_drawArea.left()-1, m_drawArea.top(), 1, m_font->getGlyphHeight());
|
||||||
else
|
else
|
||||||
cursorRect = Rect(m_glyphsCoords[m_cursorPos-1].right(), m_glyphsCoords[m_cursorPos-1].top(), 1, m_font->getGlyphHeight());
|
cursorRect = Rect(m_glyphsCoords[m_cursorPos-1].right(), m_glyphsCoords[m_cursorPos-1].top(), 1, m_font->getGlyphHeight());
|
||||||
g_graphics.drawFilledRect(cursorRect);
|
g_painter.drawFilledRect(cursorRect);
|
||||||
} else if(g_clock.ticksElapsed(m_cursorTicks) >= 2*delay) {
|
} else if(g_clock.ticksElapsed(m_cursorTicks) >= 2*delay) {
|
||||||
m_cursorTicks = g_clock.ticks();
|
m_cursorTicks = g_clock.ticks();
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
#include <framework/otml/otml.h>
|
#include <framework/otml/otml.h>
|
||||||
#include <framework/graphics/graphics.h>
|
#include <framework/graphics/graphics.h>
|
||||||
|
#include <framework/platform/platformwindow.h>
|
||||||
|
|
||||||
UIManager g_ui;
|
UIManager g_ui;
|
||||||
|
|
||||||
|
@ -33,7 +34,7 @@ void UIManager::init()
|
||||||
// creates root widget
|
// creates root widget
|
||||||
m_rootWidget = UIWidget::create<UIWidget>();
|
m_rootWidget = UIWidget::create<UIWidget>();
|
||||||
m_rootWidget->setId("root");
|
m_rootWidget->setId("root");
|
||||||
m_rootWidget->resize(g_graphics.getScreenSize());
|
m_rootWidget->resize(g_window.getSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
void UIManager::terminate()
|
void UIManager::terminate()
|
||||||
|
@ -50,7 +51,7 @@ void UIManager::render()
|
||||||
|
|
||||||
void UIManager::resize(const Size& size)
|
void UIManager::resize(const Size& size)
|
||||||
{
|
{
|
||||||
m_rootWidget->resize(g_graphics.getScreenSize());
|
m_rootWidget->resize(g_window.getSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
void UIManager::inputEvent(const InputEvent& event)
|
void UIManager::inputEvent(const InputEvent& event)
|
||||||
|
@ -174,12 +175,15 @@ UIWidgetPtr UIManager::loadWidgetFromOTML(const OTMLNodePtr& widgetNode, const U
|
||||||
if(parent)
|
if(parent)
|
||||||
parent->addChild(widget);
|
parent->addChild(widget);
|
||||||
|
|
||||||
widget->setStyleFromNode(styleNode);
|
if(widget) {
|
||||||
|
widget->setStyleFromNode(styleNode);
|
||||||
|
|
||||||
for(const OTMLNodePtr& childNode : widgetNode->children()) {
|
for(const OTMLNodePtr& childNode : widgetNode->children()) {
|
||||||
if(!childNode->isUnique())
|
if(!childNode->isUnique())
|
||||||
loadWidgetFromOTML(childNode, widget);
|
loadWidgetFromOTML(childNode, widget);
|
||||||
}
|
}
|
||||||
|
} else
|
||||||
|
logError("Unable to create widget of type '", widgetType, "'");
|
||||||
|
|
||||||
return widget;
|
return widget;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,14 +35,14 @@ void UIProgressBar::render()
|
||||||
{
|
{
|
||||||
UIWidget::render();
|
UIWidget::render();
|
||||||
|
|
||||||
g_graphics.bindColor(m_foregroundColor);
|
g_painter.setColor(m_foregroundColor);
|
||||||
g_graphics.drawBoundingRect(m_rect, 1);
|
g_painter.drawBoundingRect(m_rect, 1);
|
||||||
|
|
||||||
Rect fillRect = m_rect.expanded(-1);
|
Rect fillRect = m_rect.expanded(-1);
|
||||||
fillRect.setWidth(fillRect.width() * m_percent / 100.0);
|
fillRect.setWidth(fillRect.width() * m_percent / 100.0);
|
||||||
|
|
||||||
g_graphics.bindColor(m_backgroundColor);
|
g_painter.setColor(m_backgroundColor);
|
||||||
g_graphics.drawFilledRect(fillRect);
|
g_painter.drawFilledRect(fillRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UIProgressBar::setPercent(double percent)
|
void UIProgressBar::setPercent(double percent)
|
||||||
|
|
|
@ -69,7 +69,7 @@ void UIWidget::renderSelf()
|
||||||
{
|
{
|
||||||
// draw background
|
// draw background
|
||||||
if(m_image) {
|
if(m_image) {
|
||||||
g_graphics.bindColor(m_backgroundColor);
|
g_painter.setColor(m_backgroundColor);
|
||||||
m_image->draw(m_rect);
|
m_image->draw(m_rect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -81,20 +81,20 @@ void UIWidget::renderChildren()
|
||||||
// render only visible children with a valid rect inside our rect
|
// render only visible children with a valid rect inside our rect
|
||||||
if(child->isExplicitlyVisible() && child->getRect().isValid() && child->getRect().intersects(m_rect)) {
|
if(child->isExplicitlyVisible() && child->getRect().isValid() && child->getRect().intersects(m_rect)) {
|
||||||
// store current graphics opacity
|
// store current graphics opacity
|
||||||
int oldOpacity = g_graphics.getOpacity();
|
int oldOpacity = g_painter.getOpacity();
|
||||||
|
|
||||||
// decrease to self opacity
|
// decrease to self opacity
|
||||||
if(child->getOpacity() < oldOpacity)
|
if(child->getOpacity() < oldOpacity)
|
||||||
g_graphics.setOpacity(child->getOpacity());
|
g_painter.setOpacity(child->getOpacity());
|
||||||
|
|
||||||
child->render();
|
child->render();
|
||||||
|
|
||||||
// debug draw box
|
// debug draw box
|
||||||
//g_graphics.bindColor(Fw::green);
|
//g_painter.setColor(Fw::green);
|
||||||
//g_graphics.drawBoundingRect(child->getRect());
|
//g_painter.drawBoundingRect(child->getRect());
|
||||||
//g_fonts.getDefaultFont()->renderText(child->getId(), child->getPosition() + Point(2, 0), Fw::red);
|
//g_fonts.getDefaultFont()->renderText(child->getId(), child->getPosition() + Point(2, 0), Fw::red);
|
||||||
|
|
||||||
g_graphics.setOpacity(oldOpacity);
|
g_painter.setOpacity(oldOpacity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,8 +78,8 @@ public:
|
||||||
void setBottomLeft(const TPoint<T> &p) { x1 = p.x; y2 = p.y; }
|
void setBottomLeft(const TPoint<T> &p) { x1 = p.x; y2 = p.y; }
|
||||||
void setWidth(T width) { x2 = x1 + width - 1; }
|
void setWidth(T width) { x2 = x1 + width - 1; }
|
||||||
void setHeight(T height) { y2 = y1 + height- 1; }
|
void setHeight(T height) { y2 = y1 + height- 1; }
|
||||||
void setSize(T width, T height) { x2 = x1 + width - 1; y2 = y1 + height - 1; }
|
void resize(T width, T height) { x2 = x1 + width - 1; y2 = y1 + height - 1; }
|
||||||
void setSize(const TSize<T>& size) { x2 = x1 + size.width() - 1; y2 = y1 + size.height() - 1; }
|
void resize(const TSize<T>& size) { x2 = x1 + size.width() - 1; y2 = y1 + size.height() - 1; }
|
||||||
void setRect(T x, T y, T width, T height) { x1 = x; y1 = y; x2 = (x + width - 1); y2 = (y + height - 1); }
|
void setRect(T x, T y, T width, T height) { x1 = x; y1 = y; x2 = (x + width - 1); y2 = (y + height - 1); }
|
||||||
void setCoords(int left, int top, int right, int bottom) { x1 = left; y1 = top; x2 = right; y2 = bottom; }
|
void setCoords(int left, int top, int right, int bottom) { x1 = left; y1 = top; x2 = right; y2 = bottom; }
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ public:
|
||||||
int width() const { return wd; }
|
int width() const { return wd; }
|
||||||
int height() const { return ht; }
|
int height() const { return ht; }
|
||||||
|
|
||||||
void setSize(T w, T h) { wd = w; ht = h; }
|
void resize(T w, T h) { wd = w; ht = h; }
|
||||||
void setWidth(T w) { wd = w; }
|
void setWidth(T w) { wd = w; }
|
||||||
void setHeight(T h) { ht = h; }
|
void setHeight(T h) { ht = h; }
|
||||||
|
|
||||||
|
@ -115,7 +115,7 @@ std::istream& operator>>(std::istream& in, TSize<T>& size)
|
||||||
{
|
{
|
||||||
T w, h;
|
T w, h;
|
||||||
in >> w >> h;
|
in >> w >> h;
|
||||||
size.setSize(w, h);
|
size.resize(w, h);
|
||||||
return in;
|
return in;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,8 @@
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <exception>
|
#include <exception>
|
||||||
#include <cxxabi.h>
|
#include <cxxabi.h>
|
||||||
|
#include <vector>
|
||||||
|
#include <boost/algorithm/string.hpp>
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "exception.h"
|
#include "exception.h"
|
||||||
|
|
||||||
|
@ -258,6 +260,16 @@ inline std::string ip2str(uint32 ip) {
|
||||||
return std::string(host);
|
return std::string(host);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T = std::string>
|
||||||
|
std::vector<T> split(const std::string& str, const std::string& separators = " ") {
|
||||||
|
std::vector<std::string> splitted;
|
||||||
|
boost::split(splitted, str, boost::is_any_of(std::string(separators)));
|
||||||
|
std::vector<T> results(splitted.size());
|
||||||
|
for(uint i=0;i<splitted.size();++i)
|
||||||
|
results[i] = Fw::safeCast<T>(splitted[i]);
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
template<typename... T>
|
template<typename... T>
|
||||||
void throwException(const T&... args) {
|
void throwException(const T&... args) {
|
||||||
throw Exception(Fw::mkstr(args...));
|
throw Exception(Fw::mkstr(args...));
|
||||||
|
|
|
@ -25,9 +25,9 @@
|
||||||
int main(int argc, const char* argv[])
|
int main(int argc, const char* argv[])
|
||||||
{
|
{
|
||||||
std::vector<std::string> args(argv, argv + argc);
|
std::vector<std::string> args(argv, argv + argc);
|
||||||
OTClient otclient;
|
OTClient app;
|
||||||
otclient.init(args);
|
app.init(args);
|
||||||
otclient.run();
|
app.run();
|
||||||
otclient.terminate();
|
app.terminate();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,8 +47,8 @@ void Creature::draw(const Point& p)
|
||||||
{
|
{
|
||||||
// TODO: activate on attack, follow, discover how 'attacked' works
|
// TODO: activate on attack, follow, discover how 'attacked' works
|
||||||
if(m_showSquareColor) {
|
if(m_showSquareColor) {
|
||||||
g_graphics.bindColor(Outfit::getColor(m_squareColor));
|
g_painter.setColor(Outfit::getColor(m_squareColor));
|
||||||
g_graphics.drawBoundingRect(Rect(p + m_walkOffset - 8, Size(32, 32)), 2);
|
g_painter.drawBoundingRect(Rect(p + m_walkOffset - 8, Size(32, 32)), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render creature
|
// Render creature
|
||||||
|
@ -59,33 +59,33 @@ void Creature::draw(const Point& p)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// draw white item
|
// draw white item
|
||||||
g_graphics.bindColor(Fw::white);
|
g_painter.setColor(Fw::white);
|
||||||
internalDraw(p + m_walkOffset, 0);
|
internalDraw(p + m_walkOffset, 0);
|
||||||
|
|
||||||
// draw mask if exists
|
// draw mask if exists
|
||||||
if(m_type->dimensions[ThingType::Layers] > 1) {
|
if(m_type->dimensions[ThingType::Layers] > 1) {
|
||||||
// switch to blend color mode
|
// switch to blend color mode
|
||||||
g_graphics.bindBlendFunc(Fw::BlendColorzing);
|
g_painter.setCompositionMode(Painter::CompositionMode_ColorizeDest);
|
||||||
|
|
||||||
// head
|
// head
|
||||||
g_graphics.bindColor(m_outfit.getHeadColor());
|
g_painter.setColor(m_outfit.getHeadColor());
|
||||||
internalDraw(p + m_walkOffset, 1, Otc::SpriteYellowMask);
|
internalDraw(p + m_walkOffset, 1, Otc::SpriteYellowMask);
|
||||||
|
|
||||||
// body
|
// body
|
||||||
g_graphics.bindColor(m_outfit.getBodyColor());
|
g_painter.setColor(m_outfit.getBodyColor());
|
||||||
internalDraw(p + m_walkOffset, 1, Otc::SpriteRedMask);
|
internalDraw(p + m_walkOffset, 1, Otc::SpriteRedMask);
|
||||||
|
|
||||||
// legs
|
// legs
|
||||||
g_graphics.bindColor(m_outfit.getLegsColor());
|
g_painter.setColor(m_outfit.getLegsColor());
|
||||||
internalDraw(p + m_walkOffset, 1, Otc::SpriteGreenMask);
|
internalDraw(p + m_walkOffset, 1, Otc::SpriteGreenMask);
|
||||||
|
|
||||||
// feet
|
// feet
|
||||||
g_graphics.bindColor(m_outfit.getFeetColor());
|
g_painter.setColor(m_outfit.getFeetColor());
|
||||||
internalDraw(p + m_walkOffset, 1, Otc::SpriteBlueMask);
|
internalDraw(p + m_walkOffset, 1, Otc::SpriteBlueMask);
|
||||||
|
|
||||||
// restore default blend func
|
// restore default blend func
|
||||||
g_graphics.bindBlendFunc(Fw::BlendDefault);
|
g_painter.setCompositionMode(Painter::CompositionMode_SourceOver);
|
||||||
g_graphics.bindColor(Fw::white);
|
g_painter.setColor(Fw::white);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -115,11 +115,11 @@ void Creature::drawInformation(int x, int y, bool useGray, const Rect& rect)
|
||||||
healthRect.setWidth((m_healthPercent / 100.0) * 25);
|
healthRect.setWidth((m_healthPercent / 100.0) * 25);
|
||||||
|
|
||||||
// draw
|
// draw
|
||||||
g_graphics.bindColor(Fw::black);
|
g_painter.setColor(Fw::black);
|
||||||
g_graphics.drawFilledRect(backgroundRect);
|
g_painter.drawFilledRect(backgroundRect);
|
||||||
|
|
||||||
g_graphics.bindColor(fillColor);
|
g_painter.setColor(fillColor);
|
||||||
g_graphics.drawFilledRect(healthRect);
|
g_painter.drawFilledRect(healthRect);
|
||||||
|
|
||||||
m_informationFont->renderText(m_name, textRect, Fw::AlignTopCenter, fillColor);
|
m_informationFont->renderText(m_name, textRect, Fw::AlignTopCenter, fillColor);
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ void Map::draw(const Rect& rect)
|
||||||
if(!m_framebuffer)
|
if(!m_framebuffer)
|
||||||
m_framebuffer = FrameBufferPtr(new FrameBuffer(m_visibleSize.width() * NUM_TILE_PIXELS, m_visibleSize.height() * NUM_TILE_PIXELS));
|
m_framebuffer = FrameBufferPtr(new FrameBuffer(m_visibleSize.width() * NUM_TILE_PIXELS, m_visibleSize.height() * NUM_TILE_PIXELS));
|
||||||
|
|
||||||
g_graphics.bindColor(Fw::white);
|
g_painter.setColor(Fw::white);
|
||||||
m_framebuffer->bind();
|
m_framebuffer->bind();
|
||||||
|
|
||||||
// draw offsets
|
// draw offsets
|
||||||
|
@ -80,9 +80,9 @@ void Map::draw(const Rect& rect)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_framebuffer->unbind();
|
m_framebuffer->release();
|
||||||
|
|
||||||
g_graphics.bindColor(Fw::white);
|
g_painter.setColor(Fw::white);
|
||||||
m_framebuffer->draw(rect);
|
m_framebuffer->draw(rect);
|
||||||
|
|
||||||
// calculate stretch factor
|
// calculate stretch factor
|
||||||
|
|
|
@ -55,7 +55,7 @@ void Thing::internalDraw(const Point& p, int layers, Otc::SpriteMask mask)
|
||||||
Rect drawRect((p.x - xi*32) - m_type->parameters[ThingType::DisplacementX],
|
Rect drawRect((p.x - xi*32) - m_type->parameters[ThingType::DisplacementX],
|
||||||
(p.y - yi*32) - m_type->parameters[ThingType::DisplacementY],
|
(p.y - yi*32) - m_type->parameters[ThingType::DisplacementY],
|
||||||
32, 32);
|
32, 32);
|
||||||
g_graphics.drawTexturedRect(drawRect, spriteTex);
|
g_painter.drawTexturedRect(drawRect, spriteTex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,5 @@ void OTClient::init(const std::vector<std::string>& args)
|
||||||
g_modules.discoverModules();
|
g_modules.discoverModules();
|
||||||
g_modules.autoLoadModules(100);
|
g_modules.autoLoadModules(100);
|
||||||
g_modules.ensureModuleLoaded("client");
|
g_modules.ensureModuleLoaded("client");
|
||||||
g_modules.ensureModuleLoaded("game");
|
|
||||||
g_modules.autoLoadModules(1000);
|
g_modules.autoLoadModules(1000);
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@ void UICreature::render()
|
||||||
renderSelf();
|
renderSelf();
|
||||||
|
|
||||||
if(m_creature) {
|
if(m_creature) {
|
||||||
g_graphics.bindColor(Fw::white);
|
g_painter.setColor(Fw::white);
|
||||||
m_creature->draw(m_rect.bottomRight() - Point(32, 32) + m_creatureMargin);
|
m_creature->draw(m_rect.bottomRight() - Point(32, 32) + m_creatureMargin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ void UIItem::render()
|
||||||
renderSelf();
|
renderSelf();
|
||||||
|
|
||||||
if(m_item) {
|
if(m_item) {
|
||||||
g_graphics.bindColor(Fw::white);
|
g_painter.setColor(Fw::white);
|
||||||
m_item->draw(m_rect.bottomRight() - Point(32, 32) + m_itemMargin);
|
m_item->draw(m_rect.bottomRight() - Point(32, 32) + m_itemMargin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,8 +35,8 @@ void UIMap::render()
|
||||||
{
|
{
|
||||||
renderSelf();
|
renderSelf();
|
||||||
|
|
||||||
g_graphics.bindColor(Fw::black);
|
g_painter.setColor(Fw::black);
|
||||||
g_graphics.drawBoundingRect(m_mapRect.expanded(1));
|
g_painter.drawBoundingRect(m_mapRect.expanded(1));
|
||||||
g_map.draw(m_mapRect);
|
g_map.draw(m_mapRect);
|
||||||
|
|
||||||
renderChildren();
|
renderChildren();
|
||||||
|
@ -78,6 +78,6 @@ void UIMap::onGeometryUpdate(const Rect& oldRect, const Rect& newRect)
|
||||||
Size mapSize(g_map.getVibibleSize().width() * Map::NUM_TILE_PIXELS, g_map.getVibibleSize().height() * Map::NUM_TILE_PIXELS);
|
Size mapSize(g_map.getVibibleSize().width() * Map::NUM_TILE_PIXELS, g_map.getVibibleSize().height() * Map::NUM_TILE_PIXELS);
|
||||||
mapSize.scale(mapRect.size(), Fw::KeepAspectRatio);
|
mapSize.scale(mapRect.size(), Fw::KeepAspectRatio);
|
||||||
|
|
||||||
m_mapRect.setSize(mapSize);
|
m_mapRect.resize(mapSize);
|
||||||
m_mapRect.moveCenter(newRect.center());
|
m_mapRect.moveCenter(newRect.center());
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,16 +15,16 @@ if not io.open(cppclassheader, 'r') then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
function string.matchcount(str, pattern)
|
function string:matchcount(pattern)
|
||||||
local count = 0
|
local count = 0
|
||||||
for w in str:gmatch(pattern) do count = count + 1 end
|
for w in self:gmatch(pattern) do count = count + 1 end
|
||||||
return count
|
return count
|
||||||
end
|
end
|
||||||
|
|
||||||
function string.splitlines(str)
|
function string:splitlines()
|
||||||
local t = {}
|
local t = {}
|
||||||
local function helper(line) table.insert(t, line) return "" end
|
local function helper(line) table.insert(t, line) return "" end
|
||||||
helper((str:gsub("(.-)\r?\n", helper)))
|
helper((self:gsub("(.-)\r?\n", helper)))
|
||||||
return t
|
return t
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ for line in io.lines(cppclassheader) do
|
||||||
foundclassname = line:match('^class ([%w_]+)')
|
foundclassname = line:match('^class ([%w_]+)')
|
||||||
if foundclassname then
|
if foundclassname then
|
||||||
if not cppclassname then
|
if not cppclassname then
|
||||||
guessedclassname = cppclassheader:match('([%w_]+).h'):lower()
|
guessedclassname = cppclassheader:match('([%w_]+)\.h$'):lower()
|
||||||
if foundclassname:lower() == guessedclassname then
|
if foundclassname:lower() == guessedclassname then
|
||||||
cppclassname = foundclassname
|
cppclassname = foundclassname
|
||||||
end
|
end
|
||||||
|
@ -69,8 +69,9 @@ for line in io.lines(cppclassheader) do
|
||||||
elseif line:match('private:') or line:match('protected:') then
|
elseif line:match('private:') or line:match('protected:') then
|
||||||
publicmethods = false
|
publicmethods = false
|
||||||
elseif publicmethods then
|
elseif publicmethods then
|
||||||
for funcname,args in line:gmatch(' *[%w :_]* ([%w_]+)%(([^%(]*%)) *[;{].*$') do
|
funcname, args = line:match('^ *[%w <>&\*:_]* ([%w_]+)%(([^%)]*%))[%w ]*[;{].*$')
|
||||||
if funcname ~= cppclassname then
|
if funcname then
|
||||||
|
if funcname ~= cppclassname and funcname ~= 'create' then
|
||||||
numargs = args:matchcount('[^,)]+[,)]')
|
numargs = args:matchcount('[^,)]+[,)]')
|
||||||
|
|
||||||
if cppclassinstance then
|
if cppclassinstance then
|
||||||
|
|
Loading…
Reference in New Issue