diff options
Diffstat (limited to 'src/renderer/Mesh.zig')
-rw-r--r-- | src/renderer/Mesh.zig | 119 |
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, + }; +} |