diff --git a/lib/character/behaviors/light.lua b/lib/character/behaviors/light.lua index c282f7f..9e08c35 100644 --- a/lib/character/behaviors/light.lua +++ b/lib/character/behaviors/light.lua @@ -25,7 +25,7 @@ end function behavior:draw() Tree.level.camera:attach() - love.graphics.setCanvas(Tree.level.render.lightLayer) + love.graphics.setCanvas(Tree.level.render.textures.lightLayer) local shader = Tree.assets.files.shaders.light shader:send("color", { self.color.x, self.color.y, self.color.z }) shader:send("time", love.timer.getTime() + self.seed) diff --git a/lib/character/behaviors/shadowcaster.lua b/lib/character/behaviors/shadowcaster.lua index dbbf915..7e3f0eb 100644 --- a/lib/character/behaviors/shadowcaster.lua +++ b/lib/character/behaviors/shadowcaster.lua @@ -22,7 +22,7 @@ function behavior:draw() end Tree.level.camera:attach() - love.graphics.setCanvas(Tree.level.render.shadowLayer) + love.graphics.setCanvas(Tree.level.render.textures.shadowLayer) love.graphics.push() love.graphics.setColor(0, 0, 0, 1) love.graphics.translate(position.x, position.y) @@ -34,7 +34,7 @@ function behavior:draw() return end - love.graphics.setCanvas(Tree.level.render.spriteLightLayer) + love.graphics.setCanvas(Tree.level.render.textures.spriteLightLayer) love.graphics.setBlendMode("add") for _, light in ipairs(lights) do local lightPos = light:has(Tree.behaviors.light).position diff --git a/lib/character/behaviors/sprite.lua b/lib/character/behaviors/sprite.lua index 32ac8e0..bc8fe9a 100644 --- a/lib/character/behaviors/sprite.lua +++ b/lib/character/behaviors/sprite.lua @@ -46,7 +46,7 @@ function sprite:draw() local ppm = Tree.level.camera.pixelsPerMeter local position = map.displayedPosition + Vec3 { 0.5, 0.5 } - love.graphics.setCanvas(Tree.level.render.spriteLayer) + love.graphics.setCanvas(Tree.level.render.textures.spriteLayer) Tree.level.camera:attach() love.graphics.setColor(1, 1, 1) diff --git a/lib/level/grid/tile_grid.lua b/lib/level/grid/tile_grid.lua index 2294e33..1a89a10 100644 --- a/lib/level/grid/tile_grid.lua +++ b/lib/level/grid/tile_grid.lua @@ -13,7 +13,7 @@ local function new(type, template, size) end function map:draw() - love.graphics.setCanvas(Tree.level.render.floorLayer) + love.graphics.setCanvas(Tree.level.render.textures.floorLayer) Tree.level.camera:attach() utils.each(self.__grid, function(el) el:draw() diff --git a/lib/level/level.lua b/lib/level/level.lua index 2023691..13be418 100644 --- a/lib/level/level.lua +++ b/lib/level/level.lua @@ -27,8 +27,8 @@ local function new(type, template) selector = (require "lib.level.selector").new(), camera = (require "lib.level.camera").new(), turnOrder = (require "lib.level.turn_order").new(), - render = (require "lib.level.render").new(), - weather = (require "lib.level.weather").new { ambientLight = Vec3 { 0.36, 0.42, 0.6 }, skyLight = Vec3 { 0.9, 0.9, 0.9 } } + render = (require "lib.level.render").new {}, + weather = (require "lib.level.weather").new { ambientLight = Vec3 { 0.36, 0.42, 0.6 }, skyLight = Vec3 {} } }, level) end diff --git a/lib/level/render.lua b/lib/level/render.lua index a88ea2e..5888888 100644 --- a/lib/level/render.lua +++ b/lib/level/render.lua @@ -1,40 +1,43 @@ --- @class Render ---- @field shadowLayer love.Canvas ---- @field spriteLayer love.Canvas ---- @field spriteLightLayer love.Canvas ---- @field floorLayer love.Canvas ---- @field lightLayer love.Canvas ---- @field overlayLayer love.Canvas -local render = {} -render.__index = render +--- @field textures table +local render = { + textures = {} +} function render:clear() local weather = Tree.level.weather - love.graphics.setCanvas(self.shadowLayer) + local txs = self.textures + love.graphics.setCanvas(txs.shadowLayer) love.graphics.clear() - love.graphics.setCanvas(self.spriteLayer) + love.graphics.setCanvas(txs.spriteLayer) love.graphics.clear() - love.graphics.setCanvas(self.spriteLightLayer) + love.graphics.setCanvas(txs.spriteLightLayer) love.graphics.clear(weather.skyLight.x, weather.skyLight.y, weather.skyLight.z) - love.graphics.setCanvas(self.floorLayer) + love.graphics.setCanvas(txs.floorLayer) love.graphics.clear() - love.graphics.setCanvas(self.lightLayer) + love.graphics.setCanvas(txs.lightLayer) love.graphics.clear(weather.skyLight.x, weather.skyLight.y, weather.skyLight.z) - love.graphics.setCanvas(self.overlayLayer) + 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: это используется для блюра, должно кэшироваться и поддерживать ресайз -local tmp1 = love.graphics.newCanvas(1280, 720) -local tmp2 = love.graphics.newCanvas(1280, 720) -local function applyBlur(input, radius) + +function render:applyBlur(input, radius) local blurShader = Tree.assets.files.shaders.blur -- Горизонтальный проход blurShader:send("direction", { 1.0, 0.0 }) blurShader:send("radius", radius) - tmp1:renderTo(function() + self.textures.tmp1:renderTo(function() love.graphics.clear() love.graphics.setShader(blurShader) love.graphics.draw(input) @@ -42,53 +45,62 @@ local function applyBlur(input, radius) end) -- Вертикальный проход - tmp2:renderTo( + self.textures.tmp2:renderTo( function() love.graphics.clear() love.graphics.setShader(blurShader) blurShader:send("direction", { 0.0, 1.0 }) - love.graphics.draw(tmp1) + love.graphics.draw(self.textures.tmp1) love.graphics.setShader() end ) - return tmp2 + return self.textures.tmp2 end function render:draw() -- пол -> тени -> спрайты -> свет -> оверлей local weather = Tree.level.weather - love.graphics.setCanvas(self.lightLayer) - love.graphics.draw(applyBlur(self.shadowLayer, 4 * Tree.level.camera.scale)) + 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", self.floorLayer) - lightShader:send("light", self.lightLayer) + 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(self.floorLayer) + love.graphics.draw(txs.floorLayer) - lightShader:send("scene", self.spriteLayer) - lightShader:send("light", self.spriteLightLayer) - love.graphics.draw(self.spriteLayer) + lightShader:send("scene", txs.spriteLayer) + lightShader:send("light", txs.spriteLightLayer) + love.graphics.draw(txs.spriteLayer) love.graphics.setShader() - love.graphics.draw(self.overlayLayer) + love.graphics.draw(txs.overlayLayer) end -local function new() +---@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({ - shadowLayer = love.graphics.newCanvas(1280, 720), - spriteLayer = love.graphics.newCanvas(1280, 720), - spriteLightLayer = love.graphics.newCanvas(1280, 720), - floorLayer = love.graphics.newCanvas(1280, 720), - overlayLayer = love.graphics.newCanvas(1280, 720), - lightLayer = love.graphics.newCanvas(1280, 720) - }, render) + 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 } diff --git a/lib/spellbook.lua b/lib/spellbook.lua index 11160f1..311e5a7 100644 --- a/lib/spellbook.lua +++ b/lib/spellbook.lua @@ -69,7 +69,7 @@ function walk:draw() if not self.path then return end --- Это отрисовка пути персонажа к мышке Tree.level.camera:attach() - love.graphics.setCanvas(Tree.level.render.overlayLayer) + love.graphics.setCanvas(Tree.level.render.textures.overlayLayer) love.graphics.setColor(0.6, 0.75, 0.5) for p in self.path:values() do love.graphics.circle("fill", p.x + 0.45, p.y + 0.45, 0.1) diff --git a/main.lua b/main.lua index 506dbb1..681f988 100644 --- a/main.lua +++ b/main.lua @@ -1,14 +1,17 @@ -- CameraLoader = require 'lib/camera' local character = require "lib/character/character" -require "lib/tree" -local testLayout = require "lib.simple_ui.level.layout" +local testLayout function love.conf(t) t.console = true end function love.load() + love.window.setMode(1280, 720, { resizable = true, msaa = 4, vsync = true }) + require "lib/tree" -- важно это сделать после настройки окна + testLayout = require "lib.simple_ui.level.layout" + local chars = { character.spawn("Foodor") :addBehavior { @@ -64,7 +67,6 @@ function love.load() Tree.level.turnOrder:endRound() print("Now playing:", Tree.level.turnOrder.current) - love.window.setMode(1280, 720, { resizable = true, msaa = 4, vsync = true }) end local lt = "0" @@ -116,3 +118,10 @@ function love.draw() local t2 = love.timer.getTime() dt = string.format("%.3f", (t2 - t1) * 1000) end + +function love.resize(w, h) + local render = Tree.level.render + if not render then return end + render:free() + Tree.level.render = (require "lib.level.render").new { w, h } +end