blob: 52c8f3160c99e4d4e307a46e33c148290d50b508 [file] [log] [blame]
Serge Bazanski18c1a262022-07-07 14:24:53 +02001local node = Node:extend('nodes.shadertoy', {})
2
3local smallFont = love.graphics.newFont('fonts/Lato-Light.ttf', 20)
4
5function node:init(config)
6 node.super.init(self, config)
7
Piotr Dobrowolskia7dbf252022-07-08 00:21:37 +02008 self.prevShaderData = nil
Serge Bazanski18c1a262022-07-07 14:24:53 +02009 self.path = self.path or "test.glsl"
10 self.resolution = self.resolution or {1280, 720}
11
12 self:loadShader()
13end
14
15function node:beforeEnter()
16 self:loadShader()
Piotr Dobrowolskia7dbf252022-07-08 00:21:37 +020017 if self.iSystem and self.iSystem.iGlobalTime then
18 print("Resetting time")
19 self.iSystem.iGlobalTime = 0
20 end
Serge Bazanski18c1a262022-07-07 14:24:53 +020021end
22
23function node:loadShader()
24 local iSystem = {}
25 local header = ""
26 local ender=[[
27 vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 pixel_coords) {
28 vec2 fragCoord = texture_coords * iResolution.xy;
29 mainImage( color, fragCoord );
30 return color;
31 }
32 ]]
33 local file = io.open(self.path, "r")
Piotr Dobrowolskia7dbf252022-07-08 00:21:37 +020034
35 if file == nil then
36 self.shaderLoadError = self.path .. " does not exist"
37 return
38 end
39
Serge Bazanski18c1a262022-07-07 14:24:53 +020040 local shaderData = file:read("*all")
41
Piotr Dobrowolskia7dbf252022-07-08 00:21:37 +020042 if self.prevShaderData == shaderData then
43 print("Shader didn't change, not reloading")
44 return
45 end
46
47 self.prevShaderData = shaderData
Serge Bazanski18c1a262022-07-07 14:24:53 +020048 shaderData = string.gsub(shaderData,"texture2D","Texel")
49 shaderData = string.gsub(shaderData,"iTime","iGlobalTime")
50 shaderData = string.gsub(shaderData,"precision highp float;","")
51
52 if string.find(shaderData,"iGlobalTime") then
53 iSystem.iGlobalTime=0
54 if not string.find(shaderData,"number iGlobalTime") then
55 header="extern number iGlobalTime;\n"..header
56 end
57 end
58
59 -- TODO
60 -- if string.find(shaderData,"iChannel") then
61 -- iSystem.iChannel={}
62 -- for k,v in pairs(shaderChannel) do
63 -- header="extern Image iChannel"..k..";\n"..header
64 -- end
65 -- end
66
67 if string.find(shaderData,"iMouse") then
68 iSystem.iMouse = {0, 0, -1, -1}
69 header = "extern vec4 iMouse;\n"..header
70 end
71
72 if string.find(shaderData,"iResolution") then
73 iSystem.iResolution = {self.resolution[1], self.resolution[2],1}
74 header = "extern vec3 iResolution;\n"..header
75 end
76
77 shaderData = header..shaderData
78 if not string.find(shaderData,"vec4 effect") then
79 shaderData = shaderData.."\n"..ender
80 end
81
Piotr Dobrowolskia7dbf252022-07-08 00:21:37 +020082 print("Shader loaded, compiling...")
Serge Bazanski18c1a262022-07-07 14:24:53 +020083
84 self.shaderLoadError = nil
Piotr Dobrowolskia7dbf252022-07-08 00:21:37 +020085 shaderLoaded, shader = pcall(love.graphics.newShader, shaderData)
Serge Bazanski18c1a262022-07-07 14:24:53 +020086 if not shaderLoaded then
Piotr Dobrowolskia7dbf252022-07-08 00:21:37 +020087 print("Shader compile failed:", shader)
88 self.shaderLoadError = shader
Serge Bazanski18c1a262022-07-07 14:24:53 +020089 else
Piotr Dobrowolskia7dbf252022-07-08 00:21:37 +020090 self.shader = shader
91
Serge Bazanski18c1a262022-07-07 14:24:53 +020092 if iSystem.iResolution then
93 self.shader:send("iResolution",iSystem.iResolution)
94 end
95
96 self.iSystem = iSystem
97 self.canvas = love.graphics.newCanvas(self.resolution[1], self.resolution[2])
98 self.renderCanvas = love.graphics.newCanvas(self.resolution[1], self.resolution[2])
99 end
100end
101
102function node:update(dt)
103 if self.shader ~= nil then
104 if self.iSystem.iGlobalTime then
105 self.iSystem.iGlobalTime=self.iSystem.iGlobalTime+dt
106 self.shader:send("iGlobalTime", self.iSystem.iGlobalTime)
107 end
108 end
109end
110
111function node:render()
112 love.graphics.setColor( 0, 0, 0 )
113 love.graphics.rectangle("fill", 0, 0, love.graphics.getWidth(), love.graphics.getHeight())
114
Piotr Dobrowolskia7dbf252022-07-08 00:21:37 +0200115 if self.shader ~= nil then
Serge Bazanski18c1a262022-07-07 14:24:53 +0200116 oldCanvas = love.graphics.getCanvas( )
117 love.graphics.setColor( 1.0, 1.0, 1.0 )
118 self.canvas:renderTo(function ()
119 love.graphics.setShader(self.shader)
120 love.graphics.draw(self.renderCanvas)
121 love.graphics.setShader()
122 end)
123 love.graphics.setCanvas(oldCanvas)
124
125 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])
126 end
Piotr Dobrowolskia7dbf252022-07-08 00:21:37 +0200127
128 if self.shaderLoadError ~= nil then
129 love.graphics.setColor(1.0, 0.0, 0.0, 1.0)
130 love.graphics.setFont(smallFont)
131 love.graphics.printf(self.shaderLoadError, 0, 0.1*love.graphics.getHeight(), love.graphics.getWidth(), 'left');
132 end
Serge Bazanski18c1a262022-07-07 14:24:53 +0200133end
134
135return node