Fix loading textures

This commit is contained in:
Przemysław Gasiǹski 2024-08-06 15:54:44 +02:00
parent c0591ecb24
commit e182d73edc
14 changed files with 13216 additions and 35 deletions

View file

@ -4,7 +4,8 @@ const vk = @import("vulkan");
const builtin = @import("builtin");
const shaders = @import("shaders");
const zm = @import("zmath");
const img = @import("zigimg");
// const img = @import("zigimg");
const img = @import("zstbi");
const Utilities = @import("utilities.zig");
const QueueFamilyIndices = Utilities.QueueFamilyIndices;
@ -99,6 +100,7 @@ pub const VulkanRenderer = struct {
vp_uniform_buffer_memory: []vk.DeviceMemory,
// Assets
image_files: std.ArrayList(img.Image),
texture_images: std.ArrayList(vk.Image),
texture_image_memory: std.ArrayList(vk.DeviceMemory),
texture_image_views: std.ArrayList(vk.ImageView),
@ -131,6 +133,8 @@ pub const VulkanRenderer = struct {
self.allocator = allocator;
self.vkb = try BaseDispatch.load(try sdl.vulkan.getVkGetInstanceProcAddr());
img.init(allocator);
try self.createInstance();
try self.createSurface();
@ -157,6 +161,7 @@ pub const VulkanRenderer = struct {
try self.createSynchronisation();
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);
@ -186,7 +191,6 @@ pub const VulkanRenderer = struct {
.{ .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
@ -220,7 +224,7 @@ pub const VulkanRenderer = struct {
self.graphics_command_pool,
&mesh_vertices2,
&mesh_indices,
try self.createTexture("test.png"),
try self.createTexture("giraffe.png"),
self.allocator,
);
@ -298,6 +302,11 @@ pub const VulkanRenderer = struct {
self.instance.destroyDebugUtilsMessengerEXT(self.debug_utils.?, null);
}
for (0..self.image_files.items.len) |i| {
self.image_files.items[i].deinit();
}
self.image_files.deinit();
self.device.destroySampler(self.texture_sampler, null);
for (
@ -367,6 +376,8 @@ pub const VulkanRenderer = struct {
self.allocator.destroy(self.device.wrapper);
self.allocator.destroy(self.instance.wrapper);
img.deinit();
}
fn createInstance(self: *Self) !void {
@ -607,14 +618,14 @@ pub const VulkanRenderer = struct {
// But must happen before...
.dst_subpass = 0,
.dst_stage_mask = .{ .color_attachment_output_bit = true },
.dst_access_mask = .{ .memory_read_bit = true, .memory_write_bit = true },
.dst_access_mask = .{ .color_attachment_read_bit = true, .color_attachment_write_bit = true },
},
// Conversion from VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL to VK_IMAGE_LAYOUT_PRESENT_SRC_KHR
vk.SubpassDependency{
// Transition must happen after...
.src_subpass = 0,
.src_stage_mask = .{ .color_attachment_output_bit = true },
.src_access_mask = .{ .memory_read_bit = true, .memory_write_bit = true },
.src_access_mask = .{ .color_attachment_read_bit = true, .color_attachment_write_bit = true },
// But must happen before...
.dst_subpass = vk.SUBPASS_EXTERNAL,
.dst_stage_mask = .{ .bottom_of_pipe_bit = true },
@ -1170,10 +1181,9 @@ pub const VulkanRenderer = struct {
},
.p_clear_values = &clear_values, // List of clear values
.clear_value_count = @intCast(clear_values.len),
.framebuffer = undefined,
.framebuffer = self.swapchain_framebuffers[current_image],
};
render_pass_begin_info.framebuffer = self.swapchain_framebuffers[current_image];
const command_buffer = self.command_buffers[current_image];
// Start recording commands to command buffer
@ -1506,8 +1516,8 @@ pub const VulkanRenderer = struct {
// Create staging buffer to hold loaded data, ready to copy to device
var image_staging_buffer: vk.Buffer = undefined;
defer self.device.destroyBuffer(image_staging_buffer, null);
var image_staging_buffer_memory: vk.DeviceMemory = undefined;
defer self.device.destroyBuffer(image_staging_buffer, null);
defer self.device.freeMemory(image_staging_buffer_memory, null);
try Utilities.createBuffer(
@ -1521,10 +1531,16 @@ 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: *[]const u8 = @ptrCast(@alignCast(data));
image_data.* = image;
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);
// Create image to hold final texture
@ -1532,7 +1548,7 @@ pub const VulkanRenderer = struct {
const tex_image: vk.Image = try self.createImage(
width,
height,
.r8g8b8a8_unorm,
.r8g8b8a8_srgb,
.optimal,
.{ .transfer_dst_bit = true, .sampled_bit = true },
.{ .device_local_bit = true },
@ -1585,7 +1601,7 @@ pub const VulkanRenderer = struct {
// Create image view and add to list
const image_view = try self.createImageView(
self.texture_images.items[texture_image_loc],
.r8g8b8a8_unorm,
.r8g8b8a8_srgb,
.{ .color_bit = true },
);
@ -1640,23 +1656,19 @@ pub const VulkanRenderer = struct {
fn loadTextureFile(self: *Self, file_name: []const u8, width: *u32, height: *u32, image_size: *vk.DeviceSize) ![]const u8 {
const path_concat = [2][]const u8{ "./assets/textures/", file_name };
const path = try std.mem.concat(self.allocator, u8, &path_concat);
const path = try std.mem.concatWithSentinel(self.allocator, u8, &path_concat, 0);
defer self.allocator.free(path);
var image = try img.Image.fromFilePath(self.allocator, path);
defer image.deinit();
const image = try img.Image.loadFromFile(path, 0);
try self.image_files.append(image);
if (!image.pixelFormat().isRgba()) {
try image.convert(.rgba32);
}
width.* = @intCast(image.width);
height.* = @intCast(image.height);
width.* = image.width;
height.* = image.height;
// Calculate image size using given and known data
image_size.* = width.* * height.* * 4;
return image.rawBytes();
return image.data;
}
};
@ -1666,13 +1678,13 @@ fn chooseBestSurfaceFormat(formats: []vk.SurfaceFormatKHR) vk.SurfaceFormatKHR {
// If only one format available and is undefined, then this means all formats are available
if (formats.len == 1 and formats[0].format == vk.Format.undefined) {
return .{
.format = vk.Format.r8g8b8a8_unorm,
.format = vk.Format.r8g8b8a8_srgb,
.color_space = vk.ColorSpaceKHR.srgb_nonlinear_khr,
};
}
for (formats) |format| {
if ((format.format == vk.Format.r8g8b8a8_unorm or format.format == vk.Format.b8g8r8a8_unorm) and format.color_space == vk.ColorSpaceKHR.srgb_nonlinear_khr) {
if ((format.format == vk.Format.r8g8b8a8_srgb or format.format == vk.Format.b8g8r8a8_srgb) and format.color_space == vk.ColorSpaceKHR.srgb_nonlinear_khr) {
return format;
}
}