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 <q3k@hackerspace.pl>
diff --git a/hswaw/signage/nodes/shadertoy.lua b/hswaw/signage/nodes/shadertoy.lua
index 871ef12..52c8f31 100644
--- a/hswaw/signage/nodes/shadertoy.lua
+++ b/hswaw/signage/nodes/shadertoy.lua
@@ -5,6 +5,7 @@
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 @@
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 @@
}
]]
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 @@
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 @@
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 @@
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