diff --git a/lib/light.lua b/lib/light.lua index 59fa3ab..a0b1871 100644 --- a/lib/light.lua +++ b/lib/light.lua @@ -190,13 +190,13 @@ function light:drawShadow(l,t,w,h,s,bodies, canvas) end end -function light:drawShine(l,t,w,h) +function light:drawShine(canvas) if self.visible then - love.graphics.draw(self.shine, l, t) + util.drawCanvasToCanvas(self.shine, canvas) end end -function light:drawPixelShadow(l,t,w,h, normalMap) +function light:drawPixelShadow(l,t,w,h, normalMap, canvas) if self.visible then if self.normalInvert then self.normalInvertShader:send('screenResolution', {w, h}) @@ -206,7 +206,7 @@ function light:drawPixelShadow(l,t,w,h, normalMap) self.normalInvertShader:send("lightSmooth", self.smooth) self.normalInvertShader:send("lightAngle", math.pi - self.angle / 2.0) self.normalInvertShader:send("lightDirection", self.direction) - love.graphics.setShader(self.normalInvertShader) + util.drawCanvasToCanvas(normalMap, canvas, {shader = self.normalInvertShader}) else self.normalShader:send('screenResolution', {w, h}) self.normalShader:send('lightColor', {self.red / 255.0, self.green / 255.0, self.blue / 255.0}) @@ -215,9 +215,8 @@ function light:drawPixelShadow(l,t,w,h, normalMap) self.normalShader:send("lightSmooth", self.smooth) self.normalShader:send("lightAngle", math.pi - self.angle / 2.0) self.normalShader:send("lightDirection", self.direction) - love.graphics.setShader(self.normalShader) + util.drawCanvasToCanvas(normalMap, canvas, {shader = self.normalShader}) end - love.graphics.draw(normalMap, l, t) end end diff --git a/lib/light_world.lua b/lib/light_world.lua index 0bacea1..b91a33f 100644 --- a/lib/light_world.lua +++ b/lib/light_world.lua @@ -63,120 +63,6 @@ function light_world:init(options) self:refreshScreenSize() end -function light_world:drawBlur(blendmode, blur, canvas, canvas2, l, t, w, h, s) - if blur <= 0 then - return - end - - canvas2:clear() - self.blurv:send("steps", blur) - self.blurh:send("steps", blur) - util.drawCanvasToCanvas(canvas, canvas2, {shader = self.blurv, blendmode = blendmode}) - util.drawCanvasToCanvas(canvas2, canvas, {shader = self.blurh, blendmode = blendmode}) -end - -function light_world:updateShine(l,t,w,h,s) - -- update shine - love.graphics.setCanvas(self.shine) - love.graphics.setColor(unpack(self.ambient)) - love.graphics.setBlendMode("alpha") - love.graphics.rectangle("fill", l, t, w, h) - love.graphics.setColor(255, 255, 255) - love.graphics.setBlendMode("additive") - - for i = 1, #self.lights do - self.lights[i]:drawShine(l,t,w,h) - end - - --light_world:drawBlur("additive", self.blur, self.shine, self.shine2, l, t, w, h, s) -end - -function light_world:updatePixelShadows(l,t,w,h) - -- update pixel shadow - love.graphics.setBlendMode("alpha") - - -- create normal map - self.normalMap:clear() - love.graphics.setShader() - love.graphics.setCanvas(self.normalMap) - - for i = 1, #self.body do - self.body[i]:drawPixelShadow(l,t,w,h) - end - - love.graphics.setColor(255, 255, 255) - love.graphics.setBlendMode("alpha") - self.pixelShadow2:clear() - love.graphics.setCanvas(self.pixelShadow2) - love.graphics.setBlendMode("additive") - love.graphics.setShader(self.shader2) - - for i = 1, #self.lights do - self.lights[i]:drawPixelShadow(l,t,w,h, self.normalMap) - end - - love.graphics.setShader() - self.pixelShadow:clear(255, 255, 255) - love.graphics.setCanvas(self.pixelShadow) - love.graphics.setBlendMode("alpha") - love.graphics.draw(self.pixelShadow2, l,t) - love.graphics.setBlendMode("additive") - love.graphics.setColor({self.ambient[1], self.ambient[2], self.ambient[3]}) - love.graphics.rectangle("fill", l,t,w,h) -end - -function light_world:updateGlow(l,t,w,h,s) - -- create glow map - self.glowMap:clear(0, 0, 0) - love.graphics.setCanvas(self.glowMap) - - if self.glowDown then - self.glowTimer = math.max(0.0, self.glowTimer - love.timer.getDelta()) - if self.glowTimer == 0.0 then - self.glowDown = not self.glowDown - end - else - self.glowTimer = math.min(self.glowTimer + love.timer.getDelta(), 1.0) - if self.glowTimer == 1.0 then - self.glowDown = not self.glowDown - end - end - - for i = 1, #self.body do - self.body[i]:drawGlow(l,t,w,h) - end - - light_world:drawBlur("alpha", self.glowBlur, self.glowMap, self.glowMap2, l, t, w, h, s) -end - -function light_world:updateRefraction(l,t,w,h) - -- create refraction map - self.refractionMap:clear() - love.graphics.setCanvas(self.refractionMap) - for i = 1, #self.body do - self.body[i]:drawRefraction(l,t,w,h) - end - - love.graphics.setColor(255, 255, 255) - love.graphics.setBlendMode("alpha") - love.graphics.setCanvas(self.refractionMap2) - love.graphics.draw(self.render_buffer, l, t) -end - -function light_world:updateRelfection(l,t,w,h) - -- create reflection map - self.reflectionMap:clear(0, 0, 0) - love.graphics.setCanvas(self.reflectionMap) - for i = 1, #self.body do - self.body[i]:drawReflection(l,t,w,h) - end - - love.graphics.setColor(255, 255, 255) - love.graphics.setBlendMode("alpha") - love.graphics.setCanvas(self.reflectionMap2) - love.graphics.draw(self.render_buffer, l, t) -end - function light_world:refreshScreenSize(w, h) w, h = w or love.window.getWidth(), h or love.window.getHeight() @@ -209,22 +95,31 @@ end function light_world:draw(l,t,s) l,t,s = (l or 0), (t or 0), s or 1 - local w, h = (love.graphics.getWidth() / s), (love.graphics.getHeight() / s) + local w, h = love.graphics.getWidth(), love.graphics.getHeight() util.drawto(self.render_buffer, l, t, s, function() self.drawBackground( l,t,w,h,s) self:drawShadow( l,t,w,h,s) self.drawForground( l,t,w,h,s) - --self:drawMaterial( l,t,w,h,s) - --self:drawShine( l,t,w,h,s) - --self:drawPixelShadow(l,t,w,h,s) - --self:drawGlow( l,t,w,h,s) - --self:drawRefraction( l,t,w,h,s) - --self:drawReflection( l,t,w,h,s) + self:drawMaterial( l,t,w,h,s) + self:drawShine( l,t,w,h,s) + self:drawPixelShadow(l,t,w,h,s) + self:drawGlow( l,t,w,h,s) + self:drawRefraction( l,t,w,h,s) + self:drawReflection( l,t,w,h,s) end) + self.post_shader:drawWith(self.render_buffer, l, t, s) +end - util.drawCanvasToCanvas(self.render_buffer) - --self.post_shader:drawWith(self.render_buffer, l, t, s) +function light_world:drawBlur(blendmode, blur, canvas, canvas2, l, t, w, h, s) + if blur <= 0 then + return + end + canvas2:clear() + self.blurv:send("steps", blur) + self.blurh:send("steps", blur) + util.drawCanvasToCanvas(canvas, canvas2, {shader = self.blurv, blendmode = blendmode}) + util.drawCanvasToCanvas(canvas2, canvas, {shader = self.blurh, blendmode = blendmode}) end -- draw shadow @@ -252,13 +147,21 @@ function light_world:drawShine(l,t,w,h,s) if not self.isShadows then return end - self:updateShine(l,t,w,h) - love.graphics.setCanvas(self.render_buffer) - love.graphics.setColor(255, 255, 255) - love.graphics.setBlendMode("multiplicative") - love.graphics.setShader() - love.graphics.draw(self.shine, l, t) - love.graphics.setBlendMode("alpha") + + -- update shine + util.drawto(self.shine, l, t, s, function() + love.graphics.setColor(unpack(self.ambient)) + love.graphics.setBlendMode("alpha") + love.graphics.rectangle("fill", l, t, w, h) + love.graphics.setColor(255, 255, 255) + love.graphics.setBlendMode("additive") + for i = 1, #self.lights do + self.lights[i]:drawShine(self.shine) + end + end) + + --light_world:drawBlur("additive", self.blur, self.shine, self.shine2, l, t, w, h, s) + util.drawCanvasToCanvas(self.shine, self.render_buffer, {blendmode = "multiplicative"}) end -- draw pixel shadow @@ -266,13 +169,29 @@ function light_world:drawPixelShadow(l,t,w,h,s) if not self.isShadows then return end - self:updatePixelShadows(l,t,w,h) - love.graphics.setCanvas(self.render_buffer) - love.graphics.setColor(255, 255, 255) - love.graphics.setBlendMode("multiplicative") - love.graphics.setShader() - love.graphics.draw(self.pixelShadow, l, t) - love.graphics.setBlendMode("alpha") + -- update pixel shadow + -- create normal map + self.normalMap:clear() + util.drawto(self.normalMap, l, t, s, function() + for i = 1, #self.body do + self.body[i]:drawPixelShadow(l,t,w,h) + end + end) + + self.pixelShadow2:clear() + for i = 1, #self.lights do + self.lights[i]:drawPixelShadow(l,t,w,h, self.normalMap, self.pixelShadow2) + end + + self.pixelShadow:clear(255, 255, 255) + util.drawCanvasToCanvas(self.pixelShadow2, self.pixelShadow, {blendmode = "alpha"}) + util.drawto(self.pixelShadow, l, t, s, function() + love.graphics.setBlendMode("additive") + love.graphics.setColor({self.ambient[1], self.ambient[2], self.ambient[3]}) + love.graphics.rectangle("fill", l,t,w,h) + end) + + util.drawCanvasToCanvas(self.pixelShadow, self.render_buffer, {blendmode = "multiplicative"}) end -- draw material @@ -287,26 +206,48 @@ function light_world:drawGlow(l,t,w,h,s) if not self.isShadows then return end - self:updateGlow(l,t,w,h) - love.graphics.setCanvas(self.render_buffer) - love.graphics.setColor(255, 255, 255) - love.graphics.setBlendMode("additive") - love.graphics.setShader() - love.graphics.draw(self.glowMap, l,t) - love.graphics.setBlendMode("alpha") + + -- create glow map + self.glowMap:clear(0, 0, 0) + util.drawto(self.glowMap, l, t, s, function() + if self.glowDown then + self.glowTimer = math.max(0.0, self.glowTimer - love.timer.getDelta()) + if self.glowTimer == 0.0 then + self.glowDown = not self.glowDown + end + else + self.glowTimer = math.min(self.glowTimer + love.timer.getDelta(), 1.0) + if self.glowTimer == 1.0 then + self.glowDown = not self.glowDown + end + end + + for i = 1, #self.body do + self.body[i]:drawGlow(l,t,w,h) + end + end) + + light_world:drawBlur("alpha", self.glowBlur, self.glowMap, self.glowMap2, l, t, w, h, s) + util.drawCanvasToCanvas(self.glowMap, self.render_buffer, {blendmode = "additive"}) end -- draw refraction function light_world:drawRefraction(l,t,w,h,s) if not self.isRefraction then return end - self:updateRefraction(l,t,w,h) - love.graphics.setCanvas(self.render_buffer) + + -- create refraction map + self.refractionMap:clear() + util.drawto(self.refractionMap, l, t, s, function() + for i = 1, #self.body do + self.body[i]:drawRefraction(l,t,w,h) + end + end) + + util.drawCanvasToCanvas(self.render_buffer, self.refractionMap2) self.refractionShader:send("backBuffer", self.refractionMap2) self.refractionShader:send("refractionStrength", self.refractionStrength) - love.graphics.setShader(self.refractionShader) - love.graphics.draw(self.refractionMap, l, t) - love.graphics.setShader() + util.drawCanvasToCanvas(self.refractionMap, self.render_buffer, {shader = self.refractionShader}) end -- draw reflection @@ -314,14 +255,20 @@ function light_world:drawReflection(l,t,w,h,s) if not self.isReflection then return end - self:updateRelfection(l,t,w,h) - love.graphics.setCanvas(self.render_buffer) + + -- create reflection map + self.reflectionMap:clear(0, 0, 0) + util.drawto(self.reflectionMap, l, t, s, function() + for i = 1, #self.body do + self.body[i]:drawReflection(l,t,w,h) + end + end) + + util.drawCanvasToCanvas(self.render_buffer, self.reflectionMap2) self.reflectionShader:send("backBuffer", self.reflectionMap2) self.reflectionShader:send("reflectionStrength", self.reflectionStrength) self.reflectionShader:send("reflectionVisibility", self.reflectionVisibility) - love.graphics.setShader(self.reflectionShader) - love.graphics.draw(self.reflectionMap, l, t) - love.graphics.setShader() + util.drawCanvasToCanvas(self.reflectionMap, self.render_buffer, {shader = self.reflectionShader}) end -- new light diff --git a/lib/postshader.lua b/lib/postshader.lua index 94091ec..b3aa0be 100644 --- a/lib/postshader.lua +++ b/lib/postshader.lua @@ -23,6 +23,7 @@ SOFTWARE. ]] local _PACKAGE = (...):match("^(.+)[%./][^%./]+") or "" local class = require(_PACKAGE..'/class') +local util = require(_PACKAGE..'/util') local post_shader = class() post_shader.blurv = love.graphics.newShader(_PACKAGE.."/shaders/blurv.glsl") @@ -69,7 +70,7 @@ function post_shader:toggleEffect(shaderName, ...) end end -function post_shader:drawWith(canvas, l, t, scale) +function post_shader:drawWith(canvas) for shader, args in pairs(self.effects) do if shader == "bloom" then self:drawBloom(canvas, args) @@ -89,154 +90,72 @@ function post_shader:drawWith(canvas, l, t, scale) self:drawTest(canvas, args) end end - - love.graphics.setBackgroundColor(0, 0, 0) - love.graphics.setBlendMode("alpha") - love.graphics.setCanvas() - love.graphics.setShader() - love.graphics.setColor(255, 255, 255) - love.graphics.draw(canvas, l or 0, t or 0) + util.drawCanvasToCanvas(canvas) end function post_shader:drawBloom(canvas, args) - love.graphics.setCanvas(self.back_buffer) - love.graphics.setBlendMode("alpha") - post_shader.blurv:send("steps", args[1] or 2.0) post_shader.blurh:send("steps", args[1] or 2.0) - - love.graphics.setShader(post_shader.blurv) - love.graphics.draw(canvas) - - love.graphics.setShader(post_shader.blurh) - love.graphics.draw(self.back_buffer) - - love.graphics.setShader(post_shader.contrast) - love.graphics.draw(self.back_buffer) - - love.graphics.setCanvas(canvas) - love.graphics.setShader() - love.graphics.setColor(255, 255, 255) - love.graphics.draw(canvas) - love.graphics.setBlendMode("additive") - love.graphics.setColor(255, 255, 255, (args[2] or 0.25) * 255) - love.graphics.draw(self.back_buffer) - love.graphics.setBlendMode("alpha") + util.drawCanvasToCanvas(canvas, self.back_buffer, {shader = post_shader.blurv}) + util.drawCanvasToCanvas(self.back_buffer, self.back_buffer, {shader = post_shader.blurh}) + util.drawCanvasToCanvas(self.back_buffer, self.back_buffer, {shader = post_shader.contrast}) + util.drawCanvasToCanvas(canvas, canvas, {shader = post_shader.contrast}) + util.drawCanvasToCanvas(self.back_buffer, canvas, {blendmode = "additive", color = {255, 255, 255, (args[2] or 0.25) * 255}}) end function post_shader:drawBlur(canvas, args) - love.graphics.setCanvas(self.back_buffer) - love.graphics.setBlendMode("alpha") - post_shader.blurv:send("steps", args[1] or 2.0) post_shader.blurh:send("steps", args[2] or 2.0) - - love.graphics.setShader(post_shader.blurv) - love.graphics.draw(canvas) - - love.graphics.setShader(post_shader.blurh) - love.graphics.draw(self.back_buffer) - - love.graphics.setBlendMode("alpha") - love.graphics.setCanvas(canvas) - love.graphics.setShader() - love.graphics.setColor(255, 255, 255) - love.graphics.draw(self.back_buffer) + util.drawCanvasToCanvas(canvas, self.back_buffer, {shader = post_shader.blurv}) + util.drawCanvasToCanvas(self.back_buffer, self.back_buffer, {shader = post_shader.blurh}) + util.drawCanvasToCanvas(self.back_buffer, canvas) end function post_shader:drawChromatic(canvas, args) - love.graphics.setCanvas(self.back_buffer) - love.graphics.setBlendMode("alpha") - post_shader.chromatic_aberration:send("redStrength", {args[1] or 0.0, args[2] or 0.0}) post_shader.chromatic_aberration:send("greenStrength", {args[3] or 0.0, args[4] or 0.0}) post_shader.chromatic_aberration:send("blueStrength", {args[5] or 0.0, args[6] or 0.0}) - love.graphics.setCanvas(self.back_buffer) - love.graphics.setShader(post_shader.chromatic_aberration) - love.graphics.draw(canvas) - - love.graphics.setBlendMode("alpha") - love.graphics.setCanvas(canvas) - love.graphics.setShader() - love.graphics.setColor(255, 255, 255) - love.graphics.draw(self.back_buffer) + util.drawCanvasToCanvas(canvas, self.back_buffer, {shader = post_shader.chromatic_aberration}) + util.drawCanvasToCanvas(self.back_buffer, canvas) end function post_shader:draw4Color(canvas, args) - love.graphics.setCanvas(self.back_buffer) - love.graphics.setBlendMode("alpha") - local palette = {{unpack(args[1])}, {unpack(args[2])}, {unpack(args[3])}, {unpack(args[4])}} for i = 1, 4 do for k = 1, 3 do palette[i][k] = args[i][k] / 255.0 end end - self.four_color:send("palette", palette[1], palette[2], palette[3], palette[4]) - love.graphics.setShader(self.four_color) - love.graphics.draw(canvas) - - love.graphics.setBlendMode("alpha") - love.graphics.setCanvas(canvas) - love.graphics.setShader() - love.graphics.setColor(255, 255, 255) - love.graphics.draw(self.back_buffer) + util.drawCanvasToCanvas(canvas, self.back_buffer, {shader = post_shader.four_color}) + util.drawCanvasToCanvas(self.back_buffer, canvas) end function post_shader:drawMonochome(canvas, args) - love.graphics.setCanvas(self.back_buffer) - love.graphics.setBlendMode("alpha") - local tint = {args[1], args[2], args[3]} for i = 1, 3 do if tint[i] then tint[i] = tint[i] / 255.0 end end - post_shader.monochrome:send("tint", {tint[1] or 1.0, tint[2] or 1.0, tint[3] or 1.0}) post_shader.monochrome:send("fudge", args[4] or 0.1) post_shader.monochrome:send("time", args[5] or love.timer.getTime()) - love.graphics.setShader(post_shader.monochrome) - love.graphics.draw(canvas) - - love.graphics.setBlendMode("alpha") - love.graphics.setCanvas(canvas) - love.graphics.setShader() - love.graphics.setColor(255, 255, 255) - love.graphics.draw(self.back_buffer) + util.drawCanvasToCanvas(canvas, self.back_buffer, {shader = post_shader.monochrome}) + util.drawCanvasToCanvas(self.back_buffer, canvas) end function post_shader:drawScanlines(canvas, args) - love.graphics.setCanvas(self.back_buffer) - love.graphics.setBlendMode("alpha") - post_shader.scanlines:send("strength", args[1] or 2.0) post_shader.scanlines:send("time", args[2] or love.timer.getTime()) - love.graphics.setShader(post_shader.scanlines) - love.graphics.draw(canvas) - - love.graphics.setBlendMode("alpha") - love.graphics.setCanvas(canvas) - love.graphics.setShader() - love.graphics.setColor(255, 255, 255) - love.graphics.draw(self.back_buffer) + util.drawCanvasToCanvas(canvas, self.back_buffer, {shader = post_shader.scanlines}) + util.drawCanvasToCanvas(self.back_buffer, canvas) end function post_shader:drawTiltshift(canvas, args) - love.graphics.setCanvas(self.back_buffer) - love.graphics.setBlendMode("alpha") - post_shader.tilt_shift:send("imgBuffer", canvas) - love.graphics.setShader(post_shader.tilt_shift) - love.graphics.draw(self.back_buffer) - - love.graphics.setBlendMode("alpha") - love.graphics.setCanvas(canvas) - love.graphics.setShader() - love.graphics.setColor(255, 255, 255) - love.graphics.draw(self.back_buffer) + util.drawCanvasToCanvas(canvas, self.back_buffer, {shader = post_shader.tilt_shift}) + util.drawCanvasToCanvas(self.back_buffer, canvas) end local files = love.filesystem.getDirectoryItems(_PACKAGE.."/shaders/postshaders/test") @@ -265,23 +184,15 @@ function post_shader:drawTest(canvas, args) time = love.timer.getTime() } - love.graphics.setCanvas(self.back_buffer) - love.graphics.setBlendMode("alpha") - local effect = testShaders[args[1]] for def in pairs(effect[2]) do if defaults[def] then effect[1]:send(def, defaults[def]) end end - love.graphics.setShader(effect[1]) - love.graphics.draw(canvas) - love.graphics.setBlendMode("alpha") - love.graphics.setCanvas(canvas) - love.graphics.setShader() - love.graphics.setColor(255, 255, 255) - love.graphics.draw(self.back_buffer) + util.drawCanvasToCanvas(canvas, self.back_buffer, {shader = effect[1]}) + util.drawCanvasToCanvas(self.back_buffer, canvas) end return post_shader diff --git a/lib/util.lua b/lib/util.lua index f8a62b6..79f6595 100644 --- a/lib/util.lua +++ b/lib/util.lua @@ -13,6 +13,9 @@ function util.drawCanvasToCanvas(canvas, other_canvas, options) if options["shader"] then love.graphics.setShader(options["shader"]) end + if options["color"] then + love.graphics.setColor(unpack(options["color"])) + end love.graphics.setColor(255,255,255) love.graphics.draw(canvas,0,0) love.graphics.setCanvas(last_buffer)