From a7dbf255883d6a217f9735c55f3dbbe915a0fb9e Mon Sep 17 00:00:00 2001 From: Piotr Dobrowolski Date: Fri, 8 Jul 2022 00:21:37 +0200 Subject: [PATCH] hswaw/signage: reuse compiled shader, better error handling Shader will now only be recompiled whenever its code changes. This helps with hangs on node transitions on underpowered devices. If shader reload failed an error message will now be rendered over an existing shader. File load errors are properly handled. Change-Id: I97a75b85620614252040b76e4f3aaa0ea1f0a7e3 Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/1337 Reviewed-by: q3k --- hswaw/signage/nodes/shadertoy.lua | 42 ++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/hswaw/signage/nodes/shadertoy.lua b/hswaw/signage/nodes/shadertoy.lua index 871ef12a..52c8f316 100644 --- a/hswaw/signage/nodes/shadertoy.lua +++ b/hswaw/signage/nodes/shadertoy.lua @@ -5,6 +5,7 @@ local smallFont = love.graphics.newFont('fonts/Lato-Light.ttf', 20) function node:init(config) node.super.init(self, config) + self.prevShaderData = nil self.path = self.path or "test.glsl" self.resolution = self.resolution or {1280, 720} @@ -13,6 +14,10 @@ end function node:beforeEnter() self:loadShader() + if self.iSystem and self.iSystem.iGlobalTime then + print("Resetting time") + self.iSystem.iGlobalTime = 0 + end end function node:loadShader() @@ -26,8 +31,20 @@ function node:loadShader() } ]] local file = io.open(self.path, "r") + + if file == nil then + self.shaderLoadError = self.path .. " does not exist" + return + end + local shaderData = file:read("*all") + if self.prevShaderData == shaderData then + print("Shader didn't change, not reloading") + return + end + + self.prevShaderData = shaderData shaderData = string.gsub(shaderData,"texture2D","Texel") shaderData = string.gsub(shaderData,"iTime","iGlobalTime") shaderData = string.gsub(shaderData,"precision highp float;","") @@ -62,16 +79,16 @@ function node:loadShader() shaderData = shaderData.."\n"..ender end - print('Shader loaded') + print("Shader loaded, compiling...") self.shaderLoadError = nil - shaderLoaded, self.shader = pcall(love.graphics.newShader, shaderData) + shaderLoaded, shader = pcall(love.graphics.newShader, shaderData) if not shaderLoaded then - print('Shader load failed:', self.shader) - self.shaderLoadError = self.shader - self.shader = nil + print("Shader compile failed:", shader) + self.shaderLoadError = shader else - print(shaderLoaded, self.shader) + self.shader = shader + if iSystem.iResolution then self.shader:send("iResolution",iSystem.iResolution) end @@ -95,12 +112,7 @@ function node:render() love.graphics.setColor( 0, 0, 0 ) love.graphics.rectangle("fill", 0, 0, love.graphics.getWidth(), love.graphics.getHeight()) - if self.shaderLoadError ~= nil then - print('render!') - love.graphics.setColor(1.0, 0.0, 0.0, 1.0) - love.graphics.setFont(smallFont) - love.graphics.printf(self.shaderLoadError, 0, 0.1*love.graphics.getHeight(), love.graphics.getWidth(), 'left'); - elseif self.shader ~= nil then + if self.shader ~= nil then oldCanvas = love.graphics.getCanvas( ) love.graphics.setColor( 1.0, 1.0, 1.0 ) self.canvas:renderTo(function () @@ -112,6 +124,12 @@ function node:render() love.graphics.draw(self.canvas,0,0,math.pi,love.graphics.getWidth() / self.resolution[1], love.graphics.getHeight() / self.resolution[2], self.resolution[1], self.resolution[2]) end + + if self.shaderLoadError ~= nil then + love.graphics.setColor(1.0, 0.0, 0.0, 1.0) + love.graphics.setFont(smallFont) + love.graphics.printf(self.shaderLoadError, 0, 0.1*love.graphics.getHeight(), love.graphics.getWidth(), 'left'); + end end return node