allow window resizing TODO: get rid of fullscreen rendering

This commit is contained in:
PeaAshMeter 2026-01-14 21:35:23 +03:00
parent e6754048f6
commit 4aa470f443
8 changed files with 70 additions and 49 deletions

View File

@ -25,7 +25,7 @@ end
function behavior:draw() function behavior:draw()
Tree.level.camera:attach() 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 local shader = Tree.assets.files.shaders.light
shader:send("color", { self.color.x, self.color.y, self.color.z }) shader:send("color", { self.color.x, self.color.y, self.color.z })
shader:send("time", love.timer.getTime() + self.seed) shader:send("time", love.timer.getTime() + self.seed)

View File

@ -22,7 +22,7 @@ function behavior:draw()
end end
Tree.level.camera:attach() Tree.level.camera:attach()
love.graphics.setCanvas(Tree.level.render.shadowLayer) love.graphics.setCanvas(Tree.level.render.textures.shadowLayer)
love.graphics.push() love.graphics.push()
love.graphics.setColor(0, 0, 0, 1) love.graphics.setColor(0, 0, 0, 1)
love.graphics.translate(position.x, position.y) love.graphics.translate(position.x, position.y)
@ -34,7 +34,7 @@ function behavior:draw()
return return
end end
love.graphics.setCanvas(Tree.level.render.spriteLightLayer) love.graphics.setCanvas(Tree.level.render.textures.spriteLightLayer)
love.graphics.setBlendMode("add") love.graphics.setBlendMode("add")
for _, light in ipairs(lights) do for _, light in ipairs(lights) do
local lightPos = light:has(Tree.behaviors.light).position local lightPos = light:has(Tree.behaviors.light).position

View File

@ -46,7 +46,7 @@ function sprite:draw()
local ppm = Tree.level.camera.pixelsPerMeter local ppm = Tree.level.camera.pixelsPerMeter
local position = map.displayedPosition + Vec3 { 0.5, 0.5 } 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() Tree.level.camera:attach()
love.graphics.setColor(1, 1, 1) love.graphics.setColor(1, 1, 1)

View File

@ -13,7 +13,7 @@ local function new(type, template, size)
end end
function map:draw() function map:draw()
love.graphics.setCanvas(Tree.level.render.floorLayer) love.graphics.setCanvas(Tree.level.render.textures.floorLayer)
Tree.level.camera:attach() Tree.level.camera:attach()
utils.each(self.__grid, function(el) utils.each(self.__grid, function(el)
el:draw() el:draw()

View File

@ -27,8 +27,8 @@ local function new(type, template)
selector = (require "lib.level.selector").new(), selector = (require "lib.level.selector").new(),
camera = (require "lib.level.camera").new(), camera = (require "lib.level.camera").new(),
turnOrder = (require "lib.level.turn_order").new(), turnOrder = (require "lib.level.turn_order").new(),
render = (require "lib.level.render").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 } } weather = (require "lib.level.weather").new { ambientLight = Vec3 { 0.36, 0.42, 0.6 }, skyLight = Vec3 {} }
}, level) }, level)
end end

View File

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

View File

@ -69,7 +69,7 @@ function walk:draw()
if not self.path then return end if not self.path then return end
--- Это отрисовка пути персонажа к мышке --- Это отрисовка пути персонажа к мышке
Tree.level.camera:attach() 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) love.graphics.setColor(0.6, 0.75, 0.5)
for p in self.path:values() do for p in self.path:values() do
love.graphics.circle("fill", p.x + 0.45, p.y + 0.45, 0.1) love.graphics.circle("fill", p.x + 0.45, p.y + 0.45, 0.1)

View File

@ -1,14 +1,17 @@
-- CameraLoader = require 'lib/camera' -- CameraLoader = require 'lib/camera'
local character = require "lib/character/character" local character = require "lib/character/character"
require "lib/tree" local testLayout
local testLayout = require "lib.simple_ui.level.layout"
function love.conf(t) function love.conf(t)
t.console = true t.console = true
end end
function love.load() 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 = { local chars = {
character.spawn("Foodor") character.spawn("Foodor")
:addBehavior { :addBehavior {
@ -64,7 +67,6 @@ function love.load()
Tree.level.turnOrder:endRound() Tree.level.turnOrder:endRound()
print("Now playing:", Tree.level.turnOrder.current) print("Now playing:", Tree.level.turnOrder.current)
love.window.setMode(1280, 720, { resizable = true, msaa = 4, vsync = true })
end end
local lt = "0" local lt = "0"
@ -116,3 +118,10 @@ function love.draw()
local t2 = love.timer.getTime() local t2 = love.timer.getTime()
dt = string.format("%.3f", (t2 - t1) * 1000) dt = string.format("%.3f", (t2 - t1) * 1000)
end 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