Lighting and blend modes

General discussion about LÖVE, Lua, game development, puns, and unicorns.
Post Reply
User avatar
egordorichev
Prole
Posts: 3
Joined: Wed May 03, 2017 6:24 pm
Location: Saint-Petersburg, Russia
Contact:

Lighting and blend modes

Post by egordorichev »

Hello!
I'm trying to implement lighting in my love project. I've found this solution: https://love2d.org/forums/viewtopic.php?t=83106#p205645 (second post in the thread):

Code: Select all


local objects = {}
local lights = {}
love.graphics.setDefaultFilter("nearest", "nearest")
local images = {
  love.graphics.newImage("light256.png"),
}
local width, height = love.graphics.getDimensions()
local currentScale = 1
local lightmask = love.graphics.newCanvas(width, height)
local currentLightSelection = 2

local function newLight(image, x, y)
  local light = {}
  light.x = x or 0
  light.y = y or 0
  light.image = images[1]
  light.scale = currentScale
  light.flickerDelay = .05
  light.time = 0
  light.w = light.image:getWidth()
  light.h = light.image:getHeight()
  light.color = {255, 255, 255}
  light.setPosition = function(self, x, y)
    self.x = x
    self.y = y
  end

  light.draw = function(self)
    love.graphics.setBackgroundColor(255, 255, 255)
    love.graphics.setBlendMode("add")
    love.graphics.setColor(unpack(self.color))
    love.graphics.draw(self.image, self.x-(self.w*self.scale)/2, self.y-(self.w*self.scale)/2, 0, self.scale, self.scale)
    love.graphics.setBlendMode("alpha")
  end
  table.insert(lights, light)
  return light
end


local function refreshCanvas()
  love.graphics.setCanvas(lightmask)
  love.graphics.clear()
  for _, light in ipairs(lights) do
    light:draw()
  end
  love.graphics.setCanvas()
end


function love.load()
  -- Create Light sticked to the Mouse Position --
  mainLight = newLight()
  
  -- Create Random Objects --
  for i = 1, 100 do
    local obj = {}
    obj.x = math.random(0, width)
    obj.y = math.random(0, height)
    obj.w = math.random(16, 64)
    obj.h = math.random(16, 64)
    obj.color = {math.random(0, 255), math.random(0, 255), math.random(0, 255)}
    table.insert(objects, obj)
  end
end


function love.update(dt)
  -- Refresh canvas --

  
  -- Update mainLight's position --
  local mx, my = love.mouse.getPosition()
  mainLight:setPosition(mx, my)
end


function love.draw()
  refreshCanvas()
  -- Set Blend Mode --
  love.graphics.setBlendMode("multiply")
  
  -- Draw random Objects --
  for _, object in ipairs(objects) do
    love.graphics.setColor(unpack(object.color))
    love.graphics.rectangle("fill", object.x, object.y, object.w, object.h)
    love.graphics.setColor(255, 255, 255)
  end
  
  -- Draw lightmask --

  love.graphics.draw(lightmask, 0, 0)
  love.graphics.setBlendMode("alpha")
  
  -- Info --
  love.graphics.print("Click LEFT MOUSE BUTTON to create a Light", 10, 10)
  love.graphics.print("Click RIGHT MOUSE BUTTON to delete Lights", 10, 30)
  love.graphics.print("Use MOUSE WHEEL to change light size", 10, 50)
  love.graphics.print("Press ESC to Quit", 10, 70)
end


function love.keypressed(key)
  if key == "escape" then love.event.quit() end
end


function love.mousepressed(x, y, button)
  if button == 1 then
    newLight(images[currentLightSelection], x, y)
  end
  if button == 2 then
    lights = {}
    mainLight = newLight(nil, x, y)
  end
end


function love.wheelmoved(x, y)
  if y > 0 and currentScale > .25 then
    currentScale = currentScale * .85
    mainLight.scale = currentScale
  elseif y < 0 and currentScale < 1.5 then
    currentScale = currentScale / .85
    mainLight.scale = currentScale
  end
end
But i'm failing to implement the same thing in my code:

Code: Select all

local light = love.graphics.newCanvas(game.width, game.height)

function game.draw()
	love.graphics.setCanvas(light)
	love.graphics.clear()

	love.graphics.setBlendMode("add")
	love.graphics.setColor(255, 255, 255)
	love.graphics.draw(cache.load("data/images/light.png"), 0, 0)
	love.graphics.setBlendMode("alpha")

	love.graphics.setBlendMode("multiply")

	love.graphics.setCanvas(game.canvas)

	game.state:draw()

	love.graphics.draw(light)
	love.graphics.setBlendMode("alpha")

	game.getCamera():unset()
	game.drawCalls = love.graphics.getStats().drawcalls
end
And getting a white screen (my background color is set to white).
If I comment out this line:

Code: Select all

	
	love.graphics.setBlendMode("multiply")
All works fine.
What's wrong?
return (void *) 0;
User avatar
egordorichev
Prole
Posts: 3
Joined: Wed May 03, 2017 6:24 pm
Location: Saint-Petersburg, Russia
Contact:

Re: Lighting and blend modes

Post by egordorichev »

If any one can give me a hint, how to make an color overlay, with holes in it (from lights), that would help me much.
return (void *) 0;
Post Reply

Who is online

Users browsing this forum: No registered users and 10 guests