Import obj files
This commit is contained in:
parent
e182d73edc
commit
d81957a096
12 changed files with 5180 additions and 60 deletions
24
assets/models/cornell_box.mtl
Normal file
24
assets/models/cornell_box.mtl
Normal 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
|
145
assets/models/cornell_box.obj
Normal file
145
assets/models/cornell_box.obj
Normal 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
4663
assets/models/teapot.obj
Normal file
File diff suppressed because it is too large
Load diff
|
@ -12,8 +12,11 @@ pub fn build(b: *std.Build) void {
|
|||
.root_source_file = b.path("src/main.zig"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.link_libc = true,
|
||||
});
|
||||
|
||||
// exe.addIncludePath(b.path("include/"));
|
||||
|
||||
// --- Dependencies ---
|
||||
|
||||
// Vulkan
|
||||
|
@ -46,6 +49,9 @@ pub fn build(b: *std.Build) void {
|
|||
exe.root_module.addImport("zstbi", zstbi.module("root"));
|
||||
exe.linkLibrary(zstbi.artifact("zstbi"));
|
||||
|
||||
// Assimp
|
||||
exe.linkSystemLibrary("assimp");
|
||||
|
||||
// ---
|
||||
|
||||
b.installArtifact(exe);
|
||||
|
|
|
@ -10,6 +10,10 @@
|
|||
.url = "https://github.com/Snektron/vulkan-zig/archive/9f6e6177b1fdb3ed22231d9216a24480e84cfa5e.tar.gz",
|
||||
.hash = "1220f2961df224f7d35dee774b26194b8b937cc252fa8e4023407776c58521d53e38",
|
||||
},
|
||||
.obj = .{
|
||||
.url = "https://github.com/chip2n/zig-obj/archive/58f524ed6834790b29ac1e97b2f9e6b7de7b5346.tar.gz",
|
||||
.hash = "1220ff46dcbeb40677c0ce8560b954885beec8b699835d9e6686beab72aa9d422c79",
|
||||
},
|
||||
},
|
||||
|
||||
.paths = .{
|
||||
|
|
|
@ -49,7 +49,7 @@ pub fn new(
|
|||
self.allocator = allocator;
|
||||
|
||||
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.tex_id = tex_id;
|
||||
|
|
195
src/MeshModel.zig
Normal file
195
src/MeshModel.zig
Normal 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
9
src/assimp.zig
Normal 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);
|
||||
// }
|
14
src/main.zig
14
src/main.zig
|
@ -91,14 +91,16 @@ pub fn main() !void {
|
|||
angle -= 360.0;
|
||||
}
|
||||
|
||||
var first_model = zm.rotationZ(angle);
|
||||
var second_model = zm.rotationZ(-angle * 2);
|
||||
// var first_model = zm.rotationZ(angle);
|
||||
// var second_model = zm.rotationZ(-angle * 2);
|
||||
|
||||
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));
|
||||
// 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));
|
||||
|
||||
try vulkan_renderer.updateModel(0, first_model);
|
||||
try vulkan_renderer.updateModel(1, second_model);
|
||||
// const first_model = zm.scaling(2.0, 2.0, 0.0);
|
||||
|
||||
// try vulkan_renderer.updateModel(0, first_model);
|
||||
// try vulkan_renderer.updateModel(1, second_model);
|
||||
|
||||
try vulkan_renderer.draw();
|
||||
|
||||
|
|
|
@ -9,5 +9,6 @@ layout(location = 0) out vec4 outColour;
|
|||
layout(set = 1, binding = 0) uniform sampler2D textureSampler;
|
||||
|
||||
void main() {
|
||||
outColour = texture(textureSampler, fragTex);
|
||||
// outColour = texture(textureSampler, fragTex);
|
||||
outColour = vec4(fragCol, 1.0);
|
||||
}
|
||||
|
|
13
src/string_utils.zig
Normal file
13
src/string_utils.zig
Normal 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;
|
||||
};
|
||||
}
|
|
@ -4,9 +4,10 @@ const vk = @import("vulkan");
|
|||
const builtin = @import("builtin");
|
||||
const shaders = @import("shaders");
|
||||
const zm = @import("zmath");
|
||||
// const img = @import("zigimg");
|
||||
const img = @import("zstbi");
|
||||
const assimp = @import("assimp.zig").c;
|
||||
|
||||
const StringUtils = @import("string_utils.zig");
|
||||
const Utilities = @import("utilities.zig");
|
||||
const QueueFamilyIndices = Utilities.QueueFamilyIndices;
|
||||
const SwapchainDetails = Utilities.SwapchainDetails;
|
||||
|
@ -14,6 +15,7 @@ const SwapchainImage = Utilities.SwapchainImage;
|
|||
const Vertex = Utilities.Vertex;
|
||||
|
||||
const Mesh = @import("Mesh.zig");
|
||||
const MeshModel = @import("MeshModel.zig");
|
||||
|
||||
const enable_validation_layers = builtin.mode == .Debug;
|
||||
const validation_layers = [_][*:0]const u8{"VK_LAYER_KHRONOS_validation"};
|
||||
|
@ -61,7 +63,7 @@ pub const VulkanRenderer = struct {
|
|||
current_frame: u32 = 0,
|
||||
|
||||
// Scene objects
|
||||
meshes: [2]Mesh,
|
||||
meshes: std.ArrayList(Mesh),
|
||||
|
||||
// Scene settings
|
||||
ubo_view_projection: UboViewProjection,
|
||||
|
@ -104,6 +106,7 @@ pub const VulkanRenderer = struct {
|
|||
texture_images: std.ArrayList(vk.Image),
|
||||
texture_image_memory: std.ArrayList(vk.DeviceMemory),
|
||||
texture_image_views: std.ArrayList(vk.ImageView),
|
||||
model_list: std.ArrayList(MeshModel),
|
||||
|
||||
// Pipeline
|
||||
graphics_pipeline: vk.Pipeline,
|
||||
|
@ -161,10 +164,12 @@ pub const VulkanRenderer = struct {
|
|||
|
||||
try self.createSynchronisation();
|
||||
|
||||
self.meshes = std.ArrayList(Mesh).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_image_memory = std.ArrayList(vk.DeviceMemory).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);
|
||||
|
||||
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
|
||||
// Vertex Data
|
||||
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, 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, 1.0 } }, // 3
|
||||
};
|
||||
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, 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, 1.0 } }, // 3
|
||||
};
|
||||
// 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, 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, 1.0 } }, // 3
|
||||
// };
|
||||
// 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, 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, 1.0 } }, // 3
|
||||
// };
|
||||
|
||||
try self.createMeshModel("cornell_box.obj");
|
||||
|
||||
// Index Data
|
||||
const mesh_indices = [_]u32{
|
||||
0, 1, 2,
|
||||
2, 3, 0,
|
||||
};
|
||||
// const mesh_indices = [_]u32{
|
||||
// 0, 1, 2,
|
||||
// 2, 3, 0,
|
||||
// };
|
||||
|
||||
const first_mesh = try Mesh.new(
|
||||
self.instance,
|
||||
self.physical_device,
|
||||
self.device,
|
||||
self.graphics_queue.handle,
|
||||
self.graphics_command_pool,
|
||||
&mesh_vertices,
|
||||
&mesh_indices,
|
||||
try self.createTexture("test.png"),
|
||||
self.allocator,
|
||||
);
|
||||
// const first_mesh = try Mesh.new(
|
||||
// self.instance,
|
||||
// self.physical_device,
|
||||
// self.device,
|
||||
// self.graphics_queue.handle,
|
||||
// self.graphics_command_pool,
|
||||
// &mesh_vertices,
|
||||
// &mesh_indices,
|
||||
// try self.createTexture("test.png"),
|
||||
// self.allocator,
|
||||
// );
|
||||
|
||||
const second_mesh = try Mesh.new(
|
||||
self.instance,
|
||||
self.physical_device,
|
||||
self.device,
|
||||
self.graphics_queue.handle,
|
||||
self.graphics_command_pool,
|
||||
&mesh_vertices2,
|
||||
&mesh_indices,
|
||||
try self.createTexture("giraffe.png"),
|
||||
self.allocator,
|
||||
);
|
||||
// const second_mesh = try Mesh.new(
|
||||
// self.instance,
|
||||
// self.physical_device,
|
||||
// self.device,
|
||||
// self.graphics_queue.handle,
|
||||
// self.graphics_command_pool,
|
||||
// &mesh_vertices2,
|
||||
// &mesh_indices,
|
||||
// try self.createTexture("giraffe.png"),
|
||||
// self.allocator,
|
||||
// );
|
||||
|
||||
self.meshes = [_]Mesh{ first_mesh, second_mesh };
|
||||
// self.meshes = [_]Mesh{ first_mesh, second_mesh };
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn updateModel(self: *Self, model_id: u32, new_model: zm.Mat) !void {
|
||||
if (model_id < self.meshes.len) {
|
||||
self.meshes[model_id].ubo_model.model = new_model;
|
||||
if (model_id < self.meshes.items.len) {
|
||||
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);
|
||||
}
|
||||
|
||||
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| {
|
||||
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.descriptor_sets);
|
||||
|
||||
for (self.meshes) |mesh| {
|
||||
for (self.meshes.items) |mesh| {
|
||||
mesh.destroyBuffers();
|
||||
}
|
||||
self.meshes.deinit();
|
||||
|
||||
for (0..MAX_FRAME_DRAWS) |i| {
|
||||
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.setScissor(0, 1, @ptrCast(&self.scissor));
|
||||
|
||||
for (self.meshes) |mesh| {
|
||||
for (self.meshes.items) |mesh| {
|
||||
// Bind pipeline to be used in render pass
|
||||
command_buffer.bindPipeline(.graphics, self.graphics_pipeline);
|
||||
|
||||
|
@ -1209,7 +1222,7 @@ pub const VulkanRenderer = struct {
|
|||
command_buffer.bindVertexBuffers(0, 1, &vertex_buffers, &offsets);
|
||||
|
||||
// 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)
|
||||
command_buffer.pushConstants(
|
||||
|
@ -1237,7 +1250,8 @@ pub const VulkanRenderer = struct {
|
|||
);
|
||||
|
||||
// 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
|
||||
|
@ -1531,15 +1545,10 @@ pub const VulkanRenderer = struct {
|
|||
&image_staging_buffer_memory,
|
||||
);
|
||||
|
||||
std.debug.print("Image size: {d}\n", .{image_size});
|
||||
|
||||
// Copy data to staging buffer
|
||||
const data = try self.device.mapMemory(image_staging_buffer_memory, 0, image_size, .{});
|
||||
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..]);
|
||||
self.device.unmapMemory(image_staging_buffer_memory);
|
||||
|
||||
|
@ -1614,6 +1623,55 @@ pub const VulkanRenderer = struct {
|
|||
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 {
|
||||
var descriptor_set: vk.DescriptorSet = undefined;
|
||||
|
||||
|
|
Loading…
Reference in a new issue