Skip to content
Snippets Groups Projects
Commit 4337002d authored by DarkGod's avatar DarkGod
Browse files

Merge branch 'shadedtargetting'

parents 6b8f544b bf88f9f3
No related branches found
No related tags found
No related merge requests found
......@@ -19,6 +19,7 @@
require "engine.class"
local Map = require "engine.Map"
local Shader = require "engine.Shader"
--- handles targetting
module(..., package.seeall, class.make)
......@@ -32,34 +33,62 @@ function _M:init(map, source_actor)
self.cursor = engine.Tiles:loadImage("target_cursor.png"):glTexture()
self.arrow = engine.Tiles:loadImage("target_arrow.png"):glTexture()
self.targetshader = engine.Tiles:loadImage("ui/targetshader.png"):glTexture()
self:createTextures()
self.source_actor = source_actor
-- Setup the tracking target table
-- Notice its values are set to weak references, this has no effects on the number for x and y
-- but it means if the entity field is set to an entity, when it disappears this link wont prevent
-- the garbage collection
self.target = {x=self.source_actor.x, y=self.source_actor.y, entity=nil}
-- setmetatable(self.target, {__mode='v'})
end
function _M:createTextures()
--Use power of two (pot) width and height, rounded up
local pot_width = math.pow(2, math.ceil(math.log(map.tile_w-0.1) / math.log(2.0)))
local pot_height = math.pow(2, math.ceil(math.log(map.tile_h-0.1) / math.log(2.0)))
local pot_width = math.pow(2, math.ceil(math.log(self.tile_w-0.1) / math.log(2.0)))
local pot_height = math.pow(2, math.ceil(math.log(self.tile_h-0.1) / math.log(2.0)))
self.sr = core.display.newSurface(pot_width, pot_height)
self.sr:erase(255, 0, 0, 90)
self.sr:erase(255, 0, 0, self.fbo and 150 or 90)
self.sr = self.sr:glTexture()
self.sb = core.display.newSurface(pot_width, pot_height)
self.sb:erase(0, 0, 255, 90)
self.sb:erase(0, 0, 255, self.fbo and 150 or 90)
self.sb = self.sb:glTexture()
self.sg = core.display.newSurface(pot_width, pot_height)
self.sg:erase(0, 255, 0, 90)
self.sg:erase(0, 255, 0, self.fbo and 150 or 90)
self.sg = self.sg:glTexture()
self.sy = core.display.newSurface(pot_width, pot_height)
self.sy:erase(255, 255, 0, 90)
self.sy:erase(255, 255, 0, self.fbo and 150 or 90)
self.sy = self.sy:glTexture()
self.syg = core.display.newSurface(pot_width, pot_height)
self.syg:erase(153, 204, 50, 90)
self.syg:erase(153, 204, 50, self.fbo and 150 or 90)
self.syg = self.syg:glTexture()
end
self.source_actor = source_actor
function _M:enableFBORenderer(texture, shader)
if not shader then
self.fbo = nil
return
self:createTextures()
end
self.fbo = core.display.newFBO(Map.viewport.width, Map.viewport.height)
if not self.fbo then
self:createTextures()
return
end
-- Setup the tracking target table
-- Notice its values are set to weak references, this has no effects on the number for x and y
-- but it means if the entity field is set to an entity, when it disappears this link wont prevent
-- the garbage collection
self.target = {x=self.source_actor.x, y=self.source_actor.y, entity=nil}
-- setmetatable(self.target, {__mode='v'})
self.fbo_shader = Shader.new(shader)
if not self.fbo_shader.shad then
self.fbo = nil
self:createTextures()
return
end
self.targetshader = engine.Tiles:loadImage(texture):glTexture()
self:createTextures()
end
function _M:displayArrow(sx, sy, tx, ty, full)
......@@ -77,7 +106,41 @@ function _M:displayArrow(sx, sy, tx, ty, full)
core.display.glMatrix(false)
end
function _M:display(dispx, dispy)
function _M:display(dispx, dispy, prevfbo)
local ox, oy = self.display_x, self.display_y
local sx, sy = game.level.map._map:getScroll()
sx = sx + game.level.map.display_x
sy = sy + game.level.map.display_y
self.display_x, self.display_y = dispx or sx or self.display_x, dispy or sy or self.display_y
if self.active then
if not self.fbo then
self:realDisplay(self.display_x, self.display_y)
else
self.fbo:use(true, 0, 0, 0, 0)
self:realDisplay(0, 0)
self.fbo:use(false, prevfbo)
self.targetshader:bind(1, false)
self.fbo_shader.shad:paramNumber2("tileSize", self.tile_w, self.tile_h)
self.fbo_shader.shad:paramNumber2("scrollOffset", 0, 0)
self.fbo:toScreen(self.display_x, self.display_y, Map.viewport.width, Map.viewport.height, self.fbo_shader.shad, 1, 1, 1, 1, true)
end
if not self.target_type.immediate_keys or firstx then
self.cursor:toScreen(self.display_x + (self.target.x - game.level.map.mx) * self.tile_w * Map.zoom, self.display_y + (self.target.y - game.level.map.my + util.hexOffset(self.target.x)) * self.tile_h * Map.zoom, self.tile_w * Map.zoom, self.tile_h * Map.zoom)
end
if self.target_type.immediate_keys then
for dir, spot in pairs(util.adjacentCoords(self.target_type.start_x, self.target_type.start_y)) do
self:displayArrow(self.target_type.start_x, self.target_type.start_y, spot[1], spot[2], firstx == spot[1] and firsty == spot[2])
end
end
end
self.display_x, self.display_y = ox, oy
end
function _M:realDisplay(dispx, dispy)
-- Make sure we have a source
if not self.target_type.source_actor then
self.target_type.source_actor = self.source_actor
......@@ -92,13 +155,8 @@ function _M:display(dispx, dispy)
self.target_type.start_x = self.target_type.start_x or self.target_type.x or self.target_type.source_actor and self.target_type.source_actor.x or self.x
self.target_type.start_y = self.target_type.start_y or self.target_type.y or self.target_type.source_actor and self.target_type.source_actor.y or self.y
local ox, oy = self.display_x, self.display_y
local sx, sy = game.level.map._map:getScroll()
sx = sx + game.level.map.display_x
sy = sy + game.level.map.display_y
self.display_x, self.display_y = dispx or sx or self.display_x, dispy or sy or self.display_y
-- self.cursor:toScreen(self.display_x + (self.target.x - game.level.map.mx) * self.tile_w * Map.zoom, self.display_y + (self.target.y - game.level.map.my) * self.tile_h * Map.zoom, self.tile_w * Map.zoom, self.tile_h * Map.zoom)
-- self.cursor:toScreen(dispx + (self.target.x - game.level.map.mx) * self.tile_w * Map.zoom, dispy + (self.target.y - game.level.map.my) * self.tile_h * Map.zoom, self.tile_w * Map.zoom, self.tile_h * Map.zoom)
-- Do not display if not requested
if not self.active then return end
......@@ -107,16 +165,16 @@ function _M:display(dispx, dispy)
if util.isHex() then
display_highlight = function(texture, tx, ty)
texture:toScreenHighlightHex(
self.display_x + (tx - game.level.map.mx) * self.tile_w * Map.zoom,
self.display_y + (ty - game.level.map.my + util.hexOffset(tx)) * self.tile_h * Map.zoom,
dispx + (tx - game.level.map.mx) * self.tile_w * Map.zoom,
dispy + (ty - game.level.map.my + util.hexOffset(tx)) * self.tile_h * Map.zoom,
self.tile_w * Map.zoom,
self.tile_h * Map.zoom)
end
else
display_highlight = function(texture, tx, ty)
texture:toScreen(
self.display_x + (tx - game.level.map.mx) * self.tile_w * Map.zoom,
self.display_y + (ty - game.level.map.my) * self.tile_h * Map.zoom,
dispx + (tx - game.level.map.mx) * self.tile_w * Map.zoom,
dispy + (ty - game.level.map.my) * self.tile_h * Map.zoom,
self.tile_w * Map.zoom,
self.tile_h * Map.zoom)
end
......@@ -205,9 +263,6 @@ function _M:display(dispx, dispy)
end
end
if not self.target_type.immediate_keys or firstx then
self.cursor:toScreen(self.display_x + (self.target.x - game.level.map.mx) * self.tile_w * Map.zoom, self.display_y + (self.target.y - game.level.map.my + util.hexOffset(self.target.x)) * self.tile_h * Map.zoom, self.tile_w * Map.zoom, self.tile_h * Map.zoom)
end
if self.target_type.ball and self.target_type.ball > 0 then
core.fov.calc_circle(
......@@ -275,14 +330,6 @@ function _M:display(dispx, dispy)
end,
nil)
end
if self.target_type.immediate_keys then
for dir, spot in pairs(util.adjacentCoords(self.target_type.start_x, self.target_type.start_y)) do
self:displayArrow(self.target_type.start_x, self.target_type.start_y, spot[1], spot[2], firstx == spot[1] and firsty == spot[2])
end
end
self.display_x, self.display_y = ox, oy
end
-- @return t The target table used by ActorProject, Projectile, GameTargeting, etc.
......
......@@ -134,6 +134,7 @@ function _M:runReal()
if not self.player then self:newGame() end
engine.interface.GameTargeting.init(self)
if self.target then self.target:enableFBORenderer("ui/targetshader.png", "target_fbo") end
self.uiset.hotkeys_display.actor = self.player
self.uiset.npcs_display.actor = self.player
......@@ -515,6 +516,8 @@ function _M:createFBOs()
if self.fbo and self.fbo2 then core.particles.defineFramebuffer(self.fbo)
else core.particles.defineFramebuffer(nil) end
if self.target then self.target:enableFBORenderer("ui/targetshader.png", "target_fbo") end
-- self.mm_fbo = core.display.newFBO(200, 200)
-- if self.mm_fbo then self.mm_fbo_shader = Shader.new("mm_fbo") if not self.mm_fbo_shader.shad then self.mm_fbo = nil self.mm_fbo_shader = nil end end
end
......@@ -1359,13 +1362,13 @@ function _M:displayMap(nb_keyframes)
_2DNoise:bind(1, false)
self.fbo2:toScreen(map.display_x, map.display_y, map.viewport.width, map.viewport.height, self.fbo_shader.shad)
if self.target then self.target:display() end
if self.target then self.target:display(nil, nil, self.full_fbo) end
-- Basic display; no FBOs
else
if self.level.data.background then self.level.data.background(self.level, map.display_x, map.display_y, nb_keyframes) end
map:display(nil, nil, nb_keyframes, config.settings.tome.smooth_fov)
if self.target then self.target:display() end
if self.target then self.target:display(nil, nil, self.full_fbo) end
if self.level.data.foreground then self.level.data.foreground(self.level, map.display_x, map.display_y, nb_keyframes) end
if self.level.data.weather_particle then self.state:displayWeather(self.level, self.level.data.weather_particle, nb_keyframes) end
if self.level.data.weather_shader then self.state:displayWeatherShader(self.level, self.level.data.weather_shader, map.display_x, map.display_y, nb_keyframes) end
......
//#version 150
uniform sampler2D Texture0;
//varying vec2 texCoord;
#define HueLevCount 6
#define SatLevCount 7
#define ValLevCount 4
float[HueLevCount] HueLevels = float[] (0.0,80.0,160.0,240.0,320.0,360.0);
float[SatLevCount] SatLevels = float[] (0.0,0.15,0.3,0.45,0.6,0.8,1.0);
float[ValLevCount] ValLevels = float[] (0.0,0.3,0.6,1.0);
vec3 RGBtoHSV( float r, float g, float b) {
float minv, maxv, delta;
vec3 res;
minv = min(min(r, g), b);
maxv = max(max(r, g), b);
res.z = maxv; // v
delta = maxv - minv;
if( maxv != 0.0 )
res.y = delta / maxv; // s
else {
// r = g = b = 0 // s = 0, v is undefined
res.y = 0.0;
res.x = -1.0;
return res;
}
if( r == maxv )
res.x = ( g - b ) / delta; // between yellow & magenta
else if( g == maxv )
res.x = 2.0 + ( b - r ) / delta; // between cyan & yellow
else
res.x = 4.0 + ( r - g ) / delta; // between magenta & cyan
res.x = res.x * 60.0; // degrees
if( res.x < 0.0 )
res.x = res.x + 360.0;
return res;
}
vec3 HSVtoRGB(float h, float s, float v ) {
int i;
float f, p, q, t;
vec3 res;
if( s == 0.0 ) {
// achromatic (grey)
res.x = v;
res.y = v;
res.z = v;
return res;
}
h /= 60.0; // sector 0 to 5
i = int(floor( h ));
f = h - float(i); // factorial part of h
p = v * ( 1.0 - s );
q = v * ( 1.0 - s * f );
t = v * ( 1.0 - s * ( 1.0 - f ) );
switch( i ) {
case 0:
res.x = v;
res.y = t;
res.z = p;
break;
case 1:
res.x = q;
res.y = v;
res.z = p;
break;
case 2:
res.x = p;
res.y = v;
res.z = t;
break;
case 3:
res.x = p;
res.y = q;
res.z = v;
break;
case 4:
res.x = t;
res.y = p;
res.z = v;
break;
default: // case 5:
res.x = v;
res.y = p;
res.z = q;
break;
}
return res;
}
float nearestLevel(float col, int mode) {
int levCount;
if (mode==0) levCount = HueLevCount;
if (mode==1) levCount = SatLevCount;
if (mode==2) levCount = ValLevCount;
for (int i =0; i<levCount-1; i++ ) {
if (mode==0) {
if (col >= HueLevels[i] && col <= HueLevels[i+1]) {
return HueLevels[i+1];
}
}
if (mode==1) {
if (col >= SatLevels[i] && col <= SatLevels[i+1]) {
return SatLevels[i+1];
}
}
if (mode==2) {
if (col >= ValLevels[i] && col <= ValLevels[i+1]) {
return ValLevels[i+1];
}
}
}
}
// averaged pixel intensity from 3 color channels
float avg_intensity(vec4 pix) {
return (pix.r + pix.g + pix.b)/3.;
}
vec4 get_pixel(vec2 coords, float dx, float dy) {
return texture2D(Texture0,coords + vec2(dx, dy));
}
// returns pixel color
float IsEdge(in vec2 coords){
float dxtex = 1.0 /float(textureSize(Texture0,0)) ;
float dytex = 1.0 /float(textureSize(Texture0,0));
float pix[9];
int k = -1;
float delta;
// read neighboring pixel intensities
for (int i=-1; i<2; i++) {
for(int j=-1; j<2; j++) {
k++;
pix[k] = avg_intensity(get_pixel(coords,float(i)*dxtex,
float(j)*dytex));
}
}
// average color differences around neighboring pixels
delta = (abs(pix[1]-pix[7])+
abs(pix[5]-pix[3]) +
abs(pix[0]-pix[8])+
abs(pix[2]-pix[6])
)/4.;
return clamp(5.5*delta,0.0,1.0);
}
void main(void)
{
vec4 colorOrg = texture2D( Texture0, gl_TexCoord[0].st );
vec3 vHSV = RGBtoHSV(colorOrg.r,colorOrg.g,colorOrg.b);
vHSV.x = nearestLevel(vHSV.x, 0);
vHSV.y = nearestLevel(vHSV.y, 1);
vHSV.z = nearestLevel(vHSV.z, 2);
float edg = IsEdge(gl_TexCoord[0].st);
vec3 vRGB = (edg >= 0.3)? vec3(0.0,0.0,0.0):HSVtoRGB(vHSV.x,vHSV.y,vHSV.z);
gl_FragColor = vec4(vRGB.x,vRGB.y,vRGB.z,1.0);
}
//#version 150
uniform sampler2D fboTex;
uniform sampler2D targetSkin;
uniform vec2 mapCoord;
uniform vec2 tileSize;
uniform vec2 scrollOffset;
void main(void)
{
vec2 offset = vec2(1.0, 1.0) / mapCoord * tileSize * 0.5;
/*vec4 colorm0 = texture2D( fboTex, gl_TexCoord[0].xy + vec2(-offset.x, 0.0));
vec4 colorp0 = texture2D( fboTex, gl_TexCoord[0].xy + vec2( offset.x, 0.0));
vec4 color0m = texture2D( fboTex, gl_TexCoord[0].xy + vec2(0.0, -offset.y));
vec4 color0p = texture2D( fboTex, gl_TexCoord[0].xy + vec2(0.0, offset.y));*/
vec4 colormm = texture2D( fboTex, gl_TexCoord[0].xy + vec2(-offset.x,-offset.y));
vec4 colormp = texture2D( fboTex, gl_TexCoord[0].xy + vec2(-offset.x, offset.y));
vec4 colorpm = texture2D( fboTex, gl_TexCoord[0].xy + vec2( offset.x,-offset.y));
vec4 colorpp = texture2D( fboTex, gl_TexCoord[0].xy + vec2( offset.x, offset.y));
vec4 color00 = texture2D( fboTex, gl_TexCoord[0].xy);
vec4 resultColor = color00;
bool loc1 = false;
bool loc2 = false;
bool loc3 = false;
bool loc4 = false;
bool loc5 = false;
bool loc6 = false;
bool loc7 = false;
bool loc8 = false;
bool loc9 = false;
if(colormm.a > 0.1)
loc1 = true;
if(colormp.a > 0.1)
loc7 = true;
if(colorpm.a > 0.1)
loc3 = true;
if(colorpp.a > 0.1)
loc9 = true;
if(color00.a > 0.1)
loc5 = true;
if(gl_TexCoord[0].x + offset.x > 1.0)
{
loc9 = 0;
loc3 = 0;
}
if(gl_TexCoord[0].x - offset.x < 0.0)
{
loc1 = 0;
loc7 = 0;
}
if(gl_TexCoord[0].y + offset.y > 1.0)
{
loc7 = 0;
loc9 = 0;
}
if(gl_TexCoord[0].y - offset.y < 0.0)
{
loc1 = 0;
loc3 = 0;
}
vec2 fboCoord = gl_TexCoord[0].xy;
fboCoord.y = 1.0 - fboCoord.y;
vec2 texCoord = (fboCoord * mapCoord + scrollOffset) / tileSize + vec2(0.5, 0.5);
texCoord.x = mod(texCoord.x, 1.0);
texCoord.y = mod(texCoord.y, 1.0);
vec4 borderColor = vec4(0.0, 0.0, 0.0, 0.0);
if(loc1 && loc7 && loc3 && !loc9) //1 internal
borderColor += texture2D( targetSkin, texCoord / 4.0 + vec2(1.0 / 4.0 * 0.0, 1.0 / 4.0 * 3.0));
if(loc9 && !loc7 && !loc3 && !loc1) //1 external
borderColor += texture2D( targetSkin, texCoord / 4.0 + vec2(1.0 / 4.0 * 0.0, 1.0 / 4.0 * 1.0));
if(loc7 && !loc3 && loc9 && !loc1) //2
borderColor += texture2D( targetSkin, texCoord / vec2(4.0, 4.0) + vec2(1.0 / 4.0 * 2.0, 1.0 / 4.0 * 1.0));
if(loc3 && loc1 && loc9 && !loc7) //3 internal
borderColor += texture2D( targetSkin, texCoord / 4.0 + vec2(1.0 / 4.0 * 1.0, 1.0 / 4.0 * 3.0));
if(loc7 && !loc1 && !loc9 && !loc3) //3 external
borderColor += texture2D( targetSkin, texCoord / 4.0 + vec2(1.0 / 4.0 * 1.0, 1.0 / 4.0 * 1.0));
if(loc1 && !loc9 && loc7 && !loc3) //8
borderColor += texture2D( targetSkin, texCoord / vec2(4.0, 4.0) + vec2(1.0 / 4.0 * 3.0, 1.0 / 4.0 * 0.0));
if(loc9 && loc7 && loc3 && !loc1)
borderColor += texture2D( targetSkin, texCoord / 4.0 + vec2(1.0 / 4.0 * 1.0, 1.0 / 4.0 * 2.0));
if(loc1 && !loc7 && !loc3 && !loc9) //9 external
borderColor += texture2D( targetSkin, texCoord / 4.0 + vec2(1.0 / 4.0 * 1.0, 1.0 / 4.0 * 0.0));
if(loc1 && !loc9 && loc3 && !loc7)
borderColor += texture2D( targetSkin, texCoord / vec2(4.0, 4.0) + vec2(1.0 / 4.0 * 2.0, 1.0 / 4.0 * 0.0));
if(loc7 && loc1 && loc9 && !loc3) //7 internal
borderColor += texture2D( targetSkin, texCoord / 4.0 + vec2(1.0 / 4.0 * 0.0, 1.0 / 4.0 * 2.0));
if(loc3 && !loc1 && !loc9 && !loc7) //7 external
borderColor += texture2D( targetSkin, texCoord / 4.0 + vec2(1.0 / 4.0 * 0.0, 1.0 / 4.0 * 0.0));
if(loc3 && !loc7 && loc9 && !loc1) //4
borderColor += texture2D( targetSkin, texCoord / vec2(4.0, 4.0) + vec2(1.0 / 4.0 * 3.0, 1.0 / 4.0 * 1.0));
if(loc3 && loc7 && !loc9 && !loc1) //3-7 diag
borderColor += texture2D( targetSkin, texCoord / vec2(4.0, 4.0) + vec2(1.0 / 4.0 * 2.0, 1.0 / 4.0 * 2.0));
if(!loc3 && !loc7 && loc9 && loc1) //1-9 diag
borderColor += texture2D( targetSkin, texCoord / vec2(4.0, 4.0) + vec2(1.0 / 4.0 * 3.0, 1.0 / 4.0 * 2.0));
if(loc3 && loc7 && loc9 && loc1) //internal quad
borderColor += texture2D( targetSkin, texCoord / vec2(4.0, 4.0) + vec2(1.0 / 4.0 * 2.0, 1.0 / 4.0 * 3.0));
if(!loc5 && borderColor.a > 0.0)
{
vec4 avgColor =
(colormm * colormm.a + colormp * colormp.a + colorpm * colorpm.a + colorpp * colorpp.a)
/ (colormm.a + colormp.a + colorpm.a + colorpp.a + 1e-5);
resultColor += avgColor;
resultColor.rgb += borderColor.rgb * borderColor.a;
resultColor.a = borderColor.a;
}else
{
borderColor.rgb *= borderColor.a;
resultColor += borderColor;
}
gl_FragColor = resultColor;
}
......@@ -18,9 +18,13 @@
-- darkgod@te4.org
return {
frag = "mm_fbo",
frag = "target_fbo",
vert = nil,
args = {
fboTex = { texture = 0 },
targetSkin = { texture = 1 },
scrollOffset = {0, 0},
},
clone = false,
permanent = true,
}
game/modules/tome/data/gfx/ui/targetshader.png

27.6 KiB

0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment