diff options
| author | s-ol <s+removethis@s-ol.nu> | 2025-02-24 10:16:36 +0000 |
|---|---|---|
| committer | s-ol <s+removethis@s-ol.nu> | 2025-02-24 13:18:04 +0000 |
| commit | 96063a5d32d41a70cdbfba68e3f018c9c320aa68 (patch) | |
| tree | 3adadd5cc7ce41f68919ee28f9e56b2b1fec2c54 /src/gl.zig | |
| parent | update for zig 0.13.0 (diff) | |
| download | glsl-view-96063a5d32d41a70cdbfba68e3f018c9c320aa68.tar.gz glsl-view-96063a5d32d41a70cdbfba68e3f018c9c320aa68.zip | |
load videos and textures using libav
Diffstat (limited to 'src/gl.zig')
| -rw-r--r-- | src/gl.zig | 327 |
1 files changed, 279 insertions, 48 deletions
@@ -10,6 +10,120 @@ fn tmpZ(str: []const u8) ![:0]const u8 { return try std.fmt.bufPrintZ(state.buf[0..], "{s}", .{str}); } +var image_unit_map = [_]bool{false} ** 1024; + +pub const Texture = struct { + pub const Type = enum(c.GLenum) { + TEXTURE_1D = c.GL_TEXTURE_1D, + TEXTURE_2D = c.GL_TEXTURE_2D, + TEXTURE_3D = c.GL_TEXTURE_3D, + TEXTURE_CUBEMAP = c.GL_TEXTURE_CUBE_MAP, + TEXTURE_RECTANGLE = c.GL_TEXTURE_RECTANGLE, + TEXTURE_2D_MULTISAMPLE = c.GL_TEXTURE_2D_MULTISAMPLE, + TEXTURE_1D_ARRAY = c.GL_TEXTURE_1D_ARRAY, + TEXTURE_2D_ARRAY = c.GL_TEXTURE_2D_ARRAY, + TEXTURE_CUBEMAP_ARRAY = c.GL_TEXTURE_CUBE_MAP_ARRAY, + TEXTURE_BUFFER = c.GL_TEXTURE_BUFFER, + TEXTURE_2D_MULTISAMPLE_ARRAY = c.GL_TEXTURE_2D_MULTISAMPLE_ARRAY, + }; + + type: Type, + id: c.GLuint, + image_unit: ?usize, + + pub fn create(texture_type: Type) Texture { + var self: Texture = .{ + .type = texture_type, + .id = undefined, + .image_unit = null, + }; + c.glGenTextures(1, &self.id); + + c.glBindTexture(@intFromEnum(self.type), self.id); + defer c.glBindTexture(@intFromEnum(self.type), 0); + + c.glTexParameteri(@intFromEnum(self.type), c.GL_TEXTURE_MIN_FILTER, c.GL_LINEAR); + c.glTexParameteri(@intFromEnum(self.type), c.GL_TEXTURE_MAG_FILTER, c.GL_LINEAR); + + return self; + } + + pub fn bind(self: *Texture) usize { + if (self.image_unit == null) { + for (image_unit_map[0..], 0..) |*slot, i| { + if (slot.*) continue; + + slot.* = true; + self.image_unit = @intCast(i); + break; + } + } + + if (self.image_unit) |image_unit| { + c.glActiveTexture(@intCast(c.GL_TEXTURE0 + image_unit)); + c.glBindTexture(@intFromEnum(self.type), self.id); + return image_unit; + } else unreachable; + } + + pub fn destroy(self: *const Texture) void { + if (self.image_unit) |image_unit| { + image_unit_map[image_unit] = false; + } + c.glDeleteTextures(1, &self.id); + } + + pub fn setData2D(self: *const Texture, width: i32, height: i32, data: [*]const u8) void { + c.glBindTexture(@intFromEnum(self.type), self.id); + defer c.glBindTexture(@intFromEnum(self.type), 0); + + c.glTexImage2D( + @intFromEnum(self.type), + 0, + c.GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, // c.GL_RGBA, + width, + height, + 0, + c.GL_RGBA, + c.GL_UNSIGNED_BYTE, + data, + ); + } + + pub fn allocate3D(self: *const Texture, width: i32, height: i32, depth: i32) void { + c.glBindTexture(@intFromEnum(self.type), self.id); + defer c.glBindTexture(@intFromEnum(self.type), 0); + + c.glTexStorage3D( + @intFromEnum(self.type), + 1, + c.GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, // c.GL_RGBA, + width, + height, + depth, + ); + } + + pub fn setLayer3D(self: *const Texture, width: i32, height: i32, layer: i32, data: [*]const u8) void { + c.glBindTexture(@intFromEnum(self.type), self.id); + defer c.glBindTexture(@intFromEnum(self.type), 0); + + c.glTexSubImage3D( + @intFromEnum(self.type), + 0, + 0, + 0, + layer, + width, + height, + 1, + c.GL_RGBA, + c.GL_UNSIGNED_BYTE, + data, + ); + } +}; + const UniformType = enum(c.GLint) { FLOAT = c.GL_FLOAT, FLOAT_VEC2 = c.GL_FLOAT_VEC2, @@ -126,42 +240,42 @@ const UniformValue = union(UniformType) { 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, + SAMPLER_1D: *?Texture, + SAMPLER_2D: *?Texture, + SAMPLER_3D: *?Texture, + SAMPLER_CUBE: *?Texture, + SAMPLER_1D_SHADOW: *?Texture, + SAMPLER_2D_SHADOW: *?Texture, + SAMPLER_1D_ARRAY: *?Texture, + SAMPLER_2D_ARRAY: *?Texture, + SAMPLER_1D_ARRAY_SHADOW: *?Texture, + SAMPLER_2D_ARRAY_SHADOW: *?Texture, + SAMPLER_2D_MULTISAMPLE: *?Texture, + SAMPLER_2D_MULTISAMPLE_ARRAY: *?Texture, + SAMPLER_CUBE_SHADOW: *?Texture, + SAMPLER_BUFFER: *?Texture, + SAMPLER_2D_RECT: *?Texture, + SAMPLER_2D_RECT_SHADOW: *?Texture, + INT_SAMPLER_1D: *?Texture, + INT_SAMPLER_2D: *?Texture, + INT_SAMPLER_3D: *?Texture, + INT_SAMPLER_CUBE: *?Texture, + INT_SAMPLER_1D_ARRAY: *?Texture, + INT_SAMPLER_2D_ARRAY: *?Texture, + INT_SAMPLER_2D_MULTISAMPLE: *?Texture, + INT_SAMPLER_2D_MULTISAMPLE_ARRAY: *?Texture, + INT_SAMPLER_BUFFER: *?Texture, + INT_SAMPLER_2D_RECT: *?Texture, + UNSIGNED_INT_SAMPLER_1D: *?Texture, + UNSIGNED_INT_SAMPLER_2D: *?Texture, + UNSIGNED_INT_SAMPLER_3D: *?Texture, + UNSIGNED_INT_SAMPLER_CUBE: *?Texture, + UNSIGNED_INT_SAMPLER_1D_ARRAY: *?Texture, + UNSIGNED_INT_SAMPLER_2D_ARRAY: *?Texture, + UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: *?Texture, + UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: *?Texture, + UNSIGNED_INT_SAMPLER_BUFFER: *?Texture, + UNSIGNED_INT_SAMPLER_2D_RECT: *?Texture, pub fn init(allocator: std.mem.Allocator, comptime utype: UniformType) !UniformValue { const data = try allocator.create(std.meta.Child(std.meta.TagPayload(UniformValue, utype))); @@ -170,6 +284,46 @@ const UniformValue = union(UniformType) { pub fn deinit(self: *const UniformValue, allocator: std.mem.Allocator) void { switch (self.*) { + .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| { + if (value.*) |texture| texture.destroy(); + allocator.destroy(value); + }, inline else => |value| allocator.destroy(value), } } @@ -239,7 +393,6 @@ pub const CachedUniform = struct { return true; } - // zig fmt: off pub fn setShaderValue(self: *const CachedUniform, shader: ShaderProgram) void { const program = shader.program_id; const location = self.location; @@ -283,7 +436,48 @@ pub const CachedUniform = struct { .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.*), + .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| { + if (value.*) |*texture| { + const index = texture.bind(); + c.glProgramUniform1i(program, location, @intCast(index)); + } + }, } } @@ -330,10 +524,45 @@ pub const CachedUniform = struct { .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), + .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| value.* = null, } } - // zig fmt: on }; pub const ShaderProgram = struct { @@ -418,21 +647,18 @@ pub const UniformCache = struct { } 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) catch return null; + var uniform = CachedUniform.init(self.allocator, self.shader.*, name) catch return null; errdefer uniform.deinit(self.allocator); + uniform.getShaderValue(self.shader.*); try self.uniforms.put(cloned_name, uniform); - getValue = true; } if (self.uniforms.getPtr(name)) |ptr| { - ptr.getShaderValue(self.shader.*); return ptr; } @@ -504,9 +730,11 @@ pub const FramebufferObject = struct { var self: FramebufferObject = undefined; c.glGenFramebuffers(1, &self.buffer_id); c.glBindFramebuffer(c.GL_FRAMEBUFFER, self.buffer_id); + defer c.glBindFramebuffer(c.GL_FRAMEBUFFER, 0); c.glGenTextures(1, &self.texture_id); c.glBindTexture(c.GL_TEXTURE_2D, self.texture_id); + defer c.glBindTexture(c.GL_TEXTURE_2D, 0); c.glTexImage2D( c.GL_TEXTURE_2D, 0, @@ -520,7 +748,6 @@ pub const FramebufferObject = struct { ); 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, @@ -533,7 +760,6 @@ pub const FramebufferObject = struct { if (c.glCheckFramebufferStatus(c.GL_FRAMEBUFFER) != c.GL_FRAMEBUFFER_COMPLETE) return error.FBONotComplete; - c.glBindFramebuffer(c.GL_FRAMEBUFFER, 0); return self; } @@ -570,7 +796,12 @@ 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, @as(c_long, @intCast(@sizeOf(T) * vertices.len)), @as(*const anyopaque, @ptrCast(vertices.ptr)), c.GL_STATIC_DRAW); + c.glBufferData( + c.GL_ARRAY_BUFFER, + @as(c_long, @intCast(@sizeOf(T) * vertices.len)), + @as(*const anyopaque, @ptrCast(vertices.ptr)), + c.GL_STATIC_DRAW, + ); return self; } |
