Page 1 of 1

[help] Dynamically generate gradient

Posted: Sat Jun 01, 2013 6:45 pm
by soullessbr
how can I draw a gradient at runtime?

Thank you ...

Re: [help] Dynamically generate gradient

Posted: Sat Jun 01, 2013 7:11 pm
by Plu
Prep a canvas, select a starting color, an ending color, make a for loop and use the love.graphics.line function with slowly changing colors. You can calculate how fast the colors need to change by getting the difference between start and end and dividing by the length of the gradient. (ie from 0 to 100 in 400 lines means you add 0.25 to the color in each loop cycle)

Re: [help] Dynamically generate gradient

Posted: Sat Jun 01, 2013 7:21 pm
by T-Bone
I guess a shader can be an option, depends a little on how you want to use it. If you want to change the colors every frame, a shader will work better. If it should only be drawn once (or a few times) then a Canvas is better.

Re: [help] Dynamically generate gradient

Posted: Sun Jun 02, 2013 11:13 am
by Jasoco
I think the hardest part is doing the color transition.

Re: [help] Dynamically generate gradient

Posted: Sun Jun 02, 2013 1:12 pm
by T-Bone
It doesn't have to be all that hard. Just do a weighted average of all three components, and let the weight of the first color go from 1 to 0 linearly while the second colors weight goes from 0 to 1.

Re: [help] Dynamically generate gradient

Posted: Sun Jun 02, 2013 1:56 pm
by vrld
You can (ab)use ImageData:

Code: Select all

local function Gradient(from, to, orientation)
	orientation = orientation or 'horizontal'

	local d = 1
	if orientation == 'vertical' then
		d = 0
	elseif orientation ~= 'horizontal' then
		error('invalid orientation: ' .. tostring(orientation))
	end

	local img = love.image.newImageData(1+d, 2-d)
	print(orientation, d, 1-d, 1+d, 1+(d-1))
	img:setPixel(0,0, from[1], from[2], from[3], from[4] or 255)
	img:setPixel(d,1-d, to[1], to[2], to[3], to[4] or 255)

	img = love.graphics.newImage(img)
	img:setFilter('linear', 'linear')
	return {
		draw = function(x,y, w,h, r, ox,oy, kx,ky)
			ox = (ox or 0) / w
			oy = (oy or 0) / h
			love.graphics.draw(img, x,y, r or 0, w/(1+d), h/(2-d), ox,oy, kx,ky)
		end
	}
end

function love.load()
	gradient = Gradient({40,85,175}, {140,218,234})
	gradient2 = Gradient({200,100,30}, {80,200,50}, 'vertical')
end

function love.draw()
	gradient.draw( 10,10, love.graphics.getWidth()-10,100)
	gradient2.draw(10,120, 150,150)
end
Result:
gradient.jpg
gradient.jpg (5.37 KiB) Viewed 5012 times

Re: [help] Dynamically generate gradient

Posted: Sun Jun 02, 2013 2:14 pm
by wesleylucas
I just converted an old script for RPG Maker:

Code: Select all

function newColor(r,g,b,a)
 local c = {}
 c.red = r
 c.green = g
 c.blue = b
 if a == nil then
  c.alpha = 255
 else
  c.alpha = a
 end
 return c
end

function makeGradient(width,height,startColor,endColor)
 local rcalc = endColor.red   - startColor.red
 local gcalc = endColor.green - startColor.green
 local bcalc = endColor.blue  - startColor.blue
 local acalc = endColor.alpha - startColor.alpha
 local i = 0
 local r
 local g
 local b
 local a
 local color = love.graphics.getColor()
 local gradient = love.graphics.newCanvas(width,height)
 love.graphics.setCanvas(gradient)
 while i < width do
  r = startColor.red   + (i * rcalc / width)
  g = startColor.green + (i * gcalc / width)
  b = startColor.blue  + (i * bcalc / width)
  a = startColor.alpha + (i * acalc / width)
  love.graphics.setColor(r,g,b,a)
  love.graphics.rectangle('fill',i, 0, 1, height)
  i = i + 1
 end
 love.graphics.setCanvas()
 return gradient
end
Example:

Code: Select all

function love.load()
 rrt = makeGradient(800,600,newColor(255,0,0),newColor(0,255,0))
end

function love.draw()
 love.graphics.draw(rrt)
end
Original script: http://forums.mundorpgmaker.com.br/inde ... ic=18164.0 (PT-BR)

Re: [help] Dynamically generate gradient

Posted: Mon Jun 03, 2013 11:07 pm
by Ref
Never would have guessed that you could use 'setPixel' this way.
Thanks vrid!
Demo just confirming that I got the logic correct.

Re: [help] Dynamically generate gradient

Posted: Tue Jun 04, 2013 3:31 pm
by soullessbr
Very good! first thank you all! And two other questions, I put the static assets within the draw function, but if I'm not mistaken it is to draw all the time or not?

Because I want the gradient to be done only when the level was loaded, since it does not change anymore.

Thank you!