From 588722309031fba8b28b93e3d842a1c81872f19d Mon Sep 17 00:00:00 2001 From: Vivianne Langdon Date: Sat, 23 Jul 2022 03:00:45 -0700 Subject: [PATCH] starting to fill out entities, materials, textures. cleaned up math a little, still WIP. --- src/math/box.zig | 104 +++++++++++++++++++++ src/math/mat.zig | 84 +++++++++++++++++ src/math/vec.zig | 144 ++++++++++++++++-------------- src/rendering/Camera.zig | 12 +-- src/rendering/Entities.zig | 132 +++++++++++++++++++++++++++ src/rendering/materials.zig | 35 ++++++++ src/rendering/meshes.zig | 31 +++++++ src/rendering/textures.zig | 74 +++++++++++++++ src/rendering/vulkan/MainPass.zig | 52 ++++++----- 9 files changed, 572 insertions(+), 96 deletions(-) create mode 100644 src/math/box.zig create mode 100644 src/math/mat.zig create mode 100644 src/rendering/Entities.zig create mode 100644 src/rendering/materials.zig create mode 100644 src/rendering/meshes.zig create mode 100644 src/rendering/textures.zig diff --git a/src/math/box.zig b/src/math/box.zig new file mode 100644 index 0000000..1f1d09d --- /dev/null +++ b/src/math/box.zig @@ -0,0 +1,104 @@ +const std = @import("std"); +const Vec4f = @import("vec.zig").Vec4f; +const Mat4f = @import("vec.zig").Mat4f; + +const BoxData = packed struct {}; + +pub fn Box(comptime Vec: type, comptime Shift: comptime_int) type { + return packed struct { + const Self = @This(); + + pub const empty = Self{ + .lo = Vec.s(1 << Shift), + .hi = Vec.s(-(1 << Shift)), + }; + + lo: Vec, + hi: Vec, + + pub inline fn new(lo: Vec, hi: Vec) Self { + return Self{ + .lo = lo, + .hi = hi, + }; + } + + pub inline fn center(self: Self) Vec { + return self.lo.lerpvs(self.hi, 0.5); + } + + pub inline fn size(self: Self) Vec { + return self.hi.sub(self.lo); + } + + pub inline fn extents(self: Self) Vec { + return self.size().mulvs(0.5); + } + + pub inline fn contains(self: Self, pt: Vec) bool { + return pt.gteq(self.lo).all3() and pt.lteq(self.hi).all3(); + } + + pub inline fn area(self: Self) f32 { + const sz = self.size(); + return sz.x * sz.y * if (Vec.nelem > 2) sz.z else 1; + } + + pub inline fn fromPts(pts: []const Vec) Self { + var lo = Vec.s(1 << Shift); + var hi = Vec.s(-(1 << Shift)); + for (pts) |pt| { + lo = lo.min(pt); + hi = hi.max(pt); + } + + return Self{ + .lo = lo, + .hi = hi, + }; + } + + pub inline fn uni(lhs: Self, rhs: Self) Self { + return Self{ + .lo = lhs.lo.min(rhs.lo), + .hi = lhs.hi.max(rhs.hi), + }; + } + + pub inline fn intersect(lhs: Self, rhs: Self) Self { + var lo = lhs.lo.min(rhs.lo); + var hi = lhs.hi.max(rhs.hi); + const mid = lo.lerpvs(hi, 0.5); + const inverted = lo.gt(hi); + lo = lo.select(mid, inverted); + hi = hi.select(mid, inverted); + + return Self{ + .lo = lo, + .hi = hi, + }; + } + + // TODO: genericise + pub inline fn transform(matrix: Mat4f, box: Self) Self { + var ct = box.center(); + var exts = box.hi.sub(ct); + ct = matrix.mulPt(ct); + exts = matrix.mulExtents(exts); + return Self{ + .lo = ct.sub(exts), + .hi = ct.add(exts), + }; + } + }; +} + +// pub const Box2d = Box(Vec2f); // need to understand the shift magic +pub const Box3d = Box(Vec4f, 20); + +test "Box3d" { + const b1 = Box3d.fromPts(&.{ Vec4f.s(1), Vec4f.s(-1) }); + try std.testing.expectEqual(@as(f32, 8), b1.area()); + const v1 = Vec4f.s(0.5); + try std.testing.expect(b1.contains(v1)); +} diff --git a/src/math/mat.zig b/src/math/mat.zig new file mode 100644 index 0000000..ab44730 --- /dev/null +++ b/src/math/mat.zig @@ -0,0 +1,84 @@ +const std = @import("std"); +const vec = @import("vec.zig"); +const Vec3f = vec.Vec3f; +const Vec4f = vec.Vec4f; + +pub const Mat3f = Mat(3, Vec3f); + +pub const Mat4f = packed struct { + const Self = @This(); + pub const zero = Mat(4, Vec4f).zero; + pub const id = Mat(4, Vec4f).id; + + pub usingnamespace Mat(4, Vec4f); + + pub inline fn lookAt(eye: Vec4f, at: Vec4f, up: Vec4f) Self { + // right-handed (ew) + const f = at.sub(eye).normalize3(); + const s = f.cross3(up).normalize3(); + const u = s.cross3(f).normalize3(); + + const tx = -s.dot3(eye); + const ty = -u.dot3(eye); + const tz = f.dot3(eye); + return Self{ + .c0 = .{ .x = s.x, .y = u.x, .z = -f.x, .w = 0 }, + .c1 = .{ .x = s.y, .y = u.y, .z = -f.y, .w = 0 }, + .c2 = .{ .x = s.z, .y = u.z, .z = -f.z, .w = 0 }, + .c3 = .{ .x = tx, .y = ty, .z = tz, .w = 1 }, + }; + } + + pub inline fn glPerspective(fov_y: f32, aspect: f32, z_near: f32, z_far: f32) Self { + const t = std.math.tan(fov_y * 0.5); + var m = zero; + m.c0.x = 1.0 / (aspect * t); + m.c1.y = 1.0 / t; + m.c2.z = -1.0 * (z_far * z_near) / (z_far - z_near); + m.c3.z = -2.0 * (z_far * z_near) / (z_far - z_near); + return m; + } + + pub inline fn vkPerspective(fov_y: f32, aspect: f32, z_near: f32, z_far: f32) Self { + var m = glPerspective(fov_y, aspect, z_near, z_far); + m.c1.y *= -1.0; + return m; + } +}; + +pub fn Mat(comptime nelem: comptime_int, comptime Vec: type) type { + return packed struct { + const Self = @This(); + pub const nelem = nelem; + + pub const zero = Self{}; + pub const id = Self{ + .c0 = .{ .x = 1 }, + .c1 = .{ .y = 1 }, + .c2 = if (nelem > 2 and Vec.nelem > 2) .{ .z = 1 } else {}, + .c3 = if (nelem > 3 and Vec.nelem > 3) .{ .w = 1 } else {}, + }; + + c0: Vec = .{}, + c1: Vec = .{}, + c2: if (nelem > 2) Vec else void = if (nelem > 2) .{} else {}, + c3: if (nelem > 3) Vec else void = if (nelem > 3) .{} else {}, + + pub inline fn mulCol(self: Self, col: Vec) Vec { + const a = self.c0.mulvs(col.x); + const b = self.c1.mulvs(col.y); + const c = if (nelem > 2 and Vec.nelem > 2) self.c2.mulvs(col.z) else {}; + const d = if (nelem > 3 and Vec.nelem > 2) self.c0.mulvs(col.w) else {}; + return a.add(b).add(if (nelem > 2) if (nelem > 3) c.add(d) else c else Vec.zero); + } + + pub inline fn mul(a: Self, b: Self) Self { + return Self{ + .c0 = a.mulCol(b.c0), + .c1 = a.mulCol(b.c1), + .c2 = if (nelem > 2) a.mulCol(b.c2) else {}, + .c3 = if (nelem > 3) a.mulCol(b.c3) else {}, + }; + } + }; +} diff --git a/src/math/vec.zig b/src/math/vec.zig index d1df9a9..a2e4104 100644 --- a/src/math/vec.zig +++ b/src/math/vec.zig @@ -13,18 +13,65 @@ pub const Vec2u = Vec(2, u32); pub const Vec3u = Vec(3, u32); pub const Vec4u = Vec(4, u32); -pub fn Vec(comptime nelem: comptime_int, comptime T: anytype) type { +pub const Vec2b = BoolVec(2); +pub const Vec3b = BoolVec(3); +pub const Vec4b = BoolVec(4); + +pub fn BoolVec(comptime nelem: comptime_int) type { assert(nelem > 1); assert(nelem <= 4); return packed struct { const Self = @This(); + x: bool = false, + y: bool = false, + z: if (nelem > 2) bool else void = if (nelem > 2) false else {}, + w: if (nelem > 3) bool else void = if (nelem > 3) false else {}, + + pub inline fn all2(self: Self) bool { + return self.x and self.y; + } + + // 3-element operations + pub usingnamespace if (nelem >= 3) struct { + pub inline fn all3(self: Self) bool { + return self.all2() and if (nelem > 2) self.z else true; + } + } else struct {}; + + pub usingnamespace if (nelem >= 4) struct { + pub inline fn all4(self: Self) bool { + return self.all3() and if (nelem > 3) self.w else true; + } + } else struct {}; + }; +} + +pub fn Vec(comptime nelem: comptime_int, comptime T: type) type { + assert(nelem > 1); + assert(nelem <= 4); + + return packed struct { + const Self = @This(); + pub const nelem = nelem; + pub const T = T; + const Vecnb = BoolVec(Self.nelem); + x: T = 0, y: T = 0, z: if (nelem > 2) T else void = if (nelem > 2) 0 else {}, w: if (nelem > 3) T else void = if (nelem > 3) 0 else {}, + pub inline fn s(a: T) Self { + return Self{ + .x = a, + .y = a, + .z = if (nelem > 2) a else {}, + .w = if (nelem > 3) a else {}, + }; + } + pub inline fn add(lhs: Self, rhs: Self) Self { return Self{ .x = lhs.x + rhs.x, @@ -65,6 +112,15 @@ pub fn Vec(comptime nelem: comptime_int, comptime T: anytype) type { return lhs.mulvs(1 / rhs); } + pub inline fn min(a: Self, b: Self) Self { + return Self{ + .x = @minimum(a.x, b.x), + .y = @minimum(a.y, b.y), + .z = if (nelem > 2) @minimum(a.z, b.z) else {}, + .w = if (nelem > 3) @minimum(a.w, b.w) else {}, + }; + } + pub inline fn max(a: Self, b: Self) Self { return Self{ .x = @maximum(a.x, b.x), @@ -90,6 +146,24 @@ pub fn Vec(comptime nelem: comptime_int, comptime T: anytype) type { return self.divvs(self.length()); } + pub inline fn lteq(lhs: Self, rhs: Self) Vecnb { + return Vecnb{ + .x = lhs.x <= rhs.x, + .y = lhs.y <= rhs.y, + .z = if (nelem > 2) lhs.z <= rhs.z else {}, + .w = if (nelem > 3) lhs.w <= rhs.w else {}, + }; + } + + pub inline fn gteq(lhs: Self, rhs: Self) Vecnb { + return Vecnb{ + .x = lhs.x >= rhs.x, + .y = lhs.y >= rhs.y, + .z = if (nelem > 2) lhs.z >= rhs.z else {}, + .w = if (nelem > 3) lhs.w >= rhs.w else {}, + }; + } + // 3-element operations pub usingnamespace if (nelem >= 3) struct { pub inline fn sum3(self: Self) T { @@ -158,71 +232,3 @@ test "vec" { try std.testing.expectEqual(@as(i32, 6), boop.sum()); } - -// TODO: comptime magic? -pub const Float4x4 = packed struct { - const Self = @This(); - - pub const zero = Self{}; - pub const id = Self{ - .c0 = .{ .x = 1, .y = 0, .z = 0, .w = 0 }, - .c1 = .{ .x = 0, .y = 1, .z = 0, .w = 0 }, - .c2 = .{ .x = 0, .y = 0, .z = 1, .w = 0 }, - .c3 = .{ .x = 0, .y = 0, .z = 0, .w = 1 }, - }; - - c0: Vec4f = .{}, - c1: Vec4f = .{}, - c2: Vec4f = .{}, - c3: Vec4f = .{}, - - pub inline fn mulCol(self: Self, col: Vec4f) Vec4f { - const a = self.c0.mulvs(col.x); - const b = self.c1.mulvs(col.y); - const c = self.c2.mulvs(col.z); - const d = self.c0.mulvs(col.w); - return a.add(b).add(c.add(d)); - } - - pub inline fn mul(a: Self, b: Self) Self { - return Self{ - .c0 = a.mulCol(b.c0), - .c1 = a.mulCol(b.c1), - .c2 = a.mulCol(b.c2), - .c3 = a.mulCol(b.c3), - }; - } - - pub inline fn lookAt(eye: Vec4f, at: Vec4f, up: Vec4f) Float4x4 { - // right-handed (ew) - const f = at.sub(eye).normalize3(); - const s = f.cross3(up).normalize3(); - const u = s.cross3(f).normalize3(); - - const tx = -s.dot3(eye); - const ty = -u.dot3(eye); - const tz = f.dot3(eye); - return Float4x4{ - .c0 = .{ .x = s.x, .y = u.x, .z = -f.x, .w = 0 }, - .c1 = .{ .x = s.y, .y = u.y, .z = -f.y, .w = 0 }, - .c2 = .{ .x = s.z, .y = u.z, .z = -f.z, .w = 0 }, - .c3 = .{ .x = tx, .y = ty, .z = tz, .w = 1 }, - }; - } - - pub inline fn glPerspective(fov_y: f32, aspect: f32, z_near: f32, z_far: f32) Self { - const t = std.math.tan(fov_y * 0.5); - var m = zero; - m.c0.x = 1.0 / (aspect * t); - m.c1.y = 1.0 / t; - m.c2.z = -1.0 * (z_far * z_near) / (z_far - z_near); - m.c3.z = -2.0 * (z_far * z_near) / (z_far - z_near); - return m; - } - - pub inline fn vkPerspective(fov_y: f32, aspect: f32, z_near: f32, z_far: f32) Self { - var m = glPerspective(fov_y, aspect, z_near, z_far); - m.c1.y *= -1.0; - return m; - } -}; diff --git a/src/rendering/Camera.zig b/src/rendering/Camera.zig index fcb8547..55e9d48 100644 --- a/src/rendering/Camera.zig +++ b/src/rendering/Camera.zig @@ -1,6 +1,6 @@ const std = @import("std"); const Vec4f = @import("../math/vec.zig").Vec4f; -const Float4x4 = @import("../math/vec.zig").Float4x4; +const Mat4f = @import("../math/mat.zig").Mat4f; const Quat = @import("../math/quat.zig").Quat; const Self = @This(); @@ -17,16 +17,16 @@ pub fn get() Self { return s_camera; } -pub inline fn getProj(self: *const Self, aspect: f32) Float4x4 { - return Float4x4.vkPerspective(std.math.degreesToRadians(f32, self.fov_y), aspect, self.z_near, self.z_far); +pub inline fn getProj(self: *const Self, aspect: f32) Mat4f { + return Mat4f.vkPerspective(std.math.degreesToRadians(f32, self.fov_y), aspect, self.z_near, self.z_far); } -pub inline fn getView(self: *const Self) Float4x4 { +pub inline fn getView(self: *const Self) Mat4f { const pos = self.position; const rot = self.rotation; - return Float4x4.lookAt(pos, pos.add(rot.fwd()), rot.up()); + return Mat4f.lookAt(pos, pos.add(rot.fwd()), rot.up()); } -pub inline fn getWorldToClip(self: *const Self, aspect: f32) Float4x4 { +pub inline fn getWorldToClip(self: *const Self, aspect: f32) Mat4f { return self.getProj(aspect).mul(self.getView()); } diff --git a/src/rendering/Entities.zig b/src/rendering/Entities.zig new file mode 100644 index 0000000..e3d9373 --- /dev/null +++ b/src/rendering/Entities.zig @@ -0,0 +1,132 @@ +const std = @import("std"); +const assert = std.debug.assert; + +const UUID = @import("../common/uuid.zig").UUID; + +const mat = @import("../math/mat.zig"); +const Mat4f = mat.Mat4f; +const Mat3f = mat.Mat3f; +const vec = @import("../math/vec.zig"); +const Vec4f = vec.Vec4f; +const Quat = @import("../math/quat.zig").Quat; +const Box3d = @import("../math/box.zig").Box3d; +const Mesh = @import("meshes.zig").Mesh; +const Material = @import("materials.zig").Material; + +// TODO memory +var gpa = std.heap.GeneralPurposeAllocator(.{}){}; +const allocator = gpa.allocator(); + +const Entities = @This(); + +var s_entities: Entities = undefined; + +names: std.ArrayList(UUID), +meshes: std.ArrayList(Mesh.Id), +bounds: std.ArrayList(Box3d), +materials: std.ArrayList(Material), +matrices: std.ArrayList(Mat4f), +inv_matrices: std.ArrayList(Mat3f), +translations: std.ArrayList(Vec4f), +rotations: std.ArrayList(Quat), +scales: std.ArrayList(Vec4f), +mod_time: std.time.Instant, + +pub fn init() void { + s_entities.names = std.ArrayList(UUID).init(allocator); + s_entities.meshes = std.ArrayList(Mesh.Id).init(allocator); + s_entities.bounds = std.ArrayList(Box3d).init(allocator); + s_entities.materials = std.ArrayList(Material).init(allocator); + s_entities.matrices = std.ArrayList(Mat4f).init(allocator); + s_entities.inv_matrices = std.ArrayList(Mat3f).init(allocator); + s_entities.translations = std.ArrayList(Vec4f).init(allocator); + s_entities.rotations = std.ArrayList(Quat).init(allocator); + s_entities.scales = std.ArrayList(Vec4f).init(allocator); + s_entities.mod_time = std.time.Instant.now(); +} + +pub fn update() void {} + +pub fn get() *const Entities { + return &s_entities; +} + +pub fn deinit() void { + delete(get()); + s_entities.names.deinit(); + s_entities.meshes.deinit(); + s_entities.bounds.deinit(); + s_entities.materials.deinit(); + s_entities.matrices.deinit(); + s_entities.inv_matrices.deinit(); + s_entities.translations.deinit(); + s_entities.rotations.deinit(); + s_entities.scales.deinit(); +} + +pub fn add(self: *const Entities, name: UUID) !i32 { + self.names.append(name); + self.translations.append(Vec4f.zero); + self.scales.append(Vec4f.one); + self.rotations.append(Quat.id); + self.matrices.append(Mat4f.id); + self.inv_matrices.append(Mat3f.id); + self.mod_time = std.time.Instant.now(); +} + +pub fn destroyAtIndex(ents: *const Entities, i: i32) void { + assert(i >= 0); + assert(i < ents.names.len); + ents.meshes[i].release(); + ents.materials[i].albedo.release(); + ents.materials[i].rome.release(); + ents.materials[i].normal.release(); +} + +pub fn removeAtIndex(ents: *const Entities, i: i32) void { + ents.destroyAtIndex(i); + + ents.names.swapRemove(i); + ents.meshes.swapRemove(i); + ents.bounds.swapRemove(i); + ents.materials.swapRemove(i); + ents.matrices.swapRemove(i); + ents.inv_matrices.swapRemove(i); + ents.translations.swapRemove(i); + ents.rotations.swapRemove(i); + ents.scales.swapRemove(i); +} + +pub fn rm(ents: *const Entities, name: UUID) bool { + if (ents.find(name)) |i| { + ents.removeAtIndex(i); + ents.mod_time = std.time.Instant.now(); + return true; + } + + return false; +} + +pub fn find(ents: *const Entities, name: UUID) ?i32 { + return ents.names.find(name); +} + +pub fn clear(ents: *const Entities) void { + for (ents.names) |_, i| { + ents.destroyAtIndex(i); + } + ents.mod_time = std.time.Instant.now(); +} + +pub fn delete(ents: *const Entities) void { + ents.clear(); + ents.names.clearAndFree(); + ents.meshes.clearAndFree(); + ents.bounds.clearAndFree(); + ents.materials.clearAndFree(); + ents.matrices.clearAndFree(); + ents.inv_matrices.clearAndFree(); + ents.translations.clearAndFree(); + ents.rotations.clearAndFree(); + ents.scales.clearAndFree(); +} diff --git a/src/rendering/materials.zig b/src/rendering/materials.zig new file mode 100644 index 0000000..e1f874c --- /dev/null +++ b/src/rendering/materials.zig @@ -0,0 +1,35 @@ +const vec = @import("../math/vec.zig"); +const Vec4f = vec.Vec4f; + +const Texture = @import("textures.zig").Texture; +const DiskTexture = @import("textures.zig").DiskTexture; + +pub const MatFlags = packed struct { + emissive: bool = false, // enable emissive term + sky: bool = false, // lookup emission from sky cubemap + water: bool = false, + slime: bool = false, + lava: bool = false, + refractive: bool = false, // enable refraction term + warped: bool = false, // uv animated + animated: bool = false, // keyframe animated + underwater: bool = false, // SURF_UNDERWATER +}; + +pub const Material = packed struct { + albedo: Texture.Id, // rgba8 srgb (albedo, alpha) + rome: Texture.Id, // rgba8 srgb (roughness, occlusion, metallic, emission) + normal: Texture.Id, // rg16 (tangent space xy) + flags: MatFlags, + mean_free_path: Vec4f, // .w = scatter dir 'g' + ior: f32, // index of refraction + bumpiness: f32, +}; + +pub const DiskMaterial = packed struct { + albedo: DiskTexture.Id, + rome: DiskTexture.Id, + normal: DiskTexture.Id, + flags: MatFlags, + ior: f32, +}; diff --git a/src/rendering/meshes.zig b/src/rendering/meshes.zig new file mode 100644 index 0000000..8060c2c --- /dev/null +++ b/src/rendering/meshes.zig @@ -0,0 +1,31 @@ +const UUID = @import("uuid").UUID; + +const vec = @import("../math/vec.zig"); +const Vec4f = vec.Vec4f; +const Vec4i = vec.Vec4i; + +pub const Mesh = packed struct { + const version = 5; + + positions: [*]Vec4f, + normals: [*]Vec4f, + uvs: [*]Vec4f, + tex_indices: [*]Vec4i, + length: i32, + id: Id, + + pub const Id = packed struct { + version: u8, + index: u24, + }; +}; + +pub const DiskMesh = packed struct { + version: i32, + length: i32, + name: [64]u8, + + pub const Id = packed struct { + id: UUID, + }; +}; diff --git a/src/rendering/textures.zig b/src/rendering/textures.zig new file mode 100644 index 0000000..fdb0215 --- /dev/null +++ b/src/rendering/textures.zig @@ -0,0 +1,74 @@ +const vk = @import("vulkan"); +const UUID = @import("../common/uuid.zig").UUID; + +const Table = @import("../containers/Table.zig"); +const Vec2i = @import("../math/vec.zig").Vec2i; + +const TTable = Table(Texture.Id); +var s_table: TTable = undefined; + +pub fn init() void { + s_table = TTable.init(); +} + +pub fn update() void {} + +pub fn deinit() void {} + +pub fn getTable() *const TTable { + return &s_table; +} + +pub const Texture = packed struct { + const Self = @This(); + + const PalRow = enum { + white, + brown, + light_blue, + green, + red, + orange, + gold, + peach, + purple, + magenta, + tan, + light_green, + yellow, + blue, + fire, + brights, + + pub const count = @enumToInt(PalRow.brights); + }; + + size: Vec2i, + texels: [*]u8, + format: vk.Format, + slot: Id, + + pub fn get(id: Id) *const Self { + return s_table.get(id); + } + + pub fn isCurrent(id: Id) bool { + return s_table.exists(id); + } + + pub const Id = packed struct { + version: u8, + index: u24, + }; +}; + +pub const DiskTexture = packed struct { + version: i32, + format: vk.Format, + name: []u8, + size: Vec2i, + + pub const Id = packed struct { + id: UUID, + }; +}; diff --git a/src/rendering/vulkan/MainPass.zig b/src/rendering/vulkan/MainPass.zig index 5edcce0..799fd69 100644 --- a/src/rendering/vulkan/MainPass.zig +++ b/src/rendering/vulkan/MainPass.zig @@ -17,14 +17,17 @@ const framebuffer = @import("framebuffer.zig"); const Targets = @import("Targets.zig"); const RenderPass = @import("RenderPass.zig"); const Bindings = @import("Bindings.zig"); +const Entities = @import("../Entities.zig"); +const Texture = @import("../textures.zig").Texture; const vec = @import("../../math/vec.zig"); +const mat = @import("../../math/mat.zig"); const Vec2f = vec.Vec2f; const Vec4f = vec.Vec4f; const Vec4i = vec.Vec4i; const Vec2u = vec.Vec2u; const Vec4u = vec.Vec4u; -const Float4x4 = vec.Float4x4; +const Mat4f = mat.Mat4f; pub fn init(device: *const Device, swapchain: *Swapchain) !void { errdefer { @@ -73,7 +76,7 @@ pub fn execute(device: *const Device, swapchain: *Swapchain) !void { const DepthPass = struct { const PushConstants = packed struct { - local_to_clip: Float4x4, + local_to_clip: Mat4f, }; var s_render_pass: vk.RenderPass = undefined; @@ -91,12 +94,6 @@ const DepthPass = struct { .dst_access_mask = .{ .color_attachment_write_bit = true }, }; - //var info = RenderPass.Description{ - // .src_stage_mask = .{ .early_fragment_tests_bit = true }, - // .src_access_mask = .{ .depth_stencil_attachment_read_bit = true }, - // .dst_stage_mask = .{ .late_fragment_tests_bit = true }, - // .dst_access_mask = .{ .depth_stencil_attachment_write_bit = true }, - //}; info.attachments[0] = .{ .format = depth_buffer.format, .layout = .depth_stencil_attachment_optimal, @@ -166,7 +163,6 @@ const DepthPass = struct { defer pm_depth_execute.end(); const camera = Camera.get(); - const world_to_clip = camera.getWorldToClip(swapchain.getAspect()); const attachments = &[_]*Image{Targets.getDepthBuffer(swapchain)}; @@ -202,7 +198,7 @@ const DepthPass = struct { const OpaquePass = struct { const Globals = packed struct { - g_WorldToClip: Float4x4, + g_WorldToClip: Mat4f, g_Eye: Vec4f, g_HdrEnabled: f32, @@ -215,8 +211,8 @@ const OpaquePass = struct { }; const PushConstants = packed struct { - kLocalToWorld: Float4x4, - kIMc0: Vec4f, + kLocalToWorld: Mat4f, + kIMc0: Vec4f, // components of inverse matrix kIMc1: Vec4f, kIMc2: Vec4f, kTexInds: Vec4u, @@ -239,13 +235,6 @@ const OpaquePass = struct { .dst_access_mask = .{ .color_attachment_write_bit = true }, }; - //var info = RenderPass.Description{ - // .src_stage_mask = .{ .late_fragment_tests_bit = true }, - // .dst_stage_mask = .{ .early_fragment_tests_bit = true, .color_attachment_output_bit = true }, - // .src_access_mask = .{ .depth_stencil_attachment_write_bit = true }, - // .dst_access_mask = .{ .depth_stencil_attachment_read_bit = true, .color_attachment_write_bit = true }, - //}; - info.attachments[0] = .{ .format = depth_buffer.format, .layout = .depth_stencil_attachment_optimal, @@ -436,10 +425,31 @@ const OpaquePass = struct { cmdbuf.beginRenderPass(device, s_render_pass, fbuf, rect, &clear_values); defer cmdbuf.endRenderPass(device); - // ITERATE THROUGH ENTITIES AND DRAW THEM FINALLY OMG + const ents = Entities.get(); + for (ents.meshes.items) |mesh, i| { + const albedo = Texture.get(ents.materials.items[i].albedo); + const rome = Texture.get(ents.materials.items[i].rome); + const normal = Texture.get(ents.materials.items[i].normal); + + const pc = PushConstants{ + .kLocalToWorld = ents.matrices[i], + .kIMc0 = ents.invMatrices[i].c0, + .kIMc1 = ents.invMatrices[i].c1, + .kIMc2 = ents.invMatrices[i].c2, + .kTexInds = .{ + .x = if (albedo) albedo.slot.index else 0, + .y = if (rome) rome.slot.index else 0, + .z = if (normal) normal.slot.index else 0, + .w = 0, + }, + }; + + cmdbuf.pushConstants(device, &s_pass, &pc); + cmdbuf.drawMesh(mesh.id); + } const pc = PushConstants{ - .kLocalToWorld = Float4x4.id, + .kLocalToWorld = Mat4f.id, .kIMc0 = Vec4f{ .x = 1, .y = 0, .z = 0, .w = 0 }, .kIMc1 = Vec4f{ .x = 0, .y = 1, .z = 0, .w = 0 }, .kIMc2 = Vec4f{ .x = 0, .y = 0, .z = 1, .w = 0 },