diff options
author | alaric <alaric@netmythos.org> | 2024-04-04 05:05:25 -0700 |
---|---|---|
committer | alaric <alaric@netmythos.org> | 2024-04-04 05:05:25 -0700 |
commit | 1df80599c7157db86925e7d4ade99544285dfd30 (patch) | |
tree | fedaf626fed8c946bb0526cf54613c8458c04895 | |
parent | e4d1a7e30c586e07441e65d3062bbc7f67b1aea5 (diff) | |
download | menger-1df80599c7157db86925e7d4ade99544285dfd30.tar.gz menger-1df80599c7157db86925e7d4ade99544285dfd30.zip |
Wiggling scaling cube
-rw-r--r-- | src/fragment.glsl | 6 | ||||
-rw-r--r-- | src/matrix.zig | 79 | ||||
-rw-r--r-- | src/shell.html | 4 | ||||
-rw-r--r-- | src/vertex.glsl | 11 | ||||
-rw-r--r-- | src/wasm_msponge.zig | 186 | ||||
-rw-r--r-- | src/webgl.js | 16 | ||||
-rw-r--r-- | src/webgl.zig | 167 | ||||
-rw-r--r-- | src/webgl_bindings.zig | 21 |
8 files changed, 427 insertions, 63 deletions
diff --git a/src/fragment.glsl b/src/fragment.glsl index 1aa44f8..c1a126d 100644 --- a/src/fragment.glsl +++ b/src/fragment.glsl @@ -1,8 +1,12 @@ #version 300 es precision highp float; +in vec4 a_col; + +uniform vec3 color; + out vec4 outColor; void main() { - outColor = vec4(1, 0, 0, 1); // red + outColor = a_col * vec4(color, 1); } diff --git a/src/matrix.zig b/src/matrix.zig index 025af7c..b7cf397 100644 --- a/src/matrix.zig +++ b/src/matrix.zig @@ -1,9 +1,10 @@ -pub fn Matrix(comptime T: type, rows: usize, cols: usize) type { - const RowVec = @Vector(rows, T); - const ColVec = @Vector(cols, T); - +pub fn Matrix(comptime T: type, row_count: usize, col_count: usize) type { return struct { - pub const RowT = [rows]T; + pub const ValT = T; + pub const rows = row_count; + pub const cols = col_count; + pub const RowT = [cols]T; + pub const ColT = [rows]T; const Self = @This(); pub const identity: Self = blk: { @@ -18,22 +19,24 @@ pub fn Matrix(comptime T: type, rows: usize, cols: usize) type { break :blk .{ .data = r }; }; - data: [cols]RowT, + data: [cols]ColT, - pub fn multiply(a: Self, b: Self) Self { - comptime assert(rows == cols); - var result: Self = undefined; - for (0..rows) |ri| { - const r = a.row(ri); - for (0..cols) |ci| { - const c = b.data[ci]; + pub fn multiply(self: Self, other: anytype) MatMultResult(Self, @TypeOf(other)) { + const OtherT = @TypeOf(other); + comptime assert(Self.cols == OtherT.rows); + const ResultT = MatMultResult(Self, @TypeOf(other)); + var result: ResultT = undefined; + for (0..ResultT.rows) |ri| { + const r: @Vector(Self.cols, T) = self.row(ri); + for (0..ResultT.cols) |ci| { + const c: @Vector(OtherT.rows, T) = other.data[ci]; result.data[ci][ri] = @reduce(.Add, r * c); } } return result; } - pub fn translation(t: @Vector(cols - 1, T)) Self { + pub fn translation(t: [cols - 1]T) Self { var base = Self.identity; for (0..cols - 1) |ci| { base.data[ci][rows - 1] = t[ci]; @@ -41,7 +44,31 @@ pub fn Matrix(comptime T: type, rows: usize, cols: usize) type { return base; } - pub fn rotation(angle: T) Self { + pub fn xRotation(angle: T) Self { + if (rows < 3 or cols < 3) @compileError("Called xRotation on a Matrix smaller than 3x3"); + const c = @cos(angle); + const s = @sin(angle); + var base = Self.identity; + base.data[1][1] = c; + base.data[2][2] = c; + base.data[2][1] = s; + base.data[1][2] = -s; + return base; + } + + pub fn yRotation(angle: T) Self { + if (rows < 3 or cols < 3) @compileError("Called yRotation on a Matrix smaller than 3x3"); + const c = @cos(angle); + const s = @sin(angle); + var base = Self.identity; + base.data[0][0] = c; + base.data[2][2] = c; + base.data[2][0] = s; + base.data[0][2] = -s; + return base; + } + + pub fn zRotation(angle: T) Self { if (rows < 2 or cols < 2) @compileError("Called rotation on a Matrix smaller than 2x2"); const c = @cos(angle); const s = @sin(angle); @@ -53,28 +80,38 @@ pub fn Matrix(comptime T: type, rows: usize, cols: usize) type { return base; } - pub fn scale(sx: T, sy: T) Self { + pub fn scale(vals: [@min(rows, cols) - 1]f32) Self { var r = identity; - r.data[0][0] = sx; - r.data[1][1] = sy; + for (vals, 0..) |v, i| { + r.data[i][i] = v; + } return r; } - pub fn row(self: Self, ri: usize) RowVec { - var r: RowVec = undefined; + pub fn row(self: Self, ri: usize) RowT { + var r: RowT = undefined; for (0..cols) |ci| { r[ci] = self.data[ci][ri]; } return r; } - pub fn col(self: Self, ci: usize) ColVec { + pub fn col(self: Self, ci: usize) ColT { const start = ci * rows; return self.data[start .. start + cols]; } }; } +fn MatMultResult(a: type, b: type) type { + if (a.cols != b.rows) { + @compileLog("Matrix Multiplication requires that the number of columns in the lhs equals the number of rows in the rhs.", a, b); + @compileError("Matrix multiplication with mismatched dimensions"); + } + + return Matrix(a.ValT, a.rows, b.cols); +} + fn assert(ok: bool) void { if (!ok) unreachable; } diff --git a/src/shell.html b/src/shell.html index cc1e002..ecbf8fb 100644 --- a/src/shell.html +++ b/src/shell.html @@ -16,8 +16,10 @@ #app-canvas { display: flex; flex-grow: 1; - width: 100%; + width: 1280px; + max-height: 720px; height: 100%; + border: solid 1px black; } </style> </head> diff --git a/src/vertex.glsl b/src/vertex.glsl index cf72553..175565b 100644 --- a/src/vertex.glsl +++ b/src/vertex.glsl @@ -1,8 +1,13 @@ #version 300 es -uniform vec2 pos; +in vec4 pos; +in vec3 col; + +uniform mat4 mat; + +out vec4 a_col; void main() { - gl_Position = vec4(pos, 0, 1); // center - gl_PointSize = 120.0; + gl_Position = pos * mat; + a_col = vec4(col, 1); } diff --git a/src/wasm_msponge.zig b/src/wasm_msponge.zig index 8d43fe7..bee8e8c 100644 --- a/src/wasm_msponge.zig +++ b/src/wasm_msponge.zig @@ -1,21 +1,197 @@ const wasm = @import("wasm.zig"); const webgl = @import("webgl.zig"); +const matrix = @import("matrix.zig"); +const Mat3 = matrix.Matrix(f32, 3, 3); +const Mat4 = matrix.Matrix(f32, 4, 4); -const MyProgram = webgl.Program(&.{.{ .identifier = "pos", .shader_name = "pos", .kind = .vec2 }}); +const MyProgram = webgl.Program( + &.{ + .{ .identifier = "color", .shader_name = "color", .kind = .vec3 }, + .{ .identifier = "mat", .shader_name = "mat", .kind = .mat4 }, + }, + &.{ + .{ .identifier = "pos", .shader_name = "pos", .kind = .vec4 }, + .{ .identifier = "col", .shader_name = "col", .kind = .vec3 }, + }, +); var prog: MyProgram = undefined; +var vao: webgl.VertexArrayObject = undefined; +var pos_buffer: webgl.Buffer = undefined; +var col_buffer: webgl.Buffer = undefined; export fn init() void { wasm.print("Hello Menger Sponge {d}!", .{2}); prog = MyProgram.init(@embedFile("vertex.glsl"), @embedFile("fragment.glsl")) catch return; + vao = webgl.VertexArrayObject.init(); + pos_buffer = webgl.createBuffer(); + col_buffer = webgl.createBuffer(); + prog.setVertexAttribPointer(.pos, vao, pos_buffer, .{}); + prog.setVertexAttribPointer(.col, vao, col_buffer, .{}); + + webgl.bindBuffer(.array_buffer, pos_buffer); + webgl.bufferData(.array_buffer, &box_verts, .static_draw); + + webgl.bindBuffer(.array_buffer, col_buffer); + webgl.bufferData(.array_buffer, &col_data, .static_draw); + + //webgl.enable(.cull_face); + //webgl.enable(.depth_test); +} + +const col_data: [18 * 6]f32 = blk: { + const red: [3]f32 = .{ 1, 0, 0 }; + const green: [3]f32 = .{ 0, 1, 0 }; + const blue: [3]f32 = .{ 0, 0, 1 }; + const tri = red ++ green ++ blue; + break :blk tri ** 12; +}; +const box_verts = boxVertices(100, 100, 100); + +fn multAllMat4(in: [][3]f32, mat: Mat4) void { + for (in) |*r| { + const mat_row: [4]f32 = r.* ++ [1]f32{1}; + const in_mat: matrix.Matrix(f32, 1, 4) = .{ .data = @bitCast(mat_row) }; + const out_mat = in_mat.multiply(mat); + + r.* = out_mat.row(0)[0..3].*; + } } +fn planeVertices(width: f32, height: f32) [18]f32 { + return .{ + 0, 0, 0, + width, 0, 0, + 0, height, 0, + + 0, height, 0, + width, 0, 0, + width, height, 0, + }; +} + +fn boxVertices(x: f32, y: f32, z: f32) [18 * 6]f32 { + @setEvalBranchQuota(10000); + const front_mat = Mat4.translation(.{ -x / 2, -y / 2, z / 2 }); + const front_plane = blk: { + var base = planeVertices(x, y); + multAllMat4(@as(*[6][3]f32, @ptrCast(&base)), front_mat); + break :blk base; + }; + + const back_plane = blk: { + const center_tlate = Mat4.translation(.{ -x / 2, -y / 2, 0 }); + const rot = Mat4.yRotation(3.14); + const final_tlate = Mat4.translation(.{ 0, 0, -z / 2 }); + const mat = center_tlate.multiply(rot).multiply(final_tlate); + var base = planeVertices(x, y); + multAllMat4(@as(*[6][3]f32, @ptrCast(&base)), mat); + break :blk base; + }; + + const left_plane = blk: { + const half_tlate = Mat4.translation(.{ -x / 2, -y / 4, 0 }); + const rot = Mat4.yRotation(3.14 * 0.5); + const mat = half_tlate.multiply(rot).multiply(half_tlate); + var base = planeVertices(x, y); + multAllMat4(@as(*[6][3]f32, @ptrCast(&base)), mat); + break :blk base; + }; + + const right_plane = blk: { + const center_tlate = Mat4.translation(.{ -x / 2, 0, 0 }); + const rot = Mat4.yRotation(3.14 * -0.5); + const final_tlate = Mat4.translation(.{ x / 2, -y / 2, 0 }); + const mat = center_tlate.multiply(rot).multiply(final_tlate); + var base = planeVertices(x, y); + multAllMat4(@as(*[6][3]f32, @ptrCast(&base)), mat); + break :blk base; + }; + + const top_plane = blk: { + const center_tlate = Mat4.translation(.{ -x / 2, -y / 2, 0 }); + const rot = Mat4.xRotation(3.14 * -0.5); + const final_tlate = Mat4.translation(.{ 0, y / 2, 0 }); + const mat = center_tlate.multiply(rot).multiply(final_tlate); + var base = planeVertices(x, y); + multAllMat4(@as(*[6][3]f32, @ptrCast(&base)), mat); + break :blk base; + }; + + const bottom_plane = blk: { + const center_tlate = Mat4.translation(.{ -x / 2, -y / 2, 0 }); + const rot = Mat4.xRotation(3.14 * 0.5); + const final_tlate = Mat4.translation(.{ 0, -y / 2, 0 }); + const mat = center_tlate.multiply(rot).multiply(final_tlate); + var base = planeVertices(x, y); + multAllMat4(@as(*[6][3]f32, @ptrCast(&base)), mat); + break :blk base; + }; + + return front_plane ++ back_plane ++ left_plane ++ right_plane ++ top_plane ++ bottom_plane; +} + +var timer: f32 = 0; + export fn update(delta_time: f32) void { - _ = delta_time; - const bg = webgl.Color.fromVec(.{ 1, 0, 1, 1 }); + timer += delta_time; + const bg = webgl.Color.fromVec(.{ 1, 1, 1, 1 }); webgl.viewportToScreen(); webgl.clear(bg); prog.use(); - prog.setUniform(.pos, .{ 0.5, 0.5 }); - webgl.drawArrays(.points, 0, 1); + prog.setUniform(.color, .{ 1, 1, 1 }); + + const screen_dims = webgl.getScreenSize(); + const proj = orthographicMatrix( + -screen_dims[0] / 2, + screen_dims[0] / 2, + -screen_dims[1] / 2, + screen_dims[1] / 2, + -400, + 400, + ); + const tlate = Mat4.translation(.{ @sin(timer * 4) * 100, 0, 0 }); + const rot = Mat4.yRotation(timer).multiply(Mat4.xRotation(timer)); + const s = @sin(timer) * 2.0 + 2; + const scale = Mat4.scale(.{ s, s, s }); + const model = scale.multiply(rot).multiply(tlate); + const final_mat = model.multiply(proj); + prog.setUniform(.mat, final_mat); + webgl.drawArrays(.triangles, 0, 36); + prog.setUniform(.color, .{ 0.0, 0.0, 0.0 }); + + for (0..12) |i| { + webgl.drawArrays(.line_loop, @intCast(i * 3), 3); + } +} + +fn orthographicMatrix( + left: f32, + right: f32, + bottom: f32, + top: f32, + near: f32, + far: f32, +) Mat4 { + const vals = [4][4]f32{ + .{ 2 / (right - left), 0, 0, 0 }, + .{ 0, 2 / (top - bottom), 0, 0 }, + .{ 0, 0, 2 / (near - far), 0 }, + .{ + (left + right) / (right - left), + (bottom + top) / (top - bottom), + (near + far) / (near - far), + 1, + }, + }; + return .{ .data = vals }; +} + +fn projectionMatrix2D(width: f32, height: f32) Mat3 { + const mat_vals = .{ + .{ 2.0 / width, 0, 0 }, + .{ 0, 2.0 / height, 0 }, + .{ -1, -1, 1 }, + }; + return .{ .data = mat_vals }; } diff --git a/src/webgl.js b/src/webgl.js index 823ec53..3febf86 100644 --- a/src/webgl.js +++ b/src/webgl.js @@ -37,9 +37,6 @@ const bindBuffer = (target, id) => { const bufferData = (target, ptr, len, usage) => { const floats = new Float32Array(memory.buffer, ptr, len); - if (len === 9) { - console.log(floats); - } gfx_ctx.bufferData(target, floats, usage); }; @@ -158,6 +155,10 @@ const uniform2f = (location, v0, v1) => { gfx_ctx.uniform2f(glUniformLocations.get(location), v0, v1); }; +const uniform3f = (location, v0, v1, v2) => { + gfx_ctx.uniform3f(glUniformLocations.get(location), v0, v1, v2); +}; + const uniform4f = (location, v0, v1, v2, v3) => { gfx_ctx.uniform4f(glUniformLocations.get(location), v0, v1, v2, v3); }; @@ -169,6 +170,13 @@ const uniformMatrix3fv = (location, ptr) => { gfx_ctx.uniformMatrix3fv(glUniformLocations.get(location), false, floats); }; +const uniformMatrix4fv = (location, ptr) => { + const u = glUniformLocations.get(location); + const floats = new Float32Array(memory.buffer, ptr, 16); + + gfx_ctx.uniformMatrix4fv(glUniformLocations.get(location), false, floats); +}; + const vertexAttribPointer = (loc, size, type, normalize, stride, offset) => { gfx_ctx.vertexAttribPointer(loc, size, type, normalize, stride, offset); }; @@ -256,8 +264,10 @@ const webgl = { uniform1i, uniform2f, + uniform3f, uniform4f, uniformMatrix3fv, + uniformMatrix4fv, createTexture, bindTexture, diff --git a/src/webgl.zig b/src/webgl.zig index 145abbd..9a373f6 100644 --- a/src/webgl.zig +++ b/src/webgl.zig @@ -1,6 +1,9 @@ const std = @import("std"); const wasm = @import("wasm.zig"); const bindings = @import("webgl_bindings.zig"); +const matrix = @import("matrix.zig"); +const Mat3 = matrix.Matrix(f32, 3, 3); +const Mat4 = matrix.Matrix(f32, 4, 4); pub const Color = struct { r: f32 = 0, @@ -25,29 +28,86 @@ pub const Color = struct { const UniformInfo = struct { identifier: [:0]const u8, shader_name: []const u8, - kind: enum { vec2 }, + kind: enum { vec2, vec3, mat3, mat4 }, + + fn SetType(self: UniformInfo) type { + return switch (self.kind) { + .vec2 => [2]f32, + .vec3 => [3]f32, + .mat3 => Mat3, + .mat4 => Mat4, + }; + } }; -pub fn Program(comptime uniforms: []const UniformInfo) type { - const UniEnum: type = blk: { - const EnumField = std.builtin.Type.EnumField; - var fields: []const EnumField = &.{}; - for (uniforms, 0..) |u, i| { - const field: EnumField = .{ .name = u.identifier, .value = i }; - fields = &(fields[0..i].* ++ [1]EnumField{field}); - } +const AttributeInfo = struct { + identifier: [:0]const u8, + shader_name: []const u8, + kind: enum { vec2, vec3, vec4 }, +}; - const info: std.builtin.Type.Enum = .{ - .fields = fields, - .decls = &.{}, - .is_exhaustive = false, - .tag_type = u32, - }; - break :blk @Type(.{ .Enum = info }); - }; +pub const Buffer = bindings.Buffer; +pub const createBuffer = bindings.createBuffer; +pub const bindBuffer = bindings.bindBuffer; +pub fn bufferData(target: bindings.BindingPoint, data: []const f32, usage: bindings.UsagePattern) void { + bindings.bufferData(target, data.ptr, data.len, usage); +} + +pub const VertexArrayObject = struct { + handle: u32, + + const Self = @This(); + pub fn init() Self { + return .{ .handle = bindings.createVertexArray() }; + } + + pub fn bind(self: Self) void { + bindings.bindVertexArray(self.handle); + } +}; + +pub fn Program( + comptime uniforms: []const UniformInfo, + comptime attributes: []const AttributeInfo, +) type { return struct { + pub const Uniform: type = blk: { + const EnumField = std.builtin.Type.EnumField; + var fields: []const EnumField = &.{}; + for (uniforms, 0..) |u, i| { + const field: EnumField = .{ .name = u.identifier, .value = i }; + fields = &(fields[0..i].* ++ [1]EnumField{field}); + } + + const info: std.builtin.Type.Enum = .{ + .fields = fields, + .decls = &.{}, + .is_exhaustive = false, + .tag_type = u32, + }; + break :blk @Type(.{ .Enum = info }); + }; + + pub const Attribute: type = blk: { + const EnumField = std.builtin.Type.EnumField; + var fields: []const EnumField = &.{}; + for (attributes, 0..) |a, i| { + const field: EnumField = .{ .name = a.identifier, .value = i }; + fields = &(fields[0..i].* ++ [1]EnumField{field}); + } + + const info: std.builtin.Type.Enum = .{ + .fields = fields, + .decls = &.{}, + .is_exhaustive = false, + .tag_type = u32, + }; + break :blk @Type(.{ .Enum = info }); + }; + handle: u32, uniform_handles: [uniforms.len]i32, + attribute_handles: [attributes.len]i32, const Self = @This(); pub fn init(vert_src: []const u8, frag_src: []const u8) !Self { @@ -65,14 +125,29 @@ pub fn Program(comptime uniforms: []const UniformInfo) type { uniform_handles[i] = h; } - return .{ .handle = handle, .uniform_handles = uniform_handles }; + var attribute_handles: [attributes.len]i32 = undefined; + for (attributes, 0..) |a, i| { + const h = bindings.getAttribLocation(handle, a.shader_name.ptr, a.shader_name.len); + if (h < 0) return error.FailedToGetUniformLocation; + attribute_handles[i] = h; + } + + return .{ + .handle = handle, + .uniform_handles = uniform_handles, + .attribute_handles = attribute_handles, + }; } pub fn use(self: Self) void { bindings.useProgram(self.handle); } - pub fn setUniform(self: Self, comptime uniform: UniEnum, val: anytype) void { + pub fn setUniform( + self: Self, + comptime uniform: Uniform, + val: uniforms[@intFromEnum(uniform)].SetType(), + ) void { const handle = self.uniform_handles[@intFromEnum(uniform)]; const info = uniforms[@intFromEnum(uniform)]; @@ -80,8 +155,53 @@ pub fn Program(comptime uniforms: []const UniformInfo) type { .vec2 => { bindings.uniform2f(handle, val[0], val[1]); }, + .vec3 => { + bindings.uniform3f(handle, val[0], val[1], val[2]); + }, + .mat3 => { + const v: *const [9]f32 = @ptrCast(&val.data); + bindings.uniformMatrix3fv(handle, v); + }, + .mat4 => { + const v: *const [16]f32 = @ptrCast(&val.data); + bindings.uniformMatrix4fv(handle, v); + }, } } + + pub fn setVertexAttribPointer( + self: Self, + comptime attribute: Self.Attribute, + vao: VertexArrayObject, + buffer: Buffer, + options: anytype, + ) void { + _ = options; + vao.bind(); + bindings.bindBuffer(.array_buffer, buffer); + const attr_info = attributes[@intFromEnum(attribute)]; + const attr_handle = self.attribute_handles[@intFromEnum(attribute)]; + bindings.enableVertexAttribArray(attr_handle); + + const size = switch (attr_info.kind) { + .vec2 => 2, + .vec3, .vec4 => 3, + }; + const a_type = switch (attr_info.kind) { + .vec2, .vec3, .vec4 => .f32, + }; + const normalize = .false; + const stride = 0; + const offset = 0; + bindings.vertexAttribPointer( + attr_handle, + size, + a_type, + normalize, + stride, + offset, + ); + } }; } @@ -137,3 +257,12 @@ fn createProgram(vert: u32, frag: u32) !u32 { return program; } + +pub const Capability = enum(u32) { + cull_face = 0x0B44, + depth_test = 0x0B71, +}; + +pub fn enable(cap: Capability) void { + bindings.enable(@intFromEnum(cap)); +} diff --git a/src/webgl_bindings.zig b/src/webgl_bindings.zig index b152353..c3a2a02 100644 --- a/src/webgl_bindings.zig +++ b/src/webgl_bindings.zig @@ -12,12 +12,12 @@ pub const ShaderInfo = enum(u32) { compile_status = 0x8B81, }; -pub const GLBindingPoint = enum(u32) { +pub const BindingPoint = enum(u32) { array_buffer = 0x8892, element_array_buffer = 0x8893, }; -pub const GLUsagePattern = enum(u32) { +pub const UsagePattern = enum(u32) { stream_draw = 0x88E0, static_draw = 0x88E4, dynamic_draw = 0x88E8, @@ -36,12 +36,12 @@ pub extern fn enable(cap: u32) void; pub extern fn blendFunc(sfactor: u32, dfactor: u32) void; pub extern fn createBuffer() Buffer; -pub extern fn bindBuffer(target: GLBindingPoint, buffer: Buffer) void; +pub extern fn bindBuffer(target: BindingPoint, buffer: Buffer) void; pub extern fn bufferData( - target: GLBindingPoint, + target: BindingPoint, ptr: [*c]const f32, len: u32, - usage: GLUsagePattern, + usage: UsagePattern, ) void; pub const ShaderType = enum(u32) { @@ -69,10 +69,11 @@ pub extern fn getUniformLocation(program: u32, buf: [*c]const u8, len: u32) i32; pub extern fn uniform1i(location: i32, v0: i32) void; pub extern fn uniform2f(location: i32, v0: f32, v1: f32) void; +pub extern fn uniform3f(location: i32, v0: f32, v1: f32, v2: f32) void; pub extern fn uniform4f(location: i32, v0: f32, v1: f32, v2: f32, v3: f32) void; -pub extern fn uniformMatrix3fv(location: i32, ptr: [*c]const @Vector(3, f32)) void; +pub extern fn uniformMatrix3fv(location: i32, ptr: *const [9]f32) void; +pub extern fn uniformMatrix4fv(location: i32, ptr: *const [16]f32) void; -pub const VertexArrayObject = packed struct(u32) { handle: u32 }; const GLType = enum(u32) { i8 = 0x1400, u8 = 0x1401, @@ -88,11 +89,11 @@ const GLBool = enum(i32) { true = 1, }; -pub extern fn createVertexArray() VertexArrayObject; -pub extern fn bindVertexArray(vao: VertexArrayObject) void; +pub extern fn createVertexArray() u32; +pub extern fn bindVertexArray(vao: u32) void; pub extern fn enableVertexAttribArray(attrib_location: i32) void; pub extern fn vertexAttribPointer( - attrib_location: u32, + attrib_location: i32, size: i32, gl_type: GLType, normalize: GLBool, |