aboutsummaryrefslogtreecommitdiffstats
path: root/src/gl.zig
diff options
context:
space:
mode:
authors-ol <s-ol@users.noreply.github.com>2020-01-26 19:49:25 +0000
committers-ol <s-ol@users.noreply.github.com>2020-01-26 19:49:25 +0000
commit885a8652cb8a433a18811d90048d11c1ec67b60e (patch)
tree52b845a825c91ec878983eb1078b4bd48f27ec73 /src/gl.zig
parentremove offset default uniform (diff)
downloadglsl-view-885a8652cb8a433a18811d90048d11c1ec67b60e.tar.gz
glsl-view-885a8652cb8a433a18811d90048d11c1ec67b60e.zip
break OSC in favor of uniform caching
Diffstat (limited to 'src/gl.zig')
-rw-r--r--src/gl.zig401
1 files changed, 365 insertions, 36 deletions
diff --git a/src/gl.zig b/src/gl.zig
index 659911e..474b87d 100644
--- a/src/gl.zig
+++ b/src/gl.zig
@@ -2,6 +2,292 @@ const std = @import("std");
const c_allocator = @import("std").heap.c_allocator;
const panic = @import("std").debug.panic;
const c = @import("c.zig");
+const cfg = @import("config.zig");
+
+const UniformType = enum(c.GLint) {
+ FLOAT = c.GL_FLOAT,
+ FLOAT_VEC2 = c.GL_FLOAT_VEC2,
+ FLOAT_VEC3 = c.GL_FLOAT_VEC3,
+ FLOAT_VEC4 = c.GL_FLOAT_VEC4,
+ DOUBLE = c.GL_DOUBLE,
+ DOUBLE_VEC2 = c.GL_DOUBLE_VEC2,
+ DOUBLE_VEC3 = c.GL_DOUBLE_VEC3,
+ DOUBLE_VEC4 = c.GL_DOUBLE_VEC4,
+ INT = c.GL_INT,
+ INT_VEC2 = c.GL_INT_VEC2,
+ INT_VEC3 = c.GL_INT_VEC3,
+ INT_VEC4 = c.GL_INT_VEC4,
+ UNSIGNED_INT = c.GL_UNSIGNED_INT,
+ UNSIGNED_INT_VEC2 = c.GL_UNSIGNED_INT_VEC2,
+ UNSIGNED_INT_VEC3 = c.GL_UNSIGNED_INT_VEC3,
+ UNSIGNED_INT_VEC4 = c.GL_UNSIGNED_INT_VEC4,
+ BOOL = c.GL_BOOL,
+ BOOL_VEC2 = c.GL_BOOL_VEC2,
+ BOOL_VEC3 = c.GL_BOOL_VEC3,
+ BOOL_VEC4 = c.GL_BOOL_VEC4,
+ FLOAT_MAT2 = c.GL_FLOAT_MAT2,
+ FLOAT_MAT3 = c.GL_FLOAT_MAT3,
+ FLOAT_MAT4 = c.GL_FLOAT_MAT4,
+ FLOAT_MAT2x3 = c.GL_FLOAT_MAT2x3,
+ FLOAT_MAT2x4 = c.GL_FLOAT_MAT2x4,
+ FLOAT_MAT3x2 = c.GL_FLOAT_MAT3x2,
+ FLOAT_MAT3x4 = c.GL_FLOAT_MAT3x4,
+ FLOAT_MAT4x2 = c.GL_FLOAT_MAT4x2,
+ FLOAT_MAT4x3 = c.GL_FLOAT_MAT4x3,
+ DOUBLE_MAT2 = c.GL_DOUBLE_MAT2,
+ DOUBLE_MAT3 = c.GL_DOUBLE_MAT3,
+ DOUBLE_MAT4 = c.GL_DOUBLE_MAT4,
+ DOUBLE_MAT2x3 = c.GL_DOUBLE_MAT2x3,
+ DOUBLE_MAT2x4 = c.GL_DOUBLE_MAT2x4,
+ DOUBLE_MAT3x2 = c.GL_DOUBLE_MAT3x2,
+ DOUBLE_MAT3x4 = c.GL_DOUBLE_MAT3x4,
+ DOUBLE_MAT4x2 = c.GL_DOUBLE_MAT4x2,
+ DOUBLE_MAT4x3 = c.GL_DOUBLE_MAT4x3,
+ SAMPLER_1D = c.GL_SAMPLER_1D,
+ SAMPLER_2D = c.GL_SAMPLER_2D,
+ SAMPLER_3D = c.GL_SAMPLER_3D,
+ SAMPLER_CUBE = c.GL_SAMPLER_CUBE,
+ SAMPLER_1D_SHADOW = c.GL_SAMPLER_1D_SHADOW,
+ SAMPLER_2D_SHADOW = c.GL_SAMPLER_2D_SHADOW,
+ SAMPLER_1D_ARRAY = c.GL_SAMPLER_1D_ARRAY,
+ SAMPLER_2D_ARRAY = c.GL_SAMPLER_2D_ARRAY,
+ SAMPLER_1D_ARRAY_SHADOW = c.GL_SAMPLER_1D_ARRAY_SHADOW,
+ SAMPLER_2D_ARRAY_SHADOW = c.GL_SAMPLER_2D_ARRAY_SHADOW,
+ SAMPLER_2D_MULTISAMPLE = c.GL_SAMPLER_2D_MULTISAMPLE,
+ SAMPLER_2D_MULTISAMPLE_ARRAY = c.GL_SAMPLER_2D_MULTISAMPLE_ARRAY,
+ SAMPLER_CUBE_SHADOW = c.GL_SAMPLER_CUBE_SHADOW,
+ SAMPLER_BUFFER = c.GL_SAMPLER_BUFFER,
+ SAMPLER_2D_RECT = c.GL_SAMPLER_2D_RECT,
+ SAMPLER_2D_RECT_SHADOW = c.GL_SAMPLER_2D_RECT_SHADOW,
+ INT_SAMPLER_1D = c.GL_INT_SAMPLER_1D,
+ INT_SAMPLER_2D = c.GL_INT_SAMPLER_2D,
+ INT_SAMPLER_3D = c.GL_INT_SAMPLER_3D,
+ INT_SAMPLER_CUBE = c.GL_INT_SAMPLER_CUBE,
+ INT_SAMPLER_1D_ARRAY = c.GL_INT_SAMPLER_1D_ARRAY,
+ INT_SAMPLER_2D_ARRAY = c.GL_INT_SAMPLER_2D_ARRAY,
+ INT_SAMPLER_2D_MULTISAMPLE = c.GL_INT_SAMPLER_2D_MULTISAMPLE,
+ INT_SAMPLER_2D_MULTISAMPLE_ARRAY = c.GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY,
+ INT_SAMPLER_BUFFER = c.GL_INT_SAMPLER_BUFFER,
+ INT_SAMPLER_2D_RECT = c.GL_INT_SAMPLER_2D_RECT,
+ UNSIGNED_INT_SAMPLER_1D = c.GL_UNSIGNED_INT_SAMPLER_1D,
+ UNSIGNED_INT_SAMPLER_2D = c.GL_UNSIGNED_INT_SAMPLER_2D,
+ UNSIGNED_INT_SAMPLER_3D = c.GL_UNSIGNED_INT_SAMPLER_3D,
+ UNSIGNED_INT_SAMPLER_CUBE = c.GL_UNSIGNED_INT_SAMPLER_CUBE,
+ UNSIGNED_INT_SAMPLER_1D_ARRAY = c.GL_UNSIGNED_INT_SAMPLER_1D_ARRAY,
+ UNSIGNED_INT_SAMPLER_2D_ARRAY = c.GL_UNSIGNED_INT_SAMPLER_2D_ARRAY,
+ UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE = c.GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE,
+ UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY = c.GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY,
+ UNSIGNED_INT_SAMPLER_BUFFER = c.GL_UNSIGNED_INT_SAMPLER_BUFFER,
+ UNSIGNED_INT_SAMPLER_2D_RECT = c.GL_UNSIGNED_INT_SAMPLER_2D_RECT,
+};
+
+const UniformValue = union(UniformType) {
+ FLOAT: f32,
+ FLOAT_VEC2: [2]f32,
+ FLOAT_VEC3: [3]f32,
+ FLOAT_VEC4: [4]f32,
+ DOUBLE: f64,
+ DOUBLE_VEC2: [2]f64,
+ DOUBLE_VEC3: [3]f64,
+ DOUBLE_VEC4: [4]f64,
+ INT: c_int, // i32 but bug
+ INT_VEC2: [2]c_int,
+ INT_VEC3: [3]c_int,
+ INT_VEC4: [4]c_int,
+ UNSIGNED_INT: c_uint,
+ UNSIGNED_INT_VEC2: [2]c_uint,
+ UNSIGNED_INT_VEC3: [3]c_uint,
+ UNSIGNED_INT_VEC4: [4]c_uint,
+ BOOL: c_uint,
+ BOOL_VEC2: [2]c_uint,
+ BOOL_VEC3: [3]c_uint,
+ BOOL_VEC4: [4]c_uint,
+ FLOAT_MAT2: [2 * 2]f32,
+ FLOAT_MAT3: [3 * 3]f32,
+ FLOAT_MAT4: [4 * 4]f32,
+ FLOAT_MAT2x3: [2 * 3]f32,
+ FLOAT_MAT2x4: [2 * 4]f32,
+ FLOAT_MAT3x2: [3 * 2]f32,
+ FLOAT_MAT3x4: [3 * 4]f32,
+ FLOAT_MAT4x2: [4 * 2]f32,
+ FLOAT_MAT4x3: [4 * 3]f32,
+ DOUBLE_MAT2: [2 * 2]f64,
+ DOUBLE_MAT3: [3 * 3]f64,
+ DOUBLE_MAT4: [4 * 4]f64,
+ DOUBLE_MAT2x3: [2 * 3]f64,
+ DOUBLE_MAT2x4: [2 * 4]f64,
+ DOUBLE_MAT3x2: [3 * 2]f64,
+ DOUBLE_MAT3x4: [3 * 4]f64,
+ DOUBLE_MAT4x2: [4 * 2]f64,
+ DOUBLE_MAT4x3: [4 * 3]f64,
+ SAMPLER_1D: c_int,
+ SAMPLER_2D: c_int,
+ SAMPLER_3D: c_int,
+ SAMPLER_CUBE: c_int,
+ SAMPLER_1D_SHADOW: c_int,
+ SAMPLER_2D_SHADOW: c_int,
+ SAMPLER_1D_ARRAY: c_int,
+ SAMPLER_2D_ARRAY: c_int,
+ SAMPLER_1D_ARRAY_SHADOW: c_int,
+ SAMPLER_2D_ARRAY_SHADOW: c_int,
+ SAMPLER_2D_MULTISAMPLE: c_int,
+ SAMPLER_2D_MULTISAMPLE_ARRAY: c_int,
+ SAMPLER_CUBE_SHADOW: c_int,
+ SAMPLER_BUFFER: c_int,
+ SAMPLER_2D_RECT: c_int,
+ SAMPLER_2D_RECT_SHADOW: c_int,
+ INT_SAMPLER_1D: c_int,
+ INT_SAMPLER_2D: c_int,
+ INT_SAMPLER_3D: c_int,
+ INT_SAMPLER_CUBE: c_int,
+ INT_SAMPLER_1D_ARRAY: c_int,
+ INT_SAMPLER_2D_ARRAY: c_int,
+ INT_SAMPLER_2D_MULTISAMPLE: c_int,
+ INT_SAMPLER_2D_MULTISAMPLE_ARRAY: c_int,
+ INT_SAMPLER_BUFFER: c_int,
+ INT_SAMPLER_2D_RECT: c_int,
+ UNSIGNED_INT_SAMPLER_1D: c_int,
+ UNSIGNED_INT_SAMPLER_2D: c_int,
+ UNSIGNED_INT_SAMPLER_3D: c_int,
+ UNSIGNED_INT_SAMPLER_CUBE: c_int,
+ UNSIGNED_INT_SAMPLER_1D_ARRAY: c_int,
+ UNSIGNED_INT_SAMPLER_2D_ARRAY: c_int,
+ UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: c_int,
+ UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: c_int,
+ UNSIGNED_INT_SAMPLER_BUFFER: c_int,
+ UNSIGNED_INT_SAMPLER_2D_RECT: c_int,
+
+ pub fn init(utype: UniformType) UniformValue {
+ inline for (@typeInfo(UniformType).Enum.fields) |field| {
+ if (@intToEnum(UniformType, field.value) == utype)
+ return @unionInit(UniformValue, field.name, undefined);
+ }
+
+ unreachable;
+ }
+};
+
+const CachedUniform = struct {
+ value: UniformValue,
+ location: c.GLint,
+
+ pub fn init(shader: ShaderProgram, name: [*]const u8) !CachedUniform {
+ var index: c.GLuint = undefined;
+
+ c.glGetUniformIndices(shader.program_id, 1, &name, &index);
+ if (index == c.GL_INVALID_INDEX)
+ return error.invalidUniform;
+
+ var utype: c.GLint = undefined;
+ c.glGetActiveUniformsiv(shader.program_id, 1, &index, c.GL_UNIFORM_TYPE, &utype);
+
+ var self = CachedUniform{
+ .value = UniformValue.init(@intToEnum(UniformType, utype)),
+ .location = try shader.uniformLocation(name),
+ };
+
+ self.getShaderValue(shader);
+ return self;
+ }
+
+ // zig fmt: off
+ pub fn setShaderValue(self: *const CachedUniform, shader: ShaderProgram) void {
+ const program = shader.program_id;
+ const location = self.location;
+
+ switch (self.value) {
+ .FLOAT => |*value| c.glProgramUniform1fv(program, location, 1, value),
+ .FLOAT_VEC2 => |*value| c.glProgramUniform2fv(program, location, 1, value),
+ .FLOAT_VEC3 => |*value| c.glProgramUniform3fv(program, location, 1, value),
+ .FLOAT_VEC4 => |*value| c.glProgramUniform4fv(program, location, 1, value),
+ .DOUBLE => |*value| c.glProgramUniform1dv(program, location, 1, value),
+ .DOUBLE_VEC2 => |*value| c.glProgramUniform1dv(program, location, 1, value),
+ .DOUBLE_VEC3 => |*value| c.glProgramUniform2dv(program, location, 1, value),
+ .DOUBLE_VEC4 => |*value| c.glProgramUniform3dv(program, location, 1, value),
+ .INT => |*value| c.glProgramUniform1iv(program, location, 1, value),
+ .INT_VEC2 => |*value| c.glProgramUniform2iv(program, location, 1, value),
+ .INT_VEC3 => |*value| c.glProgramUniform3iv(program, location, 1, value),
+ .INT_VEC4 => |*value| c.glProgramUniform4iv(program, location, 1, value),
+ .UNSIGNED_INT => |*value| c.glProgramUniform1uiv(program, location, 1, value),
+ .UNSIGNED_INT_VEC2 => |*value| c.glProgramUniform2uiv(program, location, 1, value),
+ .UNSIGNED_INT_VEC3 => |*value| c.glProgramUniform3uiv(program, location, 1, value),
+ .UNSIGNED_INT_VEC4 => |*value| c.glProgramUniform4uiv(program, location, 1, value),
+ .BOOL => |*value| c.glProgramUniform1uiv(program, location, 1, value),
+ .BOOL_VEC2 => |*value| c.glProgramUniform2uiv(program, location, 1, value),
+ .BOOL_VEC3 => |*value| c.glProgramUniform3uiv(program, location, 1, value),
+ .BOOL_VEC4 => |*value| c.glProgramUniform4uiv(program, location, 1, value),
+ .FLOAT_MAT2 => |*value| c.glProgramUniformMatrix2fv(program, location, 1, c.GL_FALSE, value),
+ .FLOAT_MAT3 => |*value| c.glProgramUniformMatrix3fv(program, location, 1, c.GL_FALSE, value),
+ .FLOAT_MAT4 => |*value| c.glProgramUniformMatrix4fv(program, location, 1, c.GL_FALSE, value),
+ .FLOAT_MAT2x3 => |*value| c.glProgramUniformMatrix2x3fv(program, location, 1, c.GL_FALSE, value),
+ .FLOAT_MAT2x4 => |*value| c.glProgramUniformMatrix2x4fv(program, location, 1, c.GL_FALSE, value),
+ .FLOAT_MAT3x2 => |*value| c.glProgramUniformMatrix3x2fv(program, location, 1, c.GL_FALSE, value),
+ .FLOAT_MAT3x4 => |*value| c.glProgramUniformMatrix3x4fv(program, location, 1, c.GL_FALSE, value),
+ .FLOAT_MAT4x2 => |*value| c.glProgramUniformMatrix4x2fv(program, location, 1, c.GL_FALSE, value),
+ .FLOAT_MAT4x3 => |*value| c.glProgramUniformMatrix4x3fv(program, location, 1, c.GL_FALSE, value),
+ .DOUBLE_MAT2 => |*value| c.glProgramUniformMatrix2dv(program, location, 1, c.GL_FALSE, value),
+ .DOUBLE_MAT3 => |*value| c.glProgramUniformMatrix3dv(program, location, 1, c.GL_FALSE, value),
+ .DOUBLE_MAT4 => |*value| c.glProgramUniformMatrix4dv(program, location, 1, c.GL_FALSE, value),
+ .DOUBLE_MAT2x3 => |*value| c.glProgramUniformMatrix2x3dv(program, location, 1, c.GL_FALSE, value),
+ .DOUBLE_MAT2x4 => |*value| c.glProgramUniformMatrix2x4dv(program, location, 1, c.GL_FALSE, value),
+ .DOUBLE_MAT3x2 => |*value| c.glProgramUniformMatrix3x2dv(program, location, 1, c.GL_FALSE, value),
+ .DOUBLE_MAT3x4 => |*value| c.glProgramUniformMatrix3x4dv(program, location, 1, c.GL_FALSE, value),
+ .DOUBLE_MAT4x2 => |*value| c.glProgramUniformMatrix4x2dv(program, location, 1, c.GL_FALSE, value),
+ .DOUBLE_MAT4x3 => |*value| c.glProgramUniformMatrix4x3dv(program, location, 1, c.GL_FALSE, value),
+ .SAMPLER_1D, .SAMPLER_2D, .SAMPLER_3D, .SAMPLER_CUBE, .SAMPLER_1D_SHADOW, .SAMPLER_2D_SHADOW, .SAMPLER_1D_ARRAY, .SAMPLER_2D_ARRAY, .SAMPLER_1D_ARRAY_SHADOW, .SAMPLER_2D_ARRAY_SHADOW, .SAMPLER_2D_MULTISAMPLE, .SAMPLER_2D_MULTISAMPLE_ARRAY, .SAMPLER_CUBE_SHADOW, .SAMPLER_BUFFER, .SAMPLER_2D_RECT, .SAMPLER_2D_RECT_SHADOW, .INT_SAMPLER_1D, .INT_SAMPLER_2D, .INT_SAMPLER_3D, .INT_SAMPLER_CUBE, .INT_SAMPLER_1D_ARRAY, .INT_SAMPLER_2D_ARRAY, .INT_SAMPLER_2D_MULTISAMPLE, .INT_SAMPLER_2D_MULTISAMPLE_ARRAY, .INT_SAMPLER_BUFFER, .INT_SAMPLER_2D_RECT, .UNSIGNED_INT_SAMPLER_1D, .UNSIGNED_INT_SAMPLER_2D, .UNSIGNED_INT_SAMPLER_3D, .UNSIGNED_INT_SAMPLER_CUBE, .UNSIGNED_INT_SAMPLER_1D_ARRAY, .UNSIGNED_INT_SAMPLER_2D_ARRAY, .UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE, .UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY, .UNSIGNED_INT_SAMPLER_BUFFER, .UNSIGNED_INT_SAMPLER_2D_RECT => |value| c.glProgramUniform1i(program, location, value),
+ else => unreachable,
+ }
+ }
+
+ pub fn getShaderValue(self: *CachedUniform, shader: ShaderProgram) void {
+ const program = shader.program_id;
+ const location = self.location;
+
+ switch (self.value) {
+ .FLOAT => |*value| c.glGetnUniformfv(program, location, @sizeOf(@TypeOf(value.*)), value),
+ .FLOAT_VEC2 => |*value| c.glGetnUniformfv(program, location, @sizeOf(@TypeOf(value.*)), value),
+ .FLOAT_VEC3 => |*value| c.glGetnUniformfv(program, location, @sizeOf(@TypeOf(value.*)), value),
+ .FLOAT_VEC4 => |*value| c.glGetnUniformfv(program, location, @sizeOf(@TypeOf(value.*)), value),
+ .DOUBLE => |*value| c.glGetnUniformdv(program, location, @sizeOf(@TypeOf(value.*)), value),
+ .DOUBLE_VEC2 => |*value| c.glGetnUniformdv(program, location, @sizeOf(@TypeOf(value.*)), value),
+ .DOUBLE_VEC3 => |*value| c.glGetnUniformdv(program, location, @sizeOf(@TypeOf(value.*)), value),
+ .DOUBLE_VEC4 => |*value| c.glGetnUniformdv(program, location, @sizeOf(@TypeOf(value.*)), value),
+ .INT => |*value| c.glGetnUniformiv(program, location, @sizeOf(@TypeOf(value.*)), value),
+ .INT_VEC2 => |*value| c.glGetnUniformiv(program, location, @sizeOf(@TypeOf(value.*)), value),
+ .INT_VEC3 => |*value| c.glGetnUniformiv(program, location, @sizeOf(@TypeOf(value.*)), value),
+ .INT_VEC4 => |*value| c.glGetnUniformiv(program, location, @sizeOf(@TypeOf(value.*)), value),
+ .UNSIGNED_INT => |*value| c.glGetnUniformuiv(program, location, @sizeOf(@TypeOf(value.*)), value),
+ .UNSIGNED_INT_VEC2 => |*value| c.glGetnUniformuiv(program, location, @sizeOf(@TypeOf(value.*)), value),
+ .UNSIGNED_INT_VEC3 => |*value| c.glGetnUniformuiv(program, location, @sizeOf(@TypeOf(value.*)), value),
+ .UNSIGNED_INT_VEC4 => |*value| c.glGetnUniformuiv(program, location, @sizeOf(@TypeOf(value.*)), value),
+ .BOOL => |*value| c.glGetnUniformuiv(program, location, @sizeOf(@TypeOf(value.*)), value),
+ .BOOL_VEC2 => |*value| c.glGetnUniformuiv(program, location, @sizeOf(@TypeOf(value.*)), value),
+ .BOOL_VEC3 => |*value| c.glGetnUniformuiv(program, location, @sizeOf(@TypeOf(value.*)), value),
+ .BOOL_VEC4 => |*value| c.glGetnUniformuiv(program, location, @sizeOf(@TypeOf(value.*)), value),
+ .FLOAT_MAT2 => |*value| c.glGetUniformfv(program, location, value),
+ .FLOAT_MAT3 => |*value| c.glGetUniformfv(program, location, value),
+ .FLOAT_MAT4 => |*value| c.glGetUniformfv(program, location, value),
+ .FLOAT_MAT2x3 => |*value| c.glGetUniformfv(program, location, value),
+ .FLOAT_MAT2x4 => |*value| c.glGetUniformfv(program, location, value),
+ .FLOAT_MAT3x2 => |*value| c.glGetUniformfv(program, location, value),
+ .FLOAT_MAT3x4 => |*value| c.glGetUniformfv(program, location, value),
+ .FLOAT_MAT4x2 => |*value| c.glGetUniformfv(program, location, value),
+ .FLOAT_MAT4x3 => |*value| c.glGetUniformfv(program, location, value),
+ .DOUBLE_MAT2 => |*value| c.glGetUniformdv(program, location, value),
+ .DOUBLE_MAT3 => |*value| c.glGetUniformdv(program, location, value),
+ .DOUBLE_MAT4 => |*value| c.glGetUniformdv(program, location, value),
+ .DOUBLE_MAT2x3 => |*value| c.glGetUniformdv(program, location, value),
+ .DOUBLE_MAT2x4 => |*value| c.glGetUniformdv(program, location, value),
+ .DOUBLE_MAT3x2 => |*value| c.glGetUniformdv(program, location, value),
+ .DOUBLE_MAT3x4 => |*value| c.glGetUniformdv(program, location, value),
+ .DOUBLE_MAT4x2 => |*value| c.glGetUniformdv(program, location, value),
+ .DOUBLE_MAT4x3 => |*value| c.glGetUniformdv(program, location, value),
+ .SAMPLER_1D, .SAMPLER_2D, .SAMPLER_3D, .SAMPLER_CUBE, .SAMPLER_1D_SHADOW, .SAMPLER_2D_SHADOW, .SAMPLER_1D_ARRAY, .SAMPLER_2D_ARRAY, .SAMPLER_1D_ARRAY_SHADOW, .SAMPLER_2D_ARRAY_SHADOW, .SAMPLER_2D_MULTISAMPLE, .SAMPLER_2D_MULTISAMPLE_ARRAY, .SAMPLER_CUBE_SHADOW, .SAMPLER_BUFFER, .SAMPLER_2D_RECT, .SAMPLER_2D_RECT_SHADOW, .INT_SAMPLER_1D, .INT_SAMPLER_2D, .INT_SAMPLER_3D, .INT_SAMPLER_CUBE, .INT_SAMPLER_1D_ARRAY, .INT_SAMPLER_2D_ARRAY, .INT_SAMPLER_2D_MULTISAMPLE, .INT_SAMPLER_2D_MULTISAMPLE_ARRAY, .INT_SAMPLER_BUFFER, .INT_SAMPLER_2D_RECT, .UNSIGNED_INT_SAMPLER_1D, .UNSIGNED_INT_SAMPLER_2D, .UNSIGNED_INT_SAMPLER_3D, .UNSIGNED_INT_SAMPLER_CUBE, .UNSIGNED_INT_SAMPLER_1D_ARRAY, .UNSIGNED_INT_SAMPLER_2D_ARRAY, .UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE, .UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY, .UNSIGNED_INT_SAMPLER_BUFFER, .UNSIGNED_INT_SAMPLER_2D_RECT => |*value| c.glGetnUniformiv(program, location, @sizeOf(@TypeOf(value.*)), value),
+ else => unreachable,
+ }
+ }
+ // zig fmt: on
+};
pub const ShaderProgram = struct {
program_id: c.GLuint,
@@ -27,30 +313,6 @@ pub const ShaderProgram = struct {
return id;
}
- pub fn setUniform1i(self: ShaderProgram, uniform_id: c.GLint, value: c_int) void {
- c.glUniform1i(uniform_id, value);
- }
-
- pub fn setUniform1f(self: ShaderProgram, uniform_id: c.GLint, value: f32) void {
- c.glUniform1f(uniform_id, value);
- }
-
- pub fn setUniform2f(self: ShaderProgram, uniform_id: c.GLint, x: f32, y: f32) void {
- c.glUniform2f(uniform_id, x, y);
- }
-
- pub fn setUniform3f(self: ShaderProgram, uniform_id: c.GLint, x: f32, y: f32, z: f32) void {
- c.glUniform3f(uniform_id, x, y, z);
- }
-
- pub fn setUniform4f(self: ShaderProgram, uniform_id: c.GLint, x: f32, y: f32, z: f32, w: f32) void {
- c.glUniform4f(uniform_id, x, y, z, w);
- }
-
- 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(vert_source: []const u8, frag_source: []const u8) !ShaderProgram {
var self: ShaderProgram = undefined;
@@ -92,6 +354,69 @@ pub const ShaderProgram = struct {
}
};
+pub const UniformCache = struct {
+ uniforms: std.AutoHashMap([*]const u8, CachedUniform),
+ shader: *ShaderProgram,
+
+ pub fn init(allocator: *std.mem.Allocator, shader: *ShaderProgram) UniformCache {
+ return UniformCache{
+ .uniforms = std.AutoHashMap([*]const u8, CachedUniform).init(allocator),
+ .shader = shader,
+ };
+ }
+
+ pub fn deinit(self: *UniformCache) void {
+ self.uniforms.deinit();
+ }
+
+ pub fn refresh(self: *UniformCache) !void {
+ var uniform_count: c.GLint = undefined;
+ c.glGetProgramiv(self.shader.program_id, c.GL_ACTIVE_UNIFORMS, &uniform_count);
+
+ const count = self.uniforms.count();
+ var existing_names = try c_allocator.alloc([*]const u8, count);
+ defer c_allocator.free(existing_names);
+ var existing_indices = try c_allocator.alloc(c.GLuint, count);
+ defer c_allocator.free(existing_indices);
+
+ {
+ var it = self.uniforms.iterator();
+ var i: usize = 0;
+ while (it.next()) |entry| {
+ existing_names[i] = entry.key;
+ i += 1;
+ }
+ }
+
+ c.glGetUniformIndices(self.shader.program_id, @intCast(c.GLsizei, count), existing_names.ptr, existing_indices.ptr);
+
+ for (existing_indices) |index, i| {
+ const name = existing_names[i];
+ if (index == c.GL_INVALID_INDEX) {
+ _ = self.uniforms.remove(name);
+ // @TODO: remove OSC link
+ } else {
+ var uniform = self.uniforms.get(name).?.value;
+ uniform.location = self.shader.uniformLocation(name) catch unreachable;
+ uniform.setShaderValue(self.shader.*);
+ }
+ }
+ }
+
+ pub fn get(self: *UniformCache, name: [*]const u8) !?*CachedUniform {
+ var result = try self.uniforms.getOrPut(name);
+ if (!result.found_existing) {
+ result.kv.value = CachedUniform.init(self.shader.*, name) catch {
+ _ = self.uniforms.remove(name);
+ return null;
+ };
+ // @TODO: add OSC link
+ }
+
+ return &result.kv.value;
+ }
+};
+
fn initGlShader(source: []const u8, name: []const u8, kind: c.GLenum) !c.GLuint {
const shader_id = c.glCreateShader(kind);
errdefer c.glDeleteShader(shader_id);
@@ -179,7 +504,7 @@ pub const VertexObject = struct {
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);
+ c.glBufferData(c.GL_ARRAY_BUFFER, @intCast(c_long, @sizeOf(T) * vertices.len), @ptrCast(*const c_void, vertices.ptr), c.GL_STATIC_DRAW);
return self;
}
@@ -191,17 +516,16 @@ pub const VertexObject = struct {
};
pub const Constants = struct {
- textureShader: ShaderProgram,
- normalizedQuad: VertexObject,
+ texture_shader: ShaderProgram,
+ normalized_quad: VertexObject,
main_window: *c.GLFWwindow,
+ aspect: f32,
+ config: *cfg.Config,
- pub fn create(main_window: *c.GLFWwindow) !Constants {
- var self: Constants = undefined;
-
+ pub fn create(main_window: *c.GLFWwindow, config: *cfg.Config) !Constants {
c.glfwMakeContextCurrent(main_window);
- self.main_window = main_window;
- self.textureShader = try ShaderProgram.create(
+ const shader = try ShaderProgram.create(
\\#version 330 core
\\
\\layout(location = 0) in vec2 position;
@@ -230,13 +554,18 @@ pub const Constants = struct {
1.0, -1.0,
1.0, 1.0,
};
- self.normalizedQuad = VertexObject.create(f32, vertices[0..], 2);
- return self;
+ return Constants{
+ .main_window = main_window,
+ .texture_shader = shader,
+ .normalized_quad = VertexObject.create(f32, vertices[0..], 2),
+ .config = config,
+ .aspect = @intToFloat(f32, config.width) / @intToFloat(f32, config.height),
+ };
}
pub fn destroy(self: *Constants) void {
- self.normalizedQuad.destroy();
- self.textureShader.destroy();
+ self.normalized_quad.destroy();
+ self.texture_shader.destroy();
}
};