blob: 871ef12a0295046cac4b02499c3f25c6a4764e48 [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
8 self.path = self.path or "test.glsl"
9 self.resolution = self.resolution or {1280, 720}
10
11 self:loadShader()
12end
13
14function node:beforeEnter()
15 self:loadShader()
16end
17
18function node:loadShader()
19 local iSystem = {}
20 local header = ""
21 local ender=[[
22 vec4 effect(vec4 color, Image texture, vec2 texture_coords, vec2 pixel_coords) {
23 vec2 fragCoord = texture_coords * iResolution.xy;
24 mainImage( color, fragCoord );
25 return color;
26 }
27 ]]
28 local file = io.open(self.path, "r")
29 local shaderData = file:read("*all")
30
31 shaderData = string.gsub(shaderData,"texture2D","Texel")
32 shaderData = string.gsub(shaderData,"iTime","iGlobalTime")
33 shaderData = string.gsub(shaderData,"precision highp float;","")
34
35 if string.find(shaderData,"iGlobalTime") then
36 iSystem.iGlobalTime=0
37 if not string.find(shaderData,"number iGlobalTime") then
38 header="extern number iGlobalTime;\n"..header
39 end
40 end
41
42 -- TODO
43 -- if string.find(shaderData,"iChannel") then
44 -- iSystem.iChannel={}
45 -- for k,v in pairs(shaderChannel) do
46 -- header="extern Image iChannel"..k..";\n"..header
47 -- end
48 -- end
49
50 if string.find(shaderData,"iMouse") then
51 iSystem.iMouse = {0, 0, -1, -1}
52 header = "extern vec4 iMouse;\n"..header
53 end
54
55 if string.find(shaderData,"iResolution") then
56 iSystem.iResolution = {self.resolution[1], self.resolution[2],1}
57 header = "extern vec3 iResolution;\n"..header
58 end
59
60 shaderData = header..shaderData
61 if not string.find(shaderData,"vec4 effect") then
62 shaderData = shaderData.."\n"..ender
63 end
64
65 print('Shader loaded')
66
67 self.shaderLoadError = nil
68 shaderLoaded, self.shader = pcall(love.graphics.newShader, shaderData)
69 if not shaderLoaded then
70 print('Shader load failed:', self.shader)
71 self.shaderLoadError = self.shader
72 self.shader = nil
73 else
74 print(shaderLoaded, self.shader)
75 if iSystem.iResolution then
76 self.shader:send("iResolution",iSystem.iResolution)
77 end
78
79 self.iSystem = iSystem
80 self.canvas = love.graphics.newCanvas(self.resolution[1], self.resolution[2])
81 self.renderCanvas = love.graphics.newCanvas(self.resolution[1], self.resolution[2])
82 end
83end
84
85function node:update(dt)
86 if self.shader ~= nil then
87 if self.iSystem.iGlobalTime then
88 self.iSystem.iGlobalTime=self.iSystem.iGlobalTime+dt
89 self.shader:send("iGlobalTime", self.iSystem.iGlobalTime)
90 end
91 end
92end
93
94function node:render()
95 love.graphics.setColor( 0, 0, 0 )
96 love.graphics.rectangle("fill", 0, 0, love.graphics.getWidth(), love.graphics.getHeight())
97
98 if self.shaderLoadError ~= nil then
99 print('render!')
100 love.graphics.setColor(1.0, 0.0, 0.0, 1.0)
101 love.graphics.setFont(smallFont)
102 love.graphics.printf(self.shaderLoadError, 0, 0.1*love.graphics.getHeight(), love.graphics.getWidth(), 'left');
103 elseif self.shader ~= nil then
104 oldCanvas = love.graphics.getCanvas( )
105 love.graphics.setColor( 1.0, 1.0, 1.0 )
106 self.canvas:renderTo(function ()
107 love.graphics.setShader(self.shader)
108 love.graphics.draw(self.renderCanvas)
109 love.graphics.setShader()
110 end)
111 love.graphics.setCanvas(oldCanvas)
112
113 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])
114 end
115end
116
117return node