diff --git a/src/gl.zig b/src/gl.zig new file mode 100644 index 0000000..03a9d48 --- /dev/null +++ b/src/gl.zig @@ -0,0 +1,16 @@ +const c = @import("c.zig"); + +pub const buffer = @import("gl/buffer.zig"); + +pub fn init() void { + if (c.gladLoadGLLoader(@ptrCast(c.GLADloadproc, c.glfwGetProcAddress)) == 0) { + @panic("Failed to initialise GLAD"); + } + c.glEnable(c.GL_DEPTH_TEST); + c.glDisable(c.GL_MULTISAMPLE); + c.glEnable(c.GL_CULL_FACE); +} + +pub fn viewport(x: c_int, y: c_int, width: c_int, height: c_int) void{ + c.glViewport(x, y, width, height); +} \ No newline at end of file diff --git a/src/gl/buffer.zig b/src/gl/buffer.zig new file mode 100644 index 0000000..3335608 --- /dev/null +++ b/src/gl/buffer.zig @@ -0,0 +1,80 @@ +const c = @import("../c.zig"); + +pub const Target = enum(c_uint) { + vertex = c.GL_ARRAY_BUFFER, + index = c.GL_ELEMENT_ARRAY_BUFFER, +}; + +pub const Usage = enum(c_uint) { + stream_draw = c.GL_STREAM_DRAW, + stream_read = c.GL_STREAM_READ, + stream_copy = c.GL_STREAM_COPY, + static_draw = c.GL_STATIC_DRAW, + static_read = c.GL_STATIC_READ, + static_copy = c.GL_STATIC_COPY, + dynamic_draw = c.GL_DYNAMIC_DRAW, + dynamic_read = c.GL_DYNAMIC_READ, + dynamic_copy = c.GL_DYNAMIC_COPY, +}; + +pub fn VertexBuffer(comptime ElementT: type) type { + return Buffer(.vertex, ElementT); +} + +pub fn IndexBuffer(comptime ElementT: type) type { + return Buffer(.index, ElementT); +} + +pub const IndexBuffer8 = IndexBuffer(u8); +pub const IndexBuffer16 = IndexBuffer(u16); +pub const IndexBuffer32 = IndexBuffer(u32); + +pub fn Buffer(comptime target: Target, comptime ElementT: type) type { + return struct { + /// + handle: c_int, + + pub const Element = ElementT; + pub const Target = target; + + const Self = @This(); + + /// create a new buffer on the gpu + pub fn init() Self { + var handle: c_int = undefined; + c.glCreateBuffers(1, &handle); + return Self { .handle = handle }; + } + + /// delete this buffer + pub fn deinit(self: Self) void { + c.glDeleteBuffers(1, &self.handle); + } + + /// allocate `size` bytes and declare usage + /// old data is discarded, if it exists + pub fn alloc(self: Self, size: usize, usage: Usage) void { + c.glNamedBufferData(self.handle, @intCast(c_longlong, size * @sizeOf(Element)), c.NULL, @enumToInt(usage)); + } + + /// upload data, allocating enough bytes to store it, and declare usage + /// old data is discarded, if it exists + pub fn data(self: Self, data_slice: []const Element, usage: Usage) void { + const ptr = @ptrCast(*const c_void, data_slice.ptr); + const size = @intCast(c_longlong, @sizeOf(Element) * data_slice.len); + c.glNamedBufferData(self.handle, size, ptr, @enumToInt(usage)); + } + + /// replace a slice of data in the buffer. no reallocation will occur + pub fn subData(self: Self, data_slice: []const Element, offset: usize) void { + const ptr = @ptrCast(*const c_void, data_slice.ptr); + const size = @intCast(c_longlong, @sizeOf(Element) * data_slice.len); + c.glNamedBufferSubData(self.handle, offset, size, ptr); + } + + /// replace all data in the buffer + pub fn update(self: Self, data_slice: []const Element) void { + self.subdata(data_slice, 0); + } + }; +} \ No newline at end of file diff --git a/src/gl/types.zig b/src/gl/types.zig new file mode 100644 index 0000000..2a93d18 --- /dev/null +++ b/src/gl/types.zig @@ -0,0 +1,3 @@ +// const c = @import("../c.zig"); + +pub const Handle = c_int; \ No newline at end of file diff --git a/src/main.zig b/src/main.zig index ff38d08..8b73c6f 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1,5 +1,6 @@ const std = @import("std"); const builtin = @import("builtin"); +const gl = @import("gl.zig"); const glfw = @import("glfw.zig"); const math = @import("math.zig"); @@ -10,6 +11,8 @@ pub fn main() anyerror!void { var window = glfw.Window.init(640, 360, "a toki ma!"); defer window.deinit(); + gl.init(); + while (!window.shouldClose()) { window.update(); window.swapBuffers();