aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authors-ol <s+removethis@s-ol.nu>2023-11-03 14:56:32 +0000
committers-ol <s+removethis@s-ol.nu>2023-11-03 15:18:38 +0000
commitab68536ec557de90ff074e93f78f608d47d8609a (patch)
treefbc659499530898e7274f96cfc2e872956c9eb5e /src
parentallow indexing uniforms, fix bug (diff)
downloadglsl-view-ab68536ec557de90ff074e93f78f608d47d8609a.tar.gz
glsl-view-ab68536ec557de90ff074e93f78f608d47d8609a.zip
only restore uniform values if type unchanged
Diffstat (limited to 'src')
-rw-r--r--src/gl.zig101
1 files changed, 51 insertions, 50 deletions
diff --git a/src/gl.zig b/src/gl.zig
index 8b7ef3b..bfd3bc5 100644
--- a/src/gl.zig
+++ b/src/gl.zig
@@ -3,6 +3,13 @@ const c_allocator = @import("std").heap.c_allocator;
const c = @import("c.zig");
const cfg = @import("config.zig");
+fn tmpZ(str: []const u8) ![:0]const u8 {
+ const state = struct {
+ var buf: [256]u8 = undefined;
+ };
+ return try std.fmt.bufPrintZ(state.buf[0..], "{s}", .{str});
+}
+
const UniformType = enum(c.GLint) {
FLOAT = c.GL_FLOAT,
FLOAT_VEC2 = c.GL_FLOAT_VEC2,
@@ -194,10 +201,12 @@ pub const CachedUniform = struct {
value: UniformValue,
location: c.GLint,
- pub fn init(allocator: std.mem.Allocator, shader: ShaderProgram, name: [*]const u8) !CachedUniform {
+ pub fn init(allocator: std.mem.Allocator, shader: ShaderProgram, name: []const u8) !CachedUniform {
var index: c.GLuint = undefined;
- c.glGetUniformIndices(shader.program_id, 1, &name, &index);
+ const nameZ = try tmpZ(name);
+
+ c.glGetUniformIndices(shader.program_id, 1, &nameZ.ptr, &index);
if (index == c.GL_INVALID_INDEX)
return error.invalidUniform;
@@ -206,7 +215,7 @@ pub const CachedUniform = struct {
switch (@as(UniformType, @enumFromInt(_utype))) {
inline else => |utype| {
- const location = try shader.uniformLocation(name);
+ const location = try shader.uniformLocation(nameZ);
const value = try UniformValue.init(allocator, utype);
errdefer value.deinit(allocator);
@@ -219,6 +228,17 @@ pub const CachedUniform = struct {
self.value.deinit(allocator);
}
+ pub fn tryCopy(self: *CachedUniform, from: CachedUniform) bool {
+ if (@as(UniformType, self.value) != from.value) return false;
+
+ switch (self.value) {
+ inline else => |*val, tag| {
+ val.*.* = @field(from.value, @tagName(tag)).*;
+ },
+ }
+ return true;
+ }
+
// zig fmt: off
pub fn setShaderValue(self: *const CachedUniform, shader: ShaderProgram) void {
const program = shader.program_id;
@@ -325,10 +345,11 @@ pub const ShaderProgram = struct {
c.glUseProgram(self.program_id);
}
- pub fn uniformLocation(self: ShaderProgram, name: [*]const u8) !c.GLint {
- const id = c.glGetUniformLocation(self.program_id, name);
+ pub fn uniformLocation(self: ShaderProgram, nameZ: [:0]const u8) !c.GLint {
+ const id = c.glGetUniformLocation(self.program_id, nameZ);
if (id == -1)
return error.invalidUniform;
+
return id;
}
@@ -396,57 +417,14 @@ pub const UniformCache = struct {
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_names_c = try c_allocator.alloc([*]const u8, count);
- defer c_allocator.free(existing_names_c);
- 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_ptr.*;
- existing_names_c[i] = entry.key_ptr.*.ptr;
- i += 1;
- }
- }
-
- c.glGetUniformIndices(
- self.shader.program_id,
- @as(c.GLsizei, @intCast(count)),
- existing_names_c.ptr,
- existing_indices.ptr,
- );
-
- for (existing_indices, 0..) |index, i| {
- const name = existing_names[i];
- if (index == c.GL_INVALID_INDEX) {
- if (self.uniforms.remove(name)) {
- self.allocator.free(name);
- }
- } else {
- var uniform = self.uniforms.get(name).?;
- uniform.location = self.shader.uniformLocation(name.ptr) catch unreachable;
- uniform.setShaderValue(self.shader.*);
- }
- }
- }
-
- pub fn get(self: *UniformCache, name: [:0]u8) !?*CachedUniform {
+ pub fn get(self: *UniformCache, name: []const u8) !?*CachedUniform {
var getValue = false;
if (!self.uniforms.contains(name)) {
const cloned_name = try self.allocator.dupe(u8, name);
errdefer self.allocator.free(cloned_name);
- const uniform = CachedUniform.init(self.allocator, self.shader.*, name.ptr) catch return null;
+ const uniform = CachedUniform.init(self.allocator, self.shader.*, name) catch return null;
errdefer uniform.deinit(self.allocator);
try self.uniforms.put(cloned_name, uniform);
@@ -460,6 +438,29 @@ pub const UniformCache = struct {
return null;
}
+
+ pub fn refresh(self: *UniformCache) !void {
+ var old_uniforms = self.uniforms.move();
+ defer {
+ var it = old_uniforms.iterator();
+ while (it.next()) |entry| {
+ self.allocator.free(entry.key_ptr.*);
+ entry.value_ptr.deinit(self.allocator);
+ }
+ old_uniforms.deinit();
+ }
+
+ {
+ var it = old_uniforms.iterator();
+ while (it.next()) |old_entry| {
+ if (try self.get(old_entry.key_ptr.*)) |uniform| {
+ if (uniform.tryCopy(old_entry.value_ptr.*)) {
+ uniform.setShaderValue(self.shader.*);
+ }
+ }
+ }
+ }
+ }
};
fn initGlShader(source: []const u8, name: []const u8, kind: c.GLenum) !c.GLuint {