Added compatibility with android

Added util.loadShader - loads shaders and sets uniform variables
Fixed implicit type conversions in shaders
This commit is contained in:
SpaVec 2017-07-17 23:01:13 +02:00
parent 2d39bb48cf
commit 378586c406
13 changed files with 104 additions and 69 deletions

View File

@ -31,18 +31,18 @@ local PostShader = require(_PACKAGE..'postshader')
local light_world = {} local light_world = {}
light_world.__index = light_world light_world.__index = light_world
light_world.image_mask = love.graphics.newShader(_PACKAGE.."/shaders/image_mask.glsl") light_world.image_mask = util.loadShader(_PACKAGE.."/shaders/image_mask.glsl")
light_world.shadowShader = love.graphics.newShader(_PACKAGE.."/shaders/shadow.glsl") light_world.shadowShader = util.loadShader(_PACKAGE.."/shaders/shadow.glsl")
light_world.refractionShader = love.graphics.newShader(_PACKAGE.."shaders/refraction.glsl") light_world.refractionShader = util.loadShader(_PACKAGE.."/shaders/refraction.glsl")
light_world.reflectionShader = love.graphics.newShader(_PACKAGE.."shaders/reflection.glsl") light_world.reflectionShader = util.loadShader(_PACKAGE.."/shaders/reflection.glsl")
local function new(options) local function new(options)
local obj = {} local obj = {}
obj.lights = {} obj.lights = {}
obj.bodies = {} obj.bodies = {}
obj.post_shader = PostShader() obj.post_shader = PostShader()
obj.l, obj.t, obj.s = 0, 0, 1 obj.l, obj.t, obj.s = 0, 0, 1
obj.ambient = {0, 0, 0} obj.ambient = {0, 0, 0}
obj.refractionStrength = 8.0 obj.refractionStrength = 8.0
obj.reflectionStrength = 16.0 obj.reflectionStrength = 16.0
@ -273,7 +273,7 @@ function light_world:clear()
light_world:clearBodies() light_world:clearBodies()
end end
function light_world:setTranslation(l, t, s) function light_world:setTranslation(l, t, s)
self.l, self.t, self.s = l or self.l, t or self.t, s or self.s self.l, self.t, self.s = l or self.l, t or self.t, s or self.s
end end
@ -296,13 +296,13 @@ function light_world:newCircle(...) return self:newBody("circle", ...) end
function light_world:newPolygon(...) return self:newBody("polygon", ...) end function light_world:newPolygon(...) return self:newBody("polygon", ...) end
function light_world:newImage(...) return self:newBody("image", ...) end function light_world:newImage(...) return self:newBody("image", ...) end
function light_world:newRefraction(...) function light_world:newRefraction(...)
self.disableRefraction = false self.disableRefraction = false
return self:newBody("refraction", ...) return self:newBody("refraction", ...)
end end
function light_world:newReflection(normal, ...) function light_world:newReflection(normal, ...)
self.disableReflection = false self.disableReflection = false
return self:newBody("reflection", ...) return self:newBody("reflection", ...)
end end
-- new body -- new body

View File

@ -29,12 +29,12 @@ post_shader.__index = post_shader
local files = love.filesystem.getDirectoryItems(_PACKAGE.."/shaders/postshaders") local files = love.filesystem.getDirectoryItems(_PACKAGE.."/shaders/postshaders")
local shaders = {} local shaders = {}
for i,v in ipairs(files) do for i,v in ipairs(files) do
local name = _PACKAGE.."/shaders/postshaders".."/"..v local name = _PACKAGE.."/shaders/postshaders".."/"..v
if love.filesystem.isFile(name) then if love.filesystem.isFile(name) then
local str = love.filesystem.read(name) local str = love.filesystem.read(name)
local effect = love.graphics.newShader(name) local effect = util.loadShader(name)
local defs = {} local defs = {}
for vtype, extern in str:gmatch("extern (%w+) (%w+)") do for vtype, extern in str:gmatch("extern (%w+) (%w+)") do
defs[extern] = true defs[extern] = true
@ -73,14 +73,14 @@ function post_shader:toggleEffect(shaderName, ...)
end end
function post_shader:drawWith(canvas) function post_shader:drawWith(canvas)
for shader, args in pairs(self.effects) do for shader, args in pairs(self.effects) do
if shader == "bloom" then if shader == "bloom" then
self:drawBloom(canvas, args) self:drawBloom(canvas, args)
elseif shader == "blur" then elseif shader == "blur" then
self:drawBlur(canvas, args) self:drawBlur(canvas, args)
elseif shader == "tilt_shift" then elseif shader == "tilt_shift" then
self:drawTiltShift(canvas, args) self:drawTiltShift(canvas, args)
else else
self:drawShader(shader, canvas, args) self:drawShader(shader, canvas, args)
end end
end end
@ -126,9 +126,9 @@ function post_shader:drawShader(shaderName, canvas, args)
effect[1]:send("time", love.timer.getTime()) effect[1]:send("time", love.timer.getTime())
elseif def == "palette" then elseif def == "palette" then
effect[1]:send("palette", unpack(process_palette({ effect[1]:send("palette", unpack(process_palette({
args[current_arg], args[current_arg],
args[current_arg + 1], args[current_arg + 1],
args[current_arg + 2], args[current_arg + 2],
args[current_arg + 3] args[current_arg + 3]
}))) })))
current_arg = current_arg + 4 current_arg = current_arg + 4

View File

@ -1,13 +1,13 @@
extern float exposure = 0.7; extern float exposure=0.7;
extern float brightness = 1.0; extern float brightness = 1.0;
extern vec3 lumacomponents = vec3(1.0, 1.0, 1.0); extern vec3 lumacomponents = vec3(1.0, 1.0, 1.0);
const vec3 lumcoeff = vec3(0.212671, 0.715160, 0.072169); const vec3 lumcoeff = vec3(0.212671, 0.715160, 0.072169);
vec4 effect(vec4 vcolor, Image texture, vec2 texcoord, vec2 pixel_coords) { vec4 effect(vec4 vcolor, Image texture, vec2 texcoord, vec2 pixel_coords) {
vec4 input0 = Texel(texture, texcoord); vec4 input0 = Texel(texture, texcoord);
input0 *= (exp2(input0)*vec4(exposure)); input0 *= (exp2(input0)*vec4(exposure));
vec4 lumacomponents = vec4(lumcoeff * lumacomponents, 0.0 ); vec4 lumacomponents = vec4(lumcoeff * lumacomponents, 0.0 );
float luminance = dot(input0,lumacomponents); float luminance = dot(input0,lumacomponents);
vec4 luma = vec4(luminance); vec4 luma = vec4(luminance);
return vec4(luma.rgb * brightness, 1.0); return vec4(luma.rgb * brightness, 1.0);
} }

View File

@ -3,9 +3,9 @@ extern float steps = 2.0;
vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 pixel_coords) { vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 pixel_coords) {
vec2 pSize = vec2(1.0 / love_ScreenSize.x, 1.0 / love_ScreenSize.y); vec2 pSize = vec2(1.0 / love_ScreenSize.x, 1.0 / love_ScreenSize.y);
vec4 col = Texel(texture, texture_coords); vec4 col = Texel(texture, texture_coords);
for(int i = 1; i <= steps; i++) { for(int i = 1; i <= int(steps); i++) {
col = col + Texel(texture, vec2(texture_coords.x, texture_coords.y - pSize.y * i)); col = col + Texel(texture, vec2(texture_coords.x, texture_coords.y - pSize.y * float(i)));
col = col + Texel(texture, vec2(texture_coords.x, texture_coords.y + pSize.y * i)); col = col + Texel(texture, vec2(texture_coords.x, texture_coords.y + pSize.y * float(i)));
} }
col = col / (steps * 2.0 + 1.0); col = col / (steps * 2.0 + 1.0);
return vec4(col.r, col.g, col.b, 1.0); return vec4(col.r, col.g, col.b, 1.0);

View File

@ -3,9 +3,9 @@ extern float steps = 2.0;
vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 pixel_coords) { vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 pixel_coords) {
vec2 pSize = vec2(1.0 / love_ScreenSize.x, 1.0 / love_ScreenSize.y); vec2 pSize = vec2(1.0 / love_ScreenSize.x, 1.0 / love_ScreenSize.y);
vec4 col = Texel(texture, texture_coords); vec4 col = Texel(texture, texture_coords);
for(int i = 1; i <= steps; i++) { for(int i = 1; i <= int(steps); i++) {
col = col + Texel(texture, vec2(texture_coords.x - pSize.x * i, texture_coords.y)); col = col + Texel(texture, vec2(texture_coords.x - pSize.x * float(i), texture_coords.y));
col = col + Texel(texture, vec2(texture_coords.x + pSize.x * i, texture_coords.y)); col = col + Texel(texture, vec2(texture_coords.x + pSize.x * float(i), texture_coords.y));
} }
col = col / (steps * 2.0 + 1.0); col = col / (steps * 2.0 + 1.0);
return vec4(col.r, col.g, col.b, 1.0); return vec4(col.r, col.g, col.b, 1.0);

View File

@ -2,7 +2,7 @@ extern vec3 palette[4];
vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 pixel_coords){ vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 pixel_coords){
vec4 pixel = Texel(texture, texture_coords); vec4 pixel = Texel(texture, texture_coords);
int index = int(min(0.9999, max(0.0001,(pixel.r + pixel.g + pixel.b) / 3.0)) * 4); int index = int(min(0.9999, max(0.0001,(pixel.r + pixel.g + pixel.b) / 3.0)) * 4.0);
return vec4(palette[index], 1.0); return vec4(palette[index], 1.0);
} }

View File

@ -10,4 +10,4 @@ vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 pixel_coords){
vec4 pixel = Texel(texture, texture_coords); vec4 pixel = Texel(texture, texture_coords);
float intensity = (pixel.r + pixel.g + pixel.b) / 3.0 + (rand(texture_coords, time) - 0.5) * fudge; float intensity = (pixel.r + pixel.g + pixel.b) / 3.0 + (rand(texture_coords, time) - 0.5) * fudge;
return vec4(intensity * tint.r, intensity * tint.g, intensity * tint.b, 1.0); return vec4(intensity * tint.r, intensity * tint.g, intensity * tint.b, 1.0);
} }

View File

@ -94,22 +94,22 @@ vec4 grid_color( vec2 coords )
vec2 onex = vec2( 1.0/love_ScreenSize.x, 0.0 ); vec2 onex = vec2( 1.0/love_ScreenSize.x, 0.0 );
vec2 oney = vec2( 0.0, 1.0/love_ScreenSize.y ); vec2 oney = vec2( 0.0, 1.0/love_ScreenSize.y );
vec4 effect(vec4 vcolor, Image texture, vec2 texCoord, vec2 pixel_coords) vec4 effect(vec4 vcolor, Image texture, highp vec2 texCoord, vec2 pixel_coords)
{ {
vec2 coords = (texCoord * love_ScreenSize.xy); highp vec2 coords = (texCoord * love_ScreenSize.xy);
vec2 pixel_start = floor(coords); highp vec2 pixel_start = floor(coords);
coords -= pixel_start; coords -= pixel_start;
vec2 pixel_center = pixel_start + vec2(0.5); highp vec2 pixel_center = pixel_start + vec2(0.5);
vec2 texture_coords = pixel_center / love_ScreenSize.xy; highp vec2 texture_coords = pixel_center / love_ScreenSize.xy;
vec4 color = vec4(0.0); highp vec4 color = vec4(0.0);
vec4 pixel; highp vec4 pixel;
vec3 centers = vec3(-0.25,-0.5,-0.75); highp vec3 centers = vec3(-0.25,-0.5,-0.75);
vec3 posx = vec3(coords.x); highp vec3 posx = vec3(coords.x);
vec3 hweight; highp vec3 hweight;
float vweight; highp float vweight;
float dx,dy; highp float dx,dy;
float w; highp float w;
float i,j; float i,j;

View File

@ -5,7 +5,7 @@
*/ */
// modified by slime73 for use with love pixeleffects // modified by slime73 for use with love pixeleffects
vec3 to_focus(float pixel) vec3 to_focus(highp float pixel)
{ {
pixel = mod(pixel + 3.0, 3.0); pixel = mod(pixel + 3.0, 3.0);
if (pixel >= 2.0) // Blue if (pixel >= 2.0) // Blue
@ -16,24 +16,24 @@ vec3 to_focus(float pixel)
return vec3(1.0 - pixel, pixel, 0.0); return vec3(1.0 - pixel, pixel, 0.0);
} }
vec4 effect(vec4 vcolor, Image texture, vec2 texture_coords, vec2 pixel_coords) vec4 effect(vec4 vcolor, Image texture, highp vec2 texture_coords, vec2 pixel_coords)
{ {
float y = mod(texture_coords.y * love_ScreenSize.y, 1.0); highp float y = mod(texture_coords.y * love_ScreenSize.y, 1.0);
float intensity = exp(-0.2 * y); highp float intensity = exp(-0.2 * y);
vec2 one_x = vec2(1.0 / (3.0 * love_ScreenSize.x), 0.0); highp vec2 one_x = vec2(1.0 / (3.0 * love_ScreenSize.x), 0.0);
vec3 color = Texel(texture, texture_coords - 0.0 * one_x).rgb; highp vec3 color = Texel(texture, texture_coords - 0.0 * one_x).rgb;
vec3 color_prev = Texel(texture, texture_coords - 1.0 * one_x).rgb; highp vec3 color_prev = Texel(texture, texture_coords - 1.0 * one_x).rgb;
vec3 color_prev_prev = Texel(texture, texture_coords - 2.0 * one_x).rgb; highp vec3 color_prev_prev = Texel(texture, texture_coords - 2.0 * one_x).rgb;
float pixel_x = 3.0 * texture_coords.x * love_ScreenSize.x; highp float pixel_x = 3.0 * texture_coords.x * love_ScreenSize.x;
vec3 focus = to_focus(pixel_x - 0.0); highp vec3 focus = to_focus(pixel_x - 0.0);
vec3 focus_prev = to_focus(pixel_x - 1.0); highp vec3 focus_prev = to_focus(pixel_x - 1.0);
vec3 focus_prev_prev = to_focus(pixel_x - 2.0); highp vec3 focus_prev_prev = to_focus(pixel_x - 2.0);
vec3 result = highp vec3 result =
0.8 * color * focus + 0.8 * color * focus +
0.6 * color_prev * focus_prev + 0.6 * color_prev * focus_prev +
0.3 * color_prev_prev * focus_prev_prev; 0.3 * color_prev_prev * focus_prev_prev;
@ -42,4 +42,3 @@ vec4 effect(vec4 vcolor, Image texture, vec2 texture_coords, vec2 pixel_coords)
return vec4(intensity * result, 1.0); return vec4(intensity * result, 1.0);
} }

View File

@ -6,15 +6,15 @@ extern number blurwidth = -0.02; // -1 to 1
vec4 effect(vec4 vcolor, Image texture, vec2 texture_coords, vec2 pixel_coords) vec4 effect(vec4 vcolor, Image texture, vec2 texture_coords, vec2 pixel_coords)
{ {
vec4 c = vec4(0.0, 0.0, 0.0, 1.0); vec4 c = vec4(0.0, 0.0, 0.0, 1.0);
int i; int i;
for (i = 0; i < nsamples; i++) for (i = 0; i < nsamples; i++)
{ {
number scale = blurstart + blurwidth * (i / float(nsamples-1)); number scale = blurstart + blurwidth * (float(i) / float(nsamples-1));
c.rgb += Texel(texture, texture_coords * scale).rgb; c.rgb += Texel(texture, texture_coords * scale).rgb;
} }
c.rgb /= nsamples; c.rgb /= float(nsamples);
return c; return c;
} }

View File

@ -9,11 +9,11 @@ vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 pixel_coords) {
if(normal.a > 0.0 && normal.r > 0.0) { if(normal.a > 0.0 && normal.r > 0.0) {
vec3 pColor = Texel(backBuffer, texture_coords).rgb; vec3 pColor = Texel(backBuffer, texture_coords).rgb;
vec4 pColor2; vec4 pColor2;
for(int i = 0; i < reflectionStrength; i++) { for(int i = 0; i < int(reflectionStrength); i++) {
pColor2 = Texel(texture, vec2(texture_coords.x, texture_coords.y + pSize.y * i)); pColor2 = Texel(texture, vec2(texture_coords.x, texture_coords.y + pSize.y * float(i)));
if(pColor2.a > 0.0 && pColor2.g > 0.0) { if(pColor2.a > 0.0 && pColor2.g > 0.0) {
vec3 rColor = Texel(backBuffer, vec2(texture_coords.x, texture_coords.y + pSize.y * i * 2.0)).rgb; vec3 rColor = Texel(backBuffer, vec2(texture_coords.x, texture_coords.y + pSize.y * float(i) * 2.0)).rgb;
return vec4(rColor, (1.0 - i / reflectionStrength) * reflectionVisibility); return vec4(rColor, (1.0 - float(i) / reflectionStrength) * reflectionVisibility);
} }
} }
return vec4(0.0); return vec4(0.0);

View File

@ -32,7 +32,7 @@ vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 pixel_coords) {
pixel.rgb = lightColor * pow(att, lightSmooth); pixel.rgb = lightColor * pow(att, lightSmooth);
} }
} else { } else {
vec3 normal = normalize(vec3(normalColor.r,invert_normal ? 1 - normalColor.g : normalColor.g, normalColor.b) * 2.0 - 1.0); vec3 normal = normalize(vec3(normalColor.r,invert_normal ? 1.0 - normalColor.g : normalColor.g, normalColor.b) * 2.0 - 1.0);
//on the normal map, draw normal shadows //on the normal map, draw normal shadows
vec3 dir = vec3((lightPosition.xy - pixel_coords.xy) / love_ScreenSize.xy, lightPosition.z); vec3 dir = vec3((lightPosition.xy - pixel_coords.xy) / love_ScreenSize.xy, lightPosition.z);
dir.x *= love_ScreenSize.x / love_ScreenSize.y; dir.x *= love_ScreenSize.x / love_ScreenSize.y;
@ -47,4 +47,3 @@ vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 pixel_coords) {
return pixel; return pixel;
} }
} }

View File

@ -2,7 +2,7 @@ local util = {}
--TODO: the whole stencil/canvas system should be reviewed since it has been changed in a naive way --TODO: the whole stencil/canvas system should be reviewed since it has been changed in a naive way
function util.process(canvas, options) function util.process(canvas, options)
--TODO: now you cannot draw a canvas to itself --TODO: now you cannot draw a canvas to itself
temp = love.graphics.newCanvas() temp = love.graphics.newCanvas()
util.drawCanvasToCanvas(canvas, temp, options) util.drawCanvasToCanvas(canvas, temp, options)
util.drawCanvasToCanvas(temp, canvas, options) util.drawCanvasToCanvas(temp, canvas, options)
@ -59,4 +59,41 @@ function util.drawto(canvas, x, y, scale, cb)
love.graphics.pop() love.graphics.pop()
end end
function util.loadShader(name)
local shader = ""
local externInit = {}
for line in love.filesystem.lines(name) do
if line:sub(1,6) == "extern" then
local type, name = line:match("extern (%w+) (%w+)")
local value = line:match("=(.*);")
if value then
externInit[name] = {type=type, val=value}
line = line:match("extern %w+ %w+")..";"
end
end
shader = shader.."\n"..line
end
local effect = love.graphics.newShader(shader)
for k, v in pairs(externInit) do
if v.type == "bool" then
effect:send(k, v.val)
elseif v.type == "int" or v.type == "uint" then
effect:sendInt(k, tonumber(v.val))
elseif v.type == "float" or v.type == "double" or v.type == "number" then
effect:send(k, tonumber(v.val))
elseif v.type:sub(1,3) == "vec" then
v.val = v.val:gsub(" ", ""):sub(6):sub(1, -2)
local next = v.val:gmatch("([^,]+)")
local values = {}
for n in next do
table.insert(values, tonumber(n))
end
effect:send(k, values)
end
end
return effect
end
return util return util