starting to fill out entities, materials, textures. cleaned up math a little, still WIP.
This commit is contained in:
parent
78293db515
commit
5887223090
9 changed files with 572 additions and 96 deletions
104
src/math/box.zig
Normal file
104
src/math/box.zig
Normal file
|
@ -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));
|
||||
}
|
84
src/math/mat.zig
Normal file
84
src/math/mat.zig
Normal file
|
@ -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 {},
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
144
src/math/vec.zig
144
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;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
132
src/rendering/Entities.zig
Normal file
132
src/rendering/Entities.zig
Normal file
|
@ -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();
|
||||
}
|
35
src/rendering/materials.zig
Normal file
35
src/rendering/materials.zig
Normal file
|
@ -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,
|
||||
};
|
31
src/rendering/meshes.zig
Normal file
31
src/rendering/meshes.zig
Normal file
|
@ -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,
|
||||
};
|
||||
};
|
74
src/rendering/textures.zig
Normal file
74
src/rendering/textures.zig
Normal file
|
@ -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,
|
||||
};
|
||||
};
|
|
@ -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 },
|
||||
|
|
Loading…
Reference in a new issue