To make it up to you, here's the full corrected camera.lua. I've renamed some functions so their names express more accurately what they actually do. That's because e.g. 'scale' suggest a scaling relative to the previous scale, but that's not true. 'setScale' suggests it's setting an absolute scale value, as it's actually doing.
Code: Select all
-- Author : Lionel Leeser
-- Date : 15.02.19
-- Goal : Simplified camera for demonstrating.
-- Changes by Pedro Gimeno donated to the public domain.
local Camera = {}
Camera.x = 0
Camera.y = 0
Camera.scaleX = 1
Camera.scaleY = 1
Camera.rotation = 0
Camera.transform = nil
function Camera:init(x, y)
self.transform = love.math.newTransform(x, y)
end -- function
function Camera:set()
love.graphics.push()
self.transform:setTransformation(love.graphics.getWidth()/2, love.graphics.getHeight()/2, self.rotation, self.scaleX, self.scaleY, self.x, self.y)
love.graphics.applyTransform(self.transform)
end
function Camera:unset()
love.graphics.pop()
end
function Camera:setPosition(x, y)
self.x = x
self.y = y
end
function Camera:move(dx, dy)
self.x = self.x + dx
self.y = self.y + dy
end
function Camera:setRotation(dr)
self.rotation = dr
end
function Camera:setScale(sx, sy)
self.scaleX = sx or 1
self.scaleY = sy or sx or 1
end
function Camera:getViewMatrix()
return self.transform:getMatrix()
end -- function
return Camera
I don't believe you need a Camera:move() for relative movement. Doing so has the risk of a desynch between camera and player. Instead, you use Camera:setPosition() to e.g. follow the player.
[Edit: Forgot to say: in this version, Camera:getViewMatrix() is only valid right after Camera:set(), not before. I guess it's obvious from the code but I'm making it explicit just in case.]
The previous shader was OK. It only needs one modification (apart from the extern):
Code: Select all
vec2 norm_pos = (viewMatrix * vec4(light.position, 0.0, 1.0)).xy / screen;