summaryrefslogtreecommitdiff
path: root/src/renderer/Mesh.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/renderer/Mesh.zig')
-rw-r--r--src/renderer/Mesh.zig119
1 files changed, 119 insertions, 0 deletions
diff --git a/src/renderer/Mesh.zig b/src/renderer/Mesh.zig
new file mode 100644
index 0000000..b0f76ce
--- /dev/null
+++ b/src/renderer/Mesh.zig
@@ -0,0 +1,119 @@
+const c = @import("c.zig");
+const std = @import("std");
+const vk = @import("vulkan.zig");
+const gltf = @import("gltf.zig");
+const Allocator = std.mem.Allocator;
+
+const Mesh = @This();
+
+pub const Vertex = struct {
+ position: [3]f32,
+
+ pub fn create(x: f32, y: f32, z: f32) Vertex {
+ return Vertex{
+ .position = .{ x, y, z },
+ };
+ }
+
+ pub fn bindingDescription() c.VkVertexInputBindingDescription {
+ const binding_description: c.VkVertexInputBindingDescription = .{
+ .binding = 0,
+ .stride = @sizeOf(Vertex),
+ .inputRate = c.VK_VERTEX_INPUT_RATE_VERTEX,
+ };
+
+ return binding_description;
+ }
+
+ pub fn attributeDescription() c.VkVertexInputAttributeDescription {
+ const attribute_description: c.VkVertexInputAttributeDescription = .{
+ .location = 0,
+ .binding = 0,
+ .format = c.VK_FORMAT_R32G32B32_SFLOAT,
+ .offset = 0,
+ };
+
+ return attribute_description;
+ }
+};
+
+vertex_buffer: vk.Buffer,
+index_buffer: vk.Buffer,
+
+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;
+
+ const buffer = try device.createBuffer(vk.BufferUsage{ .transfer_src = true }, vk.BufferFlags{ .host_visible = true, .host_coherent = true }, @sizeOf(Vertex) * vertices.len);
+
+ try vk.mapError(c.vkMapMemory(
+ device.handle,
+ buffer.memory,
+ 0,
+ buffer.size,
+ 0,
+ @ptrCast(&data),
+ ));
+
+ if (data) |ptr| {
+ const gpu_vertices: [*]Vertex = @ptrCast(@alignCast(ptr));
+
+ @memcpy(gpu_vertices, @as([]Vertex, @ptrCast(vertices[0..])));
+ }
+
+ c.vkUnmapMemory(device.handle, buffer.memory);
+
+ const vertex_buffer = try device.createBuffer(vk.BufferUsage{ .vertex_buffer = true, .transfer_dst = true }, vk.BufferFlags{ .device_local = true }, @sizeOf(Vertex) * vertices.len);
+
+ try buffer.copyTo(device, vertex_buffer);
+ buffer.destroy(device.handle);
+
+ return vertex_buffer;
+}
+
+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;
+
+ const buffer = try device.createBuffer(vk.BufferUsage{ .transfer_src = true }, vk.BufferFlags{ .host_visible = true, .host_coherent = true }, @sizeOf(u16) * indices.len);
+
+ try vk.mapError(c.vkMapMemory(
+ device.handle,
+ buffer.memory,
+ 0,
+ buffer.size,
+ 0,
+ @ptrCast(&data),
+ ));
+
+ if (data) |ptr| {
+ const gpu_indices: [*]u16 = @ptrCast(@alignCast(ptr));
+
+ @memcpy(gpu_indices, indices[0..]);
+ }
+
+ c.vkUnmapMemory(device.handle, buffer.memory);
+
+ const index_buffer = try device.createBuffer(vk.BufferUsage{ .index_buffer = true, .transfer_dst = true }, vk.BufferFlags{ .device_local = true }, @sizeOf(u16) * indices.len);
+
+ try buffer.copyTo(device, index_buffer);
+ buffer.destroy(device.handle);
+
+ return index_buffer;
+}
+
+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,
+ .index_buffer = index_buffer,
+ };
+}