--- @class Render --- @field textures table 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 }