From 8aacf0f69cb03742322853824d9454c22a08bc70 Mon Sep 17 00:00:00 2001 From: Tim Anema Date: Tue, 30 Sep 2014 18:19:37 -0400 Subject: [PATCH] making it work better with a camera, now working on scaling, finally after a week or working to get here --- examples/short.lua | 78 +++++++++-------- lib/body.lua | 34 ++++---- lib/light.lua | 37 ++++---- lib/light_world.lua | 149 +++++++++++++++++-------------- vendor/gamera.lua | 208 ++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 369 insertions(+), 137 deletions(-) create mode 100644 vendor/gamera.lua diff --git a/examples/short.lua b/examples/short.lua index ccca829..0246304 100644 --- a/examples/short.lua +++ b/examples/short.lua @@ -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") - - -- 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) + --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 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 diff --git a/lib/body.lua b/lib/body.lua index 97cd4b9..2cc1c0f 100644 --- a/lib/body.lua +++ b/lib/body.lua @@ -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 diff --git a/lib/light.lua b/lib/light.lua index 485022f..a02b626 100644 --- a/lib/light.lua +++ b/lib/light.lua @@ -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 diff --git a/lib/light_world.lua b/lib/light_world.lua index c9e9b66..3ffc202 100644 --- a/lib/light_world.lua +++ b/lib/light_world.lua @@ -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} diff --git a/vendor/gamera.lua b/vendor/gamera.lua new file mode 100644 index 0000000..ebbb330 --- /dev/null +++ b/vendor/gamera.lua @@ -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 + + + +