Import obj files

This commit is contained in:
Przemyslaw Gasinski 2024-08-18 16:56:31 +02:00
parent e182d73edc
commit d81957a096
12 changed files with 5180 additions and 60 deletions

View file

@ -0,0 +1,24 @@
newmtl white
Ka 0 0 0
Kd 1 1 1
Ks 0 0 0
newmtl red
Ka 0 0 0
Kd 1 0 0
Ks 0 0 0
newmtl green
Ka 0 0 0
Kd 0 1 0
Ks 0 0 0
newmtl blue
Ka 0 0 0
Kd 0 0 1
Ks 0 0 0
newmtl light
Ka 20 20 20
Kd 1 1 1
Ks 0 0 0

View file

@ -0,0 +1,145 @@
# cornell_box.obj and cornell_box.mtl are grabbed from Intel's embree project.
# original cornell box data
# comment
# empty line including some space
mtllib cornell_box.mtl
o floor
usemtl white
v 552.8 0.0 0.0
v 0.0 0.0 0.0
v 0.0 0.0 559.2
v 549.6 0.0 559.2
v 130.0 0.0 65.0
v 82.0 0.0 225.0
v 240.0 0.0 272.0
v 290.0 0.0 114.0
v 423.0 0.0 247.0
v 265.0 0.0 296.0
v 314.0 0.0 456.0
v 472.0 0.0 406.0
f 1 2 3 4
f 8 7 6 5
f 12 11 10 9
o light
usemtl light
v 343.0 548.0 227.0
v 343.0 548.0 332.0
v 213.0 548.0 332.0
v 213.0 548.0 227.0
f -4 -3 -2 -1
o ceiling
usemtl white
v 556.0 548.8 0.0
v 556.0 548.8 559.2
v 0.0 548.8 559.2
v 0.0 548.8 0.0
f -4 -3 -2 -1
o back_wall
usemtl white
v 549.6 0.0 559.2
v 0.0 0.0 559.2
v 0.0 548.8 559.2
v 556.0 548.8 559.2
f -4 -3 -2 -1
o front_wall
usemtl blue
v 549.6 0.0 0
v 0.0 0.0 0
v 0.0 548.8 0
v 556.0 548.8 0
#f -1 -2 -3 -4
o green_wall
usemtl green
v 0.0 0.0 559.2
v 0.0 0.0 0.0
v 0.0 548.8 0.0
v 0.0 548.8 559.2
f -4 -3 -2 -1
o red_wall
usemtl red
v 552.8 0.0 0.0
v 549.6 0.0 559.2
v 556.0 548.8 559.2
v 556.0 548.8 0.0
f -4 -3 -2 -1
o short_block
usemtl white
v 130.0 165.0 65.0
v 82.0 165.0 225.0
v 240.0 165.0 272.0
v 290.0 165.0 114.0
f -4 -3 -2 -1
v 290.0 0.0 114.0
v 290.0 165.0 114.0
v 240.0 165.0 272.0
v 240.0 0.0 272.0
f -4 -3 -2 -1
v 130.0 0.0 65.0
v 130.0 165.0 65.0
v 290.0 165.0 114.0
v 290.0 0.0 114.0
f -4 -3 -2 -1
v 82.0 0.0 225.0
v 82.0 165.0 225.0
v 130.0 165.0 65.0
v 130.0 0.0 65.0
f -4 -3 -2 -1
v 240.0 0.0 272.0
v 240.0 165.0 272.0
v 82.0 165.0 225.0
v 82.0 0.0 225.0
f -4 -3 -2 -1
o tall_block
usemtl white
v 423.0 330.0 247.0
v 265.0 330.0 296.0
v 314.0 330.0 456.0
v 472.0 330.0 406.0
f -4 -3 -2 -1
usemtl white
v 423.0 0.0 247.0
v 423.0 330.0 247.0
v 472.0 330.0 406.0
v 472.0 0.0 406.0
f -4 -3 -2 -1
v 472.0 0.0 406.0
v 472.0 330.0 406.0
v 314.0 330.0 456.0
v 314.0 0.0 456.0
f -4 -3 -2 -1
v 314.0 0.0 456.0
v 314.0 330.0 456.0
v 265.0 330.0 296.0
v 265.0 0.0 296.0
f -4 -3 -2 -1
v 265.0 0.0 296.0
v 265.0 330.0 296.0
v 423.0 330.0 247.0
v 423.0 0.0 247.0
f -4 -3 -2 -1

4663
assets/models/teapot.obj Normal file

File diff suppressed because it is too large Load diff

View file

@ -12,8 +12,11 @@ pub fn build(b: *std.Build) void {
.root_source_file = b.path("src/main.zig"), .root_source_file = b.path("src/main.zig"),
.target = target, .target = target,
.optimize = optimize, .optimize = optimize,
.link_libc = true,
}); });
// exe.addIncludePath(b.path("include/"));
// --- Dependencies --- // --- Dependencies ---
// Vulkan // Vulkan
@ -46,6 +49,9 @@ pub fn build(b: *std.Build) void {
exe.root_module.addImport("zstbi", zstbi.module("root")); exe.root_module.addImport("zstbi", zstbi.module("root"));
exe.linkLibrary(zstbi.artifact("zstbi")); exe.linkLibrary(zstbi.artifact("zstbi"));
// Assimp
exe.linkSystemLibrary("assimp");
// --- // ---
b.installArtifact(exe); b.installArtifact(exe);

View file

@ -10,6 +10,10 @@
.url = "https://github.com/Snektron/vulkan-zig/archive/9f6e6177b1fdb3ed22231d9216a24480e84cfa5e.tar.gz", .url = "https://github.com/Snektron/vulkan-zig/archive/9f6e6177b1fdb3ed22231d9216a24480e84cfa5e.tar.gz",
.hash = "1220f2961df224f7d35dee774b26194b8b937cc252fa8e4023407776c58521d53e38", .hash = "1220f2961df224f7d35dee774b26194b8b937cc252fa8e4023407776c58521d53e38",
}, },
.obj = .{
.url = "https://github.com/chip2n/zig-obj/archive/58f524ed6834790b29ac1e97b2f9e6b7de7b5346.tar.gz",
.hash = "1220ff46dcbeb40677c0ce8560b954885beec8b699835d9e6686beab72aa9d422c79",
},
}, },
.paths = .{ .paths = .{

View file

@ -49,7 +49,7 @@ pub fn new(
self.allocator = allocator; self.allocator = allocator;
try self.createVertexBuffer(transfer_queue, transfer_command_pool, vertices); try self.createVertexBuffer(transfer_queue, transfer_command_pool, vertices);
try self.createIndexBuffer(transfer_queue, transfer_command_pool, indices); // try self.createIndexBuffer(transfer_queue, transfer_command_pool, indices);
self.ubo_model = .{ .model = zm.identity() }; self.ubo_model = .{ .model = zm.identity() };
self.tex_id = tex_id; self.tex_id = tex_id;

195
src/MeshModel.zig Normal file
View file

@ -0,0 +1,195 @@
const std = @import("std");
const vk = @import("vulkan");
const zm = @import("zmath");
const ai = @import("assimp.zig").c;
const Mesh = @import("Mesh.zig");
const Device = @import("vulkan_renderer.zig").Device;
const Instance = @import("vulkan_renderer.zig").Instance;
const Vertex = @import("utilities.zig").Vertex;
const Self = @This();
allocator: std.mem.Allocator,
mesh_list: std.ArrayList(Mesh),
model: zm.Mat,
pub fn new(allocator: std.mem.Allocator, mesh_list: std.ArrayList(Mesh)) Self {
var new_mesh_model: Self = undefined;
new_mesh_model.allocator = allocator;
new_mesh_model.mesh_list = mesh_list;
new_mesh_model.model = zm.identity();
return new_mesh_model;
}
pub fn destroy(self: *Self) void {
for (0..self.mesh_list.items.len) |i| {
self.mesh_list.items[i].destroyBuffers();
}
self.mesh_list.deinit();
}
pub fn getMesh(self: Self, idx: usize) !Mesh {
if (idx >= self.mesh_list.len - 1) {
return error.MeshIndexOutOfBounds;
}
return self.mesh_list.items[idx];
}
pub fn loadMaterials(allocator: std.mem.Allocator, scene: ai.aiScene) !std.ArrayList(?[]const u8) {
// Create 1:1 sized list of textures
var texture_list = try std.ArrayList(?[]const u8).initCapacity(allocator, scene.mNumMaterials);
// Go through each material and copy its texture file name (if it exists)
for (0..scene.mNumMaterials) |i| {
// Get the material
const material = scene.mMaterials[i];
// Initialise the texture to empty string (will be replaced if the texture exists)
// try texture_list.append("");
// Check for diffuse texture (standard detail texture)
if (ai.aiGetMaterialTextureCount(material, ai.aiTextureType_DIFFUSE) != 0) {
// Get the path of the texture file
var path: ai.aiString = undefined;
if (ai.aiGetMaterialTexture(
material,
ai.aiTextureType_DIFFUSE,
0,
&path,
null,
null,
null,
null,
null,
null,
) != ai.AI_SUCCESS) {
// Cut of any directory information already present
var it = std.mem.splitBackwardsAny(u8, &path.data, "\\/");
if (it.next()) |filename| {
// texture_list.items[i] = filename;
texture_list.appendAssumeCapacity(filename);
}
} else {
texture_list.appendAssumeCapacity(null);
}
} else {
texture_list.appendAssumeCapacity(null);
}
}
return texture_list;
}
pub fn loadNode(
allocator: std.mem.Allocator,
instance: Instance,
pdev: vk.PhysicalDevice,
device: Device,
transfer_queue: vk.Queue,
transfer_command_pool: vk.CommandPool,
node: *const ai.aiNode,
scene: *const ai.aiScene,
mat_to_tex: []u32,
) !std.ArrayList(Mesh) {
var mesh_list = std.ArrayList(Mesh).init(allocator);
// Go through each mesh at this node and create it, then add it to our mesh list
for (0..node.mNumMeshes) |i| {
// Load mesh here
try mesh_list.append(try loadMesh(
allocator,
instance,
pdev,
device,
transfer_queue,
transfer_command_pool,
scene.mMeshes[node.mMeshes[i]],
mat_to_tex,
));
}
// Go through each node attached to this node and load it, then append their meshes to this node's mesh list
for (0..node.mNumChildren) |i| {
var new_list = try loadNode(
allocator,
instance,
pdev,
device,
transfer_queue,
transfer_command_pool,
node.mChildren[i],
scene,
mat_to_tex,
);
defer new_list.deinit();
try mesh_list.appendSlice(try new_list.toOwnedSlice());
}
return mesh_list;
}
pub fn loadMesh(
allocator: std.mem.Allocator,
instance: Instance,
pdev: vk.PhysicalDevice,
device: Device,
transfer_queue: vk.Queue,
transfer_command_pool: vk.CommandPool,
mesh: *const ai.aiMesh,
mat_to_tex: []u32,
) !Mesh {
var vertices = try std.ArrayList(Vertex).initCapacity(allocator, mesh.mNumVertices);
var indices = std.ArrayList(u32).init(allocator);
defer vertices.deinit();
defer indices.deinit();
// Go through each vertex and copy it across to our vertices
for (0..mesh.mNumVertices) |i| {
var vertex: Vertex = undefined;
// Set position
vertex.pos = .{ mesh.mVertices[i].x, mesh.mVertices[i].y, mesh.mVertices[i].z };
// Set texture coords (if they exist)
if (mesh.mTextureCoords[0] != null) {
vertex.tex = .{ mesh.mTextureCoords[0][i].x, mesh.mTextureCoords[0][i].y };
} else {
vertex.tex = .{ 0.0, 0.0 };
}
// Set colour (just use white for now)
vertex.col = .{ 1.0, 1.0, 1.0 };
// vertices.items[i] = vertex;
vertices.appendAssumeCapacity(vertex);
}
// Iterate over indices through faces and copy across
for (0..mesh.mNumFaces - 1) |i| {
// Get a face
const face = mesh.mFaces[i];
// Go through face's indices and add to list
for (0..face.mNumIndices - 1) |j| {
try indices.append(face.mIndices[j]);
}
}
return try Mesh.new(
instance,
pdev,
device,
transfer_queue,
transfer_command_pool,
vertices.items,
indices.items,
mat_to_tex[mesh.mMaterialIndex],
allocator,
);
}

9
src/assimp.zig Normal file
View file

@ -0,0 +1,9 @@
pub const c = @cImport({
@cInclude("assimp/cimport.h");
@cInclude("assimp/scene.h");
@cInclude("assimp/postprocess.h");
});
// pub fn importFile(path: [:0]const u8, flags: c_uint) *const c.aiScene {
// return c.aiImportFile(path.ptr, flags);
// }

View file

@ -91,14 +91,16 @@ pub fn main() !void {
angle -= 360.0; angle -= 360.0;
} }
var first_model = zm.rotationZ(angle); // var first_model = zm.rotationZ(angle);
var second_model = zm.rotationZ(-angle * 2); // var second_model = zm.rotationZ(-angle * 2);
first_model = zm.mul(first_model, zm.translation(1.0, 0.0, -2.5)); // first_model = zm.mul(first_model, zm.translation(1.0, 0.0, -2.5));
second_model = zm.mul(second_model, zm.translation(-1.0, 0.0, -4.5)); // second_model = zm.mul(second_model, zm.translation(-1.0, 0.0, -4.5));
try vulkan_renderer.updateModel(0, first_model); // const first_model = zm.scaling(2.0, 2.0, 0.0);
try vulkan_renderer.updateModel(1, second_model);
// try vulkan_renderer.updateModel(0, first_model);
// try vulkan_renderer.updateModel(1, second_model);
try vulkan_renderer.draw(); try vulkan_renderer.draw();

View file

@ -9,5 +9,6 @@ layout(location = 0) out vec4 outColour;
layout(set = 1, binding = 0) uniform sampler2D textureSampler; layout(set = 1, binding = 0) uniform sampler2D textureSampler;
void main() { void main() {
outColour = texture(textureSampler, fragTex); // outColour = texture(textureSampler, fragTex);
outColour = vec4(fragCol, 1.0);
} }

13
src/string_utils.zig Normal file
View file

@ -0,0 +1,13 @@
const std = @import("std");
pub const StringError = error{ConcatError};
/// Concatenates two strings together using `std.mem.concat()`
pub fn concat(str_1: []const u8, str_2: []const u8, allocator: std.mem.Allocator) StringError![:0]const u8 {
const path_concat = [2][]const u8{ str_1, str_2 };
return std.mem.concatWithSentinel(allocator, u8, &path_concat, 0) catch |e| {
std.log.err("[{s}] Failed to concatenate the following strings: '{s}' and '{s}'\n", .{ @errorName(e), str_1, str_2 });
return StringError.ConcatError;
};
}

View file

@ -4,9 +4,10 @@ const vk = @import("vulkan");
const builtin = @import("builtin"); const builtin = @import("builtin");
const shaders = @import("shaders"); const shaders = @import("shaders");
const zm = @import("zmath"); const zm = @import("zmath");
// const img = @import("zigimg");
const img = @import("zstbi"); const img = @import("zstbi");
const assimp = @import("assimp.zig").c;
const StringUtils = @import("string_utils.zig");
const Utilities = @import("utilities.zig"); const Utilities = @import("utilities.zig");
const QueueFamilyIndices = Utilities.QueueFamilyIndices; const QueueFamilyIndices = Utilities.QueueFamilyIndices;
const SwapchainDetails = Utilities.SwapchainDetails; const SwapchainDetails = Utilities.SwapchainDetails;
@ -14,6 +15,7 @@ const SwapchainImage = Utilities.SwapchainImage;
const Vertex = Utilities.Vertex; const Vertex = Utilities.Vertex;
const Mesh = @import("Mesh.zig"); const Mesh = @import("Mesh.zig");
const MeshModel = @import("MeshModel.zig");
const enable_validation_layers = builtin.mode == .Debug; const enable_validation_layers = builtin.mode == .Debug;
const validation_layers = [_][*:0]const u8{"VK_LAYER_KHRONOS_validation"}; const validation_layers = [_][*:0]const u8{"VK_LAYER_KHRONOS_validation"};
@ -61,7 +63,7 @@ pub const VulkanRenderer = struct {
current_frame: u32 = 0, current_frame: u32 = 0,
// Scene objects // Scene objects
meshes: [2]Mesh, meshes: std.ArrayList(Mesh),
// Scene settings // Scene settings
ubo_view_projection: UboViewProjection, ubo_view_projection: UboViewProjection,
@ -104,6 +106,7 @@ pub const VulkanRenderer = struct {
texture_images: std.ArrayList(vk.Image), texture_images: std.ArrayList(vk.Image),
texture_image_memory: std.ArrayList(vk.DeviceMemory), texture_image_memory: std.ArrayList(vk.DeviceMemory),
texture_image_views: std.ArrayList(vk.ImageView), texture_image_views: std.ArrayList(vk.ImageView),
model_list: std.ArrayList(MeshModel),
// Pipeline // Pipeline
graphics_pipeline: vk.Pipeline, graphics_pipeline: vk.Pipeline,
@ -161,10 +164,12 @@ pub const VulkanRenderer = struct {
try self.createSynchronisation(); try self.createSynchronisation();
self.meshes = std.ArrayList(Mesh).init(self.allocator);
self.image_files = std.ArrayList(img.Image).init(self.allocator); self.image_files = std.ArrayList(img.Image).init(self.allocator);
self.texture_images = std.ArrayList(vk.Image).init(self.allocator); self.texture_images = std.ArrayList(vk.Image).init(self.allocator);
self.texture_image_memory = std.ArrayList(vk.DeviceMemory).init(self.allocator); self.texture_image_memory = std.ArrayList(vk.DeviceMemory).init(self.allocator);
self.texture_image_views = std.ArrayList(vk.ImageView).init(self.allocator); self.texture_image_views = std.ArrayList(vk.ImageView).init(self.allocator);
self.model_list = std.ArrayList(MeshModel).init(allocator);
self.sampler_descriptor_sets = std.ArrayList(vk.DescriptorSet).init(self.allocator); self.sampler_descriptor_sets = std.ArrayList(vk.DescriptorSet).init(self.allocator);
const aspect: f32 = @as(f32, @floatFromInt(self.extent.width)) / @as(f32, @floatFromInt(self.extent.height)); const aspect: f32 = @as(f32, @floatFromInt(self.extent.width)) / @as(f32, @floatFromInt(self.extent.height));
@ -185,57 +190,59 @@ pub const VulkanRenderer = struct {
// Create meshes // Create meshes
// Vertex Data // Vertex Data
var mesh_vertices = [_]Vertex{ // var mesh_vertices = [_]Vertex{
.{ .pos = .{ -0.4, 0.4, 0.0 }, .col = .{ 1.0, 0.0, 0.0 }, .tex = .{ 1.0, 1.0 } }, // 0 // .{ .pos = .{ -0.4, 0.4, 0.0 }, .col = .{ 1.0, 0.0, 0.0 }, .tex = .{ 1.0, 1.0 } }, // 0
.{ .pos = .{ -0.4, -0.4, 0.0 }, .col = .{ 1.0, 0.0, 0.0 }, .tex = .{ 1.0, 0.0 } }, // 1 // .{ .pos = .{ -0.4, -0.4, 0.0 }, .col = .{ 1.0, 0.0, 0.0 }, .tex = .{ 1.0, 0.0 } }, // 1
.{ .pos = .{ 0.4, -0.4, 0.0 }, .col = .{ 1.0, 0.0, 0.0 }, .tex = .{ 0.0, 0.0 } }, // 2 // .{ .pos = .{ 0.4, -0.4, 0.0 }, .col = .{ 1.0, 0.0, 0.0 }, .tex = .{ 0.0, 0.0 } }, // 2
.{ .pos = .{ 0.4, 0.4, 0.0 }, .col = .{ 1.0, 0.0, 0.0 }, .tex = .{ 0.0, 1.0 } }, // 3 // .{ .pos = .{ 0.4, 0.4, 0.0 }, .col = .{ 1.0, 0.0, 0.0 }, .tex = .{ 0.0, 1.0 } }, // 3
}; // };
var mesh_vertices2 = [_]Vertex{ // var mesh_vertices2 = [_]Vertex{
.{ .pos = .{ -0.25, 0.6, 0.0 }, .col = .{ 0.0, 0.0, 1.0 }, .tex = .{ 1.0, 1.0 } }, // 0 // .{ .pos = .{ -0.25, 0.6, 0.0 }, .col = .{ 0.0, 0.0, 1.0 }, .tex = .{ 1.0, 1.0 } }, // 0
.{ .pos = .{ -0.25, -0.6, 0.0 }, .col = .{ 0.0, 0.0, 1.0 }, .tex = .{ 1.0, 0.0 } }, // 1 // .{ .pos = .{ -0.25, -0.6, 0.0 }, .col = .{ 0.0, 0.0, 1.0 }, .tex = .{ 1.0, 0.0 } }, // 1
.{ .pos = .{ 0.25, -0.6, 0.0 }, .col = .{ 0.0, 0.0, 1.0 }, .tex = .{ 0.0, 0.0 } }, // 2 // .{ .pos = .{ 0.25, -0.6, 0.0 }, .col = .{ 0.0, 0.0, 1.0 }, .tex = .{ 0.0, 0.0 } }, // 2
.{ .pos = .{ 0.25, 0.6, 0.0 }, .col = .{ 0.0, 0.0, 1.0 }, .tex = .{ 0.0, 1.0 } }, // 3 // .{ .pos = .{ 0.25, 0.6, 0.0 }, .col = .{ 0.0, 0.0, 1.0 }, .tex = .{ 0.0, 1.0 } }, // 3
}; // };
try self.createMeshModel("cornell_box.obj");
// Index Data // Index Data
const mesh_indices = [_]u32{ // const mesh_indices = [_]u32{
0, 1, 2, // 0, 1, 2,
2, 3, 0, // 2, 3, 0,
}; // };
const first_mesh = try Mesh.new( // const first_mesh = try Mesh.new(
self.instance, // self.instance,
self.physical_device, // self.physical_device,
self.device, // self.device,
self.graphics_queue.handle, // self.graphics_queue.handle,
self.graphics_command_pool, // self.graphics_command_pool,
&mesh_vertices, // &mesh_vertices,
&mesh_indices, // &mesh_indices,
try self.createTexture("test.png"), // try self.createTexture("test.png"),
self.allocator, // self.allocator,
); // );
const second_mesh = try Mesh.new( // const second_mesh = try Mesh.new(
self.instance, // self.instance,
self.physical_device, // self.physical_device,
self.device, // self.device,
self.graphics_queue.handle, // self.graphics_queue.handle,
self.graphics_command_pool, // self.graphics_command_pool,
&mesh_vertices2, // &mesh_vertices2,
&mesh_indices, // &mesh_indices,
try self.createTexture("giraffe.png"), // try self.createTexture("giraffe.png"),
self.allocator, // self.allocator,
); // );
self.meshes = [_]Mesh{ first_mesh, second_mesh }; // self.meshes = [_]Mesh{ first_mesh, second_mesh };
return self; return self;
} }
pub fn updateModel(self: *Self, model_id: u32, new_model: zm.Mat) !void { pub fn updateModel(self: *Self, model_id: u32, new_model: zm.Mat) !void {
if (model_id < self.meshes.len) { if (model_id < self.meshes.items.len) {
self.meshes[model_id].ubo_model.model = new_model; self.meshes.items[model_id].ubo_model.model = new_model;
} }
} }
@ -302,6 +309,11 @@ pub const VulkanRenderer = struct {
self.instance.destroyDebugUtilsMessengerEXT(self.debug_utils.?, null); self.instance.destroyDebugUtilsMessengerEXT(self.debug_utils.?, null);
} }
for (0..self.model_list.items.len) |i| {
self.model_list.items[i].destroy();
}
self.model_list.deinit();
for (0..self.image_files.items.len) |i| { for (0..self.image_files.items.len) |i| {
self.image_files.items[i].deinit(); self.image_files.items[i].deinit();
} }
@ -341,9 +353,10 @@ pub const VulkanRenderer = struct {
self.allocator.free(self.vp_uniform_buffer_memory); self.allocator.free(self.vp_uniform_buffer_memory);
self.allocator.free(self.descriptor_sets); self.allocator.free(self.descriptor_sets);
for (self.meshes) |mesh| { for (self.meshes.items) |mesh| {
mesh.destroyBuffers(); mesh.destroyBuffers();
} }
self.meshes.deinit();
for (0..MAX_FRAME_DRAWS) |i| { for (0..MAX_FRAME_DRAWS) |i| {
self.device.destroySemaphore(self.render_finished[i], null); self.device.destroySemaphore(self.render_finished[i], null);
@ -1197,7 +1210,7 @@ pub const VulkanRenderer = struct {
command_buffer.setViewport(0, 1, @ptrCast(&self.viewport)); command_buffer.setViewport(0, 1, @ptrCast(&self.viewport));
command_buffer.setScissor(0, 1, @ptrCast(&self.scissor)); command_buffer.setScissor(0, 1, @ptrCast(&self.scissor));
for (self.meshes) |mesh| { for (self.meshes.items) |mesh| {
// Bind pipeline to be used in render pass // Bind pipeline to be used in render pass
command_buffer.bindPipeline(.graphics, self.graphics_pipeline); command_buffer.bindPipeline(.graphics, self.graphics_pipeline);
@ -1209,7 +1222,7 @@ pub const VulkanRenderer = struct {
command_buffer.bindVertexBuffers(0, 1, &vertex_buffers, &offsets); command_buffer.bindVertexBuffers(0, 1, &vertex_buffers, &offsets);
// Bind mesh index buffer, with 0 offset and using the uint32 type // Bind mesh index buffer, with 0 offset and using the uint32 type
command_buffer.bindIndexBuffer(mesh.index_buffer, 0, .uint32); // command_buffer.bindIndexBuffer(mesh.index_buffer, 0, .uint32);
// Push constants to given shader stage directly (no buffer) // Push constants to given shader stage directly (no buffer)
command_buffer.pushConstants( command_buffer.pushConstants(
@ -1237,7 +1250,8 @@ pub const VulkanRenderer = struct {
); );
// Execute a pipeline // Execute a pipeline
command_buffer.drawIndexed(mesh.index_count, 1, 0, 0, 0); // command_buffer.drawIndexed(mesh.index_count, 1, 0, 0, 0);
command_buffer.draw(mesh.vertex_count, 1, 0, 0);
} }
// End render pass // End render pass
@ -1531,15 +1545,10 @@ pub const VulkanRenderer = struct {
&image_staging_buffer_memory, &image_staging_buffer_memory,
); );
std.debug.print("Image size: {d}\n", .{image_size});
// Copy data to staging buffer // Copy data to staging buffer
const data = try self.device.mapMemory(image_staging_buffer_memory, 0, image_size, .{}); const data = try self.device.mapMemory(image_staging_buffer_memory, 0, image_size, .{});
const image_data: [*]u8 = @ptrCast(@alignCast(data)); const image_data: [*]u8 = @ptrCast(@alignCast(data));
// std.debug.print("Data len: {d}\tImage len:{d}\n", .{ image_data., image.len });
// image_data.* = image;
// std.mem.copyForwards(u8, image_data, image);
@memcpy(image_data, image[0..]); @memcpy(image_data, image[0..]);
self.device.unmapMemory(image_staging_buffer_memory); self.device.unmapMemory(image_staging_buffer_memory);
@ -1614,6 +1623,55 @@ pub const VulkanRenderer = struct {
return descriptor_loc; return descriptor_loc;
} }
fn createMeshModel(self: *Self, model_file: []const u8) !void {
const path = try StringUtils.concat("assets/models/", model_file, self.allocator);
defer self.allocator.free(path);
// Import model scene
const scene = assimp.aiImportFile(
path.ptr,
assimp.aiProcess_Triangulate | assimp.aiProcess_FlipUVs | assimp.aiProcess_JoinIdenticalVertices,
);
// Get array of all materials with 1:1 ID placement
const texture_names = try MeshModel.loadMaterials(self.allocator, scene.*);
defer texture_names.deinit();
// Conversion from the material list IDs to our descriptor array IDs
var mat_to_tex = try std.ArrayList(u32).initCapacity(self.allocator, texture_names.items.len);
defer mat_to_tex.deinit();
// Loop over texture names and create textures for them
for (0..texture_names.items.len) |i| {
if (texture_names.items[i]) |texture_name| {
// Create texture and set value to index of new texture
// mat_to_tex.items[i] = try self.createTexture(texture_name);
mat_to_tex.appendAssumeCapacity(try self.createTexture(texture_name));
} else {
// If material had no texture, set to 0 to indicate no texture. Texture 0 will be reserver for a default texture
// mat_to_tex.items[i] = 0;
mat_to_tex.appendAssumeCapacity(0);
}
}
// Load in all our meshes
const model_meshes = try MeshModel.loadNode(
self.allocator,
self.instance,
self.physical_device,
self.device,
self.graphics_queue.handle,
self.graphics_command_pool,
scene.*.mRootNode,
scene,
mat_to_tex.items,
);
// Create a mesh model and add to our list
const mesh_model = MeshModel.new(self.allocator, model_meshes);
try self.model_list.append(mesh_model);
}
fn createTextureDescriptor(self: *Self, texture_image: vk.ImageView) !u32 { fn createTextureDescriptor(self: *Self, texture_image: vk.ImageView) !u32 {
var descriptor_set: vk.DescriptorSet = undefined; var descriptor_set: vk.DescriptorSet = undefined;