resolve '#pragma include "...path..."' directives
s-ol
1 year, 10 months ago
103 | 103 | |
104 | 104 | const shader_file = try fs.cwd().openFile(config.fragment, .{}); |
105 | 105 | var last_stat = try shader_file.stat(); |
106 | try reloadShader(&main_program, shader_file, last_stat.size); | |
106 | try reloadShader(&main_program, shader_file, config.fragment, last_stat.size); | |
107 | 107 | |
108 | 108 | var cache = gl.UniformCache.init(std.heap.c_allocator, &main_program); |
109 | 109 | defer cache.deinit(); |
110 | 110 | |
111 | 111 | const control = try ctrl.ControlServer.init(&arena.allocator, config.osc, &cache); |
112 | 112 | defer control.destroy(); |
113 | ||
114 | _ = try cache.get("radius\x00"); | |
115 | 113 | |
116 | 114 | while (c.glfwWindowShouldClose(window) == c.GL_FALSE) { |
117 | 115 | c.glfwMakeContextCurrent(window); |
123 | 121 | |
124 | 122 | const stat = try shader_file.stat(); |
125 | 123 | if (stat.mtime > last_stat.mtime) { |
126 | try reloadShader(&main_program, shader_file, stat.size); | |
124 | try reloadShader(&main_program, shader_file, config.fragment, stat.size); | |
127 | 125 | try cache.refresh(); |
128 | 126 | last_stat = stat; |
129 | 127 | } |
153 | 151 | } |
154 | 152 | } |
155 | 153 | |
156 | fn reloadShader(current: *gl.ShaderProgram, frag_file: fs.File, size: u64) !void { | |
157 | var frag_source = try c_allocator.alloc(u8, @intCast(usize, size)); | |
154 | // given a file and the directory it is in, resolve references | |
155 | fn loadFile(writer: anytype, dir: []const u8, filename: []const u8) !void { | |
156 | const file_dir = try std.fs.path.resolve(c_allocator, &[_][]const u8{ | |
157 | dir, | |
158 | std.fs.path.dirname(filename) orelse "", | |
159 | }); | |
160 | defer c_allocator.free(file_dir); | |
161 | ||
162 | const file_path = try std.fs.path.resolve(c_allocator, &[_][]const u8{ dir, filename }); | |
163 | defer c_allocator.free(file_path); | |
164 | ||
165 | var file = try fs.openFileAbsolute(file_path, .{}); | |
166 | defer file.close(); | |
167 | var reader = file.reader(); | |
168 | ||
169 | var buf: [1024]u8 = undefined; | |
170 | while (try reader.readUntilDelimiterOrEof(&buf, '\n')) |line| { | |
171 | if (std.mem.startsWith(u8, line, "#pragma ")) { | |
172 | var parts = std.mem.split(line, " "); | |
173 | _ = parts.next(); | |
174 | const pragma = parts.next().?; | |
175 | ||
176 | if (std.mem.eql(u8, pragma, "include")) { | |
177 | var include_path = parts.next().?; | |
178 | if (include_path[0] != '"' or include_path[include_path.len - 1] != '"') { | |
179 | std.debug.warn("Invalid #pragma directive '{}'\n", .{line}); | |
180 | continue; | |
181 | } | |
182 | include_path = include_path[1 .. include_path.len - 1]; | |
183 | ||
184 | loadFile(writer, file_dir, include_path) catch unreachable; | |
185 | ||
186 | continue; | |
187 | } else { | |
188 | std.debug.warn("Unknown #pragma directive '{}'\n", .{pragma}); | |
189 | } | |
190 | } | |
191 | ||
192 | _ = try writer.write(line); | |
193 | _ = try writer.write("\n"); | |
194 | } | |
195 | } | |
196 | ||
197 | fn reloadShader(current: *gl.ShaderProgram, frag_file: fs.File, frag_filename: []const u8, size: u64) !void { | |
198 | var buffer = try std.ArrayList(u8).initCapacity(c_allocator, @intCast(usize, size)); | |
199 | var writer = buffer.writer(); | |
200 | errdefer buffer.deinit(); | |
201 | ||
202 | try loadFile(buffer.writer(), "", frag_filename); | |
203 | ||
204 | const frag_source = buffer.toOwnedSlice(); | |
158 | 205 | defer c_allocator.free(frag_source); |
159 | try frag_file.seekTo(0); | |
160 | const length = try frag_file.read(frag_source); | |
161 | 206 | |
162 | 207 | const vert_source = |
163 | 208 | \\#version 330 core |