Skip to content

Commit

Permalink
Layer visibility can now be turned on/off
Browse files Browse the repository at this point in the history
This is stored in loaded_state, has helpers for changing layer visbility (and redrawing)
Celeste renderer now passes `state` around a bit more instead of only the viewport
Allows for more rendering options in the future, if needed
  • Loading branch information
Cruor committed Jul 22, 2022
1 parent 5686d56 commit 6b21c15
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 29 deletions.
99 changes: 73 additions & 26 deletions src/celeste_render.lua
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ function celesteRender.processTasks(state, calcTime, maxTasks, backgroundTime, b
end

function celesteRender.clearBatchingTasks()
-- TODO - Check if this should release the ongoing tasks or if Lua GC is good enough
batchingTasks = {}
end

Expand Down Expand Up @@ -170,9 +171,18 @@ function celesteRender.invalidateRoomCache(roomName, key)

if roomCache[roomName] then
if key then
celesteRender.releaseBatch(roomName, key)
if type(key) == "table" then
for _, k in ipairs(key) do
celesteRender.releaseBatch(roomName, k)

roomCache[roomName][key] = nil
roomCache[roomName][k] = nil
end

else
celesteRender.releaseBatch(roomName, key)

roomCache[roomName][key] = nil
end

else
for name, task in pairs(roomCache[roomName]) do
Expand Down Expand Up @@ -687,13 +697,15 @@ local depthBatchingFunctions = {
}

-- Force all non finished room batch tasks to finish
function celesteRender.forceRoomBatchRender(room, viewport)
function celesteRender.forceRoomBatchRender(room, state)
local viewport = state.viewport
for i, data in ipairs(depthBatchingFunctions) do
local description, key, func, depth = data[1], data[2], data[3], data[4]
local layerVisible = state.getLayerVisible(key)
local result = func(room, room[key], viewport)
local task = roomCache[room.name][key]

if not result and task then
if layerVisible and not result and task then
tasks.processTask(task)
end
end
Expand Down Expand Up @@ -722,9 +734,10 @@ local function addBatch(depthBatches, depth, batches)
end
end

function celesteRender.getRoomBatches(room, viewport)
function celesteRender.getRoomBatches(room, state)
local roomName = room.name
local cache = roomCache[roomName]
local viewport = state.viewport

if not cache then
cache = {}
Expand All @@ -737,7 +750,12 @@ function celesteRender.getRoomBatches(room, viewport)

for i, data in ipairs(depthBatchingFunctions) do
local description, key, func, depth = data[1], data[2], data[3], data[4]
local batches = func(room, room[key], viewport)
local layerVisible = state.getLayerVisible(key)
local batches

if layerVisible then
batches = func(room, room[key], viewport)
end

if batches then
if depth then
Expand All @@ -750,7 +768,9 @@ function celesteRender.getRoomBatches(room, viewport)
end

else
done = false
if layerVisible then
done = false
end
end
end

Expand Down Expand Up @@ -780,8 +800,8 @@ function celesteRender.getRoomBatches(room, viewport)
return cache.complete
end

local function drawRoomFromBatches(room, viewport, selected)
local orderedBatches = celesteRender.getRoomBatches(room, viewport)
local function drawRoomFromBatches(room, state, selected)
local orderedBatches = celesteRender.getRoomBatches(room, state)

if orderedBatches then
for depth, batch in ipairs(orderedBatches) do
Expand All @@ -793,8 +813,9 @@ local function drawRoomFromBatches(room, viewport, selected)
end

-- Return the canvas if it is ready, otherwise make a task for it
local function getRoomCanvas(room, viewport, selected)
local orderedBatches = celesteRender.getRoomBatches(room, viewport)
local function getRoomCanvas(room, state, selected)
local viewport = state.viewport
local orderedBatches = celesteRender.getRoomBatches(room, state)
local roomName = room.name

local cache = roomCache[roomName]
Expand Down Expand Up @@ -829,21 +850,46 @@ local function getRoomCanvas(room, viewport, selected)
end

-- Force the rooms canvas cache to be rendered
function celesteRender.forceRoomCanvasRender(room, viewport, selected)
local task, canvas = getRoomCanvas(room, viewport, selected)
function celesteRender.forceRoomCanvasRender(room, state, selected)
local viewport = state.viewport
local task, canvas = getRoomCanvas(room, state, selected)

if task and not canvas then
tasks.processTask(task)
end
end

function celesteRender.forceRedrawRoom(room, viewport, selected)
function celesteRender.forceRedrawRoom(room, state, selected)
local viewport = state.viewport

celesteRender.invalidateRoomCache(room)
celesteRender.forceRoomBatchRender(room, viewport)
celesteRender.forceRoomCanvasRender(room, viewport, selected)
celesteRender.forceRoomBatchRender(room, state)
celesteRender.forceRoomCanvasRender(room, state, selected)
end

function celesteRender.drawRooms(rooms, viewport, selectedItem, selectedItemType)
function celesteRender.forceRedrawVisibleRooms(rooms, state, selectedItem, selectedItemType)
local viewport = state.viewport

for _, room in ipairs(rooms) do
local roomVisible = viewportHandler.roomVisible(room, viewport)
local roomVisibleWidth, roomVisibleHeight = viewportHandler.getRoomVisibleSize(room, viewport)
local selected = room == selectedItem

if selectedItemType == "table" then
selected = selectedItem[room]
end

-- No need to redraw immidietly if only the borders are visible
if roomVisible and roomVisibleWidth > 2 and roomVisibleHeight > 2 then
celesteRender.forceRoomBatchRender(room, state)
celesteRender.forceRoomCanvasRender(room, state, selected)
end
end
end

function celesteRender.drawRooms(rooms, state, selectedItem, selectedItemType)
local viewport = state.viewport

for _, room in ipairs(rooms) do
local roomVisible = viewportHandler.roomVisible(room, viewport)
local selected = room == selectedItem
Expand All @@ -853,16 +899,17 @@ function celesteRender.drawRooms(rooms, viewport, selectedItem, selectedItemType
end

if ALLOW_NON_VISIBLE_BACKGROUND_DRAWING or roomVisible then
celesteRender.drawRoom(room, viewport, selected, roomVisible)
celesteRender.drawRoom(room, state, selected, roomVisible)
end
end
end

function celesteRender.drawRoom(room, viewport, selected, visible)
function celesteRender.drawRoom(room, state, selected, visible)
-- Getting the canvas starts background drawing tasks
-- This should start regardless of the room being visible or not
local redrawRoom = selected or ALWAYS_REDRAW_UNSELECTED_ROOMS
local canvas = not redrawRoom and getRoomCanvas(room, viewport, selected)
local viewport = state.viewport
local canvas = not redrawRoom and getRoomCanvas(room, state, selected)

if visible or selected then
local roomX = room.x or 0
Expand All @@ -883,7 +930,7 @@ function celesteRender.drawRoom(room, viewport, selected, visible)
end)

if redrawRoom then
drawRoomFromBatches(room, viewport, selected)
drawRoomFromBatches(room, state, selected)

else
if canvas then
Expand All @@ -904,10 +951,10 @@ end

-- Iterate over twice
-- Batch draw all selected and unselected fillers
function celesteRender.drawFillers(fillers, viewport, selectedItem, selectedItemType)
function celesteRender.drawFillers(fillers, state, selectedItem, selectedItemType)
local pr, pb, pg, pa = love.graphics.getColor()

local multipleSelections = selectedItemType == "table"
local viewport = state.viewport

-- Unselected fillers
love.graphics.setColor(colors.fillerColor)
Expand Down Expand Up @@ -947,15 +994,15 @@ function celesteRender.drawFiller(filler, viewport)
end

function celesteRender.drawMap(state)
if state.map then
if state and state.map then
local map = state.map
local viewport = state.viewport

if viewport.visible then
local selectedItem, selectedItemType = state.getSelectedItem()

celesteRender.drawFillers(map.fillers, viewport, selectedItem, selectedItemType)
celesteRender.drawRooms(map.rooms, viewport, selectedItem, selectedItemType)
celesteRender.drawFillers(map.fillers, state, selectedItem, selectedItemType)
celesteRender.drawRooms(map.rooms, state, selectedItem, selectedItemType)
end
end
end
Expand Down
39 changes: 39 additions & 0 deletions src/loaded_state.lua
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,42 @@ function state.getRoomByName(name)
end
end

function state.getLayerVisible(layer)
local info = state.layerInformation[layer]

if info then
if info.visible == nil then
return true
end

return info.visible
end

return true
end

function state.setLayerVisible(layer, visible, silent)
local info = state.layerInformation[layer]

if not info then
info = {}
state.layerInformation[layer] = info
end

info.visible = visible

if silent ~= false then
-- Clear target canvas and complete cache for all rooms
celesteRender.invalidateRoomCache(nil, {"canvas", "complete"})

-- Redraw any visible rooms
local selectedItem, selectedItemType = state.getSelectedItem()

celesteRender.clearBatchingTasks()
celesteRender.forceRedrawVisibleRooms(state.map.rooms, state, selectedItem, selectedItemType)
end
end

-- The currently loaded map
state.map = nil

Expand All @@ -252,4 +288,7 @@ state.selectedRooms = {}
-- The viewport for the map renderer
state.viewport = viewportHandler.viewport

-- Rendering information about layers
state.layerInformation = {}

return state
2 changes: 1 addition & 1 deletion src/scenes/editor.lua
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ function editorScene:editorMapTargetChanged(item, itemType, previousItem, previo
end

if shouldForceRedraw then
self.celesteRender.forceRedrawRoom(previousItem, self.viewerState.viewport, false)
self.celesteRender.forceRedrawRoom(previousItem, self.viewerState, false)
end
end

Expand Down
2 changes: 1 addition & 1 deletion src/snapshot_utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ local function redrawLayer(room, layer)
toolUtils.redrawTargetLayer(room, layer)

else
celesteRender.forceRedrawRoom(room, state.viewport, false)
celesteRender.forceRedrawRoom(room, state, false)
end
end

Expand Down
2 changes: 1 addition & 1 deletion src/tool_utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ function toolUtils.redrawTargetLayer(room, layer)
end

celesteRender.invalidateRoomCache(room, "complete")
celesteRender.forceRoomBatchRender(room, state.viewport)
celesteRender.forceRoomBatchRender(room, state)
end

function toolUtils.getPersistenceKey(...)
Expand Down

0 comments on commit 6b21c15

Please sign in to comment.