From 6b21c1572782351cac03b4d692d1db9443b0419f Mon Sep 17 00:00:00 2001 From: Cruor Date: Fri, 22 Jul 2022 14:58:02 +0200 Subject: [PATCH] Layer visibility can now be turned on/off 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 --- src/celeste_render.lua | 99 +++++++++++++++++++++++++++++++----------- src/loaded_state.lua | 39 +++++++++++++++++ src/scenes/editor.lua | 2 +- src/snapshot_utils.lua | 2 +- src/tool_utils.lua | 2 +- 5 files changed, 115 insertions(+), 29 deletions(-) diff --git a/src/celeste_render.lua b/src/celeste_render.lua index 6129f753..87cbe464 100644 --- a/src/celeste_render.lua +++ b/src/celeste_render.lua @@ -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 @@ -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 @@ -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 @@ -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 = {} @@ -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 @@ -750,7 +768,9 @@ function celesteRender.getRoomBatches(room, viewport) end else - done = false + if layerVisible then + done = false + end end end @@ -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 @@ -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] @@ -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 @@ -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 @@ -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 @@ -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) @@ -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 diff --git a/src/loaded_state.lua b/src/loaded_state.lua index e8b58905..ee8373f3 100644 --- a/src/loaded_state.lua +++ b/src/loaded_state.lua @@ -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 @@ -252,4 +288,7 @@ state.selectedRooms = {} -- The viewport for the map renderer state.viewport = viewportHandler.viewport +-- Rendering information about layers +state.layerInformation = {} + return state \ No newline at end of file diff --git a/src/scenes/editor.lua b/src/scenes/editor.lua index 06082541..52bcecb6 100644 --- a/src/scenes/editor.lua +++ b/src/scenes/editor.lua @@ -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 diff --git a/src/snapshot_utils.lua b/src/snapshot_utils.lua index 78d94bb6..dea1f23b 100644 --- a/src/snapshot_utils.lua +++ b/src/snapshot_utils.lua @@ -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 diff --git a/src/tool_utils.lua b/src/tool_utils.lua index 9b1a2e84..3872731d 100644 --- a/src/tool_utils.lua +++ b/src/tool_utils.lua @@ -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(...)