aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authors-ol <s-ol@users.noreply.github.com>2020-01-23 14:00:16 +0000
committers-ol <s-ol@users.noreply.github.com>2020-01-23 15:06:29 +0000
commit866fccb01e40ab11add47511c922ec2dd8f0454e (patch)
tree47cde0299aa8225860fc2bfee52b8abde329fad5
parentinitial commit (diff)
downloadglsl-view-866fccb01e40ab11add47511c922ec2dd8f0454e.tar.gz
glsl-view-866fccb01e40ab11add47511c922ec2dd8f0454e.zip
Code reorganisation
-rw-r--r--src/gl.zig255
-rw-r--r--src/main.zig92
-rw-r--r--src/output.zig31
-rw-r--r--src/shader.zig118
4 files changed, 347 insertions, 149 deletions
diff --git a/src/gl.zig b/src/gl.zig
new file mode 100644
index 0000000..c974cea
--- /dev/null
+++ b/src/gl.zig
@@ -0,0 +1,255 @@
+const c_allocator = @import("std").heap.c_allocator;
+const panic = @import("std").debug.panic;
+const c = @import("c.zig");
+
+pub const ShaderProgram = struct {
+ program_id: c.GLuint,
+ vertex_id: c.GLuint,
+ fragment_id: c.GLuint,
+ maybe_geometry_id: ?c.GLuint,
+
+ pub fn bind(self: ShaderProgram) void {
+ c.glUseProgram(self.program_id);
+ }
+
+ pub fn attribLocation(self: ShaderProgram, name: [*]const u8) c.GLint {
+ const id = c.glGetAttribLocation(self.program_id, name);
+ if (id == -1) {
+ panic("invalid attrib: {}\n", .{name});
+ }
+ return id;
+ }
+
+ pub fn uniformLocation(self: ShaderProgram, name: [*]const u8) c.GLint {
+ const id = c.glGetUniformLocation(self.program_id, name);
+ if (id == -1) {
+ panic("invalid uniform: {}\n", .{name});
+ }
+ return id;
+ }
+
+ pub fn setUniformInt(self: ShaderProgram, uniform_id: c.GLint, value: c_int) void {
+ c.glUniform1i(uniform_id, value);
+ }
+
+ pub fn setUniformFloat(self: ShaderProgram, uniform_id: c.GLint, value: f32) void {
+ c.glUniform1f(uniform_id, value);
+ }
+
+ pub fn setUniformVec2(self: ShaderProgram, uniform_id: c.GLint, value: [2]f32) void {
+ c.glUniform3fv(uniform_id, 1, value.ptr);
+ }
+
+ pub fn setUniformVec3(self: ShaderProgram, uniform_id: c.GLint, value: [3]f32) void {
+ c.glUniform3fv(uniform_id, 1, value.ptr);
+ }
+
+ pub fn setUniformVec4(self: ShaderProgram, uniform_id: c.GLint, value: [4]f32) void {
+ c.glUniform4fv(uniform_id, 1, value.ptr);
+ }
+
+ pub fn setUniformMat4x4(self: ShaderProgram, uniform_id: c.GLint, value: [4][4]f32) void {
+ c.glUniformMatrix4fv(uniform_id, 1, c.GL_FALSE, &value[0][0]);
+ }
+
+ pub fn create(
+ vertex_source: []const u8,
+ frag_source: []const u8,
+ maybe_geometry_source: ?[]u8,
+ ) !ShaderProgram {
+ var self: ShaderProgram = undefined;
+ self.vertex_id = try initGlShader(vertex_source, "vertex", c.GL_VERTEX_SHADER);
+ self.fragment_id = try initGlShader(frag_source, "fragment", c.GL_FRAGMENT_SHADER);
+ self.maybe_geometry_id = if (maybe_geometry_source) |geo_source|
+ try initGlShader(geo_source, "geometry", c.GL_GEOMETRY_SHADER)
+ else
+ null;
+
+ self.program_id = c.glCreateProgram();
+ c.glAttachShader(self.program_id, self.vertex_id);
+ c.glAttachShader(self.program_id, self.fragment_id);
+ if (self.maybe_geometry_id) |geo_id| {
+ c.glAttachShader(self.program_id, geo_id);
+ }
+ c.glLinkProgram(self.program_id);
+
+ var ok: c.GLint = undefined;
+ c.glGetProgramiv(self.program_id, c.GL_LINK_STATUS, &ok);
+ if (ok != 0) return self;
+
+ var error_size: c.GLint = undefined;
+ c.glGetProgramiv(self.program_id, c.GL_INFO_LOG_LENGTH, &error_size);
+ const message = try c_allocator.alloc(u8, @intCast(usize, error_size));
+ c.glGetProgramInfoLog(self.program_id, error_size, &error_size, message.ptr);
+ panic("Error linking shader program: {s}\n", .{ @ptrCast([*:0]const u8, message.ptr) });
+ }
+
+ pub fn destroy(self: *ShaderProgram) void {
+ if (self.maybe_geometry_id) |geo_id| {
+ c.glDetachShader(self.program_id, geo_id);
+ }
+ c.glDetachShader(self.program_id, self.fragment_id);
+ c.glDetachShader(self.program_id, self.vertex_id);
+
+ if (self.maybe_geometry_id) |geo_id| {
+ c.glDeleteShader(geo_id);
+ }
+ c.glDeleteShader(self.fragment_id);
+ c.glDeleteShader(self.vertex_id);
+
+ c.glDeleteProgram(self.program_id);
+ }
+};
+
+fn initGlShader(source: []const u8, name: []const u8, kind: c.GLenum) !c.GLuint {
+ const shader_id = c.glCreateShader(kind);
+ const source_ptr: ?[*]const u8 = source.ptr;
+ const source_len = @intCast(c.GLint, source.len);
+ c.glShaderSource(shader_id, 1, &source_ptr, &source_len);
+ c.glCompileShader(shader_id);
+
+ var ok: c.GLint = undefined;
+ c.glGetShaderiv(shader_id, c.GL_COMPILE_STATUS, &ok);
+ if (ok != 0) return shader_id;
+
+ var error_size: c.GLint = undefined;
+ c.glGetShaderiv(shader_id, c.GL_INFO_LOG_LENGTH, &error_size);
+
+ const message = try c_allocator.alloc(u8, @intCast(usize, error_size));
+ c.glGetShaderInfoLog(shader_id, error_size, &error_size, message.ptr);
+ panic("Error compiling {s} shader:\n{s}\n", .{ name, @ptrCast([*:0]const u8, message.ptr) });
+}
+
+pub const FramebufferObject = struct {
+ buffer_id: c.GLuint,
+ texture_id: c.GLuint,
+
+ pub fn bind(self: FramebufferObject) void {
+ c.glBindFramebuffer(c.GL_FRAMEBUFFER, self.buffer_id);
+ }
+
+ pub fn unbind(self: FramebufferObject) void {
+ c.glBindFramebuffer(c.GL_FRAMEBUFFER, 0);
+ }
+
+ pub fn create(width: i32, height: i32) !FramebufferObject {
+ var self: FramebufferObject = undefined;
+ c.glGenFramebuffers(1, &self.buffer_id);
+ c.glBindFramebuffer(c.GL_FRAMEBUFFER, self.buffer_id);
+
+ c.glGenTextures(1, &self.texture_id);
+ c.glBindTexture(c.GL_TEXTURE_2D, self.texture_id);
+ c.glTexImage2D(c.GL_TEXTURE_2D, 0, c.GL_RGBA, width, height, 0, c.GL_RGBA, c.GL_UNSIGNED_BYTE, null);
+ c.glTexParameteri(c.GL_TEXTURE_2D, c.GL_TEXTURE_MIN_FILTER, c.GL_LINEAR);
+ c.glTexParameteri(c.GL_TEXTURE_2D, c.GL_TEXTURE_MAG_FILTER, c.GL_LINEAR);
+ c.glBindTexture(c.GL_TEXTURE_2D, 0);
+
+ c.glFramebufferTexture2D(c.GL_FRAMEBUFFER, c.GL_COLOR_ATTACHMENT0, c.GL_TEXTURE_2D, self.texture_id, 0);
+
+
+ if (c.glCheckFramebufferStatus(c.GL_FRAMEBUFFER) != c.GL_FRAMEBUFFER_COMPLETE)
+ return error.FBONotComplete;
+
+ c.glBindFramebuffer(c.GL_FRAMEBUFFER, 0);
+ return self;
+ }
+
+ pub fn destroy(self: *FramebufferObject) void {
+ c.glDeleteFramebuffers(1, &self.*.buffer_id);
+ c.glDeleteTextures(1, &self.*.texture_id);
+ }
+};
+
+pub const VertexObject = struct {
+ array_id: c.GLuint,
+ buffer_id: c.GLuint,
+ vertex_size: i32,
+ vertex_count: i32,
+
+ pub fn bind(self: VertexObject, attrib: u32) void {
+ c.glBindBuffer(c.GL_ARRAY_BUFFER, self.buffer_id);
+ c.glEnableVertexAttribArray(attrib);
+ c.glVertexAttribPointer(attrib, self.vertex_size, c.GL_FLOAT, c.GL_FALSE, 0, null);
+ }
+
+ pub fn draw(self: VertexObject) void {
+ c.glDrawArrays(c.GL_TRIANGLE_STRIP, 0, self.vertex_count);
+ }
+
+ pub fn create(comptime T: type, vertices: []const T, vertex_size: i32) VertexObject {
+ var self: VertexObject = undefined;
+
+ self.vertex_size = vertex_size;
+ self.vertex_count = @intCast(i32, vertices.len);
+
+ c.glGenVertexArrays(1, &self.array_id);
+ c.glBindVertexArray(self.array_id);
+
+ c.glGenBuffers(1, &self.buffer_id);
+ c.glBindBuffer(c.GL_ARRAY_BUFFER, self.buffer_id);
+ c.glBufferData(c.GL_ARRAY_BUFFER,
+ @intCast(c_long, @sizeOf(T) * vertices.len),
+ @ptrCast(*const c_void, &vertices[0]),
+ c.GL_STATIC_DRAW);
+
+ return self;
+ }
+
+ pub fn destroy(self: *VertexObject) void {
+ defer c.glDeleteBuffers(1, &self.*.buffer_id);
+ defer c.glDeleteVertexArrays(1, &self.*.array_id);
+ }
+};
+
+pub const Constants = struct {
+ textureShader: ShaderProgram,
+ normalizedQuad: VertexObject,
+ main_window: *c.GLFWwindow,
+
+ pub fn create(main_window: *c.GLFWwindow) !Constants {
+ var self: Constants = undefined;
+
+ c.glfwMakeContextCurrent(main_window);
+ self.main_window = main_window;
+
+ self.textureShader = try ShaderProgram.create(
+ \\#version 330 core
+ \\
+ \\layout(location = 0) in vec2 position;
+ \\out vec2 uv;
+ \\
+ \\void main() {
+ \\ uv = position / 2.0 + 0.5;
+ \\ gl_Position = vec4(position, 0, 1);
+ \\}
+ ,
+ \\#version 330 core
+ \\
+ \\in vec2 uv;
+ \\out vec4 color;
+ \\
+ \\uniform sampler2D colorTexture;
+ \\
+ \\void main(){
+ \\ color = texture(colorTexture, uv);
+ \\}
+ ,
+ null
+ );
+
+ const vertices = [_]c.GLfloat{
+ -1.0, -1.0,
+ -1.0, 1.0,
+ 1.0, -1.0,
+ 1.0, 1.0,
+ };
+ self.normalizedQuad = VertexObject.create(f32, vertices[0..], 2);
+
+ return self;
+ }
+
+ pub fn destroy(self: *Constants) void {
+ self.normalizedQuad.destroy();
+ self.textureShader.destroy();
+ }
+};
diff --git a/src/main.zig b/src/main.zig
index ce31e75..6d119af 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -4,6 +4,7 @@ const c = @import("c.zig");
const debug_gl = @import("debug_gl.zig");
const cfg = @import("config.zig");
const out = @import("output.zig");
+const gl = @import("gl.zig");
var window: *c.GLFWwindow = undefined;
@@ -22,60 +23,107 @@ pub fn main() !void {
}
defer c.glfwTerminate();
- c.glfwWindowHint(c.GLFW_CONTEXT_VERSION_MAJOR, 3);
+ c.glfwWindowHint(c.GLFW_CONTEXT_VERSION_MAJOR, 4);
c.glfwWindowHint(c.GLFW_CONTEXT_VERSION_MINOR, 2);
c.glfwWindowHint(c.GLFW_OPENGL_FORWARD_COMPAT, c.GL_TRUE);
c.glfwWindowHint(c.GLFW_OPENGL_DEBUG_CONTEXT, debug_gl.is_on);
c.glfwWindowHint(c.GLFW_OPENGL_PROFILE, c.GLFW_OPENGL_CORE_PROFILE);
c.glfwWindowHint(c.GLFW_DEPTH_BITS, 0);
- c.glfwWindowHint(c.GLFW_STENCIL_BITS, 8);
+ c.glfwWindowHint(c.GLFW_STENCIL_BITS, 0);
c.glfwWindowHint(c.GLFW_VISIBLE, c.GLFW_FALSE);
window = c.glfwCreateWindow(config.width, config.height, "glsl-view", null, null) orelse {
panic("unable to create window\n", .{});
};
defer c.glfwDestroyWindow(window);
-
+
c.glfwMakeContextCurrent(window);
c.glfwSwapInterval(1);
- c.glClearColor(0.0, 0.0, 0.0, 1.0);
-
- // c.glEnable(c.GL_BLEND);
- // c.glBlendFunc(c.GL_SRC_ALPHA, c.GL_ONE_MINUS_SRC_ALPHA);
- // c.glPixelStorei(c.GL_UNPACK_ALIGNMENT, 1);
-
- c.glViewport(0, 0, config.width, config.height);
-
- debug_gl.assertNoError();
-
- var outputs = try config.arena.allocator.alloc(*out.Output, config.outputs.len);
+ var constants = try gl.Constants.create(window);
+ defer constants.destroy();
+
+ var outputs = try std.ArrayList(*out.Output).initCapacity(&config.arena.allocator, config.outputs.len);
+ defer outputs.deinit();
for (config.outputs) |output_config, i| {
- outputs[i] = out.Output.create(&config.arena.allocator, output_config, window);
+ try outputs.append(out.Output.create(&config.arena.allocator, output_config, &constants));
}
- defer for (outputs) |output| {
+ defer for (outputs.toSlice()) |output| {
output.destroy(output);
};
+ c.glfwMakeContextCurrent(window);
+ c.glClearColor(0.0, 0.0, 0.0, 1.0);
+
+ debug_gl.assertNoError();
+
const start_time = c.glfwGetTime();
var prev_time = start_time;
+ constants.normalizedQuad.bind(0);
+
+ debug_gl.assertNoError();
+
+ var redShader = try gl.ShaderProgram.create(
+ \\#version 330 core
+ \\
+ \\layout(location = 0) in vec2 position;
+ \\out vec2 uv;
+ \\
+ \\void main() {
+ \\ uv = position / 2.0 + 0.5;
+ \\ gl_Position = vec4(position, 0, 1);
+ \\}
+ ,
+ \\#version 330 core
+ \\
+ \\in vec2 uv;
+ \\out vec4 color;
+ \\
+ \\uniform float offset;
+ \\
+ \\void main() {
+ \\ color = vec4(mod(uv + offset, vec2(1)), 0, 1);
+ \\}
+ ,
+ null
+ );
+ defer redShader.destroy();
+
+ var fbo = try gl.FramebufferObject.create(config.width, config.height);
+ defer fbo.destroy();
+
+ var offset: f32 = 0;
+
while (c.glfwWindowShouldClose(window) == c.GL_FALSE) {
- c.glClear(c.GL_COLOR_BUFFER_BIT | c.GL_DEPTH_BUFFER_BIT | c.GL_STENCIL_BUFFER_BIT);
+ c.glfwMakeContextCurrent(window);
+ c.glClear(c.GL_COLOR_BUFFER_BIT);
const now_time = c.glfwGetTime();
const elapsed = now_time - prev_time;
prev_time = now_time;
+
+ fbo.bind();
+ c.glClear(c.GL_COLOR_BUFFER_BIT);
+
+ redShader.bind();
+ offset += @floatCast(f32, elapsed / 4);
+ redShader.setUniformFloat(redShader.uniformLocation("offset"), offset);
+ constants.normalizedQuad.draw();
+ fbo.unbind();
- for (outputs) |output| {
- const close = output.update(output);
+ for (outputs.toSlice()) |output, i| {
+ const close = output.update(output, fbo.texture_id);
if (close) {
- c.glfwSetWindowShouldClose(window, c.GL_TRUE);
+ const removed = outputs.swapRemove(i);
+ removed.destroy(removed);
+ break;
}
}
- c.glfwSwapBuffers(window);
-
+ if (outputs.len == 0)
+ break;
+
c.glfwPollEvents();
}
diff --git a/src/output.zig b/src/output.zig
index 8303107..077387c 100644
--- a/src/output.zig
+++ b/src/output.zig
@@ -1,21 +1,22 @@
const c = @import("c.zig");
const std = @import("std");
const cfg = @import("config.zig");
+const gl = @import("gl.zig");
pub const Output = struct {
- update: fn (self: *Output) bool,
- destroy: fn (self: *Output) void,
+ update: fn (*Output, c.GLuint) bool,
+ destroy: fn (*Output) void,
- pub fn init(update: fn (*Output) bool, destroy: fn (*Output) void) Output {
+ pub fn init(update: fn (*Output, c.GLuint) bool, destroy: fn (*Output) void) Output {
return Output{
.update = update,
.destroy = destroy,
};
}
- pub fn create(allocator: *std.mem.Allocator, config: cfg.OutputConfig, share_window: *c.GLFWwindow) *Output {
+ pub fn create(allocator: *std.mem.Allocator, config: cfg.OutputConfig, constants: *gl.Constants) *Output {
return switch (config.type) {
- cfg.OutputType.window => WindowOutput.create(allocator, config, share_window),
+ cfg.OutputType.window => WindowOutput.create(allocator, config, constants),
else => unreachable,
};
}
@@ -24,15 +25,17 @@ pub const Output = struct {
pub const WindowOutput = struct {
output: Output,
window: *c.GLFWwindow,
+ constants: *gl.Constants,
- pub fn create(allocator: *std.mem.Allocator, config: cfg.OutputConfig, share_window: *c.GLFWwindow) *Output {
+ pub fn create(allocator: *std.mem.Allocator, config: cfg.OutputConfig, constants: *gl.Constants) *Output {
const self = allocator.create(WindowOutput) catch unreachable;
c.glfwDefaultWindowHints();
self.* = WindowOutput{
+ .constants = constants,
.output = Output.init(update, destroy),
- .window = c.glfwCreateWindow(config.width, config.height, "glsl-view output", null, share_window) orelse {
+ .window = c.glfwCreateWindow(config.width, config.height, "glsl-view output", null, constants.main_window) orelse {
std.debug.panic("unable to create output window\n", .{});
},
};
@@ -40,17 +43,27 @@ pub const WindowOutput = struct {
c.glfwSetWindowUserPointer(self.*.window, @ptrCast(*c_void, self));
_ = c.glfwSetKeyCallback(self.*.window, keyCallback);
+ c.glfwMakeContextCurrent(self.*.window);
+ constants.normalizedQuad.bind(0);
+
return &self.*.output;
}
- fn update(output: *Output) bool {
+ fn update(output: *Output, texture_id: c.GLuint) bool {
const self = @fieldParentPtr(WindowOutput, "output", output);
if (c.glfwWindowShouldClose(self.*.window) == c.GL_TRUE)
return true;
- c.glClear(c.GL_COLOR_BUFFER_BIT | c.GL_DEPTH_BUFFER_BIT | c.GL_STENCIL_BUFFER_BIT);
+ c.glfwMakeContextCurrent(self.*.window);
+ c.glClear(c.GL_COLOR_BUFFER_BIT);
+
+ c.glBindTexture(c.GL_TEXTURE_2D, texture_id);
+ c.glDrawArrays(c.GL_TRIANGLE_STRIP, 0, 4);
+ self.constants.textureShader.bind();
+ self.constants.normalizedQuad.draw();
+
c.glfwSwapBuffers(self.*.window);
return false;
}
diff --git a/src/shader.zig b/src/shader.zig
deleted file mode 100644
index ed36035..0000000
--- a/src/shader.zig
+++ /dev/null
@@ -1,118 +0,0 @@
-const std = @import("std");
-const panic = std.debug.panic
-const c = @import("c.zig");
-
-
-pub const ShaderProgram = struct {
- program_id: c.GLuint,
- vertex_id: c.GLuint,
- fragment_id: c.GLuint,
- maybe_geometry_id: ?c.GLuint,
-
- pub fn bind(sp: ShaderProgram) void {
- c.glUseProgram(sp.program_id);
- }
-
- pub fn attribLocation(sp: ShaderProgram, name: [*]const u8) c.GLint {
- const id = c.glGetAttribLocation(sp.program_id, name);
- if (id == -1) {
- panic("invalid attrib: {}\n", .{name});
- }
- return id;
- }
-
- pub fn uniformLocation(sp: ShaderProgram, name: [*]const u8) c.GLint {
- const id = c.glGetUniformLocation(sp.program_id, name);
- if (id == -1) {
- panic("invalid uniform: {}\n", .{name});
- }
- return id;
- }
-
- pub fn setUniformInt(sp: ShaderProgram, uniform_id: c.GLint, value: c_int) void {
- c.glUniform1i(uniform_id, value);
- }
-
- pub fn setUniformFloat(sp: ShaderProgram, uniform_id: c.GLint, value: f32) void {
- c.glUniform1f(uniform_id, value);
- }
-
- pub fn setUniformVec3(sp: ShaderProgram, uniform_id: c.GLint, value: math3d.Vec3) void {
- c.glUniform3fv(uniform_id, 1, value.data[0..].ptr);
- }
-
- pub fn setUniformVec4(sp: ShaderProgram, uniform_id: c.GLint, value: Vec4) void {
- c.glUniform4fv(uniform_id, 1, value.data[0..].ptr);
- }
-
- pub fn setUniformMat4x4(sp: ShaderProgram, uniform_id: c.GLint, value: Mat4x4) void {
- c.glUniformMatrix4fv(uniform_id, 1, c.GL_FALSE, value.data[0][0..].ptr);
- }
-
- pub fn create(
- vertex_source: []const u8,
- frag_source: []const u8,
- maybe_geometry_source: ?[]u8,
- ) !ShaderProgram {
- var sp: ShaderProgram = undefined;
- sp.vertex_id = try initGlShader(vertex_source, "vertex", c.GL_VERTEX_SHADER);
- sp.fragment_id = try initGlShader(frag_source, "fragment", c.GL_FRAGMENT_SHADER);
- sp.maybe_geometry_id = if (maybe_geometry_source) |geo_source|
- try initGlShader(geo_source, "geometry", c.GL_GEOMETRY_SHADER)
- else
- null;
-
- sp.program_id = c.glCreateProgram();
- c.glAttachShader(sp.program_id, sp.vertex_id);
- c.glAttachShader(sp.program_id, sp.fragment_id);
- if (sp.maybe_geometry_id) |geo_id| {
- c.glAttachShader(sp.program_id, geo_id);
- }
- c.glLinkProgram(sp.program_id);
-
- var ok: c.GLint = undefined;
- c.glGetProgramiv(sp.program_id, c.GL_LINK_STATUS, &ok);
- if (ok != 0) return sp;
-
- var error_size: c.GLint = undefined;
- c.glGetProgramiv(sp.program_id, c.GL_INFO_LOG_LENGTH, &error_size);
- const message = try c_allocator.alloc(u8, @intCast(usize, error_size));
- c.glGetProgramInfoLog(sp.program_id, error_size, &error_size, message.ptr);
- panic("Error linking shader program: {}\n", .{message.ptr});
- }
-
- pub fn destroy(sp: *ShaderProgram) void {
- if (sp.maybe_geometry_id) |geo_id| {
- c.glDetachShader(sp.program_id, geo_id);
- }
- c.glDetachShader(sp.program_id, sp.fragment_id);
- c.glDetachShader(sp.program_id, sp.vertex_id);
-
- if (sp.maybe_geometry_id) |geo_id| {
- c.glDeleteShader(geo_id);
- }
- c.glDeleteShader(sp.fragment_id);
- c.glDeleteShader(sp.vertex_id);
-
- c.glDeleteProgram(sp.program_id);
- }
-};
-
-fn initGlShader(source: []const u8, name: [*]const u8, kind: c.GLenum) !c.GLuint {
- const shader_id = c.glCreateShader(kind);
- const source_ptr: ?[*]const u8 = source.ptr;
- const source_len = @intCast(c.GLint, source.len);
- c.glShaderSource(shader_id, 1, &source_ptr, &source_len);
- c.glCompileShader(shader_id);
-
- var ok: c.GLint = undefined;
- c.glGetShaderiv(shader_id, c.GL_COMPILE_STATUS, &ok);
- if (ok != 0) return shader_id;
-
- var error_size: c.GLint = undefined;
- c.glGetShaderiv(shader_id, c.GL_INFO_LOG_LENGTH, &error_size);
-
- const message = try c_allocator.alloc(u8, @intCast(usize, error_size));
- c.glGetShaderInfoLog(shader_id, error_size, &error_size, message.ptr);
- panic("Error compiling {} shader:\n{}\n", .{ name, message.ptr });
-}