making it work better with a camera, now working on scaling, finally after a week or working to get here

This commit is contained in:
Tim Anema 2014-09-30 18:19:37 -04:00
parent 45be0c56fa
commit 8aacf0f69c
5 changed files with 369 additions and 137 deletions

View File

@ -1,8 +1,12 @@
-- Example: Short Example -- Example: Short Example
require "lib/postshader" require "lib/postshader"
local gamera = require "vendor/gamera"
local LightWorld = require "lib/light_world" local LightWorld = require "lib/light_world"
function love.load() function love.load()
scale = 1
camera = gamera.new(0,0,2000,2000)
-- load images -- load images
image = love.graphics.newImage("gfx/machine2.png") image = love.graphics.newImage("gfx/machine2.png")
image_normal = love.graphics.newImage("gfx/cone_normal.png") image_normal = love.graphics.newImage("gfx/cone_normal.png")
@ -43,43 +47,47 @@ end
function love.update(dt) function love.update(dt)
love.window.setTitle("Light vs. Shadow Engine (FPS:" .. love.timer.getFPS() .. ")") love.window.setTitle("Light vs. Shadow Engine (FPS:" .. love.timer.getFPS() .. ")")
lightMouse:setPosition(love.mouse.getX(), love.mouse.getY())
local x, y = camera:getPosition()
if love.keyboard.isDown("up") then
y = y - dt * 200
elseif love.keyboard.isDown("down") then
y = y + dt * 200
end
if love.keyboard.isDown("left") then
x = x - dt * 200
elseif love.keyboard.isDown("right") then
x = x + dt * 200
end
if love.keyboard.isDown("-") then
scale = scale - 0.01
elseif love.keyboard.isDown("=") then
scale = scale + 0.01
end
camera:setPosition(x, y)
camera:setScale(scale)
lightMouse:setPosition(camera:toWorld(love.mouse.getX(), love.mouse.getY()))
end end
function love.draw() function love.draw()
love.postshader.setBuffer("render") --camera:setScale(scale)
camera:draw(function(l,t,w,h)
-- draw background
love.graphics.setColor(255, 255, 255) love.graphics.setColor(255, 255, 255)
love.graphics.rectangle("fill", 0, 0, love.graphics.getWidth(), love.graphics.getHeight()) love.graphics.rectangle("fill", 0, 0, 2000, 2000)
--love.graphics.draw(imgFloor, quadScreen, 0, 0) lightWorld:drawShadow(l,t,w,h)
-- draw lightmap shadows
lightWorld:drawShadow()
-- draw scene objects
love.graphics.setColor(63, 255, 127) love.graphics.setColor(63, 255, 127)
love.graphics.circle("fill", circleTest:getX(), circleTest:getY(), circleTest:getRadius()) love.graphics.circle("fill", circleTest:getX(), circleTest:getY(), circleTest:getRadius())
love.graphics.polygon("fill", rectangleTest:getPoints()) love.graphics.polygon("fill", rectangleTest:getPoints())
love.graphics.setColor(255, 255, 255) love.graphics.setColor(255, 255, 255)
love.graphics.draw(image, 64 - image:getWidth() * 0.5, 64 - image:getHeight() * 0.5) love.graphics.draw(image, 64 - image:getWidth() * 0.5, 64 - image:getHeight() * 0.5)
--love.graphics.rectangle("fill", 128 - 32, 128 - 32, 64, 64) lightWorld:drawShine(l,t,w,h)
lightWorld:drawPixelShadow(l,t,w,h)
-- draw lightmap shine lightWorld:drawGlow(l,t,w,h)
lightWorld:drawShine() lightWorld:drawRefraction(l,t,w,h)
lightWorld:drawReflection(l,t,w,h)
-- draw pixel shadow end)
lightWorld:drawPixelShadow()
-- draw glow
lightWorld:drawGlow()
-- draw refraction
lightWorld:drawRefraction()
-- draw reflection
lightWorld:drawReflection()
love.postshader.draw()
end end

View File

@ -546,7 +546,7 @@ function body:setShadowType(type, ...)
end end
end end
function body:drawShadow(light) function body:drawShadow(light, l,t,w,h)
if self.alpha < 1.0 then if self.alpha < 1.0 then
love.graphics.setBlendMode("multiplicative") love.graphics.setBlendMode("multiplicative")
love.graphics.setColor(self.red, self.green, self.blue) love.graphics.setColor(self.red, self.green, self.blue)
@ -572,24 +572,25 @@ function body:drawShadow(light)
} }
self.shadowMesh:setVertices(self.shadowVert) self.shadowMesh:setVertices(self.shadowVert)
love.graphics.draw(self.shadowMesh, self.x - self.ox + self.world.translate_x, self.y - self.oy + self.world.translate_y) love.graphics.draw(self.shadowMesh, self.x - self.ox + l, self.y - self.oy + t)
end end
end end
function body:drawPixelShadow() function body:drawPixelShadow(l,t,w,h)
if self.type == "image" and self.normalMesh then if self.type == "image" and self.normalMesh then
love.graphics.setColor(255, 255, 255) love.graphics.setColor(255, 255, 255)
love.graphics.draw(self.normalMesh, self.x - self.nx + self.world.translate_x, self.y - self.ny + self.world.translate_y) love.graphics.draw(self.normalMesh, self.x - self.nx, self.y - self.ny)
end end
end end
function body:drawGlow() function body:drawGlow(l,t,w,h)
if self.glowStrength > 0.0 then if self.glowStrength > 0.0 then
love.graphics.setColor(self.glowRed * self.glowStrength, self.glowGreen * self.glowStrength, self.glowBlue * self.glowStrength) love.graphics.setColor(self.glowRed * self.glowStrength, self.glowGreen * self.glowStrength, self.glowBlue * self.glowStrength)
else else
love.graphics.setColor(0, 0, 0) love.graphics.setColor(0, 0, 0)
end end
--glow has no translation compensation?!
if self.type == "circle" then if self.type == "circle" then
love.graphics.circle("fill", self.x, self.y, self.radius) love.graphics.circle("fill", self.x, self.y, self.radius)
elseif self.type == "rectangle" then elseif self.type == "rectangle" then
@ -606,25 +607,26 @@ function body:drawGlow()
love.graphics.setShader() love.graphics.setShader()
love.graphics.setColor(0, 0, 0) love.graphics.setColor(0, 0, 0)
end end
love.graphics.draw(self.img, self.x - self.ix + self.world.translate_x, self.y - self.iy + self.world.translate_y) love.graphics.draw(self.img, self.x - self.ix, self.y - self.iy)
end end
love.graphics.setShader() love.graphics.setShader()
end end
function body:drawRefraction() function body:drawRefraction(l,t,w,h)
if self.refraction and self.normal then if self.refraction and self.normal then
love.graphics.setColor(255, 255, 255) love.graphics.setColor(255, 255, 255)
if self.tileX == 0.0 and self.tileY == 0.0 then if self.tileX == 0.0 and self.tileY == 0.0 then
love.graphics.draw(normal, self.x - self.nx + self.world.translate_x, self.y - self.ny + self.world.translate_y) love.graphics.draw(normal, self.x - self.nx + l, self.y - self.ny + t)
else else
self.normalMesh:setVertices(self.normalVert) self.normalMesh:setVertices(self.normalVert)
love.graphics.draw(self.normalMesh, self.x - self.nx + self.world.translate_x, self.y - self.ny + self.world.translate_y) love.graphics.draw(self.normalMesh, self.x - self.nx + l, self.y - self.ny + t)
end end
end end
love.graphics.setColor(0, 0, 0) love.graphics.setColor(0, 0, 0)
-- no translation compensation again?
if not self.refractive then if not self.refractive then
if self.type == "circle" then if self.type == "circle" then
love.graphics.circle("fill", self.x, self.y, self.radius) love.graphics.circle("fill", self.x, self.y, self.radius)
@ -633,32 +635,32 @@ function body:drawRefraction()
elseif self.type == "polygon" then elseif self.type == "polygon" then
love.graphics.polygon("fill", unpack(self.data)) love.graphics.polygon("fill", unpack(self.data))
elseif self.type == "image" and self.img then elseif self.type == "image" and self.img then
love.graphics.draw(self.img, self.x - self.ix + self.world.translate_x, self.y - self.iy + self.world.translate_y) love.graphics.draw(self.img, self.x - self.ix + l, self.y - self.iy + t)
end end
end end
end end
function body:drawReflection() function body:drawReflection(l,t,w,h)
if self.reflection and self.normal then if self.reflection and self.normal then
love.graphics.setColor(255, 0, 0) love.graphics.setColor(255, 0, 0)
self.normalMesh:setVertices(self.normalVert) self.normalMesh:setVertices(self.normalVert)
love.graphics.draw(self.normalMesh, self.x - self.nx + self.world.translate_x, self.y - self.ny + self.world.translate_y) love.graphics.draw(self.normalMesh, self.x - self.nx + l, self.y - self.ny + t)
end end
if self.reflective and self.img then if self.reflective and self.img then
love.graphics.setColor(0, 255, 0) love.graphics.setColor(0, 255, 0)
love.graphics.draw(self.img, self.x - self.ix + self.world.translate_x, self.y - self.iy + self.world.translate_y) love.graphics.draw(self.img, self.x - self.ix + l, self.y - self.iy + t)
elseif not self.reflection and self.img then elseif not self.reflection and self.img then
love.graphics.setColor(0, 0, 0) love.graphics.setColor(0, 0, 0)
love.graphics.draw(self.img, self.x - self.ix + self.world.translate_x, self.y - self.iy + self.world.translate_y) love.graphics.draw(self.img, self.x - self.ix + l, self.y - self.iy + t)
end end
end end
function body:drawMaterial() function body:drawMaterial(l,t,w,h)
if self.material and self.normal then if self.material and self.normal then
love.graphics.setShader(self.materialShader) love.graphics.setShader(self.materialShader)
love.graphics.setColor(255, 255, 255) love.graphics.setColor(255, 255, 255)
self.materialShader:send("material", self.material) self.materialShader:send("material", self.material)
love.graphics.draw(self.normal, self.x - self.nx + self.world.translate_x, self.y - self.ny + self.world.translate_y) love.graphics.draw(self.normal, self.x - self.nx + l, self.y - self.ny + t)
love.graphics.setShader() love.graphics.setShader()
end end
end end

View File

@ -118,13 +118,11 @@ function light:setGlowStrength(strength)
self.glowStrength = strength self.glowStrength = strength
end end
function light:updateShadow() function light:updateShadow(l,t,w,h)
love.graphics.setShader(self.shader) love.graphics.setShader(self.shader)
if self.x + self.range > self.world.translate_x and self.x - self.range < love.graphics.getWidth() + self.world.translate_x 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
and self.y + self.range > self.world.translate_y and self.y - self.range < love.graphics.getHeight() + self.world.translate_y local lightposrange = {self.x, h - self.y, self.range}
then self.shader:send("lightPosition", {self.x - l, h - (self.y - t), self.z})
local lightposrange = {self.x, love.graphics.getHeight() - self.y, self.range}
self.shader:send("lightPosition", {self.x - self.world.translate_x, love.graphics.getHeight() - (self.y - self.world.translate_y), self.z})
self.shader:send("lightRange", self.range) self.shader:send("lightRange", self.range)
self.shader:send("lightColor", {self.red / 255.0, self.green / 255.0, self.blue / 255.0}) self.shader:send("lightColor", {self.red / 255.0, self.green / 255.0, self.blue / 255.0})
self.shader:send("lightSmooth", self.smooth) self.shader:send("lightSmooth", self.smooth)
@ -141,8 +139,7 @@ function light:updateShadow()
-- draw shadow -- draw shadow
love.graphics.setInvertedStencil(stencils.shadow(shadow_geometry, self.world.body)) love.graphics.setInvertedStencil(stencils.shadow(shadow_geometry, self.world.body))
love.graphics.setBlendMode("additive") love.graphics.setBlendMode("additive")
-- FIND THIS TOOOO love.graphics.rectangle("fill", l,t,w,h)
love.graphics.rectangle("fill", self.world.translate_x, self.world.translate_y, love.graphics.getWidth(), love.graphics.getHeight())
-- draw color shadows -- draw color shadows
love.graphics.setBlendMode("multiplicative") love.graphics.setBlendMode("multiplicative")
@ -159,7 +156,7 @@ function light:updateShadow()
end end
for k = 1, #self.world.body do for k = 1, #self.world.body do
self.world.body[k]:drawShadow(self) self.world.body[k]:drawShadow(self, l,t,w,h)
end end
love.graphics.setShader(self.shader) love.graphics.setShader(self.shader)
@ -170,7 +167,7 @@ function light:updateShadow()
love.graphics.setBlendMode("alpha") love.graphics.setBlendMode("alpha")
love.graphics.setStencil(stencils.poly(self.world.body)) love.graphics.setStencil(stencils.poly(self.world.body))
-- WHOA THIS MAY BE THE ISSUE HERE FIND THIS! -- 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()) love.graphics.rectangle("fill", l,t,w,h)
self.visible = true self.visible = true
else else
@ -179,15 +176,15 @@ function light:updateShadow()
love.graphics.setShader() love.graphics.setShader()
end end
function light:drawShadow() function light:drawShadow(l,t,w,h)
if self.visible then if self.visible then
love.graphics.draw(self.shadow, self.world.translate_x, self.world.translate_y) love.graphics.draw(self.shadow, l, t)
end end
end end
function light:drawShine() function light:drawShine(l,t,w,h)
if self.visible then if self.visible then
love.graphics.draw(self.shine, self.world.translate_x, self.world.translate_y) love.graphics.draw(self.shine, l, t)
end end
end end
@ -303,28 +300,28 @@ function light:calculateCircleShadow(circle)
end end
end end
function light:drawPixelShadow() function light:drawPixelShadow(l,t,w,h)
if self.visible then if self.visible then
if self.normalInvert then if self.normalInvert then
self.normalInvertShader:send('screenResolution', {love.graphics.getWidth(), love.graphics.getHeight()}) self.normalInvertShader:send('screenResolution', {w, h})
self.normalInvertShader:send('lightColor', {self.red / 255.0, self.green / 255.0, self.blue / 255.0}) self.normalInvertShader:send('lightColor', {self.red / 255.0, self.green / 255.0, self.blue / 255.0})
self.normalInvertShader:send('lightPosition',{self.x, love.graphics.getHeight() - self.y, self.z / 255.0}) self.normalInvertShader:send('lightPosition',{self.x, lh - self.y, self.z / 255.0})
self.normalInvertShader:send('lightRange',{self.range}) self.normalInvertShader:send('lightRange',{self.range})
self.normalInvertShader:send("lightSmooth", self.smooth) self.normalInvertShader:send("lightSmooth", self.smooth)
self.normalInvertShader:send("lightAngle", math.pi - self.angle / 2.0) self.normalInvertShader:send("lightAngle", math.pi - self.angle / 2.0)
self.normalInvertShader:send("lightDirection", self.direction) self.normalInvertShader:send("lightDirection", self.direction)
love.graphics.setShader(self.normalInvertShader) love.graphics.setShader(self.normalInvertShader)
else else
self.normalShader:send('screenResolution', {love.graphics.getWidth(), love.graphics.getHeight()}) self.normalShader:send('screenResolution', {w, h})
self.normalShader:send('lightColor', {self.red / 255.0, self.green / 255.0, self.blue / 255.0}) self.normalShader:send('lightColor', {self.red / 255.0, self.green / 255.0, self.blue / 255.0})
self.normalShader:send('lightPosition',{self.x, love.graphics.getHeight() - self.y, self.z / 255.0}) self.normalShader:send('lightPosition',{self.x, h - self.y, self.z / 255.0})
self.normalShader:send('lightRange',{self.range}) self.normalShader:send('lightRange',{self.range})
self.normalShader:send("lightSmooth", self.smooth) self.normalShader:send("lightSmooth", self.smooth)
self.normalShader:send("lightAngle", math.pi - self.angle / 2.0) self.normalShader:send("lightAngle", math.pi - self.angle / 2.0)
self.normalShader:send("lightDirection", self.direction) self.normalShader:send("lightDirection", self.direction)
love.graphics.setShader(self.normalShader) love.graphics.setShader(self.normalShader)
end end
love.graphics.draw(self.world.normalMap, self.world.translate_x, self.world.translate_y) love.graphics.draw(self.world.normalMap, l, t)
end end
end end

View File

@ -40,8 +40,7 @@ light_world.refractionShader:send("screen", {love.window.getWidth(), love.window
light_world.reflectionShader:send("screen", {love.window.getWidth(), love.window.getHeight()}) light_world.reflectionShader:send("screen", {love.window.getWidth(), love.window.getHeight()})
function light_world:init() function light_world:init()
self.translate_x = 0 self.scale = 1
self.translate_y = 0
self.last_buffer = nil self.last_buffer = nil
self.lights = {} self.lights = {}
@ -60,15 +59,14 @@ function light_world:init()
self:refreshScreenSize() self:refreshScreenSize()
end end
function light_world:updateShadows() function light_world:updateShadows(l,t,w,h)
if not self.isShadows and not self.isLight then if not self.isShadows and not self.isLight then
return return
end end
self.last_buffer = love.graphics.getCanvas() self.last_buffer = love.graphics.getCanvas()
for i = 1, #self.lights do for i = 1, #self.lights do
self.lights[i]:updateShadow() self.lights[i]:updateShadow(l,t,w,h)
end end
-- update shadow -- update shadow
@ -76,29 +74,33 @@ function light_world:updateShadows()
love.graphics.setStencil() love.graphics.setStencil()
love.graphics.setColor(unpack(self.ambient)) love.graphics.setColor(unpack(self.ambient))
love.graphics.setBlendMode("alpha") love.graphics.setBlendMode("alpha")
love.graphics.rectangle("fill", self.translate_x, self.translate_y, love.graphics.getWidth(), love.graphics.getHeight()) love.graphics.rectangle("fill", l, t, w, h)
love.graphics.setColor(255, 255, 255) love.graphics.setColor(255, 255, 255)
love.graphics.setBlendMode("additive") love.graphics.setBlendMode("additive")
for i = 1, #self.lights do for i = 1, #self.lights do
self.lights[i]:drawShadow() self.lights[i]:drawShadow(l,t,w,h)
end
-- update shine
love.graphics.setCanvas(self.shine)
love.graphics.setColor(unpack(self.ambient))
love.graphics.setBlendMode("alpha")
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 end
love.graphics.setCanvas(self.last_buffer) love.graphics.setCanvas(self.last_buffer)
end end
function light_world:updatePixelShadows() function light_world:updateShine(l,t,w,h)
self.last_buffer = love.graphics.getCanvas()
-- 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
love.graphics.setCanvas(self.last_buffer)
end
function light_world:updatePixelShadows(l,t,w,h)
if not self.isPixelShadows then if not self.isPixelShadows then
return return
end end
@ -112,7 +114,7 @@ function light_world:updatePixelShadows()
love.graphics.setShader() love.graphics.setShader()
love.graphics.setCanvas(self.normalMap) love.graphics.setCanvas(self.normalMap)
for i = 1, #self.body do for i = 1, #self.body do
self.body[i]:drawPixelShadow() self.body[i]:drawPixelShadow(l,t,w,h)
end end
love.graphics.setColor(255, 255, 255) love.graphics.setColor(255, 255, 255)
love.graphics.setBlendMode("alpha") love.graphics.setBlendMode("alpha")
@ -123,23 +125,23 @@ function light_world:updatePixelShadows()
love.graphics.setShader(self.shader2) love.graphics.setShader(self.shader2)
for i = 1, #self.lights do for i = 1, #self.lights do
self.lights[i]:drawPixelShadow() self.lights[i]:drawPixelShadow(l,t,w,h)
end end
love.graphics.setShader() love.graphics.setShader()
self.pixelShadow:clear(255, 255, 255) self.pixelShadow:clear(255, 255, 255)
love.graphics.setCanvas(self.pixelShadow) love.graphics.setCanvas(self.pixelShadow)
love.graphics.setBlendMode("alpha") love.graphics.setBlendMode("alpha")
love.graphics.draw(self.pixelShadow2, self.translate_x, self.translate_y) love.graphics.draw(self.pixelShadow2, l,t)
love.graphics.setBlendMode("additive") love.graphics.setBlendMode("additive")
love.graphics.setColor({self.ambient[1], self.ambient[2], self.ambient[3]}) love.graphics.setColor({self.ambient[1], self.ambient[2], self.ambient[3]})
love.graphics.rectangle("fill", self.translate_x, self.translate_y, love.graphics.getWidth(), love.graphics.getHeight()) love.graphics.rectangle("fill", l,t,w,h)
love.graphics.setBlendMode("alpha") love.graphics.setBlendMode("alpha")
love.graphics.setCanvas(self.last_buffer) love.graphics.setCanvas(self.last_buffer)
end end
function light_world:updateGlow() function light_world:updateGlow(l,t,w,h)
if not self.isGlow then if not self.isGlow then
return return
end end
@ -162,12 +164,12 @@ function light_world:updateGlow()
end end
for i = 1, #self.body do for i = 1, #self.body do
self.body[i]:drawGlow() self.body[i]:drawGlow(l,t,w,h)
end end
love.graphics.setCanvas(self.last_buffer) love.graphics.setCanvas(self.last_buffer)
end end
function light_world:updateRefraction() function light_world:updateRefraction(l,t,w,h)
if not self.isRefraction then if not self.isRefraction then
return return
end end
@ -178,12 +180,12 @@ function light_world:updateRefraction()
self.refractionMap:clear() self.refractionMap:clear()
love.graphics.setCanvas(self.refractionMap) love.graphics.setCanvas(self.refractionMap)
for i = 1, #self.body do for i = 1, #self.body do
self.body[i]:drawRefraction() self.body[i]:drawRefraction(l,t,w,h)
end end
love.graphics.setCanvas(self.last_buffer) love.graphics.setCanvas(self.last_buffer)
end end
function light_world:updateRelfection() function light_world:updateRelfection(l,t,w,h)
if not self.isReflection then if not self.isReflection then
return return
end end
@ -193,7 +195,7 @@ function light_world:updateRelfection()
self.reflectionMap:clear(0, 0, 0) self.reflectionMap:clear(0, 0, 0)
love.graphics.setCanvas(self.reflectionMap) love.graphics.setCanvas(self.reflectionMap)
for i = 1, #self.body do for i = 1, #self.body do
self.body[i]:drawReflection() self.body[i]:drawReflection(l,t,w,h)
end end
love.graphics.setCanvas(self.last_buffer) love.graphics.setCanvas(self.last_buffer)
end end
@ -214,13 +216,19 @@ function light_world:refreshScreenSize()
self.reflectionMap2 = love.graphics.newCanvas() self.reflectionMap2 = love.graphics.newCanvas()
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())
end
-- draw shadow -- draw shadow
function light_world:drawShadow() function light_world:drawShadow(l,t,w,h)
if not self.isShadows and not self.isLight then if not self.isShadows and not self.isLight then
return return
end end
self:updateShadows() l,t,w,h = self.clampScreen(l,t,w,h)
self:updateShadows(l,t,w,h)
love.graphics.setColor(255, 255, 255) love.graphics.setColor(255, 255, 255)
if self.blur then if self.blur then
self.last_buffer = love.graphics.getCanvas() self.last_buffer = love.graphics.getCanvas()
@ -229,28 +237,32 @@ function light_world:drawShadow()
love.graphics.setBlendMode("alpha") love.graphics.setBlendMode("alpha")
love.graphics.setCanvas(self.shadow2) love.graphics.setCanvas(self.shadow2)
love.graphics.setShader(self.blurv) love.graphics.setShader(self.blurv)
love.graphics.draw(self.shadow, self.translate_x, self.translate_y) love.graphics.draw(self.shadow, l, t)
love.graphics.setCanvas(self.shadow) love.graphics.setCanvas(self.shadow)
love.graphics.setShader(self.blurh) love.graphics.setShader(self.blurh)
love.graphics.draw(self.shadow2, self.translate_x, self.translate_y) love.graphics.draw(self.shadow2, l, t)
love.graphics.setCanvas(self.last_buffer) love.graphics.setCanvas(self.last_buffer)
love.graphics.setBlendMode("multiplicative") love.graphics.setBlendMode("multiplicative")
love.graphics.setShader() love.graphics.setShader()
love.graphics.draw(self.shadow, self.translate_x, self.translate_y) love.graphics.draw(self.shadow, l, t)
love.graphics.setBlendMode("alpha") love.graphics.setBlendMode("alpha")
else else
love.graphics.setBlendMode("multiplicative") love.graphics.setBlendMode("multiplicative")
love.graphics.setShader() love.graphics.setShader()
love.graphics.draw(self.shadow, self.translate_x, self.translate_y) love.graphics.draw(self.shadow, l, t)
love.graphics.setBlendMode("alpha") love.graphics.setBlendMode("alpha")
end end
end end
-- draw shine -- draw shine
function light_world:drawShine() function light_world:drawShine(l,t,w,h)
if not self.isShadows then if not self.isShadows then
return return
end 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.setColor(255, 255, 255)
if self.blur and false then if self.blur and false then
self.last_buffer = love.graphics.getCanvas() self.last_buffer = love.graphics.getCanvas()
@ -259,55 +271,62 @@ function light_world:drawShine()
love.graphics.setBlendMode("alpha") love.graphics.setBlendMode("alpha")
love.graphics.setCanvas(self.shine2) love.graphics.setCanvas(self.shine2)
love.graphics.setShader(self.blurv) love.graphics.setShader(self.blurv)
love.graphics.draw(self.shine, self.translate_x, self.translate_y) love.graphics.draw(self.shine, l, t)
love.graphics.setCanvas(self.shine) love.graphics.setCanvas(self.shine)
love.graphics.setShader(self.blurh) love.graphics.setShader(self.blurh)
love.graphics.draw(self.shine2, self.translate_x, self.translate_y) love.graphics.draw(self.shine2, l, t)
love.graphics.setCanvas(self.last_buffer) love.graphics.setCanvas(self.last_buffer)
love.graphics.setBlendMode("multiplicative") love.graphics.setBlendMode("multiplicative")
love.graphics.setShader() love.graphics.setShader()
love.graphics.draw(self.shine, self.translate_x, self.translate_y) love.graphics.draw(self.shine, l, t)
love.graphics.setBlendMode("alpha") love.graphics.setBlendMode("alpha")
else else
love.graphics.setBlendMode("multiplicative") love.graphics.setBlendMode("multiplicative")
love.graphics.setShader() love.graphics.setShader()
love.graphics.draw(self.shine, self.translate_x, self.translate_y) love.graphics.draw(self.shine, l, t)
love.graphics.setBlendMode("alpha") love.graphics.setBlendMode("alpha")
end end
end end
-- draw pixel shadow -- draw pixel shadow
function light_world:drawPixelShadow() function light_world:drawPixelShadow(l,t,w,h)
if not self.isPixelShadows then if not self.isPixelShadows then
return return
end end
self:updatePixelShadows()
l,t,w,h = self.clampScreen(l,t,w,h)
self:updatePixelShadows(l,t,w,h)
love.graphics.setColor(255, 255, 255) love.graphics.setColor(255, 255, 255)
love.graphics.setBlendMode("multiplicative") love.graphics.setBlendMode("multiplicative")
love.graphics.setShader() love.graphics.setShader()
love.graphics.draw(self.pixelShadow, self.translate_x, self.translate_y) love.graphics.draw(self.pixelShadow, l, t)
love.graphics.setBlendMode("alpha") love.graphics.setBlendMode("alpha")
end end
-- draw material -- draw material
function light_world:drawMaterial() function light_world:drawMaterial(l,t,w,h)
l,t,w,h = self.clampScreen(l,t,w,h)
for i = 1, #self.body do for i = 1, #self.body do
self.body[i]:drawMaterial() self.body[i]:drawMaterial(l,t,w,h)
end end
end end
-- draw glow -- draw glow
function light_world:drawGlow() function light_world:drawGlow(l,t,w,h)
if not self.isGlow then if not self.isGlow then
return return
end end
self:updateGlow() l,t,w,h = self.clampScreen(l,t,w,h)
self:updateGlow(l,t,w,h)
love.graphics.setColor(255, 255, 255) love.graphics.setColor(255, 255, 255)
if self.glowBlur == 0.0 then if self.glowBlur == 0.0 then
love.graphics.setBlendMode("additive") love.graphics.setBlendMode("additive")
love.graphics.setShader() love.graphics.setShader()
love.graphics.draw(self.glowMap, self.translate_x, self.translate_y) love.graphics.draw(self.glowMap, l,t)
love.graphics.setBlendMode("alpha") love.graphics.setBlendMode("alpha")
else else
self.blurv:send("steps", self.glowBlur) self.blurv:send("steps", self.glowBlur)
@ -317,57 +336,61 @@ function light_world:drawGlow()
self.glowMap2:clear() self.glowMap2:clear()
love.graphics.setCanvas(self.glowMap2) love.graphics.setCanvas(self.glowMap2)
love.graphics.setShader(self.blurv) love.graphics.setShader(self.blurv)
love.graphics.draw(self.glowMap, self.translate_x, self.translate_y) love.graphics.draw(self.glowMap, l, t)
love.graphics.setCanvas(self.glowMap) love.graphics.setCanvas(self.glowMap)
love.graphics.setShader(self.blurh) love.graphics.setShader(self.blurh)
love.graphics.draw(self.glowMap2, self.translate_x, self.translate_y) love.graphics.draw(self.glowMap2, l, t)
love.graphics.setCanvas(self.last_buffer) love.graphics.setCanvas(self.last_buffer)
love.graphics.setShader() love.graphics.setShader()
love.graphics.draw(self.glowMap, self.translate_x, self.translate_y) love.graphics.draw(self.glowMap, l, t)
love.graphics.setBlendMode("alpha") love.graphics.setBlendMode("alpha")
end end
end end
-- draw refraction -- draw refraction
function light_world:drawRefraction() function light_world:drawRefraction(l,t,w,h)
if not self.isRefraction then if not self.isRefraction then
return return
end end
self:updateRefraction() l,t,w,h = self.clampScreen(l,t,w,h)
self:updateRefraction(l,t,w,h)
self.last_buffer = love.graphics.getCanvas() self.last_buffer = love.graphics.getCanvas()
if self.last_buffer then if self.last_buffer then
love.graphics.setColor(255, 255, 255) love.graphics.setColor(255, 255, 255)
love.graphics.setBlendMode("alpha") love.graphics.setBlendMode("alpha")
love.graphics.setCanvas(self.refractionMap2) love.graphics.setCanvas(self.refractionMap2)
love.graphics.draw(self.last_buffer, self.translate_x, self.translate_y) love.graphics.draw(self.last_buffer, l, t)
love.graphics.setCanvas(self.last_buffer) love.graphics.setCanvas(self.last_buffer)
self.refractionShader:send("backBuffer", self.refractionMap2) self.refractionShader:send("backBuffer", self.refractionMap2)
self.refractionShader:send("refractionStrength", self.refractionStrength) self.refractionShader:send("refractionStrength", self.refractionStrength)
love.graphics.setShader(self.refractionShader) love.graphics.setShader(self.refractionShader)
love.graphics.draw(self.refractionMap, self.translate_x, self.translate_y) love.graphics.draw(self.refractionMap, l, t)
love.graphics.setShader() love.graphics.setShader()
end end
end end
-- draw reflection -- draw reflection
function light_world:drawReflection() function light_world:drawReflection(l,t,w,h)
if not self.isReflection then if not self.isReflection then
return return
end end
self:updateRelfection() l,t,w,h = self.clampScreen(l,t,w,h)
self:updateRelfection(l,t,w,h)
self.last_buffer = love.graphics.getCanvas() self.last_buffer = love.graphics.getCanvas()
if self.last_buffer then if self.last_buffer then
love.graphics.setColor(255, 255, 255) love.graphics.setColor(255, 255, 255)
love.graphics.setBlendMode("alpha") love.graphics.setBlendMode("alpha")
love.graphics.setCanvas(self.reflectionMap2) love.graphics.setCanvas(self.reflectionMap2)
love.graphics.draw(self.last_buffer, self.translate_x, self.translate_y) love.graphics.draw(self.last_buffer, l, t)
love.graphics.setCanvas(self.last_buffer) love.graphics.setCanvas(self.last_buffer)
self.reflectionShader:send("backBuffer", self.reflectionMap2) self.reflectionShader:send("backBuffer", self.reflectionMap2)
self.reflectionShader:send("reflectionStrength", self.reflectionStrength) self.reflectionShader:send("reflectionStrength", self.reflectionStrength)
self.reflectionShader:send("reflectionVisibility", self.reflectionVisibility) self.reflectionShader:send("reflectionVisibility", self.reflectionVisibility)
love.graphics.setShader(self.reflectionShader) love.graphics.setShader(self.reflectionShader)
love.graphics.draw(self.reflectionMap, self.translate_x, self.translate_y) love.graphics.draw(self.reflectionMap, l, t)
love.graphics.setShader() love.graphics.setShader()
end end
end end
@ -395,12 +418,6 @@ function light_world:clearBodys()
self.isReflection = false self.isReflection = false
end end
-- set offset
function light_world:setTranslation(translateX, translateY)
self.translate_x = translateX
self.translate_y = translateY
end
-- set ambient color -- set ambient color
function light_world:setAmbientColor(red, green, blue) function light_world:setAmbientColor(red, green, blue)
self.ambient = {red, green, blue} self.ambient = {red, green, blue}

208
vendor/gamera.lua vendored Normal file
View File

@ -0,0 +1,208 @@
-- gamera.lua v1.0.1
-- Copyright (c) 2012 Enrique García Cota
-- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-- Based on YaciCode, from Julien Patte and LuaObject, from Sebastien Rocca-Serra
local gamera = {}
-- Private attributes and methods
local gameraMt = {__index = gamera}
local abs, min, max = math.abs, math.min, math.max
local function clamp(x, minX, maxX)
return x < minX and minX or (x>maxX and maxX or x)
end
local function checkNumber(value, name)
if type(value) ~= 'number' then
error(name .. " must be a number (was: " .. tostring(value) .. ")")
end
end
local function checkPositiveNumber(value, name)
if type(value) ~= 'number' or value <=0 then
error(name .. " must be a positive number (was: " .. tostring(value) ..")")
end
end
local function checkAABB(l,t,w,h)
checkNumber(l, "l")
checkNumber(t, "t")
checkPositiveNumber(w, "w")
checkPositiveNumber(h, "h")
end
local function getVisibleArea(self, scale)
scale = scale or self.scale
local sin, cos = abs(self.sin), abs(self.cos)
local w,h = self.w / scale, self.h / scale
w,h = cos*w + sin*h, sin*w + cos*h
return min(w,self.ww), min(h, self.wh)
end
local function cornerTransform(self, x,y)
local scale, sin, cos = self.scale, self.sin, self.cos
x,y = x - self.x, y - self.y
x,y = -cos*x + sin*y, -sin*x - cos*y
return self.x - (x/scale + self.l), self.y - (y/scale + self.t)
end
local function adjustPosition(self)
local wl,wt,ww,wh = self.wl, self.wt, self.ww, self.wh
local w,h = getVisibleArea(self)
local w2,h2 = w*0.5, h*0.5
local left, right = wl + w2, wl + ww - w2
local top, bottom = wt + h2, wt + wh - h2
self.x, self.y = clamp(self.x, left, right), clamp(self.y, top, bottom)
end
local function adjustScale(self)
local w,h,ww,wh = self.w, self.h, self.ww, self.wh
local rw,rh = getVisibleArea(self, 1) -- rotated frame: area around the window, rotated without scaling
local sx,sy = rw/ww, rh/wh -- vert/horiz scale: minimun scales that the window needs to occupy the world
local rscale = max(sx,sy)
self.scale = max(self.scale, rscale)
end
-- Public interface
function gamera.new(l,t,w,h)
local sw,sh = love.graphics.getWidth(), love.graphics.getHeight()
local cam = setmetatable({
x=0, y=0,
scale=1,
angle=0, sin=math.sin(0), cos=math.cos(0),
l=0, t=0, w=sw, h=sh, w2=sw*0.5, h2=sh*0.5
}, gameraMt)
cam:setWorld(l,t,w,h)
return cam
end
function gamera:setWorld(l,t,w,h)
checkAABB(l,t,w,h)
self.wl, self.wt, self.ww, self.wh = l,t,w,h
adjustPosition(self)
end
function gamera:setWindow(l,t,w,h)
checkAABB(l,t,w,h)
self.l, self.t, self.w, self.h, self.w2, self.h2 = l,t,w,h, w*0.5, h*0.5
adjustPosition(self)
end
function gamera:setPosition(x,y)
checkNumber(x, "x")
checkNumber(y, "y")
self.x, self.y = x,y
adjustPosition(self)
end
function gamera:setScale(scale)
checkNumber(scale, "scale")
self.scale = scale
adjustScale(self)
adjustPosition(self)
end
function gamera:setAngle(angle)
checkNumber(angle, "angle")
self.angle = angle
self.cos, self.sin = math.cos(angle), math.sin(angle)
adjustScale(self)
adjustPosition(self)
end
function gamera:getWorld()
return self.wl, self.wt, self.ww, self.wh
end
function gamera:getWindow()
return self.l, self.t, self.w, self.h
end
function gamera:getPosition()
return self.x, self.y
end
function gamera:getScale()
return self.scale
end
function gamera:getAngle()
return self.angle
end
function gamera:getVisible()
local w,h = getVisibleArea(self)
return self.x - w*0.5, self.y - h*0.5, w, h
end
function gamera:getVisibleCorners()
local x,y,w2,h2 = self.x, self.y, self.w2, self.h2
local x1,y1 = cornerTransform(self, x-w2,y-h2)
local x2,y2 = cornerTransform(self, x+w2,y-h2)
local x3,y3 = cornerTransform(self, x+w2,y+h2)
local x4,y4 = cornerTransform(self, x-w2,y+h2)
return x1,y1,x2,y2,x3,y3,x4,y4
end
function gamera:draw(f)
love.graphics.setScissor(self:getWindow())
love.graphics.push()
local scale = self.scale
love.graphics.scale(scale)
love.graphics.translate((self.w2 + self.l) / scale, (self.h2+self.t) / scale)
love.graphics.rotate(-self.angle)
love.graphics.translate(-self.x, -self.y)
f(self:getVisible())
love.graphics.pop()
love.graphics.setScissor()
end
function gamera:toWorld(x,y)
local scale, sin, cos = self.scale, self.sin, self.cos
x,y = (x - self.w2 - self.l) / scale, (y - self.h2 - self.t) / scale
x,y = cos*x - sin*y, sin*x + cos*y
return x + self.x, y + self.y
end
function gamera:toScreen(x,y)
local scale, sin, cos = self.scale, self.sin, self.cos
x,y = x - self.x, y - self.y
x,y = cos*x + sin*y, -sin*x + cos*y
return scale * x + self.w2 + self.l, scale * y + self.h2 + self.t
end
return gamera