Merge branch 'revgraphics'
Conflicts: src/framework/CMakeLists.txt src/framework/application.cpp src/framework/graphics/graphics.cpp
This commit is contained in:
commit
2030a4da29
14
TODO
14
TODO
|
@ -14,11 +14,10 @@ fix moving windows and tooltips conflicts
|
|||
todo display otclient icon in window bar
|
||||
remake otui styles states system
|
||||
padding
|
||||
|
||||
break UILabel lines
|
||||
|
||||
rename Game to g_game, etc
|
||||
implement Console key binding
|
||||
fatal error if sprite load fails
|
||||
impl vertical sync, clipboard
|
||||
crash handler
|
||||
modify COnnection::poll()
|
||||
|
@ -29,4 +28,13 @@ bind every global lua function in a static class
|
|||
use metatable for Point,Rect,Color,Size lua classes
|
||||
lua binder generator
|
||||
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
|
||||
|
||||
create image class
|
||||
use CoordsBuffer in font
|
||||
cache into framebuffers
|
||||
implement glbuffer for CoordsBuffer
|
||||
use indices in CoordsBuffer
|
|
@ -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()
|
||||
if cursorPos == 0 then return end
|
||||
|
||||
local commandBegin = string.sub(commandLineEdit:getText(), 1, cursorPos)
|
||||
local commandBegin = commandLineEdit:getText():sub(1, cursorPos)
|
||||
local possibleCommands = {}
|
||||
|
||||
-- create a list containing all globals
|
||||
|
@ -43,7 +43,7 @@ local function completeCommand()
|
|||
|
||||
-- match commands
|
||||
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)
|
||||
end
|
||||
end
|
||||
|
@ -63,9 +63,9 @@ local function completeCommand()
|
|||
if #possibleCommands[1] < cursorPos then
|
||||
break
|
||||
end
|
||||
expandedComplete = commandBegin .. string.sub(possibleCommands[1], cursorPos, cursorPos)
|
||||
expandedComplete = commandBegin .. possibleCommands[1]:sub(cursorPos, cursorPos)
|
||||
for i,v in ipairs(possibleCommands) do
|
||||
if string.sub(v, 1, #expandedComplete) ~= expandedComplete then
|
||||
if v:sub(1, #expandedComplete) ~= expandedComplete then
|
||||
done = true
|
||||
end
|
||||
end
|
||||
|
|
|
@ -8,11 +8,9 @@ Module
|
|||
autoLoad: true
|
||||
autoLoadPriority: 20
|
||||
|
||||
dependencies:
|
||||
- core
|
||||
|
||||
onLoad: |
|
||||
require 'console'
|
||||
require 'commands'
|
||||
Console.init()
|
||||
return true
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ Client = { }
|
|||
-- TODO: load and save configurations
|
||||
function Client.init()
|
||||
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.setIcon('clienticon.png')
|
||||
return true
|
||||
|
|
|
@ -23,8 +23,8 @@ local function onError(protocol, error)
|
|||
end
|
||||
|
||||
local function onMotd(protocol, motd)
|
||||
motdNumber = tonumber(string.sub(motd, 0, string.find(motd, "\n")))
|
||||
motdMessage = string.sub(motd, string.find(motd, "\n") + 1, string.len(motd))
|
||||
motdNumber = tonumber(motd:sub(0, motd:find("\n")))
|
||||
motdMessage = motd:sub(motd:find("\n") + 1, #motd)
|
||||
TopMenu.getButton('motdButton'):show()
|
||||
end
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ local vsyncEnabled = false
|
|||
|
||||
function getConfig(name, default)
|
||||
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
|
||||
return toboolean(val)
|
||||
else
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
-- AnchorEdge
|
||||
AnchorNone = 0
|
||||
AnchorTop = 1
|
||||
AnchorBottom = 2
|
||||
|
@ -15,9 +14,6 @@ LogFatal = 4
|
|||
|
||||
ActiveFocusReason = 2
|
||||
|
||||
EmptyFunction = function() end
|
||||
|
||||
-- KeyCodes
|
||||
KeyUnknown = 0
|
||||
KeyEscape = 1
|
||||
KeyTab = 2
|
||||
|
@ -57,7 +53,7 @@ KeyLeftParen = 40 -- (
|
|||
KeyRightParen = 41 -- )
|
||||
KeyAsterisk = 42 -- *
|
||||
KeyPlus = 43 -- +
|
||||
KeyComma = 44 --
|
||||
KeyComma = 44 -- ,
|
||||
KeyMinus = 45 -- -
|
||||
KeyPeriod = 46 -- .
|
||||
KeySlash = 47 -- /
|
|
@ -7,10 +7,14 @@ Module
|
|||
onLoad: |
|
||||
require 'ext/table'
|
||||
require 'ext/string'
|
||||
require 'constants'
|
||||
require 'util/point'
|
||||
require 'util/size'
|
||||
require 'util/color'
|
||||
require 'util/rect'
|
||||
require 'const'
|
||||
require 'util'
|
||||
require 'dispatcher'
|
||||
require 'widget'
|
||||
require 'ui'
|
||||
require 'gfx'
|
||||
require 'effects'
|
||||
return true
|
||||
|
|
|
@ -1,43 +1,33 @@
|
|||
local eventId = 0
|
||||
local eventsTable = { }
|
||||
local orig = { scheduleEvent = scheduleEvent,
|
||||
addEvent = addEvent }
|
||||
local eventList = {}
|
||||
|
||||
-- fix original scheduleEvent
|
||||
function scheduleEvent(func, delay)
|
||||
eventId = eventId + 1
|
||||
local id = eventId
|
||||
local function proxyFunc()
|
||||
if eventsTable[id] then
|
||||
func()
|
||||
eventsTable[id] = nil
|
||||
if eventList[id] then
|
||||
if eventList[id].active then
|
||||
func()
|
||||
end
|
||||
eventList[id] = nil
|
||||
end
|
||||
end
|
||||
eventsTable[id] = proxyFunc
|
||||
orig.scheduleEvent(proxyFunc, delay)
|
||||
eventList[id] = { func = proxyFunc, active = true }
|
||||
if delay and delay > 0 then
|
||||
g_dispatcher.scheduleEvent(proxyFunc, delay)
|
||||
else
|
||||
g_dispatcher.addEvent(proxyFunc, false)
|
||||
end
|
||||
return id
|
||||
end
|
||||
|
||||
-- FIXME: the event function can be collected
|
||||
-- and the dispatcher would call an invalid function, generating an warning
|
||||
function addEvent(func)
|
||||
return scheduleEvent(func, 0)
|
||||
end
|
||||
|
||||
function removeEvent(id)
|
||||
if id and eventsTable[id] then
|
||||
eventsTable[id] = nil
|
||||
if id and eventList[id] then
|
||||
eventList[id].active = false
|
||||
return true
|
||||
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 time then time = 250 end
|
||||
widget:setOpacity(math.min((255*elapsed)/time, 255))
|
||||
|
@ -11,7 +11,7 @@ function GFX.fadeIn(widget, time, elapsed)
|
|||
end
|
||||
end
|
||||
|
||||
function GFX.fadeOut(widget, time, elapsed)
|
||||
function Effects.fadeOut(widget, time, elapsed)
|
||||
if not elapsed then elapsed = 0 end
|
||||
if not time then time = 250 end
|
||||
widget:setOpacity((255*(time - elapsed))/time)
|
|
@ -13,12 +13,12 @@ function string:starts(start)
|
|||
return self:sub(1, #start) == start
|
||||
end
|
||||
|
||||
function string.trim(str)
|
||||
return str:match'^%s*(.*%S)' or ''
|
||||
function string:trim()
|
||||
return self:match('^%s*(.*%S)') or ''
|
||||
end
|
||||
|
||||
function toboolean(str)
|
||||
str = string.trim(str)
|
||||
str = str:trim()
|
||||
if str == '1' or str == 'true' then
|
||||
return true
|
||||
end
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
function table.dump(t, depth)
|
||||
if not depth then depth = 0 end
|
||||
for k,v in pairs(t) do
|
||||
str = string.rep(' ', depth * 2) .. k .. ': '
|
||||
str = (' '):rep(depth * 2) .. k .. ': '
|
||||
if type(v) ~= "table" then
|
||||
print(str .. tostring(v))
|
||||
else
|
||||
|
|
|
@ -6,10 +6,8 @@ function print(...)
|
|||
Logger.log(LogInfo, msg)
|
||||
end
|
||||
|
||||
function createEnvironment()
|
||||
local env = { }
|
||||
setmetatable(env, { __index = _G} )
|
||||
return env
|
||||
function fatal(msg)
|
||||
Logger.log(LogFatal, msg)
|
||||
end
|
||||
|
||||
function connect(object, signalsAndSlots, pushFront)
|
||||
|
@ -28,10 +26,10 @@ function connect(object, signalsAndSlots, pushFront)
|
|||
end
|
||||
end
|
||||
|
||||
function dumpWidgets()
|
||||
for i=1,UI.root:getChildCount() do
|
||||
print(UI.root:getChildByIndex(i):getId())
|
||||
end
|
||||
function createEnvironment()
|
||||
local env = { }
|
||||
setmetatable(env, { __index = _G} )
|
||||
return env
|
||||
end
|
||||
|
||||
function getCallingScriptSourcePath(depth)
|
||||
|
|
|
@ -16,4 +16,4 @@ function UIWidget:setMargin(...)
|
|||
self:setMarginBottom(params[3])
|
||||
self:setMarginLeft(params[4])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -28,7 +28,7 @@ function MessageBox.create(title, text, flags)
|
|||
|
||||
if flags == MessageBoxOk then
|
||||
buttonRight:setText("Ok")
|
||||
box.onOk = EmptyFunction
|
||||
box.onOk = function() end
|
||||
buttonRight.onClick = function()
|
||||
box.onOk()
|
||||
box:destroy()
|
||||
|
@ -37,7 +37,7 @@ function MessageBox.create(title, text, flags)
|
|||
window.onEscape = buttonRight.onClick
|
||||
elseif flags == MessageBoxCancel then
|
||||
buttonRight:setText("Cancel")
|
||||
box.onCancel = EmptyFunction
|
||||
box.onCancel = function() end
|
||||
buttonRight.onClick = function()
|
||||
box.onCancel()
|
||||
box:destroy()
|
||||
|
|
|
@ -28,7 +28,7 @@ function ToolTip.display(text)
|
|||
local size = label:getSize()
|
||||
size.width = size.width + 4
|
||||
size.height = size.height + 4
|
||||
currentToolTip:setSize(size)
|
||||
currentToolTip:resize(size)
|
||||
moveToolTip(currentToolTip)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
uniform float opacity;
|
||||
uniform vec4 color;
|
||||
uniform float ticks;
|
||||
|
||||
uniform sampler2D texture; // outfit texture
|
||||
varying vec2 textureCoords; // outfit texture coords
|
||||
uniform sampler2D maskTexture; // outfit color mask
|
||||
|
||||
uniform vec4 headColor;
|
||||
uniform vec4 bodyColor;
|
||||
uniform vec4 legsColor;
|
||||
uniform vec4 feetColor;
|
||||
|
||||
vec4 calcPixel(vec2 texCoord)
|
||||
{
|
||||
vec4 pixel = texture2D(texture, texCoord);
|
||||
vec4 maskColor = texture2D(maskTexture, texCoord);
|
||||
|
||||
vec4 outColor = vec4(0);
|
||||
if(maskColor.r == 1.0 && maskColor.g == 1.0) {
|
||||
outColor = headColor;
|
||||
} else if(maskColor.r == 1.0) {
|
||||
outColor = bodyColor;
|
||||
} else if(maskColor.g == 1.0) {
|
||||
outColor = legsColor;
|
||||
} else if(maskColor.b == 1.0) {
|
||||
outColor = feetColor;
|
||||
}
|
||||
|
||||
if(outColor.a != 0.0)
|
||||
pixel = pixel * outColor;
|
||||
return pixel;
|
||||
}
|
||||
void main()
|
||||
{
|
||||
vec4 pixel = calcPixel(textureCoords);
|
||||
int num = 16;
|
||||
|
||||
vec4 sum = vec4(0);
|
||||
int i, j;
|
||||
for(i=-num/2;i<num/2;++i) {
|
||||
for(j=-num/2;j<num/2;++j) {
|
||||
sum += calcPixel(textureCoords + vec2(i+1, j+1)*0.005) * 1.0/(num*num);
|
||||
}
|
||||
}
|
||||
sum = sin(ticks/500.0)*sum;
|
||||
|
||||
gl_FragColor = pixel * color * opacity + sum;
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
varying vec2 textureCoords;
|
||||
uniform float opacity;
|
||||
uniform vec4 color;
|
||||
uniform float ticks;
|
||||
uniform sampler2D texture;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = texture2D(texture, textureCoords) * color * opacity;
|
||||
}
|
||||
|
||||
/*
|
||||
varying vec2 textureCoords;
|
||||
uniform vec4 color;
|
||||
uniform float ticks;
|
||||
uniform sampler2D texture;
|
||||
|
||||
void main()
|
||||
{
|
||||
int num = 4;
|
||||
vec4 sum = vec4(0);
|
||||
int i, j;
|
||||
for(i=-num/2;i<num/2;++i) {
|
||||
for(j=-num/2;j<num/2;++j) {
|
||||
sum += texture2D(texture, textureCoords + vec2(i+1, j+1)*0.001) * 1.0/(num*num);
|
||||
}
|
||||
}
|
||||
|
||||
float period = ticks/1000.0;
|
||||
float a = (sin(period)+1.0)/2.0;
|
||||
sum.a = 0;
|
||||
gl_FragColor = vec4(1,1,1,2) - texture2D(texture, textureCoords);
|
||||
}
|
||||
*/
|
||||
/*
|
||||
uniform sampler2D texture;
|
||||
varying vec2 textureCoords;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 sum = vec4(0);
|
||||
vec2 texcoord = textureCoords;
|
||||
int j;
|
||||
int i;
|
||||
|
||||
for( i= -4 ;i < 4; i++)
|
||||
{
|
||||
for (j = -3; j < 3; j++)
|
||||
{
|
||||
sum += texture2D(texture, texcoord + vec2(j, i)*0.004) * 0.25;
|
||||
}
|
||||
}
|
||||
if (texture2D(texture, texcoord).r < 0.3)
|
||||
{
|
||||
gl_FragColor = sum*sum*0.012 + texture2D(texture, texcoord);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (texture2D(texture, texcoord).r < 0.5)
|
||||
{
|
||||
gl_FragColor = sum*sum*0.009 + texture2D(texture, texcoord);
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_FragColor = sum*sum*0.0075 + texture2D(texture, texcoord);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
/*
|
||||
uniform sampler2D texture;
|
||||
varying vec2 textureCoords;
|
||||
uniform vec4 color;
|
||||
uniform float opacity;
|
||||
|
||||
uniform float ticks;
|
||||
uniform float rt_w = 18*32;
|
||||
uniform float rt_h = 14*32;
|
||||
|
||||
uniform float radius = 300.0;
|
||||
uniform float angle = 0.2;
|
||||
uniform vec2 center = vec2(8*32, 5*32);
|
||||
|
||||
vec4 PostFX(sampler2D tex, vec2 uv, float time)
|
||||
{
|
||||
vec2 texSize = vec2(rt_w, rt_h);
|
||||
vec2 tc = uv * texSize;
|
||||
tc -= center;
|
||||
float dist = length(tc);
|
||||
if (dist < radius)
|
||||
{
|
||||
float percent = (radius - dist) / radius;
|
||||
float theta = percent * percent * ((int)ticks % 1000)/1000.0 * 8.0;
|
||||
float s = sin(theta);
|
||||
float c = cos(theta);
|
||||
tc = vec2(dot(tc, vec2(c, -s)), dot(tc, vec2(s, c)));
|
||||
}
|
||||
tc += center;
|
||||
vec3 color = texture2D(texture, tc / texSize).rgb;
|
||||
return vec4(color, 1.0);
|
||||
}
|
||||
|
||||
void main (void)
|
||||
{
|
||||
vec2 uv = textureCoords.st;
|
||||
gl_FragColor = PostFX(texture, uv, ticks) * opacity;
|
||||
}
|
||||
*/
|
||||
/*
|
||||
uniform float opacity;
|
||||
vec4 calculatePixel();
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = calculatePixel() * opacity;
|
||||
}
|
||||
|
||||
varying vec2 textureCoords;
|
||||
uniform vec4 color;
|
||||
uniform sampler2D texture;
|
||||
vec4 calculatePixel() {
|
||||
return texture2D(texture, textureCoords) * color;
|
||||
}
|
||||
*/
|
|
@ -79,7 +79,7 @@ IF(WIN32)
|
|||
ENDIF(NO_CONSOLE)
|
||||
ELSE(WIN32)
|
||||
SET(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -rdynamic")
|
||||
SET(ADDITIONAL_LIBRARIES pthread)
|
||||
SET(ADDITIONAL_LIBRARIES pthread X11)
|
||||
SET(framework_SOURCES ${framework_SOURCES} ${CMAKE_CURRENT_LIST_DIR}/platform/x11window.cpp)
|
||||
ENDIF(WIN32)
|
||||
|
||||
|
@ -135,6 +135,7 @@ SET(framework_SOURCES ${framework_SOURCES}
|
|||
${CMAKE_CURRENT_LIST_DIR}/graphics/font.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/graphics/fontmanager.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/framebuffer.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/graphics/animatedtexture.cpp
|
||||
|
@ -144,6 +145,10 @@ SET(framework_SOURCES ${framework_SOURCES}
|
|||
${CMAKE_CURRENT_LIST_DIR}/graphics/image.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/graphics/particlesmanager.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/graphics/particlessystem.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/graphics/shader.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/graphics/shaderprogram.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/graphics/paintershaderprogram.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/graphics/coordsbuffer.cpp
|
||||
|
||||
# framework otml
|
||||
${CMAKE_CURRENT_LIST_DIR}/otml/otmldocument.cpp
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include <framework/ui/uiwidget.h>
|
||||
#include <framework/graphics/graphics.h>
|
||||
#include <framework/graphics/particlesmanager.h>
|
||||
#include <framework/graphics/painter.h>
|
||||
#include <framework/luascript/luainterface.h>
|
||||
|
||||
Application *g_app = nullptr;
|
||||
|
@ -135,7 +136,6 @@ void Application::terminate()
|
|||
// terminate graphics
|
||||
if(m_appFlags & Fw::AppEnableGraphics) {
|
||||
g_ui.terminate();
|
||||
g_graphics.terminate();
|
||||
g_window.terminate();
|
||||
}
|
||||
|
||||
|
@ -222,8 +222,8 @@ void Application::render()
|
|||
|
||||
void Application::resize(const Size& size)
|
||||
{
|
||||
g_graphics.resize(size);
|
||||
g_ui.resize(size);
|
||||
g_graphics.resize(size);
|
||||
}
|
||||
|
||||
void Application::inputEvent(const InputEvent& event)
|
||||
|
|
|
@ -178,12 +178,6 @@ namespace Fw
|
|||
LogFatal
|
||||
};
|
||||
|
||||
enum BlendFunc {
|
||||
BlendDefault,
|
||||
BlendColorzing,
|
||||
BlendParticles
|
||||
};
|
||||
|
||||
enum AspectRatioMode {
|
||||
IgnoreAspectRatio,
|
||||
KeepAspectRatio,
|
||||
|
|
|
@ -79,15 +79,13 @@ bool Module::load()
|
|||
}
|
||||
}
|
||||
|
||||
if(m_loadCallback) {
|
||||
m_loaded = m_loadCallback();
|
||||
if(!m_loaded) {
|
||||
logError("Unable to load module '", m_name, "' because its onLoad event returned false");
|
||||
return false;
|
||||
}
|
||||
if(m_loadCallback && !m_loadCallback()) {
|
||||
logError("Unable to load module '", m_name, "' because its onLoad event returned false");
|
||||
return false;
|
||||
}
|
||||
|
||||
logInfo("Loaded module '", m_name, "'");
|
||||
m_loaded = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ AnimatedTexture::AnimatedTexture(int width, int height, int channels, int numFra
|
|||
Texture(),
|
||||
m_numFrames(numFrames)
|
||||
{
|
||||
m_size.setSize(width, height);
|
||||
m_size.resize(width, height);
|
||||
|
||||
m_framesTextureId.resize(numFrames);
|
||||
m_framesDelay.resize(numFrames);
|
||||
|
|
|
@ -133,72 +133,72 @@ BorderImagePtr BorderImage::loadFromOTML(const OTMLNodePtr& borderImageNode)
|
|||
void BorderImage::draw(const Rect& screenCoords)
|
||||
{
|
||||
//TODO: borderimage drawing could be optimized by caching the render into a texture
|
||||
if(screenCoords != m_cachedScreenCoords) {
|
||||
m_cachedScreenCoords = screenCoords;
|
||||
m_coordsBuffer.clear();
|
||||
|
||||
Rect rectCoords;
|
||||
Size centerSize = screenCoords.size() - m_bordersSize;
|
||||
Rect rectCoords;
|
||||
Size centerSize = screenCoords.size() - m_bordersSize;
|
||||
|
||||
g_graphics.bindTexture(m_texture);
|
||||
g_graphics.startDrawing();
|
||||
// first the center
|
||||
if(centerSize.area() > 0) {
|
||||
rectCoords = Rect(screenCoords.left() + m_leftBorderTexCoords.width(),
|
||||
screenCoords.top() + m_topBorderTexCoords.height(),
|
||||
centerSize);
|
||||
m_coordsBuffer.addRepeatedRects(rectCoords, m_centerTexCoords);
|
||||
}
|
||||
|
||||
// first the center
|
||||
if(centerSize.area() > 0) {
|
||||
rectCoords = Rect(screenCoords.left() + m_leftBorderTexCoords.width(),
|
||||
screenCoords.top() + m_topBorderTexCoords.height(),
|
||||
centerSize);
|
||||
g_graphics.drawRepeatedTexturedRect(rectCoords, m_texture, m_centerTexCoords);
|
||||
// top left corner
|
||||
rectCoords = Rect(screenCoords.topLeft(),
|
||||
m_topLeftCornerTexCoords.size());
|
||||
m_coordsBuffer.addRepeatedRects(rectCoords, m_topLeftCornerTexCoords);
|
||||
|
||||
// top
|
||||
rectCoords = Rect(screenCoords.left() + m_topLeftCornerTexCoords.width(),
|
||||
screenCoords.topLeft().y,
|
||||
centerSize.width(),
|
||||
m_topBorderTexCoords.height());
|
||||
m_coordsBuffer.addRepeatedRects(rectCoords, m_topBorderTexCoords);
|
||||
|
||||
|
||||
// top right corner
|
||||
rectCoords = Rect(screenCoords.left() + m_topLeftCornerTexCoords.width() + centerSize.width(),
|
||||
screenCoords.top(),
|
||||
m_topRightCornerTexCoords.size());
|
||||
m_coordsBuffer.addRepeatedRects(rectCoords, m_topRightCornerTexCoords);
|
||||
|
||||
// left
|
||||
rectCoords = Rect(screenCoords.left(),
|
||||
screenCoords.top() + m_topLeftCornerTexCoords.height(),
|
||||
m_leftBorderTexCoords.width(),
|
||||
centerSize.height());
|
||||
m_coordsBuffer.addRepeatedRects(rectCoords, m_leftBorderTexCoords);
|
||||
|
||||
// right
|
||||
rectCoords = Rect(screenCoords.left() + m_leftBorderTexCoords.width() + centerSize.width(),
|
||||
screenCoords.top() + m_topRightCornerTexCoords.height(),
|
||||
m_rightBorderTexCoords.width(),
|
||||
centerSize.height());
|
||||
m_coordsBuffer.addRepeatedRects(rectCoords, m_rightBorderTexCoords);
|
||||
|
||||
// bottom left corner
|
||||
rectCoords = Rect(screenCoords.left(),
|
||||
screenCoords.top() + m_topLeftCornerTexCoords.height() + centerSize.height(),
|
||||
m_bottomLeftCornerTexCoords.size());
|
||||
m_coordsBuffer.addRepeatedRects(rectCoords, m_bottomLeftCornerTexCoords);
|
||||
|
||||
// bottom
|
||||
rectCoords = Rect(screenCoords.left() + m_bottomLeftCornerTexCoords.width(),
|
||||
screenCoords.top() + m_topBorderTexCoords.height() + centerSize.height(),
|
||||
centerSize.width(),
|
||||
m_bottomBorderTexCoords.height());
|
||||
m_coordsBuffer.addRepeatedRects(rectCoords, m_bottomBorderTexCoords);
|
||||
|
||||
// bottom right corner
|
||||
rectCoords = Rect(screenCoords.left() + m_bottomLeftCornerTexCoords.width() + centerSize.width(),
|
||||
screenCoords.top() + m_topRightCornerTexCoords.height() + centerSize.height(),
|
||||
m_bottomRightCornerTexCoords.size());
|
||||
m_coordsBuffer.addRepeatedRects(rectCoords, m_bottomRightCornerTexCoords);
|
||||
}
|
||||
|
||||
// top left corner
|
||||
rectCoords = Rect(screenCoords.topLeft(),
|
||||
m_topLeftCornerTexCoords.size());
|
||||
g_graphics.drawTexturedRect(rectCoords, m_texture, m_topLeftCornerTexCoords);
|
||||
|
||||
// top
|
||||
rectCoords = Rect(screenCoords.left() + m_topLeftCornerTexCoords.width(),
|
||||
screenCoords.topLeft().y,
|
||||
centerSize.width(),
|
||||
m_topBorderTexCoords.height());
|
||||
g_graphics.drawRepeatedTexturedRect(rectCoords, m_texture, m_topBorderTexCoords);
|
||||
|
||||
|
||||
// top right corner
|
||||
rectCoords = Rect(screenCoords.left() + m_topLeftCornerTexCoords.width() + centerSize.width(),
|
||||
screenCoords.top(),
|
||||
m_topRightCornerTexCoords.size());
|
||||
g_graphics.drawTexturedRect(rectCoords, m_texture, m_topRightCornerTexCoords);
|
||||
|
||||
// left
|
||||
rectCoords = Rect(screenCoords.left(),
|
||||
screenCoords.top() + m_topLeftCornerTexCoords.height(),
|
||||
m_leftBorderTexCoords.width(),
|
||||
centerSize.height());
|
||||
g_graphics.drawRepeatedTexturedRect(rectCoords, m_texture, m_leftBorderTexCoords);
|
||||
|
||||
// right
|
||||
rectCoords = Rect(screenCoords.left() + m_leftBorderTexCoords.width() + centerSize.width(),
|
||||
screenCoords.top() + m_topRightCornerTexCoords.height(),
|
||||
m_rightBorderTexCoords.width(),
|
||||
centerSize.height());
|
||||
g_graphics.drawRepeatedTexturedRect(rectCoords, m_texture, m_rightBorderTexCoords);
|
||||
|
||||
// bottom left corner
|
||||
rectCoords = Rect(screenCoords.left(),
|
||||
screenCoords.top() + m_topLeftCornerTexCoords.height() + centerSize.height(),
|
||||
m_bottomLeftCornerTexCoords.size());
|
||||
g_graphics.drawTexturedRect(rectCoords, m_texture, m_bottomLeftCornerTexCoords);
|
||||
|
||||
// bottom
|
||||
rectCoords = Rect(screenCoords.left() + m_bottomLeftCornerTexCoords.width(),
|
||||
screenCoords.top() + m_topBorderTexCoords.height() + centerSize.height(),
|
||||
centerSize.width(),
|
||||
m_bottomBorderTexCoords.height());
|
||||
g_graphics.drawRepeatedTexturedRect(rectCoords, m_texture, m_bottomBorderTexCoords);
|
||||
|
||||
// bottom right corner
|
||||
rectCoords = Rect(screenCoords.left() + m_bottomLeftCornerTexCoords.width() + centerSize.width(),
|
||||
screenCoords.top() + m_topRightCornerTexCoords.height() + centerSize.height(),
|
||||
m_bottomRightCornerTexCoords.size());
|
||||
g_graphics.drawTexturedRect(rectCoords, m_texture, m_bottomRightCornerTexCoords);
|
||||
|
||||
g_graphics.stopDrawing();
|
||||
g_painter.drawTextureCoords(m_coordsBuffer, m_texture);
|
||||
}
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* 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 "coordsbuffer.h"
|
||||
|
||||
void CoordsBuffer::clear()
|
||||
{
|
||||
m_destRects.reset();
|
||||
m_srcRects.reset();
|
||||
m_textureCoords.clear();
|
||||
m_vertices.clear();
|
||||
m_updateCache = true;
|
||||
}
|
||||
|
||||
void CoordsBuffer::addRect(const Rect& dest)
|
||||
{
|
||||
m_destRects << dest;
|
||||
m_updateCache = true;
|
||||
}
|
||||
|
||||
void CoordsBuffer::addRect(const Rect& dest, const Rect& src)
|
||||
{
|
||||
m_destRects << dest;
|
||||
m_srcRects << src;
|
||||
m_updateCache = true;
|
||||
}
|
||||
|
||||
void CoordsBuffer::addBoudingRect(const Rect& dest, int innerLineWidth)
|
||||
{
|
||||
int left = dest.left();
|
||||
int right = dest.right();
|
||||
int top = dest.top();
|
||||
int bottom = dest.bottom();
|
||||
int width = dest.width();
|
||||
int height = dest.height();
|
||||
int w = innerLineWidth;
|
||||
|
||||
addRect(Rect(left, top, width - w, w)); // top
|
||||
addRect(Rect(right - w + 1, top, w, height - w)); // right
|
||||
addRect(Rect(left + w, bottom - w + 1, width - w, w)); // bottom
|
||||
addRect(Rect(left, top + w, w, height - w)); // left
|
||||
m_updateCache = true;
|
||||
}
|
||||
|
||||
void CoordsBuffer::addRepeatedRects(const Rect& dest, const Rect& src)
|
||||
{
|
||||
if(dest.isEmpty() || src.isEmpty())
|
||||
return;
|
||||
|
||||
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());
|
||||
m_destRects << partialDest;
|
||||
m_srcRects << partialSrc;
|
||||
}
|
||||
}
|
||||
m_updateCache = true;
|
||||
}
|
||||
|
||||
void CoordsBuffer::cacheVertexArrays()
|
||||
{
|
||||
if(!m_updateCache)
|
||||
return;
|
||||
|
||||
int numDestRects = m_destRects.size();
|
||||
int numSrcRects = m_srcRects.size();
|
||||
m_vertices.clear();
|
||||
m_textureCoords.clear();
|
||||
|
||||
for(int i=0;i<numDestRects;++i) {
|
||||
m_vertices.addRect(m_destRects[i]);
|
||||
if(numSrcRects == numDestRects)
|
||||
m_textureCoords.addRect(m_srcRects[i]);
|
||||
}
|
||||
|
||||
m_updateCache = false;
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* 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 COORDSBUFFER_H
|
||||
#define COORDSBUFFER_H
|
||||
|
||||
#include "vertexarray.h"
|
||||
|
||||
class CoordsBuffer
|
||||
{
|
||||
public:
|
||||
void clear();
|
||||
|
||||
// no texture
|
||||
void addRect(const Rect& dest);
|
||||
void addBoudingRect(const Rect& dest, int innerLineWidth);
|
||||
|
||||
// textured
|
||||
void addRect(const Rect& dest, const Rect& src);
|
||||
void addRepeatedRects(const Rect& dest, const Rect& src);
|
||||
|
||||
void cacheVertexArrays();
|
||||
|
||||
GLfloat *getVertices() const { return m_vertices.vertices(); }
|
||||
GLfloat *getTextureCoords() const { return m_textureCoords.vertices(); }
|
||||
int getVertexCount() const { return m_vertices.vertexCount(); }
|
||||
int getTextureCoordsCount() const { return m_textureCoords.vertexCount(); }
|
||||
|
||||
private:
|
||||
DataBuffer<Rect> m_destRects;
|
||||
DataBuffer<Rect> m_srcRects;
|
||||
VertexArray m_vertices;
|
||||
VertexArray m_textureCoords;
|
||||
Boolean<true> m_updateCache;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -32,6 +32,9 @@ class Font;
|
|||
class Image;
|
||||
class BorderImage;
|
||||
class FrameBuffer;
|
||||
class Shader;
|
||||
class ShaderProgram;
|
||||
class PainterShaderProgram;
|
||||
|
||||
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<BorderImage> BorderImagePtr;
|
||||
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
|
||||
|
|
|
@ -64,7 +64,7 @@ void Font::renderText(const std::string& text,
|
|||
const Point& startPos,
|
||||
const Color& color)
|
||||
{
|
||||
Size boxSize = g_graphics.getScreenSize() - startPos.toSize();
|
||||
Size boxSize = g_graphics.getViewportSize() - startPos.toSize();
|
||||
Rect screenCoords(startPos, boxSize);
|
||||
renderText(text, screenCoords, Fw::AlignTopLeft, color);
|
||||
}
|
||||
|
@ -85,9 +85,7 @@ void Font::renderText(const std::string& text,
|
|||
Size textBoxSize;
|
||||
const std::vector<Point>& glyphsPositions = calculateGlyphsPositions(text, align, &textBoxSize);
|
||||
|
||||
g_graphics.bindColor(color);
|
||||
g_graphics.bindTexture(m_texture);
|
||||
g_graphics.startDrawing();
|
||||
g_painter.setColor(color);
|
||||
|
||||
for(int i = 0; i < textLenght; ++i) {
|
||||
int glyph = (uchar)text[i];
|
||||
|
@ -149,10 +147,8 @@ void Font::renderText(const std::string& text,
|
|||
}
|
||||
|
||||
// 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,
|
||||
|
@ -172,7 +168,7 @@ const std::vector<Point>& Font::calculateGlyphsPositions(const std::string& text
|
|||
// return if there is no text
|
||||
if(textLength == 0) {
|
||||
if(textBoxSize)
|
||||
textBoxSize->setSize(0,m_glyphHeight);
|
||||
textBoxSize->resize(0,m_glyphHeight);
|
||||
return glyphsPositions;
|
||||
}
|
||||
|
||||
|
@ -280,6 +276,6 @@ void Font::calculateGlyphsWidthsAutomatically(const Size& glyphSize)
|
|||
lastColumnFilledPixels = columnFilledPixels;
|
||||
}
|
||||
// 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)
|
||||
{
|
||||
m_fbo = 0;
|
||||
|
||||
// create FBO texture
|
||||
m_texture = TexturePtr(new Texture(width, height, 4));
|
||||
m_texture->enableBilinearFilter();
|
||||
|
||||
// use FBO ext only if supported
|
||||
if(g_graphics.isExtensionSupported("GL_ARB_framebuffer_object")) {
|
||||
m_fallbackOldImp = false;
|
||||
// generate FBO
|
||||
glGenFramebuffers(1, &m_fbo);
|
||||
if(!m_fbo)
|
||||
logFatal("Unable to create framebuffer object");
|
||||
|
||||
// generate FBO
|
||||
glGenFramebuffers(1, &m_fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER_EXT, m_fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
|
||||
|
||||
// attach 2D texture to this FBO
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_texture->getId(), 0);
|
||||
// attach 2D texture to this FBO
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture->getId(), 0);
|
||||
|
||||
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER_EXT);
|
||||
switch(status) {
|
||||
case GL_FRAMEBUFFER_COMPLETE_EXT:
|
||||
//ok
|
||||
break;
|
||||
default: // fallback to old implementation
|
||||
m_fallbackOldImp = true;
|
||||
break;
|
||||
}
|
||||
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
if(status != GL_FRAMEBUFFER_COMPLETE)
|
||||
logFatal("Unable to create framebuffer object");
|
||||
|
||||
// restore back buffer
|
||||
glBindFramebuffer(GL_FRAMEBUFFER_EXT, 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.");
|
||||
// restore back buffer
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
FrameBuffer::~FrameBuffer()
|
||||
{
|
||||
if(m_fbo)
|
||||
glDeleteFramebuffers(1, &m_fbo);
|
||||
glDeleteFramebuffers(1, &m_fbo);
|
||||
}
|
||||
|
||||
void FrameBuffer::bind()
|
||||
{
|
||||
if(!m_fallbackOldImp) {
|
||||
// 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);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
|
||||
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
|
||||
glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
|
||||
glDrawBuffer(GL_BACK);
|
||||
glReadBuffer(GL_BACK);
|
||||
// bind back buffer again
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
|
||||
// restore graphics viewport
|
||||
g_graphics.restoreViewport();
|
||||
} else {
|
||||
// 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);
|
||||
}
|
||||
// restore graphics viewport
|
||||
glViewport(0, 0, g_graphics.getViewportSize().width(), g_graphics.getViewportSize().height());
|
||||
g_painter.updateProjectionMatrix(g_graphics.getViewportSize());
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
void bind();
|
||||
void unbind();
|
||||
void draw(const Rect& screenCoords, const Rect& framebufferCoords = Rect());
|
||||
void release();
|
||||
void draw(const Rect& dest);
|
||||
|
||||
TexturePtr getTexture() { return m_texture; }
|
||||
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* 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 "glbuffer.h"
|
||||
|
||||
GLBuffer::GLBuffer()
|
||||
{
|
||||
glGenBuffers(1, &m_id);
|
||||
if(!m_id)
|
||||
logFatal("Unable to create a simple GL buffer");
|
||||
}
|
||||
|
||||
void GLBuffer::bind()
|
||||
{
|
||||
gl
|
||||
}
|
||||
|
||||
void GLBuffer::release()
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* 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 GLBUFFER_H
|
||||
#define GLBUFFER_H
|
||||
|
||||
#include "declarations.h"
|
||||
|
||||
class GLBuffer
|
||||
{
|
||||
public:
|
||||
GLBuffer();
|
||||
~GLBuffer();
|
||||
|
||||
void write(const
|
||||
void bind();
|
||||
void release();
|
||||
|
||||
GLuint bufferId();
|
||||
|
||||
private:
|
||||
GLuint m_id;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -30,310 +30,47 @@ Graphics g_graphics;
|
|||
void Graphics::init()
|
||||
{
|
||||
// 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);
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
logInfo("GPU ", glGetString(GL_RENDERER));
|
||||
logInfo("OpenGL ", glGetString(GL_VERSION));
|
||||
|
||||
m_drawing = false;
|
||||
m_opacity = 255;
|
||||
//if(!isExtensionSupported("GL_ARB_framebuffer_object"))
|
||||
// logFatal("Your graphics card is not supported.");
|
||||
|
||||
m_emptyTexture = TexturePtr(new Texture);
|
||||
|
||||
bindColor(Fw::white);
|
||||
bindBlendFunc(Fw::BlendDefault);
|
||||
g_painter.init();
|
||||
}
|
||||
|
||||
void Graphics::terminate()
|
||||
{
|
||||
g_fonts.releaseFonts();
|
||||
g_painter.terminate();
|
||||
m_emptyTexture.reset();
|
||||
}
|
||||
|
||||
bool Graphics::isExtensionSupported(const char *extension)
|
||||
{
|
||||
const GLubyte *extensions = NULL;
|
||||
const GLubyte *start;
|
||||
GLubyte *where, *terminator;
|
||||
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;
|
||||
std::string extensionsString = (const char*)glGetString(GL_EXTENSIONS);
|
||||
auto extensions = Fw::split(extensionsString);
|
||||
return std::find(extensions.begin(), extensions.end(), extension) != extensions.end();
|
||||
}
|
||||
|
||||
void Graphics::resize(const Size& size)
|
||||
{
|
||||
m_screenSize = size;
|
||||
restoreViewport();
|
||||
}
|
||||
|
||||
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();
|
||||
glViewport(0, 0, size.width(), size.height());
|
||||
g_painter.updateProjectionMatrix(size);
|
||||
m_viewportSize = size;
|
||||
}
|
||||
|
||||
void Graphics::beginRender()
|
||||
{
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glLoadIdentity();
|
||||
}
|
||||
|
||||
void Graphics::endRender()
|
||||
{
|
||||
assert(!m_drawing);
|
||||
}
|
||||
|
||||
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;
|
||||
case Fw::BlendParticles:
|
||||
glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_ONE);
|
||||
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
|
||||
|
||||
#include "declarations.h"
|
||||
#include "painter.h"
|
||||
|
||||
class Graphics
|
||||
{
|
||||
public:
|
||||
/// Initialize default OpenGL states
|
||||
void init();
|
||||
|
||||
/// Termiante graphics
|
||||
void terminate();
|
||||
|
||||
/// Check if a GL extension is supported
|
||||
bool isExtensionSupported(const char *extension);
|
||||
|
||||
/// Resizes OpenGL viewport
|
||||
void resize(const Size& size);
|
||||
|
||||
/// Restore original viewport
|
||||
void restoreViewport();
|
||||
|
||||
/// Called before every render
|
||||
void beginRender();
|
||||
|
||||
/// Called after every render
|
||||
void endRender();
|
||||
|
||||
void bindColor(const Color& color);
|
||||
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; }
|
||||
const Size& getViewportSize() const { return m_viewportSize; }
|
||||
TexturePtr getEmptyTexture() { return m_emptyTexture; }
|
||||
|
||||
private:
|
||||
bool m_drawing;
|
||||
int m_opacity;
|
||||
Size m_screenSize;
|
||||
Size m_viewportSize;
|
||||
TexturePtr m_emptyTexture;
|
||||
};
|
||||
|
||||
|
|
|
@ -52,7 +52,13 @@ void Image::loadFromOTML(const OTMLNodePtr& imageNode)
|
|||
|
||||
void Image::draw(const Rect& screenCoords)
|
||||
{
|
||||
if(m_texture) {
|
||||
if(!m_texture)
|
||||
return;
|
||||
|
||||
if(m_cachedScreenCoords != screenCoords) {
|
||||
m_cachedScreenCoords = screenCoords;
|
||||
m_coordsBuffer.clear();
|
||||
|
||||
if(m_fixedRatio) {
|
||||
const Size& texSize = m_texture->getSize();
|
||||
Size texCoordsSize = screenCoords.size();
|
||||
|
@ -63,12 +69,14 @@ void Image::draw(const Rect& screenCoords)
|
|||
else if(texSize.width() > texCoordsSize.width())
|
||||
texCoordsOffset.x = (texSize.width() - texCoordsSize.width())/2;
|
||||
|
||||
g_graphics.drawTexturedRect(screenCoords, m_texture, Rect(texCoordsOffset, texCoordsSize));
|
||||
m_coordsBuffer.addRect(screenCoords, Rect(texCoordsOffset, texCoordsSize));
|
||||
} else {
|
||||
if(m_repeated)
|
||||
g_graphics.drawRepeatedTexturedRect(screenCoords, m_texture, m_textureCoords);
|
||||
m_coordsBuffer.addRepeatedRects(screenCoords, m_textureCoords);
|
||||
else
|
||||
g_graphics.drawTexturedRect(screenCoords, m_texture, m_textureCoords);
|
||||
m_coordsBuffer.addRect(screenCoords, m_textureCoords);
|
||||
}
|
||||
}
|
||||
|
||||
g_painter.drawTextureCoords(m_coordsBuffer, m_texture);
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#define IMAGE_H
|
||||
|
||||
#include "declarations.h"
|
||||
#include "coordsbuffer.h"
|
||||
|
||||
#include <framework/otml/declarations.h>
|
||||
|
||||
|
@ -41,6 +42,9 @@ protected:
|
|||
Rect m_textureCoords;
|
||||
bool m_fixedRatio;
|
||||
bool m_repeated;
|
||||
|
||||
Rect m_cachedScreenCoords;
|
||||
CoordsBuffer m_coordsBuffer;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,167 @@
|
|||
/*
|
||||
* 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"
|
||||
#include "vertexarray.h"
|
||||
|
||||
Painter g_painter;
|
||||
|
||||
void Painter::init()
|
||||
{
|
||||
setColor(Fw::white);
|
||||
setOpacity(255);
|
||||
setCompositionMode(CompositionMode_SourceOver);
|
||||
|
||||
m_drawTexturedProgram = PainterShaderProgramPtr(new PainterShaderProgram);
|
||||
m_drawTexturedProgram->addShaderFromSourceCode(Shader::Vertex, glslMainWithTexCoordsVertexShader + glslPositionOnlyVertexShader);
|
||||
m_drawTexturedProgram->addShaderFromSourceCode(Shader::Fragment, glslMainFragmentShader + glslTextureSrcFragmentShader);
|
||||
assert(m_drawTexturedProgram->link());
|
||||
|
||||
m_drawSolidColorProgram = PainterShaderProgramPtr(new PainterShaderProgram);
|
||||
m_drawSolidColorProgram->addShaderFromSourceCode(Shader::Vertex, glslMainVertexShader + glslPositionOnlyVertexShader);
|
||||
m_drawSolidColorProgram->addShaderFromSourceCode(Shader::Fragment, glslMainFragmentShader + glslSolidColorFragmentShader);
|
||||
assert(m_drawSolidColorProgram->link());
|
||||
}
|
||||
|
||||
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::drawProgram(const PainterShaderProgramPtr& program, CoordsBuffer& coordsBuffer, PainterShaderProgram::DrawMode drawMode)
|
||||
{
|
||||
coordsBuffer.cacheVertexArrays();
|
||||
if(coordsBuffer.getVertexCount() == 0)
|
||||
return;
|
||||
|
||||
program->setProjectionMatrix(m_projectionMatrix);
|
||||
program->setOpacity(m_currentOpacity);
|
||||
program->setColor(m_currentColor);
|
||||
program->draw(coordsBuffer, drawMode);
|
||||
}
|
||||
|
||||
void Painter::drawTextureCoords(CoordsBuffer& coordsBuffer, const TexturePtr& texture)
|
||||
{
|
||||
PainterShaderProgramPtr program = m_customProgram ? m_customProgram : m_drawTexturedProgram;
|
||||
program->setTexture(texture);
|
||||
drawProgram(program, coordsBuffer);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
m_coordsBuffer.clear();
|
||||
m_coordsBuffer.addRect(dest, src);
|
||||
drawTextureCoords(m_coordsBuffer, texture);
|
||||
}
|
||||
|
||||
void Painter::drawRepeatedTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src)
|
||||
{
|
||||
if(dest.isEmpty() || src.isEmpty() || !texture->getId())
|
||||
return;
|
||||
|
||||
m_coordsBuffer.clear();
|
||||
m_coordsBuffer.addRepeatedRects(dest, src);
|
||||
drawTextureCoords(m_coordsBuffer, texture);
|
||||
}
|
||||
|
||||
void Painter::drawFilledRect(const Rect& dest)
|
||||
{
|
||||
if(dest.isEmpty())
|
||||
return;
|
||||
|
||||
m_coordsBuffer.clear();
|
||||
m_coordsBuffer.addRect(dest);
|
||||
drawProgram(m_customProgram ? m_customProgram : m_drawSolidColorProgram, m_coordsBuffer);
|
||||
}
|
||||
|
||||
void Painter::drawBoundingRect(const Rect& dest, int innerLineWidth)
|
||||
{
|
||||
if(dest.isEmpty() || innerLineWidth == 0)
|
||||
return;
|
||||
|
||||
m_coordsBuffer.clear();
|
||||
m_coordsBuffer.addBoudingRect(dest, innerLineWidth);
|
||||
drawProgram(m_customProgram ? m_customProgram : m_drawSolidColorProgram, m_coordsBuffer);
|
||||
}
|
||||
|
||||
void Painter::setCustomProgram(PainterShaderProgramPtr program)
|
||||
{
|
||||
m_customProgram = program;
|
||||
}
|
||||
|
||||
void Painter::setCompositionMode(Painter::CompositionMode compositionMode)
|
||||
{
|
||||
switch(compositionMode) {
|
||||
case CompositionMode_SourceOver:
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
break;
|
||||
case CompositionMode_ColorizeSource:
|
||||
glBlendFunc(GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA);
|
||||
break;
|
||||
case CompositionMode_AdditiveSource:
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||
break;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* 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"
|
||||
#include <framework/util/databuffer.h>
|
||||
#include "coordsbuffer.h"
|
||||
#include "paintershaderprogram.h"
|
||||
|
||||
class Painter
|
||||
{
|
||||
public:
|
||||
enum CompositionMode {
|
||||
CompositionMode_SourceOver,
|
||||
CompositionMode_ColorizeSource,
|
||||
CompositionMode_AdditiveSource
|
||||
};
|
||||
|
||||
void init();
|
||||
void terminate();
|
||||
|
||||
void updateProjectionMatrix(const Size& viewportSize, bool inverseYAxis = false);
|
||||
|
||||
void drawProgram(const PainterShaderProgramPtr& program, CoordsBuffer& coordsBuffer, PainterShaderProgram::DrawMode drawMode = PainterShaderProgram::Triangles);
|
||||
void drawTextureCoords(CoordsBuffer& coordsBuffer, const TexturePtr& texture);
|
||||
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 setCustomProgram(PainterShaderProgramPtr program);
|
||||
void releaseCustomProgram() { m_customProgram = nullptr; }
|
||||
void setCompositionMode(CompositionMode compositionMode);
|
||||
|
||||
GLfloat *getProjectionMatrix() { return (GLfloat*)m_projectionMatrix; }
|
||||
|
||||
private:
|
||||
PainterShaderProgramPtr m_drawTexturedProgram;
|
||||
PainterShaderProgramPtr m_drawSolidColorProgram;
|
||||
PainterShaderProgramPtr m_customProgram;
|
||||
GLfloat m_projectionMatrix[3][3];
|
||||
Color m_currentColor;
|
||||
GLfloat m_currentOpacity;
|
||||
CoordsBuffer m_coordsBuffer;
|
||||
};
|
||||
|
||||
extern Painter g_painter;
|
||||
|
||||
#endif
|
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
* 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"
|
||||
#include <framework/core/clock.h>
|
||||
|
||||
bool PainterShaderProgram::link()
|
||||
{
|
||||
bindAttributeLocation(VERTEX_COORDS_ATTR, "vertexCoord");
|
||||
bindAttributeLocation(TEXTURE_COORDS_ATTR, "textureCoord");
|
||||
if(ShaderProgram::link()) {
|
||||
bindUniformLocation(PROJECTION_MATRIX_UNIFORM, "projectionMatrix");
|
||||
bindUniformLocation(TEXTURE_TRANSFORM_MATRIX_UNIFORM, "textureTransformMatrix");
|
||||
bindUniformLocation(COLOR_UNIFORM, "color");
|
||||
bindUniformLocation(OPACITY_UNIFORM, "opacity");
|
||||
bindUniformLocation(TEXTURE_UNIFORM, "texture");
|
||||
bindUniformLocation(TICKS_UNIFORM, "ticks");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void PainterShaderProgram::setProjectionMatrix(float projectionMatrix[3][3])
|
||||
{
|
||||
bind();
|
||||
setUniformValue(PROJECTION_MATRIX_UNIFORM, projectionMatrix, true);
|
||||
}
|
||||
|
||||
void PainterShaderProgram::setColor(const Color& color)
|
||||
{
|
||||
bind();
|
||||
setUniformValue(COLOR_UNIFORM, color);
|
||||
}
|
||||
|
||||
void PainterShaderProgram::setOpacity(GLfloat opacity)
|
||||
{
|
||||
bind();
|
||||
setUniformValue(OPACITY_UNIFORM, opacity);
|
||||
}
|
||||
|
||||
void PainterShaderProgram::setUniformTexture(int location, const TexturePtr& texture, int index)
|
||||
{
|
||||
if(!texture)
|
||||
return;
|
||||
glActiveTexture(GL_TEXTURE0 + index);
|
||||
glBindTexture(GL_TEXTURE_2D, texture->getId());
|
||||
setUniformValue(location, index);
|
||||
}
|
||||
|
||||
void PainterShaderProgram::setTexture(const TexturePtr& texture)
|
||||
{
|
||||
if(!texture)
|
||||
return;
|
||||
|
||||
float w = texture->getGlSize().width();
|
||||
float h = texture->getGlSize().height();
|
||||
|
||||
GLfloat textureTransformMatrix[2][2] = {
|
||||
{ 1.0f/w, 0.0f },
|
||||
{ 0.0f, 1.0f/h }
|
||||
};
|
||||
|
||||
bind();
|
||||
setUniformTexture(TEXTURE_UNIFORM, texture, 0);
|
||||
setUniformValue(TEXTURE_TRANSFORM_MATRIX_UNIFORM, textureTransformMatrix, true);
|
||||
}
|
||||
|
||||
void PainterShaderProgram::draw(const CoordsBuffer& coordsBuffer, DrawMode drawMode)
|
||||
{
|
||||
assert(bind());
|
||||
|
||||
setUniformValue(TICKS_UNIFORM, (GLfloat)g_clock.ticks());
|
||||
|
||||
int numVertices = coordsBuffer.getVertexCount();
|
||||
if(numVertices == 0)
|
||||
return;
|
||||
|
||||
bool mustDisableVertexArray = false;
|
||||
if(coordsBuffer.getVertexCount() > 0) {
|
||||
enableAttributeArray(PainterShaderProgram::VERTEX_COORDS_ATTR);
|
||||
setAttributeArray(PainterShaderProgram::VERTEX_COORDS_ATTR, coordsBuffer.getVertices(), 2);
|
||||
mustDisableVertexArray = true;
|
||||
}
|
||||
|
||||
bool mustDisableTexCoordsArray = false;
|
||||
if(coordsBuffer.getTextureCoords() > 0) {
|
||||
enableAttributeArray(PainterShaderProgram::TEXTURE_COORDS_ATTR);
|
||||
setAttributeArray(PainterShaderProgram::TEXTURE_COORDS_ATTR, coordsBuffer.getTextureCoords(), 2);
|
||||
mustDisableTexCoordsArray = true;
|
||||
}
|
||||
|
||||
glDrawArrays(drawMode, 0, numVertices);
|
||||
|
||||
if(mustDisableVertexArray)
|
||||
disableAttributeArray(PainterShaderProgram::VERTEX_COORDS_ATTR);
|
||||
|
||||
if(mustDisableTexCoordsArray)
|
||||
disableAttributeArray(PainterShaderProgram::TEXTURE_COORDS_ATTR);
|
||||
|
||||
//release();
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* 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"
|
||||
#include "coordsbuffer.h"
|
||||
|
||||
class PainterShaderProgram : public ShaderProgram
|
||||
{
|
||||
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,
|
||||
TICKS_UNIFORM = 5
|
||||
};
|
||||
public:
|
||||
enum DrawMode {
|
||||
Triangles = GL_TRIANGLES,
|
||||
TriangleStrip = GL_TRIANGLE_STRIP
|
||||
};
|
||||
|
||||
bool link();
|
||||
|
||||
void setProjectionMatrix(GLfloat projectionMatrix[3][3]);
|
||||
void setColor(const Color& color);
|
||||
void setOpacity(GLfloat opacity);
|
||||
void setTexture(const TexturePtr& texture);
|
||||
void setUniformTexture(int location, const TexturePtr& texture, int index);
|
||||
void draw(const CoordsBuffer& coordsBuffer, DrawMode drawMode = Triangles);
|
||||
|
||||
private:
|
||||
DrawMode m_drawMode;
|
||||
};
|
||||
|
||||
#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 std::string glslMainVertexShader = "\n\
|
||||
highp vec4 calculatePosition();\n\
|
||||
void main() {\n\
|
||||
gl_Position = calculatePosition();\n\
|
||||
}\n";
|
||||
|
||||
static const std::string glslMainWithTexCoordsVertexShader = "\n\
|
||||
attribute highp vec2 textureCoord;\n\
|
||||
uniform highp mat2 textureTransformMatrix;\n\
|
||||
varying highp vec2 textureCoords;\n\
|
||||
highp vec4 calculatePosition();\n\
|
||||
void main()\n\
|
||||
{\n\
|
||||
gl_Position = calculatePosition();\n\
|
||||
textureCoords = textureTransformMatrix * textureCoord;\n\
|
||||
}\n";
|
||||
|
||||
static std::string glslPositionOnlyVertexShader = "\n\
|
||||
attribute highp vec2 vertexCoord;\n\
|
||||
uniform highp mat3 projectionMatrix;\n\
|
||||
highp vec4 calculatePosition() {\n\
|
||||
return vec4(projectionMatrix * vec3(vertexCoord.xy, 1), 1);\n\
|
||||
}\n";
|
||||
|
||||
static const std::string glslMainFragmentShader = "\n\
|
||||
uniform lowp float opacity;\n\
|
||||
lowp vec4 calculatePixel();\n\
|
||||
void main()\n\
|
||||
{\n\
|
||||
gl_FragColor = calculatePixel() * opacity;\n\
|
||||
}\n";
|
||||
|
||||
static const std::string glslTextureSrcFragmentShader = "\n\
|
||||
varying mediump vec2 textureCoords;\n\
|
||||
uniform lowp vec4 color;\n\
|
||||
uniform sampler2D texture;\n\
|
||||
lowp vec4 calculatePixel() {\n\
|
||||
return texture2D(texture, textureCoords) * color;\n\
|
||||
}\n";
|
||||
|
||||
static const std::string glslSolidColorFragmentShader = "\n\
|
||||
uniform lowp vec4 color;\n\
|
||||
lowp vec4 calculatePixel() {\n\
|
||||
return color;\n\
|
||||
}\n";
|
|
@ -19,19 +19,19 @@ Particle::Particle(const Rect& rect, float vx, float vy, float ax, float ay, flo
|
|||
|
||||
Particle::~Particle()
|
||||
{
|
||||
dump << "deleted";
|
||||
//dump << "deleted";
|
||||
}
|
||||
|
||||
void Particle::render()
|
||||
{
|
||||
g_graphics.bindColor(m_color);
|
||||
g_painter.setColor(m_color);
|
||||
|
||||
if(!m_texture)
|
||||
g_graphics.drawFilledRect(m_rect);
|
||||
g_painter.drawFilledRect(m_rect);
|
||||
else {
|
||||
g_graphics.bindBlendFunc(Fw::BlendParticles);
|
||||
g_graphics.drawTexturedRect(m_rect, m_texture);
|
||||
g_graphics.bindBlendFunc(Fw::BlendDefault);
|
||||
g_painter.setCompositionMode(Painter::CompositionMode_AdditiveSource);
|
||||
g_painter.drawTexturedRect(m_rect, m_texture);
|
||||
g_painter.setCompositionMode(Painter::CompositionMode_SourceOver);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* 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"
|
||||
#include <framework/core/resourcemanager.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)
|
||||
{
|
||||
#ifndef OPENGL_ES2
|
||||
static const char *qualifierDefines =
|
||||
"#define lowp\n"
|
||||
"#define mediump\n"
|
||||
"#define highp\n";
|
||||
#else
|
||||
static const char *qualifierDefines =
|
||||
"#ifndef GL_FRAGMENT_PRECISION_HIGH\n"
|
||||
"#define highp mediump\n"
|
||||
"#endif\n";
|
||||
#endif
|
||||
|
||||
std::string code = qualifierDefines;
|
||||
code.append(sourceCode);
|
||||
const char *c_source = code.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::string sourceCode = g_resources.loadFile(sourceFile);
|
||||
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 < MAX_UNIFORM_LOCATIONS);
|
||||
m_uniformLocations[location] = glGetUniformLocation(m_programId, name);
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* 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 = 30
|
||||
};
|
||||
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();
|
||||
virtual 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, const Color& color) { glUniform4f(m_uniformLocations[location], color.r() / 255.0f, color.g() / 255.0f, color.b() / 255.0f, color.a() / 255.0f); }
|
||||
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, const Color& color) { glUniform4f(glGetUniformLocation(m_programId, name), color.r() / 255.0f, color.g() / 255.0f, color.b() / 255.0f, color.a() / 255.0f); }
|
||||
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()
|
||||
{
|
||||
assert(!g_graphics.isDrawing());
|
||||
// free texture from gl memory
|
||||
if(m_textureId > 0)
|
||||
glDeleteTextures(1, &m_textureId);
|
||||
|
@ -44,9 +43,7 @@ Texture::~Texture()
|
|||
|
||||
uint Texture::internalLoadGLTexture(uchar *pixels, int channels, int width, int height)
|
||||
{
|
||||
assert(!g_graphics.isDrawing());
|
||||
|
||||
m_size.setSize(width, height);
|
||||
m_size.resize(width, height);
|
||||
|
||||
// gets max texture size supported by the driver
|
||||
static GLint maxTexSize = -1;
|
||||
|
@ -70,7 +67,7 @@ uint Texture::internalLoadGLTexture(uchar *pixels, int channels, int width, int
|
|||
std::vector<uint8> tmp;
|
||||
|
||||
// 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;
|
||||
while(glWidth < width)
|
||||
glWidth = glWidth << 1;
|
||||
|
@ -88,7 +85,7 @@ uint Texture::internalLoadGLTexture(uchar *pixels, int channels, int width, int
|
|||
pixels = &tmp[0];
|
||||
}
|
||||
|
||||
m_glSize.setSize(glWidth, glHeight);
|
||||
m_glSize.resize(glWidth, glHeight);
|
||||
//} else
|
||||
// m_glSize = m_size;
|
||||
|
||||
|
@ -110,7 +107,7 @@ uint Texture::internalLoadGLTexture(uchar *pixels, int channels, int width, int
|
|||
}
|
||||
|
||||
// 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
|
||||
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)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
|
|
|
@ -37,22 +37,22 @@ public:
|
|||
virtual void enableBilinearFilter();
|
||||
|
||||
/// Get OpenGL texture id
|
||||
uint getId() const { return m_textureId; }
|
||||
GLuint getId() { return m_textureId; }
|
||||
|
||||
/// Copy pixels from OpenGL texture
|
||||
std::vector<uint8> getPixels();
|
||||
|
||||
int getWidth() const { return m_size.width(); }
|
||||
int getHeight() const { return m_size.height(); }
|
||||
const Size& getSize() const { return m_size; }
|
||||
const Size& getGlSize() const { return m_glSize; }
|
||||
int getWidth() { return m_size.width(); }
|
||||
int getHeight() { return m_size.height(); }
|
||||
const Size& getSize() { return m_size; }
|
||||
const Size& getGlSize() { return m_glSize; }
|
||||
|
||||
bool isEmpty() const { return m_textureId == 0; }
|
||||
|
||||
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_glSize;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* 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 "textureglyphcache.h"
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* 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 TEXTUREGLYPHCACHE_H
|
||||
#define TEXTUREGLYPHCACHE_H
|
||||
|
||||
class TextureGlyphCache
|
||||
{
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* 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 VERTEXARRAY_H
|
||||
#define VERTEXARRAY_H
|
||||
|
||||
#include "declarations.h"
|
||||
#include <framework/util/databuffer.h>
|
||||
|
||||
class VertexArray
|
||||
{
|
||||
public:
|
||||
inline void addVertex(GLfloat x, GLfloat y) { m_buffer << x << y; }
|
||||
inline void addRect(const Rect& rect) {
|
||||
GLfloat top = rect.top();
|
||||
GLfloat right = rect.right()+1;
|
||||
GLfloat bottom = rect.bottom()+1;
|
||||
GLfloat left = rect.left();
|
||||
|
||||
addVertex(left, top);
|
||||
addVertex(right, top);
|
||||
addVertex(left, bottom);
|
||||
addVertex(left, bottom);
|
||||
addVertex(right, top);
|
||||
addVertex(right, bottom);
|
||||
}
|
||||
|
||||
inline void addQuad(const Rect& rect) {
|
||||
GLfloat top = rect.top();
|
||||
GLfloat right = rect.right()+1;
|
||||
GLfloat bottom = rect.bottom()+1;
|
||||
GLfloat left = rect.left();
|
||||
|
||||
addVertex(left, top);
|
||||
addVertex(right, top);
|
||||
addVertex(left, bottom);
|
||||
addVertex(right, bottom);
|
||||
}
|
||||
|
||||
void clear() { m_buffer.reset(); }
|
||||
GLfloat *vertices() const { return m_buffer.data(); }
|
||||
int vertexCount() const { return m_buffer.size() / 2; }
|
||||
|
||||
private:
|
||||
DataBuffer<GLfloat> m_buffer;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -36,73 +36,110 @@ void Application::registerLuaFunctions()
|
|||
// UIWidget
|
||||
g_lua.registerClass<UIWidget>();
|
||||
g_lua.bindClassStaticFunction<UIWidget>("create", &UIWidget::create<UIWidget>);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("getId", &UIWidget::getId);
|
||||
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>("destroy", &UIWidget::destroy);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("setVisible", &UIWidget::setVisible);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("getWidth", &UIWidget::getWidth);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("setWidth", &UIWidget::setWidth);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("getHeight", &UIWidget::getHeight);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("setHeight", &UIWidget::setHeight);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("getSize", &UIWidget::getSize);
|
||||
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>("setEnabled", &UIWidget::setEnabled);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("setPressed", &UIWidget::setPressed);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("setId", &UIWidget::setId);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("setFocusable", &UIWidget::setFocusable);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("setPhantom", &UIWidget::setPhantom);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("setStyle", &UIWidget::setStyle);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("applyStyle", &UIWidget::applyStyle);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("getStyle", &UIWidget::getStyle);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("getMarginTop", &UIWidget::getMarginTop);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("setStyleFromNode", &UIWidget::setStyleFromNode);
|
||||
//g_lua.bindClassMemberFunction<UIWidget>("setLayout", &UIWidget::setLayout);
|
||||
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>("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>("isVisible", &UIWidget::isVisible);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("isHidden", &UIWidget::isHidden);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("isHovered", &UIWidget::isHovered);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("isFocused", &UIWidget::isFocused);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("isPressed", &UIWidget::isPressed);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("isEnabled", &UIWidget::isEnabled);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("isDisabled", &UIWidget::isDisabled);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("isActive", &UIWidget::isActive);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("setMarginBottom", &UIWidget::setMarginBottom);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("setMarginLeft", &UIWidget::setMarginLeft);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("setSizeFixed", &UIWidget::setSizeFixed);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("setLastFocusReason", &UIWidget::setLastFocusReason);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("resize", &UIWidget::resize);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("moveTo", &UIWidget::moveTo);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("hide", &UIWidget::hide);
|
||||
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>("unlock", &UIWidget::unlock);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("focus", &UIWidget::focus);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("getChildren", &UIWidget::getChildren);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("recursiveGetChildById", &UIWidget::recursiveGetChildById);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("getChildById", &UIWidget::getChildById);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("getChildByIndex", &UIWidget::getChildByIndex);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("isActive", &UIWidget::isActive);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("isEnabled", &UIWidget::isEnabled);
|
||||
g_lua.bindClassMemberFunction<UIWidget>("isDisabled", &UIWidget::isDisabled);
|
||||
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>("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>("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>("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>("focusNextChild", &UIWidget::focusNextChild);
|
||||
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>("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>("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
|
||||
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>("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
|
||||
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("setDefaultFont", std::bind(&FontManager::setDefaultFont, &g_fonts, _1));
|
||||
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("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);
|
||||
#else
|
||||
static int attrList[] = {
|
||||
EGL_BUFFER_SIZE, 16,
|
||||
//EGL_BUFFER_SIZE, 24,
|
||||
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
|
||||
EGL_NONE
|
||||
};
|
||||
|
|
|
@ -40,9 +40,9 @@ void UIButton::render()
|
|||
|
||||
if(m_icon) {
|
||||
Rect iconRect;
|
||||
iconRect.setSize(m_icon->getSize());
|
||||
iconRect.resize(m_icon->getSize());
|
||||
iconRect.moveCenter(m_rect.center());
|
||||
g_graphics.drawTexturedRect(iconRect, m_icon);
|
||||
g_painter.drawTexturedRect(iconRect, m_icon);
|
||||
}
|
||||
|
||||
Rect textRect = m_rect;
|
||||
|
|
|
@ -38,10 +38,10 @@ void UICheckBox::render()
|
|||
{
|
||||
if(m_image) {
|
||||
Rect boxRect;
|
||||
boxRect.setSize(m_boxSize);
|
||||
boxRect.resize(m_boxSize);
|
||||
boxRect.moveLeft(m_rect.left());
|
||||
boxRect.moveVerticalCenter(m_rect.verticalCenter());
|
||||
g_graphics.bindColor(m_backgroundColor);
|
||||
g_painter.setColor(m_backgroundColor);
|
||||
m_image->draw(boxRect);
|
||||
}
|
||||
|
||||
|
|
|
@ -47,9 +47,9 @@ void UILineEdit::render()
|
|||
int textLength = m_text.length();
|
||||
const TexturePtr& texture = m_font->getTexture();
|
||||
|
||||
g_graphics.bindColor(m_foregroundColor);
|
||||
g_painter.setColor(m_foregroundColor);
|
||||
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
|
||||
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());
|
||||
else
|
||||
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) {
|
||||
m_cursorTicks = g_clock.ticks();
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include <framework/otml/otml.h>
|
||||
#include <framework/graphics/graphics.h>
|
||||
#include <framework/platform/platformwindow.h>
|
||||
|
||||
UIManager g_ui;
|
||||
|
||||
|
@ -33,7 +34,7 @@ void UIManager::init()
|
|||
// creates root widget
|
||||
m_rootWidget = UIWidget::create<UIWidget>();
|
||||
m_rootWidget->setId("root");
|
||||
m_rootWidget->resize(g_graphics.getScreenSize());
|
||||
m_rootWidget->resize(g_window.getSize());
|
||||
}
|
||||
|
||||
void UIManager::terminate()
|
||||
|
@ -50,7 +51,7 @@ void UIManager::render()
|
|||
|
||||
void UIManager::resize(const Size& size)
|
||||
{
|
||||
m_rootWidget->resize(g_graphics.getScreenSize());
|
||||
m_rootWidget->resize(g_window.getSize());
|
||||
}
|
||||
|
||||
void UIManager::inputEvent(const InputEvent& event)
|
||||
|
@ -174,12 +175,15 @@ UIWidgetPtr UIManager::loadWidgetFromOTML(const OTMLNodePtr& widgetNode, const U
|
|||
if(parent)
|
||||
parent->addChild(widget);
|
||||
|
||||
widget->setStyleFromNode(styleNode);
|
||||
if(widget) {
|
||||
widget->setStyleFromNode(styleNode);
|
||||
|
||||
for(const OTMLNodePtr& childNode : widgetNode->children()) {
|
||||
if(!childNode->isUnique())
|
||||
loadWidgetFromOTML(childNode, widget);
|
||||
}
|
||||
for(const OTMLNodePtr& childNode : widgetNode->children()) {
|
||||
if(!childNode->isUnique())
|
||||
loadWidgetFromOTML(childNode, widget);
|
||||
}
|
||||
} else
|
||||
logError("Unable to create widget of type '", widgetType, "'");
|
||||
|
||||
return widget;
|
||||
}
|
||||
|
|
|
@ -35,14 +35,14 @@ void UIProgressBar::render()
|
|||
{
|
||||
UIWidget::render();
|
||||
|
||||
g_graphics.bindColor(m_foregroundColor);
|
||||
g_graphics.drawBoundingRect(m_rect, 1);
|
||||
g_painter.setColor(m_foregroundColor);
|
||||
g_painter.drawBoundingRect(m_rect, 1);
|
||||
|
||||
Rect fillRect = m_rect.expanded(-1);
|
||||
fillRect.setWidth(fillRect.width() * m_percent / 100.0);
|
||||
|
||||
g_graphics.bindColor(m_backgroundColor);
|
||||
g_graphics.drawFilledRect(fillRect);
|
||||
g_painter.setColor(m_backgroundColor);
|
||||
g_painter.drawFilledRect(fillRect);
|
||||
}
|
||||
|
||||
void UIProgressBar::setPercent(double percent)
|
||||
|
|
|
@ -69,7 +69,7 @@ void UIWidget::renderSelf()
|
|||
{
|
||||
// draw background
|
||||
if(m_image) {
|
||||
g_graphics.bindColor(m_backgroundColor);
|
||||
g_painter.setColor(m_backgroundColor);
|
||||
m_image->draw(m_rect);
|
||||
}
|
||||
}
|
||||
|
@ -81,20 +81,20 @@ void UIWidget::renderChildren()
|
|||
// render only visible children with a valid rect inside our rect
|
||||
if(child->isExplicitlyVisible() && child->getRect().isValid() && child->getRect().intersects(m_rect)) {
|
||||
// store current graphics opacity
|
||||
int oldOpacity = g_graphics.getOpacity();
|
||||
int oldOpacity = g_painter.getOpacity();
|
||||
|
||||
// decrease to self opacity
|
||||
if(child->getOpacity() < oldOpacity)
|
||||
g_graphics.setOpacity(child->getOpacity());
|
||||
g_painter.setOpacity(child->getOpacity());
|
||||
|
||||
child->render();
|
||||
|
||||
// debug draw box
|
||||
//g_graphics.bindColor(Fw::green);
|
||||
//g_graphics.drawBoundingRect(child->getRect());
|
||||
//g_painter.setColor(Fw::green);
|
||||
//g_painter.drawBoundingRect(child->getRect());
|
||||
//g_fonts.getDefaultFont()->renderText(child->getId(), child->getPosition() + Point(2, 0), Fw::red);
|
||||
|
||||
g_graphics.setOpacity(oldOpacity);
|
||||
g_painter.setOpacity(oldOpacity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* 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 DATABUFFER_H
|
||||
#define DATABUFFER_H
|
||||
|
||||
template<class T>
|
||||
class DataBuffer
|
||||
{
|
||||
public:
|
||||
DataBuffer(int res = 64) {
|
||||
m_capacity = res;
|
||||
m_buffer = new T[m_capacity];
|
||||
m_size = 0;
|
||||
}
|
||||
~DataBuffer() { delete[] m_buffer; }
|
||||
|
||||
inline void reset() { m_size = 0; }
|
||||
inline bool isEmpty() const { return m_size == 0; }
|
||||
|
||||
inline int size() const { return m_size; }
|
||||
inline T *data() const { return m_buffer; }
|
||||
|
||||
inline const T& at(int i) const { return m_buffer[i]; }
|
||||
inline const T& last() const { return m_buffer[m_size-1]; }
|
||||
inline const T& first() const { return m_buffer[0]; }
|
||||
inline const T& operator[](int i) const { return m_buffer[i]; }
|
||||
inline T& operator[](int i) { return m_buffer[i]; }
|
||||
|
||||
inline void add(const T &t) {
|
||||
if(m_size >= m_capacity) {
|
||||
m_capacity *= 2;
|
||||
T *buffer = new T[m_capacity];
|
||||
for(int i=0;i<m_size;++i)
|
||||
buffer[i] = m_buffer[i];
|
||||
delete[] m_buffer;
|
||||
m_buffer = buffer;
|
||||
}
|
||||
m_buffer[m_size++] = t;
|
||||
}
|
||||
|
||||
inline DataBuffer &operator<<(const T &t) { add(t); return *this; }
|
||||
|
||||
private:
|
||||
int m_size;
|
||||
int m_capacity;
|
||||
T *m_buffer;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -78,8 +78,8 @@ public:
|
|||
void setBottomLeft(const TPoint<T> &p) { x1 = p.x; y2 = p.y; }
|
||||
void setWidth(T width) { x2 = x1 + width - 1; }
|
||||
void setHeight(T height) { y2 = y1 + height- 1; }
|
||||
void setSize(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(T width, T height) { x2 = x1 + width - 1; y2 = y1 + 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 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 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 setHeight(T h) { ht = h; }
|
||||
|
||||
|
@ -115,7 +115,7 @@ std::istream& operator>>(std::istream& in, TSize<T>& size)
|
|||
{
|
||||
T w, h;
|
||||
in >> w >> h;
|
||||
size.setSize(w, h);
|
||||
size.resize(w, h);
|
||||
return in;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
#include <sstream>
|
||||
#include <exception>
|
||||
#include <cxxabi.h>
|
||||
#include <vector>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include "types.h"
|
||||
#include "exception.h"
|
||||
|
||||
|
@ -258,6 +260,16 @@ inline std::string ip2str(uint32 ip) {
|
|||
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>
|
||||
void throwException(const T&... args) {
|
||||
throw Exception(Fw::mkstr(args...));
|
||||
|
|
|
@ -25,9 +25,9 @@
|
|||
int main(int argc, const char* argv[])
|
||||
{
|
||||
std::vector<std::string> args(argv, argv + argc);
|
||||
OTClient otclient;
|
||||
otclient.init(args);
|
||||
otclient.run();
|
||||
otclient.terminate();
|
||||
OTClient app;
|
||||
app.init(args);
|
||||
app.run();
|
||||
app.terminate();
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -250,14 +250,6 @@ namespace Otc
|
|||
ClientGetObjectInfo = 243
|
||||
};
|
||||
|
||||
enum SpriteMask {
|
||||
SpriteRedMask = 0,
|
||||
SpriteGreenMask,
|
||||
SpriteBlueMask,
|
||||
SpriteYellowMask,
|
||||
SpriteNoMask = 255
|
||||
};
|
||||
|
||||
enum InventorySlots {
|
||||
InventorySlotHead = 1,
|
||||
InventorySlotNecklace,
|
||||
|
|
|
@ -31,6 +31,10 @@
|
|||
#include <framework/core/eventdispatcher.h>
|
||||
#include <framework/core/clock.h>
|
||||
|
||||
#include <framework/graphics/paintershaderprogram.h>
|
||||
#include <framework/graphics/paintershadersources.h>
|
||||
#include "spritemanager.h"
|
||||
|
||||
Creature::Creature() : Thing()
|
||||
{
|
||||
m_healthPercent = 0;
|
||||
|
@ -43,12 +47,31 @@ Creature::Creature() : Thing()
|
|||
m_informationFont = g_fonts.getFont("verdana-11px-rounded");
|
||||
}
|
||||
|
||||
PainterShaderProgramPtr outfitProgram;
|
||||
int HEAD_COLOR_UNIFORM = 10;
|
||||
int BODY_COLOR_UNIFORM = 11;
|
||||
int LEGS_COLOR_UNIFORM = 12;
|
||||
int FEET_COLOR_UNIFORM = 13;
|
||||
int MASK_TEXTURE_UNIFORM = 14;
|
||||
|
||||
void Creature::draw(const Point& p)
|
||||
{
|
||||
// TODO: activate on attack, follow, discover how 'attacked' works
|
||||
if(m_showSquareColor) {
|
||||
g_graphics.bindColor(Outfit::getColor(m_squareColor));
|
||||
g_graphics.drawBoundingRect(Rect(p + m_walkOffset - 8, Size(32, 32)), 2);
|
||||
g_painter.setColor(Outfit::getColor(m_squareColor));
|
||||
g_painter.drawBoundingRect(Rect(p + m_walkOffset - 8, Size(32, 32)), 2);
|
||||
}
|
||||
|
||||
if(!outfitProgram) {
|
||||
outfitProgram = PainterShaderProgramPtr(new PainterShaderProgram);
|
||||
outfitProgram->addShaderFromSourceCode(Shader::Vertex, glslMainWithTexCoordsVertexShader + glslPositionOnlyVertexShader);
|
||||
outfitProgram->addShaderFromSourceFile(Shader::Fragment, "/outfit.frag");
|
||||
assert(outfitProgram->link());
|
||||
outfitProgram->bindUniformLocation(HEAD_COLOR_UNIFORM, "headColor");
|
||||
outfitProgram->bindUniformLocation(BODY_COLOR_UNIFORM, "bodyColor");
|
||||
outfitProgram->bindUniformLocation(LEGS_COLOR_UNIFORM, "legsColor");
|
||||
outfitProgram->bindUniformLocation(FEET_COLOR_UNIFORM, "feetColor");
|
||||
outfitProgram->bindUniformLocation(MASK_TEXTURE_UNIFORM, "maskTexture");
|
||||
}
|
||||
|
||||
// Render creature
|
||||
|
@ -58,35 +81,52 @@ void Creature::draw(const Point& p)
|
|||
if(m_yPattern > 0 && !(m_outfit.getAddons() & (1 << (m_yPattern-1))))
|
||||
continue;
|
||||
|
||||
// draw white item
|
||||
g_graphics.bindColor(Fw::white);
|
||||
internalDraw(p + m_walkOffset, 0);
|
||||
g_painter.setCustomProgram(outfitProgram);
|
||||
|
||||
// draw mask if exists
|
||||
if(m_type->dimensions[ThingType::Layers] > 1) {
|
||||
// switch to blend color mode
|
||||
g_graphics.bindBlendFunc(Fw::BlendColorzing);
|
||||
outfitProgram->bind();
|
||||
outfitProgram->setUniformValue(HEAD_COLOR_UNIFORM, m_outfit.getHeadColor());
|
||||
outfitProgram->setUniformValue(BODY_COLOR_UNIFORM, m_outfit.getBodyColor());
|
||||
outfitProgram->setUniformValue(LEGS_COLOR_UNIFORM, m_outfit.getLegsColor());
|
||||
outfitProgram->setUniformValue(FEET_COLOR_UNIFORM, m_outfit.getFeetColor());
|
||||
|
||||
// head
|
||||
g_graphics.bindColor(m_outfit.getHeadColor());
|
||||
internalDraw(p + m_walkOffset, 1, Otc::SpriteYellowMask);
|
||||
for(int yi = 0; yi < m_type->dimensions[ThingType::Height]; yi++) {
|
||||
for(int xi = 0; xi < m_type->dimensions[ThingType::Width]; xi++) {
|
||||
int sprIndex = ((((((m_animation % m_type->dimensions[ThingType::AnimationPhases])
|
||||
* m_type->dimensions[ThingType::PatternZ] + m_zPattern)
|
||||
* m_type->dimensions[ThingType::PatternY] + m_yPattern)
|
||||
* m_type->dimensions[ThingType::PatternX] + m_xPattern)
|
||||
* m_type->dimensions[ThingType::Layers] + 0)
|
||||
* m_type->dimensions[ThingType::Height] + yi)
|
||||
* m_type->dimensions[ThingType::Width] + xi;
|
||||
if(m_type->dimensions[ThingType::Layers] > 1) {
|
||||
int maskIndex = ((((((m_animation % m_type->dimensions[ThingType::AnimationPhases])
|
||||
* m_type->dimensions[ThingType::PatternZ] + m_zPattern)
|
||||
* m_type->dimensions[ThingType::PatternY] + m_yPattern)
|
||||
* m_type->dimensions[ThingType::PatternX] + m_xPattern)
|
||||
* m_type->dimensions[ThingType::Layers] + 1)
|
||||
* m_type->dimensions[ThingType::Height] + yi)
|
||||
* m_type->dimensions[ThingType::Width] + xi;
|
||||
int spriteId = m_type->sprites[maskIndex];
|
||||
if(!spriteId)
|
||||
continue;
|
||||
TexturePtr maskTex = g_sprites.getSpriteTexture(spriteId);
|
||||
outfitProgram->setUniformTexture(MASK_TEXTURE_UNIFORM, maskTex, 1);
|
||||
}
|
||||
|
||||
// body
|
||||
g_graphics.bindColor(m_outfit.getBodyColor());
|
||||
internalDraw(p + m_walkOffset, 1, Otc::SpriteRedMask);
|
||||
int spriteId = m_type->sprites[sprIndex];
|
||||
if(!spriteId)
|
||||
continue;
|
||||
|
||||
// legs
|
||||
g_graphics.bindColor(m_outfit.getLegsColor());
|
||||
internalDraw(p + m_walkOffset, 1, Otc::SpriteGreenMask);
|
||||
TexturePtr spriteTex = g_sprites.getSpriteTexture(spriteId);
|
||||
|
||||
// feet
|
||||
g_graphics.bindColor(m_outfit.getFeetColor());
|
||||
internalDraw(p + m_walkOffset, 1, Otc::SpriteBlueMask);
|
||||
|
||||
// restore default blend func
|
||||
g_graphics.bindBlendFunc(Fw::BlendDefault);
|
||||
g_graphics.bindColor(Fw::white);
|
||||
Rect drawRect(((p + m_walkOffset).x - xi*32) - m_type->parameters[ThingType::DisplacementX],
|
||||
((p + m_walkOffset).y - yi*32) - m_type->parameters[ThingType::DisplacementY],
|
||||
32, 32);
|
||||
g_painter.drawTexturedRect(drawRect, spriteTex);
|
||||
}
|
||||
}
|
||||
|
||||
g_painter.releaseCustomProgram();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -115,11 +155,11 @@ void Creature::drawInformation(int x, int y, bool useGray, const Rect& rect)
|
|||
healthRect.setWidth((m_healthPercent / 100.0) * 25);
|
||||
|
||||
// draw
|
||||
g_graphics.bindColor(Fw::black);
|
||||
g_graphics.drawFilledRect(backgroundRect);
|
||||
g_painter.setColor(Fw::black);
|
||||
g_painter.drawFilledRect(backgroundRect);
|
||||
|
||||
g_graphics.bindColor(fillColor);
|
||||
g_graphics.drawFilledRect(healthRect);
|
||||
g_painter.setColor(fillColor);
|
||||
g_painter.drawFilledRect(healthRect);
|
||||
|
||||
m_informationFont->renderText(m_name, textRect, Fw::AlignTopCenter, fillColor);
|
||||
}
|
||||
|
|
|
@ -28,7 +28,9 @@
|
|||
#include "missile.h"
|
||||
#include <framework/graphics/graphics.h>
|
||||
#include <framework/graphics/framebuffer.h>
|
||||
|
||||
#include <framework/graphics/paintershaderprogram.h>
|
||||
#include <framework/graphics/paintershadersources.h>
|
||||
#include <framework/graphics/texture.h>
|
||||
Map g_map;
|
||||
|
||||
Map::Map()
|
||||
|
@ -36,12 +38,20 @@ Map::Map()
|
|||
setVisibleSize(Size(MAP_VISIBLE_WIDTH, MAP_VISIBLE_HEIGHT));
|
||||
}
|
||||
|
||||
PainterShaderProgramPtr program;
|
||||
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));
|
||||
|
||||
g_graphics.bindColor(Fw::white);
|
||||
|
||||
program = PainterShaderProgramPtr(new PainterShaderProgram);
|
||||
program->addShaderFromSourceCode(Shader::Vertex, glslMainWithTexCoordsVertexShader + glslPositionOnlyVertexShader);
|
||||
program->addShaderFromSourceFile(Shader::Fragment, "/shadertest.frag");
|
||||
assert(program->link());
|
||||
}
|
||||
|
||||
g_painter.setColor(Fw::white);
|
||||
m_framebuffer->bind();
|
||||
|
||||
// draw offsets
|
||||
|
@ -80,10 +90,13 @@ void Map::draw(const Rect& rect)
|
|||
}
|
||||
}
|
||||
|
||||
m_framebuffer->unbind();
|
||||
m_framebuffer->release();
|
||||
|
||||
g_graphics.bindColor(Fw::white);
|
||||
|
||||
g_painter.setCustomProgram(program);
|
||||
g_painter.setColor(Fw::white);
|
||||
m_framebuffer->draw(rect);
|
||||
g_painter.releaseCustomProgram();
|
||||
|
||||
// calculate stretch factor
|
||||
float horizontalStretchFactor = rect.width() / (float)(m_visibleSize.width() * NUM_TILE_PIXELS);
|
||||
|
|
|
@ -118,30 +118,7 @@ TexturePtr SpriteManager::loadSpriteTexture(int id)
|
|||
return TexturePtr(new Texture(32, 32, 4, pixels));
|
||||
}
|
||||
|
||||
TexturePtr SpriteManager::loadSpriteMask(TexturePtr spriteTex, Otc::SpriteMask mask)
|
||||
{
|
||||
auto pixels = spriteTex->getPixels();
|
||||
|
||||
static uint32 maskColors[4] = { Fw::red, Fw::green, Fw::blue, Fw::yellow };
|
||||
uint32 maskColor = maskColors[mask];
|
||||
uint32 whiteColor = Fw::white;
|
||||
uint32 alphaColor = Fw::alpha;
|
||||
|
||||
// convert pixels
|
||||
// masked color -> white color
|
||||
// any other color -> alpha color
|
||||
for(int i=0;i<4096;i+=4) {
|
||||
uint32& currentColor = *(uint32*)&pixels[i];
|
||||
if(currentColor == maskColor)
|
||||
currentColor = whiteColor;
|
||||
else
|
||||
currentColor = alphaColor;
|
||||
}
|
||||
|
||||
return TexturePtr(new Texture(32, 32, 4, &pixels[0]));
|
||||
}
|
||||
|
||||
TexturePtr SpriteManager::getSpriteTexture(int id, Otc::SpriteMask mask)
|
||||
TexturePtr SpriteManager::getSpriteTexture(int id)
|
||||
{
|
||||
if(id == 0)
|
||||
return g_graphics.getEmptyTexture();
|
||||
|
@ -149,17 +126,11 @@ TexturePtr SpriteManager::getSpriteTexture(int id, Otc::SpriteMask mask)
|
|||
assert(id > 0 && id <= m_spritesCount);
|
||||
|
||||
// load sprites on demand
|
||||
Sprite& sprite = m_sprites[id-1];
|
||||
if(!sprite.texture)
|
||||
sprite.texture = loadSpriteTexture(id);
|
||||
TexturePtr& sprite = m_sprites[id-1];
|
||||
if(!sprite)
|
||||
sprite = loadSpriteTexture(id);
|
||||
|
||||
//TODO: release unused sprites textures after X seconds
|
||||
// to avoid massive texture allocations
|
||||
|
||||
if(mask != Otc::SpriteNoMask) {
|
||||
if(!sprite.masks[mask])
|
||||
sprite.masks[mask] = loadSpriteMask(sprite.texture, mask);
|
||||
return sprite.masks[mask];
|
||||
} else
|
||||
return sprite.texture;
|
||||
return sprite;
|
||||
}
|
||||
|
|
|
@ -26,11 +26,6 @@
|
|||
#include "declarations.h"
|
||||
#include <framework/graphics/texture.h>
|
||||
|
||||
struct Sprite {
|
||||
TexturePtr texture;
|
||||
TexturePtr masks[4];
|
||||
};
|
||||
|
||||
class SpriteManager
|
||||
{
|
||||
public:
|
||||
|
@ -42,16 +37,15 @@ public:
|
|||
uint32 getSignature() { return m_signature; }
|
||||
int getSpritesCount() { return m_spritesCount; }
|
||||
|
||||
TexturePtr getSpriteTexture(int id, Otc::SpriteMask mask = Otc::SpriteNoMask);
|
||||
TexturePtr getSpriteTexture(int id);
|
||||
|
||||
private:
|
||||
TexturePtr loadSpriteTexture(int id);
|
||||
TexturePtr loadSpriteMask(TexturePtr spriteTex, Otc::SpriteMask mask);
|
||||
|
||||
uint32 m_signature;
|
||||
uint16 m_spritesCount;
|
||||
std::stringstream m_fin;
|
||||
std::vector<Sprite> m_sprites;
|
||||
std::vector<TexturePtr> m_sprites;
|
||||
TexturePtr m_transparentSprite;
|
||||
};
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ Thing::Thing() : m_id(0)
|
|||
m_type = g_thingsType.getEmptyThingType();
|
||||
}
|
||||
|
||||
void Thing::internalDraw(const Point& p, int layers, Otc::SpriteMask mask)
|
||||
void Thing::internalDraw(const Point& p, int layers)
|
||||
{
|
||||
for(int yi = 0; yi < m_type->dimensions[ThingType::Height]; yi++) {
|
||||
for(int xi = 0; xi < m_type->dimensions[ThingType::Width]; xi++) {
|
||||
|
@ -50,12 +50,12 @@ void Thing::internalDraw(const Point& p, int layers, Otc::SpriteMask mask)
|
|||
if(!spriteId)
|
||||
continue;
|
||||
|
||||
TexturePtr spriteTex = g_sprites.getSpriteTexture(spriteId, mask);
|
||||
TexturePtr spriteTex = g_sprites.getSpriteTexture(spriteId);
|
||||
|
||||
Rect drawRect((p.x - xi*32) - m_type->parameters[ThingType::DisplacementX],
|
||||
(p.y - yi*32) - m_type->parameters[ThingType::DisplacementY],
|
||||
32, 32);
|
||||
g_graphics.drawTexturedRect(drawRect, spriteTex);
|
||||
g_painter.drawTexturedRect(drawRect, spriteTex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ public:
|
|||
virtual LocalPlayerPtr asLocalPlayer() { return nullptr; }
|
||||
|
||||
protected:
|
||||
void internalDraw(const Point& p, int layers, Otc::SpriteMask mask = Otc::SpriteNoMask);
|
||||
void internalDraw(const Point& p, int layers);
|
||||
|
||||
uint32 m_id;
|
||||
Position m_position;
|
||||
|
|
|
@ -36,6 +36,5 @@ void OTClient::init(const std::vector<std::string>& args)
|
|||
g_modules.discoverModules();
|
||||
g_modules.autoLoadModules(100);
|
||||
g_modules.ensureModuleLoaded("client");
|
||||
g_modules.ensureModuleLoaded("game");
|
||||
g_modules.autoLoadModules(1000);
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ void UICreature::render()
|
|||
renderSelf();
|
||||
|
||||
if(m_creature) {
|
||||
g_graphics.bindColor(Fw::white);
|
||||
g_painter.setColor(Fw::white);
|
||||
m_creature->draw(m_rect.bottomRight() - Point(32, 32) + m_creatureMargin);
|
||||
}
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ void UIItem::render()
|
|||
renderSelf();
|
||||
|
||||
if(m_item) {
|
||||
g_graphics.bindColor(Fw::white);
|
||||
g_painter.setColor(Fw::white);
|
||||
m_item->draw(m_rect.bottomRight() - Point(32, 32) + m_itemMargin);
|
||||
}
|
||||
|
||||
|
|
|
@ -35,8 +35,8 @@ void UIMap::render()
|
|||
{
|
||||
renderSelf();
|
||||
|
||||
g_graphics.bindColor(Fw::black);
|
||||
g_graphics.drawBoundingRect(m_mapRect.expanded(1));
|
||||
g_painter.setColor(Fw::black);
|
||||
g_painter.drawBoundingRect(m_mapRect.expanded(1));
|
||||
g_map.draw(m_mapRect);
|
||||
|
||||
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);
|
||||
mapSize.scale(mapRect.size(), Fw::KeepAspectRatio);
|
||||
|
||||
m_mapRect.setSize(mapSize);
|
||||
m_mapRect.resize(mapSize);
|
||||
m_mapRect.moveCenter(newRect.center());
|
||||
}
|
||||
|
|
|
@ -15,16 +15,16 @@ if not io.open(cppclassheader, 'r') then
|
|||
return false
|
||||
end
|
||||
|
||||
function string.matchcount(str, pattern)
|
||||
function string:matchcount(pattern)
|
||||
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
|
||||
end
|
||||
|
||||
function string.splitlines(str)
|
||||
function string:splitlines()
|
||||
local t = {}
|
||||
local function helper(line) table.insert(t, line) return "" end
|
||||
helper((str:gsub("(.-)\r?\n", helper)))
|
||||
helper((self:gsub("(.-)\r?\n", helper)))
|
||||
return t
|
||||
end
|
||||
|
||||
|
@ -34,7 +34,7 @@ for line in io.lines(cppclassheader) do
|
|||
foundclassname = line:match('^class ([%w_]+)')
|
||||
if foundclassname then
|
||||
if not cppclassname then
|
||||
guessedclassname = cppclassheader:match('([%w_]+).h'):lower()
|
||||
guessedclassname = cppclassheader:match('([%w_]+)\.h$'):lower()
|
||||
if foundclassname:lower() == guessedclassname then
|
||||
cppclassname = foundclassname
|
||||
end
|
||||
|
@ -69,8 +69,9 @@ for line in io.lines(cppclassheader) do
|
|||
elseif line:match('private:') or line:match('protected:') then
|
||||
publicmethods = false
|
||||
elseif publicmethods then
|
||||
for funcname,args in line:gmatch(' *[%w :_]* ([%w_]+)%(([^%(]*%)) *[;{].*$') do
|
||||
if funcname ~= cppclassname then
|
||||
funcname, args = line:match('^ *[%w <>&\*:_]* ([%w_]+)%(([^%)]*%))[%w ]*[;{].*$')
|
||||
if funcname then
|
||||
if funcname ~= cppclassname and funcname ~= 'create' then
|
||||
numargs = args:matchcount('[^,)]+[,)]')
|
||||
|
||||
if cppclassinstance then
|
||||
|
|
Loading…
Reference in New Issue