summaryrefslogtreecommitdiff
path: root/src/rendering
diff options
context:
space:
mode:
Diffstat (limited to 'src/rendering')
-rw-r--r--src/rendering/gltf.zig160
-rw-r--r--src/rendering/mesh.zig26
-rw-r--r--src/rendering/renderer_vulkan.zig2
-rw-r--r--src/rendering/vulkan.zig2
4 files changed, 170 insertions, 20 deletions
diff --git a/src/rendering/gltf.zig b/src/rendering/gltf.zig
index 614ee25..888191d 100644
--- a/src/rendering/gltf.zig
+++ b/src/rendering/gltf.zig
@@ -2,15 +2,165 @@ const std = @import("std");
const mesh = @import("mesh.zig");
const Allocator = std.mem.Allocator;
-pub const Model = packed struct {
+pub const Model = struct {
+ const Asset = struct {
+ version: []u8,
+ generator: ?[]u8 = null,
+ copyright: ?[]u8 = null,
+ };
+ const Buffer = struct {
+ byteLength: usize,
+ uri: ?[]u8 = null,
+ };
+ const BufferView = struct {
+ buffer: usize,
+ byteLength: usize,
+ byteOffset: usize,
+ byteStride: ?usize = null,
+ target: ?usize = null,
+ };
+ const Node = struct {
+ name: []u8,
+ mesh: ?usize = null,
+ weights: ?[]f64 = null,
+ children: ?[]usize = null,
+ rotation: ?[4]f64 = null,
+ scale: ?[3]f64 = null,
+ translation: ?[3]f64 = null,
+ camera: ?usize = null,
+ matrix: ?[16]usize = null,
+ };
+ const Accessor = struct {
+ bufferView: usize,
+ byteOffset: ?usize = null,
+ componentType: usize,
+ count: usize,
+ type: []u8,
+ max: ?[]f64 = null,
+ min: ?[]f64 = null,
+ };
+ const Primitive = struct {
+ const Attributes = struct {
+ NORMAL: ?usize = null,
+ POSITION: ?usize = null,
+ TANGENT: ?usize = null,
+ TEXCOORD_0: ?usize = null,
+ TEXCOORD_1: ?usize = null,
+ COLOR_0: ?usize = null,
+ JOINTS_0: ?usize = null,
+ WEIGHTS_0: ?usize = null,
+ };
+
+ attributes: ?Attributes = null,
+ indices: ?usize = null,
+ material: ?usize = null,
+ mode: ?usize = null,
+ };
+ const Mesh = struct {
+ name: ?[]u8 = null,
+ primitives: ?[]Primitive = null,
+ weights: ?[]f64 = null,
+ };
+ const Skin = struct {
+ inverseBindMatrices: usize,
+ joints: []usize,
+ skeleton: usize,
+ };
+ const Texture = struct {
+ sampler: usize,
+ source: usize,
+ };
+ const Image = struct {
+ uri: ?[]u8 = null,
+ bufferView: ?usize = null,
+ mimeType: ?[]u8 = null,
+ };
+ const Material = struct {
+ const Pbr = struct {
+ baseColorFactor: ?[4]f64 = null,
+ baseColorTexture: ?struct {
+ index: usize,
+ texCoord: usize,
+ } = null,
+ metallicFactor: ?f64 = null,
+ roughnessFactor: ?f64 = null,
+ };
+ name: ?[]u8 = null,
+ pbrMetallicRoughness: Pbr,
+ doubleSided: bool,
+ };
+ const Scene = struct {
+ nodes: ?[]usize = null,
+ name: ?[]u8 = null,
+ };
+
const Chunk = packed struct {
+ const offset = Header.offset + 8;
length: u32,
- ty: u32,
+ type: u32,
+ };
- },
- header: packed struct {
+ const JsonChunk = struct {
+ asset: Asset,
+ scene: usize,
+ scenes: ?[]Scene = null,
+ nodes: ?[]Node = null,
+ materials: ?[]Material = null,
+ meshes: ?[]Mesh = null,
+ accessors: ?[]Accessor = null,
+ bufferViews: ?[]BufferView = null,
+ buffers: ?[]Buffer = null,
+ };
+
+ const Header = packed struct {
+ const offset = 12;
magic: u32,
version: u32,
length: u32,
- },
+ };
+
+ const Binary = struct {
+ data: []u8,
+ const Vec3 = [3]f32;
+
+ pub fn readU16(self: Binary, allocator: Allocator, view: BufferView, count: usize) ![]u16 {
+ const data = self.data[view.byteOffset .. view.byteOffset + view.byteLength];
+ const scalars = try allocator.alloc(u16, count);
+
+ var j: usize = 0;
+ for (0..data.len / 2) |i| {
+ scalars[i] = std.mem.bytesAsValue(u16, data[j .. j + 1]).*;
+ j += 2;
+ }
+
+ return scalars;
+ }
+
+ pub fn readVec3(self: Binary, allocator: Allocator, view: BufferView, count: usize) ![]Vec3 {
+ const data = self.data[view.byteOffset .. view.byteOffset + view.byteLength];
+ const vectors = try allocator.alloc(Vec3, count);
+
+ for (0..count) |i| {
+ vectors[i] = std.mem.bytesAsValue(Vec3, data[(@sizeOf(Vec3) * i) .. (@sizeOf(Vec3) * i) + @sizeOf(Vec3)]).*;
+ }
+
+ return vectors;
+ }
+ };
};
+
+pub fn parseFile(allocator: Allocator, name: []const u8) !struct { vertices: [][3]f32, indices: []u16 } {
+ const file = try std.fs.cwd().openFile(name, .{});
+ const all = try file.readToEndAlloc(allocator, 1_000_000);
+ const json_chunk = std.mem.bytesAsValue(Model.Chunk, all[Model.Header.offset..]);
+
+ const data = (try std.json.parseFromSlice(Model.JsonChunk, allocator, @constCast(all[Model.Chunk.offset .. Model.Chunk.offset + json_chunk.length]), .{ .ignore_unknown_fields = true })).value;
+ const binary = Model.Binary{ .data = all[Model.Chunk.offset + json_chunk.length + 8 ..] };
+
+ const vertices = try binary.readVec3(allocator, data.bufferViews.?[data.meshes.?[0].primitives.?[0].attributes.?.POSITION.?], 24);
+ const indices = try binary.readU16(allocator, data.bufferViews.?[data.meshes.?[0].primitives.?[0].indices.?], 36);
+ std.debug.print("vertices: {any}\n", .{vertices});
+ std.debug.print("indices: {any}\n", .{indices});
+
+ return .{ .vertices = vertices, .indices = indices };
+}
diff --git a/src/rendering/mesh.zig b/src/rendering/mesh.zig
index 92fa303..46000ad 100644
--- a/src/rendering/mesh.zig
+++ b/src/rendering/mesh.zig
@@ -1,6 +1,7 @@
const c = @import("../c.zig");
const std = @import("std");
const vk = @import("vulkan.zig");
+const gltf = @import("gltf.zig");
const Allocator = std.mem.Allocator;
pub const Vertex = struct {
@@ -38,13 +39,10 @@ pub const Mesh = struct {
vertex_buffer: vk.Buffer,
index_buffer: vk.Buffer,
- pub fn createVertexBuffer(device: anytype) !vk.Buffer {
- const vertices = [_]Vertex{
- Vertex.create(0.5, -0.5, 0.0),
- Vertex.create(0.5, 0.5, 0.0),
- Vertex.create(-0.5, 0.5, 0.0),
- Vertex.create(-0.5, -0.5, 0.0),
- };
+ pub fn createVertexBuffer(allocator: Allocator, device: anytype) !vk.Buffer {
+ const gltf_data = try gltf.parseFile(allocator, "assets/models/block.glb");
+
+ const vertices = gltf_data.vertices;
var data: [*c]?*anyopaque = null;
@@ -62,7 +60,7 @@ pub const Mesh = struct {
if (data) |ptr| {
const gpu_vertices: [*]Vertex = @ptrCast(@alignCast(ptr));
- @memcpy(gpu_vertices, vertices[0..]);
+ @memcpy(gpu_vertices, @as([]Vertex, @ptrCast(vertices[0..])));
}
c.vkUnmapMemory(device.handle, buffer.memory);
@@ -75,8 +73,10 @@ pub const Mesh = struct {
return vertex_buffer;
}
- pub fn createIndexBuffer(device: anytype) !vk.Buffer {
- const indices = [_]u16{ 0, 1, 2, 3, 0, 2 };
+ pub fn createIndexBuffer(allocator: Allocator, device: anytype) !vk.Buffer {
+ const gltf_data = try gltf.parseFile(allocator, "assets/models/block.glb");
+ const indices = gltf_data.indices;
+ //const indices = [_]u16{ 0, 1, 2, 3, 0, 2 };
var data: [*c]?*anyopaque = null;
@@ -107,9 +107,9 @@ pub const Mesh = struct {
return index_buffer;
}
- pub fn create(device: anytype) !Mesh {
- const vertex_buffer = try Mesh.createVertexBuffer(device);
- const index_buffer = try Mesh.createIndexBuffer(device);
+ pub fn create(allocator: Allocator, device: anytype) !Mesh {
+ const vertex_buffer = try Mesh.createVertexBuffer(allocator, device);
+ const index_buffer = try Mesh.createIndexBuffer(allocator, device);
return Mesh{
.vertex_buffer = vertex_buffer,
diff --git a/src/rendering/renderer_vulkan.zig b/src/rendering/renderer_vulkan.zig
index 0726616..47f91c7 100644
--- a/src/rendering/renderer_vulkan.zig
+++ b/src/rendering/renderer_vulkan.zig
@@ -44,7 +44,7 @@ pub fn create(allocator: Allocator, w: window.Window) !Renderer {
// renderer.render(some_other_thing);
// ...
// renderer.submit()
- const triangle = try mesh.Mesh.create(device);
+ const triangle = try mesh.Mesh.create(allocator, device);
return Renderer{
.instance = instance,
diff --git a/src/rendering/vulkan.zig b/src/rendering/vulkan.zig
index 8e937dc..556a465 100644
--- a/src/rendering/vulkan.zig
+++ b/src/rendering/vulkan.zig
@@ -372,7 +372,7 @@ pub fn GraphicsPipeline(comptime n: usize) type {
.polygonMode = c.VK_POLYGON_MODE_FILL,
.lineWidth = 1.0,
.cullMode = c.VK_CULL_MODE_BACK_BIT,
- .frontFace = c.VK_FRONT_FACE_CLOCKWISE,
+ .frontFace = c.VK_FRONT_FACE_COUNTER_CLOCKWISE,
.depthBiasEnable = c.VK_FALSE,
};