light world no longer has any more globals

This commit is contained in:
Tim Anema 2014-09-27 13:46:46 -04:00
parent 8115657d11
commit 9dd4e53119
5 changed files with 173 additions and 227 deletions

View File

@ -175,20 +175,21 @@ function love.update(dt)
if offsetX ~= offsetOldX or offsetY ~= offsetOldY then
offsetChanged = true
for i = 2, lightWorld:getLightCount() do
lightWorld:setLightPosition(i, lightWorld:getLightX(i) + (offsetX - offsetOldX), lightWorld:getLightY(i) + (offsetY - offsetOldY))
local light = lightWorld:getLight(i)
light:setPosition(light:getX() + (offsetX - offsetOldX), light:getY() + (offsetY - offsetOldY))
end
else
offsetChanged = false
end
for i = 1, lightWorld:getLightCount() do
lightWorld:setLightDirection(i, lightDirection)
end
for i = 1, lightWorld:getLightCount() do
lightWorld:getLight(i):setDirection(lightDirection)
end
tileX = tileX + dt * 32.0
tileY = tileY + dt * 8.0
for i = 1, phyCnt do
for i = 1, phyCnt do
if phyBody[i] and (phyBody[i]:isAwake() or offsetChanged) then
if offsetChanged then
phyBody[i]:setX(phyBody[i]:getX() + (offsetX - offsetOldX))
@ -209,7 +210,7 @@ function love.update(dt)
phyLight[i]:setNormalTileOffset(tileX, tileY)
--end
if offsetChanged then
phyLight[i]:setPosition(phyLight[i].getX() + (offsetX - offsetOldX), phyLight[i].getY() + (offsetY - offsetOldY))
phyLight[i]:setPosition(phyLight[i]:getX() + (offsetX - offsetOldX), phyLight[i]:getY() + (offsetY - offsetOldY))
end
end
end
@ -703,10 +704,10 @@ function love.keypressed(k, u)
else
light = lightWorld:newLight(mx, my, 31, 63, 127, lightRange)
end
light.setSmooth(lightSmooth)
light.setGlowStrength(0.3)
light:setSmooth(lightSmooth)
light:setGlowStrength(0.3)
math.randomseed(love.timer.getTime())
light.setAngle(math.random(1, 5) * 0.1 * math.pi)
light:setAngle(math.random(1, 5) * 0.1 * math.pi)
elseif k == "c" then
if colorAberration == 0.0 then
colorAberration = 3.0

View File

@ -1,5 +1,6 @@
local _PACKAGE = (...):match("^(.+)[%./][^%./]+") or ""
local class = require(_PACKAGE.."/class")
local height_map_conv = require(_PACKAGE..'/height_map_conv')
local body = class()
@ -11,6 +12,24 @@ function body:init(world, id, type, ...)
self.material = nil
self.glow = nil
self.world = world
self.reflection = false
self.reflective = false
self.refraction = false
self.refractive = false
self.shine = true
self.red = 0
self.green = 0
self.blue = 0
self.alpha = 1.0
self.glowRed = 255
self.glowGreen = 255
self.glowBlue = 255
self.glowStrength = 0.0
self.tileX = 0
self.tileY = 0
if self.type == "circle" then
self.x = args[1] or 0
self.y = args[2] or 0
@ -18,10 +37,6 @@ function body:init(world, id, type, ...)
self.ox = args[4] or 0
self.oy = args[5] or 0
self.shadowType = "circle"
self.reflection = false
self.reflective = false
self.refraction = false
self.refractive = false
world.isShadows = true
elseif self.type == "rectangle" then
self.x = args[1] or 0
@ -41,18 +56,10 @@ function body:init(world, id, type, ...)
self.x - self.ox,
self.y - self.oy + self.height
}
self.reflection = false
self.reflective = false
self.refraction = false
self.refractive = false
world.isShadows = true
elseif self.type == "polygon" then
self.shadowType = "polygon"
self.data = args or {0, 0, 0, 0, 0, 0}
self.reflection = false
self.reflective = false
self.refraction = false
self.refractive = false
world.isShadows = true
elseif self.type == "image" then
self.img = args[1]
@ -89,10 +96,7 @@ function body:init(world, id, type, ...)
self.x - self.ox,
self.y - self.oy + self.height
}
self.reflection = false
self.reflective = true
self.refraction = false
self.refractive = false
world.isShadows = true
elseif self.type == "refraction" then
self.normal = args[1]
@ -119,10 +123,7 @@ function body:init(world, id, type, ...)
end
self.ox = self.width * 0.5
self.oy = self.height * 0.5
self.reflection = false
self.reflective = false
self.refraction = true
self.refractive = false
world.isRefraction = true
elseif self.type == "reflection" then
self.normal = args[1]
@ -150,22 +151,8 @@ function body:init(world, id, type, ...)
self.ox = self.width * 0.5
self.oy = self.height * 0.5
self.reflection = true
self.reflective = false
self.refraction = false
self.refractive = false
world.isReflection = true
end
self.shine = true
self.red = 0
self.green = 0
self.blue = 0
self.alpha = 1.0
self.glowRed = 255
self.glowGreen = 255
self.glowBlue = 255
self.glowStrength = 0.0
self.tileX = 0
self.tileY = 0
end
-- refresh
@ -370,7 +357,7 @@ function body:setNormalMap(normal, width, height, nx, ny)
end
-- set height map
function body:setHeightMap(heightMap, strength)
self:setNormalMap(HeightMapToNormalMap(heightMap, strength))
self:setNormalMap(height_map_conv.toNormalMap(heightMap, strength))
end
-- generate flat normal map
function body:generateNormalMapFlat(mode)
@ -443,14 +430,16 @@ function body:generateNormalMapGradient(horizontalGradient, verticalGradient)
end
-- generate normal map
function body:generateNormalMap(strength)
self:setNormalMap(HeightMapToNormalMap(self.img, strength))
self:setNormalMap(height_map_conv.toNormalMap(self.img, strength))
end
-- set material
function body:setMaterial(material)
if material then
self.material = material
end
end
-- set normal
function body:setGlowMap(glow)
self.glow = glow
@ -458,6 +447,7 @@ function body:setGlowMap(glow)
self.world.isGlow = true
end
-- set tile offset
function body:setNormalTileOffset(tx, ty)
self.tileX = tx / self.normalWidth
@ -470,10 +460,12 @@ function body:setNormalTileOffset(tx, ty)
}
self.world.changed = true
end
-- get type
function body:getType()
return self.type
end
-- get type
function body:setShadowType(type, ...)
self.shadowType = type
@ -553,7 +545,6 @@ function body:drawShadow(light)
end
end
function body:drawPixelShadow()
if self.type == "image" and self.normalMesh then
love.graphics.setColor(255, 255, 255)
@ -561,7 +552,6 @@ function body:drawPixelShadow()
end
end
function body:drawGlow()
if self.glowStrength > 0.0 then
love.graphics.setColor(self.glowRed * self.glowStrength, self.glowGreen * self.glowStrength, self.glowBlue * self.glowStrength)

50
lib/height_map_conv.lua Normal file
View File

@ -0,0 +1,50 @@
height_map = {}
function height_map.toNormalMap(heightMap, strength)
local imgData = heightMap:getData()
local imgData2 = love.image.newImageData(heightMap:getWidth(), heightMap:getHeight())
local red, green, blue, alpha
local x, y
local matrix = {}
matrix[1] = {}
matrix[2] = {}
matrix[3] = {}
strength = strength or 1.0
for i = 0, heightMap:getHeight() - 1 do
for k = 0, heightMap:getWidth() - 1 do
for l = 1, 3 do
for m = 1, 3 do
if k + (l - 1) < 1 then
x = heightMap:getWidth() - 1
elseif k + (l - 1) > heightMap:getWidth() - 1 then
x = 1
else
x = k + l - 1
end
if i + (m - 1) < 1 then
y = heightMap:getHeight() - 1
elseif i + (m - 1) > heightMap:getHeight() - 1 then
y = 1
else
y = i + m - 1
end
local red, green, blue, alpha = imgData:getPixel(x, y)
matrix[l][m] = red
end
end
red = (255 + ((matrix[1][2] - matrix[2][2]) + (matrix[2][2] - matrix[3][2])) * strength) / 2.0
green = (255 + ((matrix[2][2] - matrix[1][1]) + (matrix[2][3] - matrix[2][2])) * strength) / 2.0
blue = 192
imgData2:setPixel(k, i, red, green, blue)
end
end
return love.graphics.newImage(imgData2)
end
return height_map

View File

@ -22,7 +22,6 @@ function light:init(world, x, y, r, g, b, range)
self.smooth = 1.0
self.glowSize = 0.1
self.glowStrength = 0.0
self.changed = true
self.visible = true
end
@ -34,7 +33,6 @@ function light:setPosition(x, y, z)
if z then
self.z = z
end
self.changed = true
end
end
@ -52,7 +50,6 @@ end
function light:setX(x)
if x ~= self.x then
self.x = x
self.changed = true
end
end
@ -60,7 +57,6 @@ end
function light:setY(y)
if y ~= self.y then
self.y = y
self.changed = true
end
end
-- set color
@ -74,7 +70,6 @@ end
function light:setRange(range)
if range ~= self.range then
self.range = range
self.changed = true
end
end
@ -88,9 +83,9 @@ function light:setDirection(direction)
else
self.direction = direction
end
self.changed = true
end
end
-- set angle
function light:setAngle(angle)
if angle ~= self.angle then
@ -101,91 +96,82 @@ function light:setAngle(angle)
else
self.angle = angle
end
self.changed = true
end
end
-- set glow size
function light:setSmooth(smooth)
self.smooth = smooth
self.changed = true
end
-- set glow size
function light:setGlowSize(size)
self.glowSize = size
self.changed = true
end
-- set glow strength
function light:setGlowStrength(strength)
self.glowStrength = strength
self.changed = true
end
-- get type
function light:getType()
return "light"
end
function light:updateShadow()
if self.changed or self.changed then
if self.x + self.range > self.world.translate_x and self.x - self.range < love.graphics.getWidth() + self.world.translate_x
and self.y + self.range > self.world.translate_y and self.y - self.range < love.graphics.getHeight() + self.world.translate_y
then
local lightposrange = {self.x, love.graphics.getHeight() - self.y, self.range}
local light = self
self.world.direction = self.world.direction + 0.002
self.world.shader:send("lightPosition", {self.x - self.world.translate_x, love.graphics.getHeight() - (self.y - self.world.translate_y), self.z})
self.world.shader:send("lightRange", self.range)
self.world.shader:send("lightColor", {self.red / 255.0, self.green / 255.0, self.blue / 255.0})
self.world.shader:send("lightSmooth", self.smooth)
self.world.shader:send("lightGlow", {1.0 - self.glowSize, self.glowStrength})
self.world.shader:send("lightAngle", math.pi - self.angle / 2.0)
self.world.shader:send("lightDirection", self.direction)
if self.x + self.range > self.world.translate_x and self.x - self.range < love.graphics.getWidth() + self.world.translate_x
and self.y + self.range > self.world.translate_y and self.y - self.range < love.graphics.getHeight() + self.world.translate_y
then
local lightposrange = {self.x, love.graphics.getHeight() - self.y, self.range}
local light = self
self.world.direction = self.world.direction + 0.002
self.world.shader:send("lightPosition", {self.x - self.world.translate_x, love.graphics.getHeight() - (self.y - self.world.translate_y), self.z})
self.world.shader:send("lightRange", self.range)
self.world.shader:send("lightColor", {self.red / 255.0, self.green / 255.0, self.blue / 255.0})
self.world.shader:send("lightSmooth", self.smooth)
self.world.shader:send("lightGlow", {1.0 - self.glowSize, self.glowStrength})
self.world.shader:send("lightAngle", math.pi - self.angle / 2.0)
self.world.shader:send("lightDirection", self.direction)
love.graphics.setCanvas(self.shadow)
love.graphics.clear()
love.graphics.setCanvas(self.shadow)
love.graphics.clear()
-- calculate shadows
local shadow_geometry = calculateShadows(light, self.world.body)
-- calculate shadows
local shadow_geometry = self.calculateShadows(light, self.world.body)
-- draw shadow
love.graphics.setInvertedStencil(stencils.shadow(shadow_geometry, self.world.body))
love.graphics.setBlendMode("additive")
-- FIND THIS TOOOO
love.graphics.rectangle("fill", self.world.translate_x, self.world.translate_y, love.graphics.getWidth(), love.graphics.getHeight())
-- draw shadow
love.graphics.setInvertedStencil(stencils.shadow(shadow_geometry, self.world.body))
love.graphics.setBlendMode("additive")
-- FIND THIS TOOOO
love.graphics.rectangle("fill", self.world.translate_x, self.world.translate_y, love.graphics.getWidth(), love.graphics.getHeight())
-- draw color shadows
love.graphics.setBlendMode("multiplicative")
love.graphics.setShader()
for k = 1,#shadow_geometry do
if shadow_geometry[k].alpha < 1.0 then
love.graphics.setColor(
shadow_geometry[k].red * (1.0 - shadow_geometry[k].alpha),
shadow_geometry[k].green * (1.0 - shadow_geometry[k].alpha),
shadow_geometry[k].blue * (1.0 - shadow_geometry[k].alpha)
)
love.graphics.polygon("fill", unpack(shadow_geometry[k]))
end
-- draw color shadows
love.graphics.setBlendMode("multiplicative")
love.graphics.setShader()
for k = 1,#shadow_geometry do
if shadow_geometry[k].alpha < 1.0 then
love.graphics.setColor(
shadow_geometry[k].red * (1.0 - shadow_geometry[k].alpha),
shadow_geometry[k].green * (1.0 - shadow_geometry[k].alpha),
shadow_geometry[k].blue * (1.0 - shadow_geometry[k].alpha)
)
love.graphics.polygon("fill", unpack(shadow_geometry[k]))
end
for k = 1, #self.world.body do
self.world.body[k]:drawShadow(self)
end
love.graphics.setShader(self.world.shader)
-- draw shine
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.rectangle("fill", self.world.translate_x, self.world.translate_y, love.graphics.getWidth(), love.graphics.getHeight())
self.visible = true
else
self.visible = false
end
self.changed = self.world.changed
for k = 1, #self.world.body do
self.world.body[k]:drawShadow(self)
end
love.graphics.setShader(self.world.shader)
-- draw shine
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.rectangle("fill", self.world.translate_x, self.world.translate_y, love.graphics.getWidth(), love.graphics.getHeight())
self.visible = true
else
self.visible = false
end
end
@ -201,7 +187,7 @@ function light:drawShine()
end
end
function calculateShadows(light, body)
function light.calculateShadows(light, body)
local shadowGeometry = {}
local shadowLength = 100000

View File

@ -25,14 +25,13 @@ local _PACKAGE = (...):match("^(.+)[%./][^%./]+") or ""
local class = require(_PACKAGE..'/class')
local Light = require(_PACKAGE..'/light')
local Body = require(_PACKAGE..'/body')
local height_map_conv = require(_PACKAGE..'/height_map_conv')
local light_world = class()
function light_world:init()
self.translate_x = 0
self.translate_y = 0
self.translate_x_old = 0
self.translate_y_old = 0
self.direction = 0
self.last_buffer = nil
@ -78,7 +77,6 @@ function light_world:init()
self.reflectionStrength = 16.0
self.reflectionVisibility = 1.0
self.changed = true
self.blur = 2.0
self.optionShadows = true
self.optionPixelShadows = true
@ -96,13 +94,6 @@ end
-- update
function light_world:update()
self.last_buffer = love.graphics.getCanvas()
if self.translate_x ~= self.translate_x_old or self.translate_y ~= self.translate_y_old then
self.translate_x_old = self.translate_x
self.translate_y_old = self.translate_y
self.changed = true
end
love.graphics.setColor(255, 255, 255)
love.graphics.setBlendMode("alpha")
self:updateShadows()
@ -114,7 +105,6 @@ function light_world:update()
love.graphics.setBlendMode("alpha")
love.graphics.setStencil()
love.graphics.setCanvas(self.last_buffer)
self.changed = false
end
function light_world:updateShadows()
@ -137,10 +127,10 @@ function light_world:updateShadows()
love.graphics.rectangle("fill", self.translate_x, self.translate_y, love.graphics.getWidth(), love.graphics.getHeight())
love.graphics.setColor(255, 255, 255)
love.graphics.setBlendMode("additive")
for i = 1, #self.lights do
self.lights[i]:drawShadow()
end
self.isShadowBlur = false
-- update shine
love.graphics.setCanvas(self.shine)
@ -149,6 +139,7 @@ function light_world:updateShadows()
love.graphics.rectangle("fill", self.translate_x, self.translate_y, love.graphics.getWidth(), love.graphics.getHeight())
love.graphics.setColor(255, 255, 255)
love.graphics.setBlendMode("additive")
for i = 1, #self.lights do
self.lights[i]:drawShine()
end
@ -234,12 +225,10 @@ function light_world:updateRelfection()
return
end
-- create reflection map
if self.changed then
self.reflectionMap:clear(0, 0, 0)
love.graphics.setCanvas(self.reflectionMap)
for i = 1, #self.body do
self.body[i]:drawReflection()
end
self.reflectionMap:clear(0, 0, 0)
love.graphics.setCanvas(self.reflectionMap)
for i = 1, #self.body do
self.body[i]:drawReflection()
end
end
@ -424,13 +413,11 @@ end
function light_world:clearLights()
self.lights = {}
self.isLight = false
self.changed = true
end
-- clear objects
function light_world:clearBodys()
self.body = {}
self.changed = true
self.isShadows = false
self.isPixelShadows = false
self.isGlow = false
@ -472,13 +459,11 @@ end
-- set blur
function light_world:setBlur(blur)
self.blur = blur
self.changed = true
end
-- set blur
function light_world:setShadowBlur(blur)
self.blur = blur
self.changed = true
end
-- set buffer
@ -493,160 +478,94 @@ function light_world:setBuffer(buffer)
love.graphics.setCanvas(self.glowMap)
end
end
-- set glow blur
function light_world:setGlowStrength(strength)
self.glowBlur = strength
self.changed = true
end
-- set refraction blur
function light_world:setRefractionStrength(strength)
self.refractionStrength = strength
end
-- set reflection strength
function light_world:setReflectionStrength(strength)
self.reflectionStrength = strength
end
-- set reflection visibility
function light_world:setReflectionVisibility(visibility)
self.reflectionVisibility = visibility
end
-- new rectangle
function light_world:newRectangle(x, y, w, h)
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)
end
-- new polygon
function light_world:newPolygon(...)
return self:newBody("polygon", ...)
end
-- new image
function light_world:newImage(img, x, y, width, height, ox, oy)
return self:newBody("image", img, x, y, width, height, ox, oy)
end
-- new refraction
function light_world:newRefraction(normal, x, y, width, height)
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 = HeightMapToNormalMap(heightMap, strength)
local normal = height_map_conv.toNormalMap(heightMap, strength)
return self.newRefraction(p, normal, x, y)
end
-- new reflection
function light_world:newReflection(normal, x, y, width, height)
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 = HeightMapToNormalMap(heightMap, strength)
local normal = height_map_conv.toNormalMap(heightMap, strength)
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.changed = true
return self.body[#self.body]
end
-- set polygon data
function light_world:setPoints(n, ...)
self.body[n].data = {...}
end
-- get polygon count
-- get body count
function light_world:getBodyCount()
return #self.body
end
-- get polygon
function light_world:getPoints(n)
if self.body[n].data then
return unpack(self.body[n].data)
end
end
-- set light position
function light_world:setLightPosition(n, x, y, z)
self.lights[n]:setPosition(x, y, z)
end
-- set light x
function light_world:setLightX(n, x)
self.lights[n]:setX(x)
end
-- set light y
function light_world:setLightY(n, y)
self.lights[n]:setY(y)
end
-- set light angle
function light_world:setLightAngle(n, angle)
self.lights[n]:setAngle(angle)
end
-- set light direction
function light_world:setLightDirection(n, direction)
self.lights[n]:setDirection(direction)
-- get light
function light_world:getBody(n)
return self.body[n]
end
-- get light count
function light_world:getLightCount()
return #self.lights
end
-- get light x position
function light_world:getLightX(n)
return self.lights[n].x
end
-- get light y position
function light_world:getLightY(n)
return self.lights[n].y
end
-- get type
function light_world:getType()
return "world"
end
function HeightMapToNormalMap(heightMap, strength)
local imgData = heightMap:getData()
local imgData2 = love.image.newImageData(heightMap:getWidth(), heightMap:getHeight())
local red, green, blue, alpha
local x, y
local matrix = {}
matrix[1] = {}
matrix[2] = {}
matrix[3] = {}
strength = strength or 1.0
for i = 0, heightMap:getHeight() - 1 do
for k = 0, heightMap:getWidth() - 1 do
for l = 1, 3 do
for m = 1, 3 do
if k + (l - 1) < 1 then
x = heightMap:getWidth() - 1
elseif k + (l - 1) > heightMap:getWidth() - 1 then
x = 1
else
x = k + l - 1
end
if i + (m - 1) < 1 then
y = heightMap:getHeight() - 1
elseif i + (m - 1) > heightMap:getHeight() - 1 then
y = 1
else
y = i + m - 1
end
local red, green, blue, alpha = imgData:getPixel(x, y)
matrix[l][m] = red
end
end
red = (255 + ((matrix[1][2] - matrix[2][2]) + (matrix[2][2] - matrix[3][2])) * strength) / 2.0
green = (255 + ((matrix[2][2] - matrix[1][1]) + (matrix[2][3] - matrix[2][2])) * strength) / 2.0
blue = 192
imgData2:setPixel(k, i, red, green, blue)
end
end
return love.graphics.newImage(imgData2)
-- get light
function light_world:getLight(n)
return self.lights[n]
end
return light_world