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
require "lib/postshader"
local gamera = require "vendor/gamera"
local LightWorld = require "lib/light_world"
function love.load()
scale = 1
camera = gamera.new(0,0,2000,2000)
-- load images
image = love.graphics.newImage("gfx/machine2.png")
image_normal = love.graphics.newImage("gfx/cone_normal.png")
@ -43,43 +47,47 @@ end
function love.update(dt)
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
function love.draw()
love.postshader.setBuffer("render")
--camera:setScale(scale)
camera:draw(function(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)
-- draw background
love.graphics.setColor(255, 255, 255)
love.graphics.rectangle("fill", 0, 0, love.graphics.getWidth(), love.graphics.getHeight())
--love.graphics.draw(imgFloor, quadScreen, 0, 0)
-- draw lightmap shadows
lightWorld:drawShadow()
-- draw scene objects
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)
--love.graphics.rectangle("fill", 128 - 32, 128 - 32, 64, 64)
-- draw lightmap shine
lightWorld:drawShine()
-- draw pixel shadow
lightWorld:drawPixelShadow()
-- draw glow
lightWorld:drawGlow()
-- draw refraction
lightWorld:drawRefraction()
-- draw reflection
lightWorld:drawReflection()
love.postshader.draw()
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)
end)
end

View File

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

View File

@ -118,13 +118,11 @@ function light:setGlowStrength(strength)
self.glowStrength = strength
end
function light:updateShadow()
function light:updateShadow(l,t,w,h)
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
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}
self.shader:send("lightPosition", {self.x - self.world.translate_x, love.graphics.getHeight() - (self.y - self.world.translate_y), self.z})
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}
self.shader:send("lightPosition", {self.x - l, h - (self.y - t), self.z})
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("lightSmooth", self.smooth)
@ -141,8 +139,7 @@ function light:updateShadow()
-- 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())
love.graphics.rectangle("fill", l,t,w,h)
-- draw color shadows
love.graphics.setBlendMode("multiplicative")
@ -159,7 +156,7 @@ function light:updateShadow()
end
for k = 1, #self.world.body do
self.world.body[k]:drawShadow(self)
self.world.body[k]:drawShadow(self, l,t,w,h)
end
love.graphics.setShader(self.shader)
@ -170,7 +167,7 @@ function light:updateShadow()
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())
love.graphics.rectangle("fill", l,t,w,h)
self.visible = true
else
@ -179,15 +176,15 @@ function light:updateShadow()
love.graphics.setShader()
end
function light:drawShadow()
function light:drawShadow(l,t,w,h)
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
function light:drawShine()
function light:drawShine(l,t,w,h)
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
@ -303,28 +300,28 @@ function light:calculateCircleShadow(circle)
end
end
function light:drawPixelShadow()
function light:drawPixelShadow(l,t,w,h)
if self.visible 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('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("lightSmooth", self.smooth)
self.normalInvertShader:send("lightAngle", math.pi - self.angle / 2.0)
self.normalInvertShader:send("lightDirection", self.direction)
love.graphics.setShader(self.normalInvertShader)
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('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("lightSmooth", self.smooth)
self.normalShader:send("lightAngle", math.pi - self.angle / 2.0)
self.normalShader:send("lightDirection", self.direction)
love.graphics.setShader(self.normalShader)
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

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