107 lines
3.5 KiB
Lua
107 lines
3.5 KiB
Lua
--- @class Render
|
|
--- @field textures table<string, love.Canvas>
|
|
local render = {
|
|
textures = {}
|
|
}
|
|
|
|
function render:clear()
|
|
local weather = Tree.level.weather
|
|
local txs = self.textures
|
|
love.graphics.setCanvas(txs.shadowLayer)
|
|
love.graphics.clear()
|
|
love.graphics.setCanvas(txs.spriteLayer)
|
|
love.graphics.clear()
|
|
love.graphics.setCanvas(txs.spriteLightLayer)
|
|
love.graphics.clear(weather.skyLight.x, weather.skyLight.y, weather.skyLight.z)
|
|
love.graphics.setCanvas(txs.floorLayer)
|
|
love.graphics.clear()
|
|
love.graphics.setCanvas(txs.lightLayer)
|
|
love.graphics.clear(weather.skyLight.x, weather.skyLight.y, weather.skyLight.z)
|
|
love.graphics.setCanvas(txs.overlayLayer)
|
|
love.graphics.clear()
|
|
end
|
|
|
|
function render:free()
|
|
for _, tx in pairs(self.textures) do
|
|
tx:release()
|
|
end
|
|
self.textures = nil
|
|
end
|
|
|
|
--- TODO: это используется для блюра, должно кэшироваться и поддерживать ресайз
|
|
|
|
function render:applyBlur(input, radius)
|
|
local blurShader = Tree.assets.files.shaders.blur
|
|
|
|
-- Горизонтальный проход
|
|
blurShader:send("direction", { 1.0, 0.0 })
|
|
blurShader:send("radius", radius)
|
|
|
|
self.textures.tmp1:renderTo(function()
|
|
love.graphics.clear()
|
|
love.graphics.setShader(blurShader)
|
|
love.graphics.draw(input)
|
|
love.graphics.setShader()
|
|
end)
|
|
|
|
-- Вертикальный проход
|
|
self.textures.tmp2:renderTo(
|
|
function()
|
|
love.graphics.clear()
|
|
love.graphics.setShader(blurShader)
|
|
blurShader:send("direction", { 0.0, 1.0 })
|
|
love.graphics.draw(self.textures.tmp1)
|
|
love.graphics.setShader()
|
|
end
|
|
)
|
|
return self.textures.tmp2
|
|
end
|
|
|
|
function render:draw()
|
|
-- пол -> тени -> спрайты -> свет -> оверлей
|
|
local weather = Tree.level.weather
|
|
local txs = self.textures
|
|
love.graphics.setCanvas(txs.lightLayer)
|
|
love.graphics.draw(self:applyBlur(txs.shadowLayer, 4 * Tree.level.camera.scale))
|
|
love.graphics.setCanvas()
|
|
|
|
-- self.lightLayer:newImageData():encode("png", "lightLayer.png")
|
|
-- os.exit(0)
|
|
|
|
local lightShader = Tree.assets.files.shaders.light_postprocess
|
|
lightShader:send("scene", txs.floorLayer)
|
|
lightShader:send("light", self:applyBlur(txs.lightLayer, 2))
|
|
lightShader:send("ambient", { weather.ambientLight.x, weather.ambientLight.y, weather.ambientLight.z })
|
|
love.graphics.setShader(lightShader)
|
|
love.graphics.draw(txs.floorLayer)
|
|
|
|
|
|
lightShader:send("scene", txs.spriteLayer)
|
|
lightShader:send("light", txs.spriteLightLayer)
|
|
love.graphics.draw(txs.spriteLayer)
|
|
love.graphics.setShader()
|
|
|
|
love.graphics.draw(txs.overlayLayer)
|
|
end
|
|
|
|
---@param params {w: number?, h: number?}
|
|
---@return table|Render
|
|
local function new(params)
|
|
local w = params.w or love.graphics.getWidth()
|
|
local h = params.h or love.graphics.getHeight()
|
|
return setmetatable({
|
|
textures = {
|
|
shadowLayer = love.graphics.newCanvas(w, h),
|
|
spriteLayer = love.graphics.newCanvas(w, h),
|
|
spriteLightLayer = love.graphics.newCanvas(w, h),
|
|
floorLayer = love.graphics.newCanvas(w, h),
|
|
overlayLayer = love.graphics.newCanvas(w, h),
|
|
lightLayer = love.graphics.newCanvas(w, h),
|
|
tmp1 = love.graphics.newCanvas(w, h),
|
|
tmp2 = love.graphics.newCanvas(w, h),
|
|
}
|
|
}, { __index = render })
|
|
end
|
|
|
|
return { new = new }
|