113 lines
2.8 KiB
Lua
113 lines
2.8 KiB
Lua
|
local love = assert( love )
|
||
|
local lg = love.graphics
|
||
|
local lt = love.timer
|
||
|
local coroutine = assert( coroutine )
|
||
|
local bmp = require 'map.bmp'
|
||
|
|
||
|
local scale = 1
|
||
|
local w, h = scale * 512, scale * 285
|
||
|
|
||
|
local dilateShader = require 'shaders.dilate'
|
||
|
local finalCanvas = lg.newCanvas( w, h )
|
||
|
local canvas = lg.newCanvas( w, h )
|
||
|
local identityTransform = love.math.newTransform()
|
||
|
|
||
|
local tiles = {}
|
||
|
do
|
||
|
local sideLength = 4
|
||
|
local i = 1
|
||
|
for x = 1, sideLength do
|
||
|
for y = 1, sideLength do
|
||
|
local width = math.floor( w / sideLength )
|
||
|
local height = math.floor( h / sideLength )
|
||
|
tiles[i] = function() return
|
||
|
(x - 1) * width, (y - 1) * height,
|
||
|
width, height
|
||
|
end
|
||
|
i = i + 1
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
--the coroutine library doesn't reset all the global graphics state for us
|
||
|
--so this yield function does
|
||
|
local function y( s, currentTile )
|
||
|
lg.pop( "all" )
|
||
|
coroutine.yield( s )
|
||
|
lg.push( "all" )
|
||
|
lg.setCanvas( canvas )
|
||
|
lg.setShader( dilateShader )
|
||
|
lg.setScissor( currentTile() )
|
||
|
lg.setBlendMode( "add" )
|
||
|
end
|
||
|
|
||
|
local function renderRadar( map, filename )
|
||
|
local statusString = "%s: rendering %s radius\n %s\n %d/%d"
|
||
|
--we need this first push to the stack to keep y() simple
|
||
|
lg.push( "all" )
|
||
|
y( filename, tiles[1] )
|
||
|
--then we clear the whole canvas to opaque black, pause, and select the first tile
|
||
|
lg.setScissor()
|
||
|
lg.clear( 0, 0, 0, 1 )
|
||
|
dilateShader:send( "sailable", map.sailable.img )
|
||
|
for tile = 1, #tiles do
|
||
|
|
||
|
--dilate placeable land area by 30 degrees (radar radius)
|
||
|
dilateShader:send( "radius", math.floor( 512 * 30 / 360 ) )
|
||
|
|
||
|
for name, terr in pairs( map.territory ) do
|
||
|
y( statusString:format( filename, "radar", name, tile, #tiles ), tiles[tile] )
|
||
|
lg.setColor(
|
||
|
0.9 + terr.colour[1],
|
||
|
0.9 + terr.colour[2],
|
||
|
0.9 + terr.colour[3],
|
||
|
1 / 6 )
|
||
|
lg.draw( terr.img, 0, 0, 0, scale, scale )
|
||
|
end
|
||
|
|
||
|
--dilate placeable land area by 45 degrees (sub launch radius)
|
||
|
dilateShader:send( "radius", math.floor( 512 * 45 / 360 ) )
|
||
|
for name, terr in pairs( map.territory ) do
|
||
|
y( statusString:format( filename, "sub", name, tile, #tiles ), tiles[tile] )
|
||
|
lg.setColor(
|
||
|
0.9 + terr.colour[1],
|
||
|
0.9 + terr.colour[2],
|
||
|
0.9 + terr.colour[3],
|
||
|
1 / 12 )
|
||
|
lg.draw( terr.img, 0, 0, 0, scale, scale )
|
||
|
end
|
||
|
end
|
||
|
|
||
|
lg.setCanvas( finalCanvas )
|
||
|
lg.setScissor()
|
||
|
lg.setShader()
|
||
|
lg.clear( 0, 0, 0, 1 )
|
||
|
lg.setColor( 1, 1, 1, 1 )
|
||
|
lg.draw( canvas )
|
||
|
lg.pop( "all" )
|
||
|
|
||
|
coroutine.yield( ("%s: encoding image data"):format( filename ))
|
||
|
|
||
|
return bmp.blur( finalCanvas:newImageData() )
|
||
|
end
|
||
|
|
||
|
|
||
|
|
||
|
local t = {}
|
||
|
|
||
|
function t:save( )
|
||
|
return renderRadar( self.map, self.filename )
|
||
|
end
|
||
|
|
||
|
function t.load( filename, map )
|
||
|
t.filename = filename
|
||
|
t.map = map
|
||
|
return t
|
||
|
end
|
||
|
|
||
|
function t.draw()
|
||
|
lg.setScissor()
|
||
|
return lg.draw( canvas )
|
||
|
end
|
||
|
|
||
|
return t
|