summaryrefslogtreecommitdiff
path: root/src/rendering/mesh.zig
blob: 46000ad34c269eec5ae5d96db58d7330ae0f388f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
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;

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;
    }
};

pub const Mesh = struct {
    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,
        };
    }
};