singled out the drawing into one function with background and foreground callbacks, this will draw the refraction and reflection without the post shader

This commit is contained in:
Tim Anema 2014-10-02 20:32:31 -04:00
parent 6739da8423
commit 3d15d0832e
6 changed files with 248 additions and 329 deletions

View File

@ -89,10 +89,15 @@ function love.load()
-- light world
lightRange = 400
lightSmooth = 1.0
lightWorld = LightWorld()
lightWorld:setAmbientColor(15, 15, 31)
lightWorld:setRefractionStrength(16.0)
lightWorld:setReflectionVisibility(0.75)
lightWorld = LightWorld({
ambient = {15,15,15},
refractionStrength = 16.0,
reflectionVisibility = 0.75,
drawBackground = drawBackground,
drawForground = drawForground
})
mouseLight = lightWorld:newLight(0, 0, 255, 191, 127, lightRange)
mouseLight:setGlowStrength(0.3)
mouseLight:setSmooth(lightSmooth)
@ -224,95 +229,12 @@ function love.update(dt)
end
function love.draw()
lightWorld:update()
-- set shader buffer
if bloomOn then
love.postshader.setBuffer("render")
end
love.graphics.setBlendMode("alpha")
if normalOn then
love.graphics.setColor(127, 127, 255)
love.graphics.rectangle("fill", 0, 0, love.graphics.getWidth(), love.graphics.getHeight())
else
love.graphics.setColor(255, 255, 255)
if textureOn then
love.graphics.draw(imgFloor, quadScreen, offsetX % 32 - 32, offsetY % 24 - 24)
else
love.graphics.rectangle("fill", 0, 0, love.graphics.getWidth(), love.graphics.getHeight())
end
end
for i = 1, phyCnt do
if phyLight[i]:getType() == "refraction" then
if not normalOn then
--if math.mod(i, 2) == 0 then
love.graphics.setBlendMode("alpha")
love.graphics.setColor(255, 255, 255, 191)
love.graphics.draw(water, phyLight[i].x - phyLight[i].ox, phyLight[i].y - phyLight[i].oy)
--else
--love.graphics.setBlendMode("multiplicative")
--math.randomseed(i)
--love.graphics.setColor(math.random(0, 255), math.random(0, 255), math.random(0, 255))
--love.graphics.rectangle("fill", phyLight[i].x - phyLight[i].ox, phyLight[i].y - phyLight[i].oy, 128, 128)
--end
end
end
end
-- draw lightmap shadows
if lightOn and not normalOn then
lightWorld:drawShadow()
end
for i = 1, phyCnt do
math.randomseed(i)
love.graphics.setColor(math.random(0, 255), math.random(0, 255), math.random(0, 255))
if phyLight[i]:getType() == "polygon" then
love.graphics.polygon("fill", phyLight[i]:getPoints())
elseif phyLight[i]:getType() == "circle" then
love.graphics.circle("fill", phyLight[i]:getX(), phyLight[i]:getY(), phyLight[i]:getRadius())
end
end
-- draw lightmap shine
if lightOn and not normalOn then
lightWorld:drawShine()
end
love.graphics.setBlendMode("alpha")
for i = 1, phyCnt do
if phyLight[i]:getType() == "image" then
if normalOn and phyLight[i].normal then
love.graphics.setColor(255, 255, 255)
love.graphics.draw(phyLight[i].normal, phyLight[i].x - phyLight[i].nx, phyLight[i].y - phyLight[i].ny)
elseif not phyLight[i].material then
math.randomseed(i)
love.graphics.setColor(math.random(127, 255), math.random(127, 255), math.random(127, 255))
love.graphics.draw(phyLight[i].img, phyLight[i].x - phyLight[i].ix, phyLight[i].y - phyLight[i].iy)
end
end
end
if not normalOn then
lightWorld:drawMaterial()
end
-- draw pixel shadow
if lightOn and not normalOn then
lightWorld:drawPixelShadow()
end
-- draw glow
if lightOn and not normalOn then
lightWorld:drawGlow()
end
-- draw reflection
lightWorld:drawReflection()
-- draw refraction
lightWorld:drawRefraction()
lightWorld:draw()
love.graphics.draw(imgLight, mx - 5, (my - 5) - (16.0 + (math.sin(lightDirection) + 1.0) * 64.0))
@ -432,6 +354,61 @@ function love.draw()
love.postshader.draw()
end
function drawBackground(l,t,w,h)
love.graphics.setBlendMode("alpha")
if normalOn then
love.graphics.setColor(127, 127, 255)
love.graphics.rectangle("fill", 0, 0, love.graphics.getWidth(), love.graphics.getHeight())
else
love.graphics.setColor(255, 255, 255)
if textureOn then
love.graphics.draw(imgFloor, quadScreen, offsetX % 32 - 32, offsetY % 24 - 24)
else
love.graphics.rectangle("fill", 0, 0, love.graphics.getWidth(), love.graphics.getHeight())
end
end
for i = 1, phyCnt do
if phyLight[i]:getType() == "refraction" then
if not normalOn then
love.graphics.setBlendMode("alpha")
love.graphics.setColor(255, 255, 255, 191)
love.graphics.draw(water, phyLight[i].x - phyLight[i].ox, phyLight[i].y - phyLight[i].oy)
end
end
end
end
function drawForground(l,t,w,h)
for i = 1, phyCnt do
math.randomseed(i)
love.graphics.setColor(math.random(0, 255), math.random(0, 255), math.random(0, 255))
if phyLight[i]:getType() == "polygon" then
love.graphics.polygon("fill", phyLight[i]:getPoints())
elseif phyLight[i]:getType() == "circle" then
love.graphics.circle("fill", phyLight[i]:getX(), phyLight[i]:getY(), phyLight[i]:getRadius())
end
end
love.graphics.setBlendMode("alpha")
for i = 1, phyCnt do
if phyLight[i]:getType() == "image" then
if normalOn and phyLight[i].normal then
love.graphics.setColor(255, 255, 255)
love.graphics.draw(phyLight[i].normal, phyLight[i].x - phyLight[i].nx, phyLight[i].y - phyLight[i].ny)
elseif not phyLight[i].material then
math.randomseed(i)
love.graphics.setColor(math.random(127, 255), math.random(127, 255), math.random(127, 255))
love.graphics.draw(phyLight[i].img, phyLight[i].x - phyLight[i].ix, phyLight[i].y - phyLight[i].iy)
end
end
end
if not normalOn then
lightWorld:drawMaterial(l,t,w,h)
end
end
function love.mousepressed(x, y, c)
if c == "m" then
-- add light

View File

@ -1,6 +1,5 @@
require 'lib/postshader'
-- Example: Short Example
require "lib/postshader"
local gamera = require "vendor/gamera"
local LightWorld = require "lib/light_world"
@ -14,14 +13,16 @@ function love.load()
glow = love.graphics.newImage("gfx/machine2_glow.png")
-- create light world
lightWorld = LightWorld()
lightWorld = LightWorld({
drawBackground = drawBackground,
drawForground = drawForground
})
lightWorld:setAmbientColor(15, 15, 31)
lightWorld:setRefractionStrength(32.0)
-- create light
lightMouse = lightWorld:newLight(0, 0, 255, 127, 63, 300)
lightMouse:setGlowStrength(0.3)
--lightMouse:setSmooth(0.01)
-- create shadow bodys
circleTest = lightWorld:newCircle(256, 256, 16)
@ -34,15 +35,7 @@ function love.load()
-- create body object
objectTest = lightWorld:newRefraction(normal, 64, 64, 128, 128)
--objectTest:setShine(false)
--objectTest:setShadowType("rectangle")
--objectTest:setShadowDimension(64, 64)
objectTest:setReflection(true)
-- set background
quadScreen = love.graphics.newQuad(0, 0, love.window.getWidth(), love.window.getHeight(), 32, 24)
imgFloor = love.graphics.newImage("gfx/floor.png")
imgFloor:setWrap("repeat", "repeat")
end
function love.update(dt)
@ -74,19 +67,20 @@ end
function love.draw()
camera:draw(function(l,t,w,h)
lightWorld:update(l,t,w,h)
love.graphics.setColor(255, 255, 255)
love.graphics.rectangle("fill", 0, 0, 2000, 2000)
lightWorld:drawShadow(l,t,w,h)
love.graphics.setColor(63, 255, 127)
love.graphics.circle("fill", circleTest:getX(), circleTest:getY(), circleTest:getRadius())
love.graphics.polygon("fill", rectangleTest:getPoints())
love.graphics.setColor(255, 255, 255)
love.graphics.draw(image, 64 - image:getWidth() * 0.5, 64 - image:getHeight() * 0.5)
lightWorld:drawShine(l,t,w,h)
lightWorld:drawPixelShadow(l,t,w,h)
lightWorld:drawGlow(l,t,w,h)
lightWorld:drawRefraction(l,t,w,h)
lightWorld:drawReflection(l,t,w,h)
lightWorld:draw(l,t,w,h,scale)
end)
end
function drawBackground(l,t,w,h)
love.graphics.setColor(255, 255, 255)
love.graphics.rectangle("fill", 0, 0, 2000, 2000)
end
function drawForground(l,t,w,h)
love.graphics.setColor(63, 255, 127)
love.graphics.circle("fill", circleTest:getX(), circleTest:getY(), circleTest:getRadius())
love.graphics.polygon("fill", rectangleTest:getPoints())
love.graphics.setColor(255, 255, 255)
love.graphics.draw(image, 64 - image:getWidth() * 0.5, 64 - image:getHeight() * 0.5)
end

View File

@ -7,14 +7,13 @@ local body = class()
body.glowShader = love.graphics.newShader(_PACKAGE.."/shaders/glow.glsl")
body.materialShader = love.graphics.newShader(_PACKAGE.."/shaders/material.glsl")
function body:init(world, id, type, ...)
function body:init(id, type, ...)
local args = {...}
self.id = id
self.type = type
self.normal = nil
self.material = nil
self.glow = nil
self.world = world
self.shine = true
self.red = 0
@ -35,7 +34,6 @@ function body:init(world, id, type, ...)
self.ox = args[4] or 0
self.oy = args[5] or 0
self.shadowType = "circle"
world.isShadows = true
elseif self.type == "rectangle" then
self.x = args[1] or 0
self.y = args[2] or 0
@ -54,11 +52,9 @@ function body:init(world, id, type, ...)
self.x - self.ox,
self.y - self.oy + self.height
}
world.isShadows = true
elseif self.type == "polygon" then
self.shadowType = "polygon"
self.data = args or {0, 0, 0, 0, 0, 0}
world.isShadows = true
elseif self.type == "image" then
self.img = args[1]
self.x = args[2] or 0
@ -95,7 +91,6 @@ function body:init(world, id, type, ...)
self.y - self.oy + self.height
}
self.reflective = true
world.isShadows = true
elseif self.type == "refraction" then
self.normal = args[1]
self.x = args[2] or 0
@ -122,7 +117,6 @@ function body:init(world, id, type, ...)
self.ox = self.width * 0.5
self.oy = self.height * 0.5
self.refraction = true
world.isRefraction = true
elseif self.type == "reflection" then
self.normal = args[1]
self.x = args[2] or 0
@ -149,7 +143,6 @@ function body:init(world, id, type, ...)
self.ox = self.width * 0.5
self.oy = self.height * 0.5
self.reflection = true
world.isReflection = true
end
end
@ -173,7 +166,6 @@ function body:setPosition(x, y)
self.x = x
self.y = y
self:refresh()
self.world.changed = true
end
end
@ -182,7 +174,6 @@ function body:setX(x)
if x ~= self.x then
self.x = x
self:refresh()
self.world.changed = true
end
end
@ -191,7 +182,6 @@ function body:setY(y)
if y ~= self.y then
self.y = y
self:refresh()
self.world.changed = true
end
end
@ -230,7 +220,6 @@ function body:setDimension(width, height)
self.width = width
self.height = height
self:refresh()
self.world.changed = true
end
-- set offset
@ -241,7 +230,6 @@ function body:setOffset(ox, oy)
if self.shadowType == "rectangle" then
self:refresh()
end
self.world.changed = true
end
end
@ -251,7 +239,6 @@ function body:setImageOffset(ix, iy)
self.ix = ix
self.iy = iy
self:refresh()
self.world.changed = true
end
end
@ -261,7 +248,6 @@ function body:setNormalOffset(nx, ny)
self.nx = nx
self.ny = ny
self:refresh()
self.world.changed = true
end
end
@ -270,13 +256,11 @@ function body:setGlowColor(red, green, blue)
self.glowRed = red
self.glowGreen = green
self.glowBlue = blue
self.world.changed = true
end
-- set glow alpha
function body:setGlowStrength(strength)
self.glowStrength = strength
self.world.changed = true
end
-- get radius
@ -288,14 +272,12 @@ end
function body:setRadius(radius)
if radius ~= self.radius then
self.radius = radius
self.world.changed = true
end
end
-- set polygon data
function body:setPoints(...)
self.data = {...}
self.world.changed = true
end
-- get polygon data
@ -306,13 +288,11 @@ end
-- set shadow on/off
function body:setShadow(b)
self.castsNoShadow = not b
self.world.changed = true
end
-- set shine on/off
function body:setShine(b)
self.shine = b
self.world.changed = true
end
-- set glass color
@ -320,13 +300,11 @@ function body:setColor(red, green, blue)
self.red = red
self.green = green
self.blue = blue
self.world.changed = true
end
-- set glass alpha
function body:setAlpha(alpha)
self.alpha = alpha
self.world.changed = true
end
-- set reflection on/off
@ -376,8 +354,6 @@ function body:setNormalMap(normal, width, height, nx, ny)
{0.0, self.normalHeight, 0.0, self.normalHeight / self.normal:getHeight()}
}
self.normalMesh = love.graphics.newMesh(self.normalVert, self.normal, "fan")
self.world.isPixelShadows = true
else
self.normalMesh = nil
end
@ -475,8 +451,6 @@ end
function body:setGlowMap(glow)
self.glow = glow
self.glowStrength = 1.0
self.world.isGlow = true
end
-- set tile offset
@ -489,7 +463,6 @@ function body:setNormalTileOffset(tx, ty)
{self.normalWidth, self.normalHeight, self.tileX + 1.0, self.tileY + 1.0},
{0.0, self.normalHeight, self.tileX, self.tileY + 1.0}
}
self.world.changed = true
end
-- get type

View File

@ -9,13 +9,10 @@ light.shader = love.graphics.newShader(_PACKAGE.."/shaders/poly_shad
light.normalShader = love.graphics.newShader(_PACKAGE.."/shaders/normal.glsl")
light.normalInvertShader = love.graphics.newShader(_PACKAGE.."/shaders/normal_invert.glsl")
function light:init(world, x, y, r, g, b, range)
self.world = world
function light:init(x, y, r, g, b, range)
self.direction = 0
self.angle = math.pi * 2.0
self.range = 0
self.shadow = love.graphics.newCanvas()
self.shine = love.graphics.newCanvas()
self.x = x or 0
self.y = y or 0
self.z = 15
@ -27,6 +24,12 @@ function light:init(world, x, y, r, g, b, range)
self.glowSize = 0.1
self.glowStrength = 0.0
self.visible = true
self:refresh()
end
function light:refresh()
self.shadow = love.graphics.newCanvas()
self.shine = love.graphics.newCanvas()
end
-- set position
@ -63,6 +66,7 @@ function light:setY(y)
self.y = y
end
end
-- set color
function light:setColor(red, green, blue)
self.red = red
@ -118,7 +122,7 @@ function light:setGlowStrength(strength)
self.glowStrength = strength
end
function light:updateShadow(l,t,w,h)
function light:updateShadow(l,t,w,h, bodies)
love.graphics.setShader(self.shader)
if self.x + self.range > l and self.x - self.range < (l+w) and self.y + self.range > t and self.y - self.range < (t+h) then
local lightposrange = {self.x, h - self.y, self.range}
@ -134,10 +138,10 @@ function light:updateShadow(l,t,w,h)
love.graphics.clear()
-- calculate shadows
local shadow_geometry = self:calculateShadows()
local shadow_geometry = self:calculateShadows(bodies)
-- draw shadow
love.graphics.setInvertedStencil(stencils.shadow(shadow_geometry, self.world.body))
love.graphics.setInvertedStencil(stencils.shadow(shadow_geometry, bodies))
love.graphics.setBlendMode("additive")
love.graphics.rectangle("fill", l,t,w,h)
@ -155,8 +159,8 @@ function light:updateShadow(l,t,w,h)
end
end
for k = 1, #self.world.body do
self.world.body[k]:drawShadow(self, l,t,w,h)
for k = 1, #bodies do
bodies[k]:drawShadow(self, l,t,w,h)
end
love.graphics.setShader(self.shader)
@ -165,10 +169,9 @@ function light:updateShadow(l,t,w,h)
love.graphics.setCanvas(self.shine)
self.shine:clear(255, 255, 255)
love.graphics.setBlendMode("alpha")
love.graphics.setStencil(stencils.poly(self.world.body))
-- WHOA THIS MAY BE THE ISSUE HERE FIND THIS!
love.graphics.setStencil(stencils.poly(bodies))
love.graphics.rectangle("fill", l,t,w,h)
love.graphics.setStencil()
self.visible = true
else
self.visible = false
@ -178,6 +181,8 @@ end
function light:drawShadow(l,t,w,h)
if self.visible then
love.graphics.setColor(255, 255, 255)
love.graphics.setBlendMode("additive")
love.graphics.draw(self.shadow, l, t)
end
end
@ -189,16 +194,15 @@ function light:drawShine(l,t,w,h)
end
local shadowLength = 100000
function light:calculateShadows()
function light:calculateShadows(bodies)
local shadowGeometry = {}
local body = self.world.body
for i = 1, #body do
for i = 1, #bodies do
local current
if body[i].shadowType == "rectangle" or body[i].shadowType == "polygon" then
current = self:calculatePolyShadow(body[i])
elseif body[i].shadowType == "circle" then
current = self:calculateCircleShadow(body[i])
if bodies[i].shadowType == "rectangle" or bodies[i].shadowType == "polygon" then
current = self:calculatePolyShadow(bodies[i])
elseif bodies[i].shadowType == "circle" then
current = self:calculateCircleShadow(bodies[i])
end
if current ~= nil then
shadowGeometry[#shadowGeometry + 1] = current
@ -300,7 +304,7 @@ function light:calculateCircleShadow(circle)
end
end
function light:drawPixelShadow(l,t,w,h)
function light:drawPixelShadow(l,t,w,h, normalMap)
if self.visible then
if self.normalInvert then
self.normalInvertShader:send('screenResolution', {w, h})
@ -321,7 +325,7 @@ function light:drawPixelShadow(l,t,w,h)
self.normalShader:send("lightDirection", self.direction)
love.graphics.setShader(self.normalShader)
end
love.graphics.draw(self.world.normalMap, l, t)
love.graphics.draw(normalMap, l, t)
end
end

View File

@ -34,81 +34,72 @@ light_world.blurh = love.graphics.newShader(_PACKAGE.."/shaders/blu
light_world.refractionShader = love.graphics.newShader(_PACKAGE.."/shaders/refraction.glsl")
light_world.reflectionShader = love.graphics.newShader(_PACKAGE.."/shaders/reflection.glsl")
light_world.blurv:send("screen", {love.window.getWidth(), love.window.getHeight()})
light_world.blurh:send("screen", {love.window.getWidth(), love.window.getHeight()})
light_world.refractionShader:send("screen", {love.window.getWidth(), love.window.getHeight()})
light_world.reflectionShader:send("screen", {love.window.getWidth(), love.window.getHeight()})
function light_world:init()
self.last_buffer = nil
function light_world:init(options)
self.lights = {}
self.body = {}
self.ambient = {0, 0, 0}
self.normalInvert = false
self.glowBlur = 1.0
self.glowTimer = 0.0
self.glowDown = false
self.refractionStrength = 8.0
self.reflectionStrength = 16.0
self.reflectionVisibility = 1.0
self.blur = 2.0
self.glowBlur = 1.0
self.glowTimer = 0.0
self.glowDown = false
self.drawBackground = function() end
self.drawForground = function() end
options = options or {}
for k, v in pairs(options) do self[k] = v end
self:refreshScreenSize()
end
function light_world:update(l,t,w,h)
l,t,w,h = self.clampScreen(l,t,w,h)
self:updateShadows(l,t,w,h)
self:updateShine(l,t,w,h)
self:updatePixelShadows(l,t,w,h)
self:updateGlow(l,t,w,h)
self:updateRefraction(l,t,w,h)
self:updateRelfection(l,t,w,h)
function light_world:drawBlur(blendmode, blur, canvas, canvas2, l, t, w, h)
if blur <= 0 then
return
end
love.graphics.setColor(255, 255, 255)
self.blurv:send("steps", blur)
self.blurh:send("steps", blur)
love.graphics.setBlendMode(blendmode)
canvas2:clear()
love.graphics.setCanvas(canvas2)
love.graphics.setShader(self.blurv)
love.graphics.draw(canvas, l, t)
love.graphics.setCanvas(canvas)
love.graphics.setShader(self.blurh)
love.graphics.draw(canvas2, l, t)
end
function light_world:updateShadows(l,t,w,h)
if not self.isShadows and not self.isLight then
return
end
self.last_buffer = love.graphics.getCanvas()
local last_buffer = love.graphics.getCanvas()
for i = 1, #self.lights do
self.lights[i]:updateShadow(l,t,w,h)
self.lights[i]:updateShadow(l,t,w,h, self.body)
end
-- update shadow
love.graphics.setCanvas(self.shadow)
love.graphics.setStencil()
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]:drawShadow(l,t,w,h)
end
if self.blur then
love.graphics.setColor(255, 255, 255)
self.blurv:send("steps", self.blur)
self.blurh:send("steps", self.blur)
love.graphics.setBlendMode("alpha")
love.graphics.setCanvas(self.shadow2)
love.graphics.setShader(self.blurv)
love.graphics.draw(self.shadow, l, t)
love.graphics.setCanvas(self.shadow)
love.graphics.setShader(self.blurh)
love.graphics.draw(self.shadow2, l, t)
end
love.graphics.setCanvas(self.last_buffer)
light_world:drawBlur("alpha", self.blur, self.shadow, self.shadow2, l, t, w, h)
love.graphics.setCanvas(last_buffer)
end
function light_world:updateShine(l,t,w,h)
self.last_buffer = love.graphics.getCanvas()
local last_buffer = love.graphics.getCanvas()
-- update shine
love.graphics.setCanvas(self.shine)
love.graphics.setColor(unpack(self.ambient))
@ -121,28 +112,12 @@ function light_world:updateShine(l,t,w,h)
self.lights[i]:drawShine(l,t,w,h)
end
if self.blur and false then
love.graphics.setColor(255, 255, 255)
self.blurv:send("steps", self.blur)
self.blurh:send("steps", self.blur)
love.graphics.setBlendMode("alpha")
love.graphics.setCanvas(self.shine2)
love.graphics.setShader(self.blurv)
love.graphics.draw(self.shine, l, t)
love.graphics.setCanvas(self.shine)
love.graphics.setShader(self.blurh)
love.graphics.draw(self.shine2, l, t)
end
love.graphics.setCanvas(self.last_buffer)
--light_world:drawBlur("additive", self.blur, self.shine, self.shine2, l, t, w, h)
love.graphics.setCanvas(last_buffer)
end
function light_world:updatePixelShadows(l,t,w,h)
if not self.isPixelShadows then
return
end
self.last_buffer = love.graphics.getCanvas()
local last_buffer = love.graphics.getCanvas()
-- update pixel shadow
love.graphics.setBlendMode("alpha")
@ -150,19 +125,20 @@ function light_world:updatePixelShadows(l,t,w,h)
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.lights[i]:drawPixelShadow(l,t,w,h, self.normalMap)
end
love.graphics.setShader()
@ -175,15 +151,11 @@ function light_world:updatePixelShadows(l,t,w,h)
love.graphics.rectangle("fill", l,t,w,h)
love.graphics.setBlendMode("alpha")
love.graphics.setCanvas(self.last_buffer)
love.graphics.setCanvas(last_buffer)
end
function light_world:updateGlow(l,t,w,h)
if not self.isGlow then
return
end
self.last_buffer = love.graphics.getCanvas()
local last_buffer = love.graphics.getCanvas()
-- create glow map
self.glowMap:clear(0, 0, 0)
love.graphics.setCanvas(self.glowMap)
@ -204,30 +176,12 @@ function light_world:updateGlow(l,t,w,h)
self.body[i]:drawGlow(l,t,w,h)
end
love.graphics.setColor(255, 255, 255)
if self.glowBlur == 0.0 then
self.blurv:send("steps", self.glowBlur)
self.blurh:send("steps", self.glowBlur)
love.graphics.setBlendMode("additive")
self.glowMap2:clear()
love.graphics.setCanvas(self.glowMap2)
love.graphics.setShader(self.blurv)
love.graphics.draw(self.glowMap, l, t)
love.graphics.setCanvas(self.glowMap)
love.graphics.setShader(self.blurh)
love.graphics.draw(self.glowMap2, l, t)
love.graphics.setBlendMode("alpha")
end
love.graphics.setCanvas(self.last_buffer)
light_world:drawBlur("alpha", self.glowBlur, self.glowMap, self.glowMap2, l, t, w, h)
love.graphics.setCanvas(last_buffer)
end
function light_world:updateRefraction(l,t,w,h)
if not self.isRefraction then
return
end
self.last_buffer = love.graphics.getCanvas()
local last_buffer = love.graphics.getCanvas()
-- create refraction map
self.refractionMap:clear()
@ -236,24 +190,20 @@ function light_world:updateRefraction(l,t,w,h)
self.body[i]:drawRefraction(l,t,w,h)
end
if self.last_buffer then
if last_buffer then
love.graphics.setColor(255, 255, 255)
love.graphics.setBlendMode("alpha")
love.graphics.setCanvas(self.refractionMap2)
love.graphics.draw(self.last_buffer, l, t)
love.graphics.setCanvas(self.last_buffer)
love.graphics.draw(last_buffer, l, t)
love.graphics.setCanvas(last_buffer)
love.graphics.setShader()
end
love.graphics.setCanvas(self.last_buffer)
love.graphics.setCanvas(last_buffer)
end
function light_world:updateRelfection(l,t,w,h)
if not self.isReflection then
return
end
self.last_buffer = love.graphics.getCanvas()
local last_buffer = love.graphics.getCanvas()
-- create reflection map
self.reflectionMap:clear(0, 0, 0)
love.graphics.setCanvas(self.reflectionMap)
@ -261,18 +211,19 @@ function light_world:updateRelfection(l,t,w,h)
self.body[i]:drawReflection(l,t,w,h)
end
if self.last_buffer then
if last_buffer then
love.graphics.setColor(255, 255, 255)
love.graphics.setBlendMode("alpha")
love.graphics.setCanvas(self.reflectionMap2)
love.graphics.draw(self.last_buffer, l, t)
love.graphics.draw(last_buffer, l, t)
love.graphics.setShader()
end
love.graphics.setCanvas(self.last_buffer)
love.graphics.setCanvas(last_buffer)
end
function light_world:refreshScreenSize()
self.render_buffer = love.graphics.newCanvas()
self.shadow = love.graphics.newCanvas()
self.shadow2 = love.graphics.newCanvas()
self.pixelShadow = love.graphics.newCanvas()
@ -286,20 +237,45 @@ function light_world:refreshScreenSize()
self.refractionMap2 = love.graphics.newCanvas()
self.reflectionMap = love.graphics.newCanvas()
self.reflectionMap2 = love.graphics.newCanvas()
self.blurv:send("screen", {love.window.getWidth(), love.window.getHeight()})
self.blurh:send("screen", {love.window.getWidth(), love.window.getHeight()})
self.refractionShader:send("screen", {love.window.getWidth(), love.window.getHeight()})
self.reflectionShader:send("screen", {love.window.getWidth(), love.window.getHeight()})
for i = 1, #self.lights do
self.lights[i]:refresh()
end
end
function light_world.clampScreen(l,t,w,h)
return (l or 0), (t or 0), (w or love.graphics.getWidth()), (h or love.graphics.getHeight())
function light_world:draw(l,t,w,h,s)
l,t,w,h,s = (l or 0), (t or 0), (w or love.graphics.getWidth()), (h or love.graphics.getHeight()), s or 1
local last_buffer = love.graphics.getCanvas()
love.graphics.setCanvas(self.render_buffer)
self.drawBackground(l,t,w,h,s)
self:drawShadow(l,t,w,h,scale)
self.drawForground(l,t,w,h,s)
self:drawShine(l,t,w,h,scale)
self:drawPixelShadow(l,t,w,h,scale)
self:drawGlow(l,t,w,h,scale)
self:drawRefraction(l,t,w,h,scale)
self:drawReflection(l,t,w,h,scale)
love.graphics.setBackgroundColor(0, 0, 0)
love.graphics.setBlendMode("alpha")
love.graphics.setCanvas(last_buffer)
love.graphics.setShader()
love.graphics.setColor(255, 255, 255)
love.graphics.draw(self.render_buffer)
end
-- draw shadow
function light_world:drawShadow(l,t,w,h)
function light_world:drawShadow(l,t,w,h,s)
if not self.isShadows and not self.isLight then
return
end
l,t,w,h = self.clampScreen(l,t,w,h)
self:updateShadows(l,t,w,h)
love.graphics.setColor(255, 255, 255)
love.graphics.setBlendMode("multiplicative")
love.graphics.setShader()
@ -308,13 +284,11 @@ function light_world:drawShadow(l,t,w,h)
end
-- draw shine
function light_world:drawShine(l,t,w,h)
function light_world:drawShine(l,t,w,h,s)
if not self.isShadows then
return
end
l,t,w,h = self.clampScreen(l,t,w,h)
self:updateShine(l,t,w,h)
love.graphics.setColor(255, 255, 255)
love.graphics.setBlendMode("multiplicative")
love.graphics.setShader()
@ -323,13 +297,11 @@ function light_world:drawShine(l,t,w,h)
end
-- draw pixel shadow
function light_world:drawPixelShadow(l,t,w,h)
if not self.isPixelShadows then
function light_world:drawPixelShadow(l,t,w,h,s)
if not self.isShadows then
return
end
l,t,w,h = self.clampScreen(l,t,w,h)
self:updatePixelShadows(l,t,w,h)
love.graphics.setColor(255, 255, 255)
love.graphics.setBlendMode("multiplicative")
love.graphics.setShader()
@ -338,22 +310,18 @@ function light_world:drawPixelShadow(l,t,w,h)
end
-- draw material
function light_world:drawMaterial(l,t,w,h)
l,t,w,h = self.clampScreen(l,t,w,h)
function light_world:drawMaterial(l,t,w,h,s)
for i = 1, #self.body do
self.body[i]:drawMaterial(l,t,w,h)
end
end
-- draw glow
function light_world:drawGlow(l,t,w,h)
if not self.isGlow then
function light_world:drawGlow(l,t,w,h,s)
if not self.isShadows then
return
end
l,t,w,h = self.clampScreen(l,t,w,h)
self:updateGlow(l,t,w,h)
love.graphics.setColor(255, 255, 255)
love.graphics.setBlendMode("additive")
love.graphics.setShader()
@ -361,13 +329,11 @@ function light_world:drawGlow(l,t,w,h)
love.graphics.setBlendMode("alpha")
end
-- draw refraction
function light_world:drawRefraction(l,t,w,h)
function light_world:drawRefraction(l,t,w,h,s)
if not self.isRefraction then
return
end
l,t,w,h = self.clampScreen(l,t,w,h)
self:updateRefraction(l,t,w,h)
self.refractionShader:send("backBuffer", self.refractionMap2)
self.refractionShader:send("refractionStrength", self.refractionStrength)
love.graphics.setShader(self.refractionShader)
@ -376,13 +342,11 @@ function light_world:drawRefraction(l,t,w,h)
end
-- draw reflection
function light_world:drawReflection(l,t,w,h)
function light_world:drawReflection(l,t,w,h,s)
if not self.isReflection then
return
end
l,t,w,h = self.clampScreen(l,t,w,h)
self:updateRelfection(l,t,w,h)
self.reflectionShader:send("backBuffer", self.reflectionMap2)
self.reflectionShader:send("reflectionStrength", self.reflectionStrength)
self.reflectionShader:send("reflectionVisibility", self.reflectionVisibility)
@ -393,7 +357,7 @@ end
-- new light
function light_world:newLight(x, y, red, green, blue, range)
self.lights[#self.lights + 1] = Light(self, x, y, red, green, blue, range)
self.lights[#self.lights + 1] = Light(x, y, red, green, blue, range)
self.isLight = true
return self.lights[#self.lights]
end
@ -408,12 +372,18 @@ end
function light_world:clearBodys()
self.body = {}
self.isShadows = false
self.isPixelShadows = false
self.isGlow = false
self.isRefraction = false
self.isReflection = false
end
function light_world:setBackgroundMethod(fn)
self.drawBackground = fn or function() end
end
function light_world:setForegroundMethod(fn)
self.drawForground = fn or function() end
end
-- set ambient color
function light_world:setAmbientColor(red, green, blue)
self.ambient = {red, green, blue}
@ -449,19 +419,6 @@ function light_world:setShadowBlur(blur)
self.blur = blur
end
-- set buffer
function light_world:setBuffer(buffer)
if buffer == "render" then
love.graphics.setCanvas(self.last_buffer)
else
self.last_buffer = love.graphics.getCanvas()
end
if buffer == "glow" then
love.graphics.setCanvas(self.glowMap)
end
end
-- set glow blur
function light_world:setGlowStrength(strength)
self.glowBlur = strength
@ -484,50 +441,58 @@ end
-- new rectangle
function light_world:newRectangle(x, y, w, h)
self.isShadows = true
return self:newBody("rectangle", x, y, width, height)
end
-- new circle
function light_world:newCircle(x, y, r)
return self:newBody("circle", x, y, radius)
self.isShadows = true
return self:newBody("circle", x, y, r)
end
-- new polygon
function light_world:newPolygon(...)
self.isShadows = true
return self:newBody("polygon", ...)
end
-- new image
function light_world:newImage(img, x, y, width, height, ox, oy)
self.isShadows = true
return self:newBody("image", img, x, y, width, height, ox, oy)
end
-- new refraction
function light_world:newRefraction(normal, x, y, width, height)
self.isRefraction = true
return self:newBody("refraction", normal, x, y, width, height)
end
-- new refraction from height map
function light_world:newRefractionHeightMap(heightMap, x, y, strength)
local normal = height_map_conv.toNormalMap(heightMap, strength)
self.isRefraction = true
return self.newRefraction(p, normal, x, y)
end
-- new reflection
function light_world:newReflection(normal, x, y, width, height)
self.isReflection = true
return self:newBody("reflection", normal, x, y, width, height)
end
-- new reflection from height map
function light_world:newReflectionHeightMap(heightMap, x, y, strength)
local normal = height_map_conv.toNormalMap(heightMap, strength)
self.isReflection = true
return self.newReflection(p, normal, x, y)
end
-- new body
function light_world:newBody(type, ...)
local id = #self.body + 1
self.body[id] = Body(self, id, type, ...)
self.body[id] = Body(id, type, ...)
return self.body[#self.body]
end

View File

@ -58,25 +58,28 @@ function exf.update(dt)
end
function exf.draw()
love.graphics.setBackgroundColor(0, 0, 0)
lightWorld:draw(0, 0, love.window.getWidth(), love.window.getHeight(), 1)
end
love.graphics.setColor(48, 156, 225)
love.graphics.rectangle("fill", 0, 0, love.window.getWidth(), love.window.getHeight())
function exf.drawBackground()
love.graphics.setBackgroundColor(0, 0, 0)
love.graphics.setColor(255, 255, 255, 191)
love.graphics.setFont(exf.bigfont)
love.graphics.print("Examples:", 50, 50)
love.graphics.setColor(48, 156, 225)
love.graphics.rectangle("fill", 0, 0, love.window.getWidth(), love.window.getHeight())
love.graphics.setFont(exf.smallfont)
love.graphics.print("Browse and click on the example you \nwant to run. To return the the example \nselection screen, press escape.", 500, 80)
love.graphics.setColor(255, 255, 255, 191)
love.graphics.setFont(exf.bigfont)
love.graphics.print("Examples:", 50, 50)
exf.list:draw()
love.graphics.setFont(exf.smallfont)
love.graphics.print("Browse and click on the example you \nwant to run. To return the the example \nselection screen, press escape.", 500, 80)
lightWorld:update()
lightWorld:drawShadow()
exf.list:draw()
end
love.graphics.setColor(255, 255, 255)
love.graphics.draw(exf.bigball, 800 - 128, 600 - 128, love.timer.getTime(), 1, 1, exf.bigball:getWidth() * 0.5, exf.bigball:getHeight() * 0.5)
function exf.drawForground()
love.graphics.setColor(255, 255, 255)
love.graphics.draw(exf.bigball, 800 - 128, 600 - 128, love.timer.getTime(), 1, 1, exf.bigball:getWidth() * 0.5, exf.bigball:getHeight() * 0.5)
end
function exf.keypressed(k)
@ -179,7 +182,10 @@ function exf.resume()
love.window.setTitle("LOVE Example Browser")
-- create light world
lightWorld = LightWorld()
lightWorld = LightWorld({
drawBackground = exf.drawBackground,
drawForground = exf.drawForground
})
lightWorld:setAmbientColor(127, 127, 127)
-- create light
@ -187,7 +193,7 @@ function exf.resume()
lightMouse:setSmooth(2)
-- create shadow bodys
circleTest = lightWorld:newCircle(800 - 128, 600 - 128, 46)
circleTest = lightWorld:newCircle(800 - 128, 600 - 128, exf.bigball:getWidth()*0.5)
end
function inside(mx, my, x, y, w, h)