forked from hswaw/hscloud
136 lines
3.9 KiB
Lua
136 lines
3.9 KiB
Lua
local node = Node:extend('nodes.shadertoy', {})
|
|
|
|
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}
|
|
|
|
self:loadShader()
|
|
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()
|
|
local iSystem = {}
|
|
local header = ""
|
|
local ender=[[
|
|
vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 pixel_coords) {
|
|
vec2 fragCoord = texture_coords * iResolution.xy;
|
|
mainImage( color, fragCoord );
|
|
return color;
|
|
}
|
|
]]
|
|
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;","")
|
|
|
|
if string.find(shaderData,"iGlobalTime") then
|
|
iSystem.iGlobalTime=0
|
|
if not string.find(shaderData,"number iGlobalTime") then
|
|
header="extern number iGlobalTime;\n"..header
|
|
end
|
|
end
|
|
|
|
-- TODO
|
|
-- if string.find(shaderData,"iChannel") then
|
|
-- iSystem.iChannel={}
|
|
-- for k,v in pairs(shaderChannel) do
|
|
-- header="extern Image iChannel"..k..";\n"..header
|
|
-- end
|
|
-- end
|
|
|
|
if string.find(shaderData,"iMouse") then
|
|
iSystem.iMouse = {0, 0, -1, -1}
|
|
header = "extern vec4 iMouse;\n"..header
|
|
end
|
|
|
|
if string.find(shaderData,"iResolution") then
|
|
iSystem.iResolution = {self.resolution[1], self.resolution[2],1}
|
|
header = "extern vec3 iResolution;\n"..header
|
|
end
|
|
|
|
shaderData = header..shaderData
|
|
if not string.find(shaderData,"vec4 effect") then
|
|
shaderData = shaderData.."\n"..ender
|
|
end
|
|
|
|
print("Shader loaded, compiling...")
|
|
|
|
self.shaderLoadError = nil
|
|
shaderLoaded, shader = pcall(love.graphics.newShader, shaderData)
|
|
if not shaderLoaded then
|
|
print("Shader compile failed:", shader)
|
|
self.shaderLoadError = shader
|
|
else
|
|
self.shader = shader
|
|
|
|
if iSystem.iResolution then
|
|
self.shader:send("iResolution",iSystem.iResolution)
|
|
end
|
|
|
|
self.iSystem = iSystem
|
|
self.canvas = love.graphics.newCanvas(self.resolution[1], self.resolution[2])
|
|
self.renderCanvas = love.graphics.newCanvas(self.resolution[1], self.resolution[2])
|
|
end
|
|
end
|
|
|
|
function node:update(dt)
|
|
if self.shader ~= nil then
|
|
if self.iSystem.iGlobalTime then
|
|
self.iSystem.iGlobalTime=self.iSystem.iGlobalTime+dt
|
|
self.shader:send("iGlobalTime", self.iSystem.iGlobalTime)
|
|
end
|
|
end
|
|
end
|
|
|
|
function node:render()
|
|
love.graphics.setColor( 0, 0, 0 )
|
|
love.graphics.rectangle("fill", 0, 0, love.graphics.getWidth(), love.graphics.getHeight())
|
|
|
|
if self.shader ~= nil then
|
|
oldCanvas = love.graphics.getCanvas( )
|
|
love.graphics.setColor( 1.0, 1.0, 1.0 )
|
|
self.canvas:renderTo(function ()
|
|
love.graphics.setShader(self.shader)
|
|
love.graphics.draw(self.renderCanvas)
|
|
love.graphics.setShader()
|
|
end)
|
|
love.graphics.setCanvas(oldCanvas)
|
|
|
|
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
|