From 5e766ab9c6a84c0de5fc9142edd5fdbe8437da3a Mon Sep 17 00:00:00 2001 From: IntegratedQuantum Date: Sun, 28 Aug 2022 09:54:00 +0200 Subject: [PATCH] Add shader compilation and use reflection to assign uniform locations. --- src/graphics.zig | 94 ++++++++++++++++++++++++++++++++++++++++++++++++ src/main.zig | 13 ++++++- 2 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 src/graphics.zig diff --git a/src/graphics.zig b/src/graphics.zig new file mode 100644 index 00000000..dc1ef240 --- /dev/null +++ b/src/graphics.zig @@ -0,0 +1,94 @@ +/// A collection of things that should make dealing with opengl easier. +/// Also contains some basic 2d drawing stuff. + +const std = @import("std"); + +const Allocator = std.mem.Allocator; + +const c = @cImport ({ + @cInclude("glad/glad.h"); +}); + +fn fileToString(allocator: Allocator, path: []const u8) ![]u8 { + const file = try std.fs.cwd().openFile(path, .{}); + return file.readToEndAlloc(allocator, std.math.maxInt(usize)); +} + +pub fn init() void { + +} + +pub fn deinit() void { + +} + +pub const Shader = struct { + id: c_uint, + + fn addShader(self: *const Shader, filename: []const u8, shader_stage: c_uint) !void { + const source = try fileToString(std.heap.page_allocator, filename); + defer std.heap.page_allocator.free(source); + const ref_buffer = [_] [*c]u8 {@ptrCast([*c]u8, source.ptr)}; + const shader = c.glCreateShader(shader_stage); + defer c.glDeleteShader(shader); + + var sourceLen: c_int = @intCast(c_int, source.len); + c.glShaderSource(shader, 1, @ptrCast([*c]const [*c]const u8, &ref_buffer[0]), &sourceLen); + + c.glCompileShader(shader); + + var success: c_int = undefined; + c.glGetShaderiv(shader, c.GL_COMPILE_STATUS, &success); + if(success != c.GL_TRUE) { + var len: u32 = undefined; + c.glGetShaderiv(shader, c.GL_INFO_LOG_LENGTH, @ptrCast(*c_int, &len)); + var buf: [4096] u8 = undefined; + c.glGetShaderInfoLog(shader, 4096, @ptrCast(*c_int, &len), &buf); + std.log.err("Error compiling shader {s}:\n{s}\n", .{filename, buf[0..len]}); + return error.FailedCompiling; + } + + c.glAttachShader(self.id, shader); + } + + fn link(self: *const Shader) !void { + c.glLinkProgram(self.id); + + var success: c_int = undefined; + c.glGetProgramiv(self.id, c.GL_LINK_STATUS, &success); + if(success != c.GL_TRUE) { + var len: u32 = undefined; + c.glGetProgramiv(self.id, c.GL_INFO_LOG_LENGTH, @ptrCast(*c_int, &len)); + var buf: [4096] u8 = undefined; + c.glGetProgramInfoLog(self.id, 4096, @ptrCast(*c_int, &len), &buf); + std.log.err("Error Linking Shader program:\n{s}\n", .{buf[0..len]}); + return error.FailedLinking; + } + } + + pub fn create(vertex: []const u8, fragment: []const u8) !Shader { + var shader = Shader{.id = c.glCreateProgram()}; + try shader.addShader(vertex, c.GL_VERTEX_SHADER); + try shader.addShader(fragment, c.GL_FRAGMENT_SHADER); + try shader.link(); + return shader; + } + + pub fn bulkGetUniformLocation(self: *const Shader, comptime T: type) T { + var ret: T = undefined; + inline for(@typeInfo(T).Struct.fields) |field| { + if(field.field_type == c_int) { + @field(ret, field.name) = c.glGetUniformLocation(self.id, field.name[0..]); + } + } + return ret; + } + + pub fn bind(self: *const Shader) void { + c.glUseProgram(self.id); + } + + pub fn delete(self: *const Shader) void { + c.glDeleteProgram(self.id); + } +}; \ No newline at end of file diff --git a/src/main.zig b/src/main.zig index 427864fc..00628a92 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1,5 +1,7 @@ const std = @import("std"); +const graphics = @import("graphics.zig"); + pub const c = @cImport ({ @cInclude("glad/glad.h"); @cInclude("GLFW/glfw3.h"); @@ -99,7 +101,7 @@ pub const Window = struct { return; } const vidMode = c.glfwGetVideoMode(monitor).?; - c.glfwSetWindowMonitor(window, monitor, 0, 0, vidMode.width, vidMode.height, c.GLFW_DONT_CARE); + c.glfwSetWindowMonitor(window, monitor, 0, 0, vidMode[0].width, vidMode[0].height, c.GLFW_DONT_CARE); } else { c.glfwSetWindowMonitor(window, null, oldX, oldY, oldWidth, oldHeight, c.GLFW_DONT_CARE); c.glfwSetWindowAttrib(window, c.GLFW_DECORATED, c.GLFW_TRUE); @@ -115,7 +117,16 @@ pub fn main() !void { try Window.init(); defer Window.deinit(); + graphics.init(); + defer graphics.deinit(); + while(c.glfwWindowShouldClose(Window.window) == 0) { + { // Check opengl errors: + const err = c.glGetError(); + if(err != 0) { + std.log.err("Got opengl error: {}", .{err}); + } + } c.glfwSwapBuffers(Window.window); c.glfwPollEvents(); c.glViewport(0, 0, Window.width, Window.height);