added in checking to see if the shadow bodies should be drawn, if they are within the screen and within range of the light

This commit is contained in:
Tim Anema 2014-12-03 14:08:44 -05:00
parent 64bcbd1e94
commit d02bc54b05
5 changed files with 68 additions and 30 deletions

View File

@ -1,5 +1,6 @@
:todoing :todoing
-make sure all draw calls check if the object is within range -make sure all draw calls check if the object is within range
-add body animations
-optimize shadow body calculations and drawing methods -optimize shadow body calculations and drawing methods
# light_world.lua # light_world.lua

View File

@ -165,7 +165,6 @@ function love.draw()
end) end)
love.graphics.pop() love.graphics.pop()
love.graphics.setBlendMode("alpha") love.graphics.setBlendMode("alpha")
love.graphics.setColor(0, 0, 0, 191) love.graphics.setColor(0, 0, 0, 191)
love.graphics.rectangle("fill", 0, 0, love.graphics.getWidth(), 24) love.graphics.rectangle("fill", 0, 0, love.graphics.getWidth(), 24)

View File

@ -24,6 +24,9 @@ function body:init(id, type, ...)
self.tileX = 0 self.tileX = 0
self.tileY = 0 self.tileY = 0
self.zheight = 1 self.zheight = 1
self.castsNoShadow = false
self.visible = true
if self.type == "circle" then if self.type == "circle" then
self.x = args[1] or 0 self.x = args[1] or 0
@ -218,6 +221,10 @@ function body:setGlowStrength(strength)
self.glowStrength = strength self.glowStrength = strength
end end
function body:setVisible(visible)
self.visible = visible
end
-- get radius -- get radius
function body:getRadius() function body:getRadius()
return self.radius return self.radius
@ -434,6 +441,27 @@ function body:setShadowType(type, ...)
end end
end end
function body:isInLightRange(light, l, t, w, h, s)
local distance
if self.type == 'circle' then
return light.range > math.sqrt(math.pow(light.x - self.x, 2) + math.pow(light.y - self.y, 2))
else
local cx, cy = self.x + (self.width * 0.5), self.y + (self.height * 0.5)
distance = math.sqrt(math.pow(light.x - cx, 2) + math.pow(light.y - cy, 2))
return distance <= light.range + (self.width > self.height and self.width or self.height)
end
end
function body:isInRange(l, t, w, h, s)
local bx, by, bw, bh
if self.type == 'circle' then
bx, by, bw, bh = (self.x + l/s) * s, (self.y + t/s) * s, self.radius/s, self.radius/s
else
bx, by, bw, bh = (self.x + l/s) * s, (self.y + t/s) * s, self.width/s, self.height/s
end
return self.visible and (bx + bw) > 0 and (bx - bw) < w/s and (by + bh) > 0 and (by - bh) < h/s
end
function body:drawNormal() function body:drawNormal()
if not self.refraction and not self.reflection and self.normalMesh then if not self.refraction and not self.reflection and self.normalMesh then
love.graphics.setColor(255, 255, 255) love.graphics.setColor(255, 255, 255)

View File

@ -103,21 +103,27 @@ function light_world:drawNormalShading(l,t,w,h,s)
self.normalMap:clear() self.normalMap:clear()
util.drawto(self.normalMap, l, t, s, function() util.drawto(self.normalMap, l, t, s, function()
for i = 1, #self.body do for i = 1, #self.body do
self.body[i]:drawNormal() if self.body[i]:isInRange(l,t,w,h,s) then
self.body[i]:drawNormal()
end
end end
end) end)
self.normal2:clear() self.normal2:clear()
for i = 1, #self.lights do for i = 1, #self.lights do
-- create shadow map for this light if self.lights[i]:inRange(l,t,w,h,s) then
self.shadowMap:clear() -- create shadow map for this light
util.drawto(self.shadowMap, l, t, s, function() self.shadowMap:clear()
for k = 1, #self.body do util.drawto(self.shadowMap, l, t, s, function()
self.body[k]:drawShadow(self.lights[i]) for k = 1, #self.body do
end if self.body[k]:isInLightRange(self.lights[i]) and self.body[k]:isInRange(l,t,w,h,s) then
end) self.body[k]:drawShadow(self.lights[i])
-- draw scene for this light using normals and shadowmap end
self.lights[i]:drawNormalShading(l,t,w,h,s, self.normalMap, self.shadowMap, self.normal2) end
end)
-- draw scene for this light using normals and shadowmap
self.lights[i]:drawNormalShading(l,t,w,h,s, self.normalMap, self.shadowMap, self.normal2)
end
end end
-- add in ambient color -- add in ambient color
@ -135,7 +141,9 @@ end
-- draw material -- draw material
function light_world:drawMaterial(l,t,w,h,s) function light_world:drawMaterial(l,t,w,h,s)
for i = 1, #self.body do for i = 1, #self.body do
self.body[i]:drawMaterial() if self.body[i]:isInRange(l,t,w,h,s) then
self.body[i]:drawMaterial()
end
end end
end end
@ -155,7 +163,9 @@ function light_world:drawGlow(l,t,w,h,s)
self.glowMap:clear(0, 0, 0) self.glowMap:clear(0, 0, 0)
util.drawto(self.glowMap, l, t, s, function() util.drawto(self.glowMap, l, t, s, function()
for i = 1, #self.body do for i = 1, #self.body do
self.body[i]:drawGlow() if self.body[i]:isInRange(l,t,w,h,s) then
self.body[i]:drawGlow()
end
end end
end) end)
@ -188,7 +198,9 @@ function light_world:drawReflection(l,t,w,h,s)
self.reflectionMap:clear(0, 0, 0) self.reflectionMap:clear(0, 0, 0)
util.drawto(self.reflectionMap, l, t, s, function() util.drawto(self.reflectionMap, l, t, s, function()
for i = 1, #self.body do for i = 1, #self.body do
self.body[i]:drawReflection() if self.body[i]:isInRange(l,t,w,h,s) then
self.body[i]:drawReflection()
end
end end
end) end)

View File

@ -114,25 +114,23 @@ end
function light:inRange(l,t,w,h,s) function light:inRange(l,t,w,h,s)
local lx, ly, rs = (self.x + l/s) * s, (self.y + t/s) * s, self.range * s local lx, ly, rs = (self.x + l/s) * s, (self.y + t/s) * s, self.range * s
return (lx + rs) > 0 and (lx - rs) < w/s and (ly + rs) > 0 and (ly - rs) < h/s return self.visible and (lx + rs) > 0 and (lx - rs) < w/s and (ly + rs) > 0 and (ly - rs) < h/s
end end
function light:drawNormalShading(l,t,w,h,s, normalMap, shadowMap, canvas) function light:drawNormalShading(l,t,w,h,s, normalMap, shadowMap, canvas)
if self.visible and self:inRange(l,t,w,h,s) then self.shadowShader:send('shadowMap', shadowMap)
self.shadowShader:send('shadowMap', shadowMap) self.shadowShader:send('lightColor', {self.red / 255.0, self.green / 255.0, self.blue / 255.0})
self.shadowShader:send('lightColor', {self.red / 255.0, self.green / 255.0, self.blue / 255.0}) self.shadowShader:send("lightPosition", {(self.x + l/s) * s, (h/s - (self.y + t/s)) * s, (self.z * 10) / 255.0})
self.shadowShader:send("lightPosition", {(self.x + l/s) * s, (h/s - (self.y + t/s)) * s, (self.z * 10) / 255.0}) self.shadowShader:send('lightRange',{self.range * s})
self.shadowShader:send('lightRange',{self.range * s}) self.shadowShader:send("lightSmooth", self.smooth)
self.shadowShader:send("lightSmooth", self.smooth) self.shadowShader:send("lightGlow", {1.0 - self.glowSize, self.glowStrength})
self.shadowShader:send("lightGlow", {1.0 - self.glowSize, self.glowStrength}) self.shadowShader:send("lightAngle", math.pi - self.angle / 2.0)
self.shadowShader:send("lightAngle", math.pi - self.angle / 2.0) self.shadowShader:send("lightDirection", self.direction)
self.shadowShader:send("lightDirection", self.direction) self.shadowShader:send("invert_normal", self.normalInvert == true)
self.shadowShader:send("invert_normal", self.normalInvert == true) util.drawCanvasToCanvas(normalMap, canvas, {
util.drawCanvasToCanvas(normalMap, canvas, { blendmode = 'additive',
blendmode = 'additive', shader = self.shadowShader
shader = self.shadowShader })
})
end
end end
function light:setVisible(visible) function light:setVisible(visible)