Vertical movement, deinit logs, persistent global uniform transfers

This commit is contained in:
2025-11-27 17:07:22 +01:00
parent b9a804ead6
commit 6069249bf8
11 changed files with 212 additions and 82 deletions

View File

@@ -10,6 +10,7 @@ const Materials = @import("assets/Materials.zig");
const Textures = @import("assets/Textures.zig");
const Engine = @import("engine/Engine.zig");
const GenericBuffer = @import("engine/GenericBuffer.zig").GenericBuffer;
const StagingBuffer = @import("engine/StagingBuffer.zig");
const Swapchain = @import("engine/Swapchain.zig");
const Iterator3 = math.Iterator3;
const Matrix4x4 = math.Matrix4x4;
@@ -113,6 +114,9 @@ vertex_buffer: VertexBuffer,
index_buffer: IndexBuffer,
global_uniforms: GlobalUniformsBuffer,
global_uniforms_staging_buffer: StagingBuffer,
global_uniforms_transfer_command_buffer: vk.CommandBuffer,
global_uniforms_transfer_semaphore: vk.Semaphore,
point_lights: PointLightBuffer,
directional_lights: DirectionalLightBuffer,
object_uniforms: ObjectUniformsBuffer,
@@ -130,6 +134,8 @@ input_forwards: bool = false,
input_backwards: bool = false,
input_left: bool = false,
input_right: bool = false,
input_up: bool = false,
input_down: bool = false,
const max_textures = 1024;
const max_point_lights = 1024;
@@ -139,9 +145,10 @@ const max_objects = 1024;
const camera_near_plane = 0.1;
const camera_vertical_fov_deg = 90.0;
const camera_half_vertical_fov_rad = 0.5 * camera_vertical_fov_deg * std.math.rad_per_deg;
const camera_mouse_sensitivity = 0.0015;
const camera_mouse_sensitivity = 0.002;
const player_speed = 5.0;
const player_horizontal_speed = 11.0;
const player_vertical_speed = 7.49;
pub fn init(allocator: std.mem.Allocator, engine: *Engine, swapchain: *Swapchain) !Game {
var materials = try Materials.init(engine, allocator);
@@ -295,6 +302,33 @@ pub fn init(allocator: std.mem.Allocator, engine: *Engine, swapchain: *Swapchain
});
errdefer global_uniforms.deinit(engine);
var global_uniforms_staging_buffer = try StagingBuffer.init(engine, .{
.capacity = @sizeOf(GlobalUniforms),
.target_queue = .graphics,
});
errdefer global_uniforms_staging_buffer.deinit(engine);
const global_uniforms_transfer_command_buffer = try engine.allocateTransferCommandBuffer();
errdefer engine.freeTransferCommandBuffer(global_uniforms_transfer_command_buffer);
try global_uniforms_transfer_command_buffer.beginCommandBuffer(&.{});
global_uniforms_transfer_command_buffer.copyBuffer(
global_uniforms_staging_buffer.buffer,
global_uniforms.buffer,
1,
&.{
.{
.src_offset = 0,
.dst_offset = 0,
.size = @sizeOf(GlobalUniforms),
},
},
);
try global_uniforms_transfer_command_buffer.endCommandBuffer();
const global_uniforms_transfer_semaphore = try engine.createSemaphore();
errdefer engine.destroySemaphore(global_uniforms_transfer_semaphore);
var point_lights = try PointLightBuffer.init(engine, .{
.usage = .storage,
.target_queue = .graphics,
@@ -550,6 +584,44 @@ pub fn init(allocator: std.mem.Allocator, engine: *Engine, swapchain: *Swapchain
},
});
const point_lights_data: []const PointLight = &.{
.{
.positionWS = .{ 0, 0, 1 },
.color = .{ 10, 10, 10 },
},
.{
.positionWS = .{ -7, 7, 1 },
.color = .{ 5, 0, 0 },
},
.{
.positionWS = .{ 7, 7, 1 },
.color = .{ 0, 0, 5 },
},
.{
.positionWS = .{ -7, -7, 1 },
.color = .{ 0, 5, 0 },
},
.{
.positionWS = .{ 7, -7, 1 },
.color = .{ 5, 5, 0 },
},
};
try point_lights.write(engine, .{
.header = @intCast(point_lights_data.len),
.elements = point_lights_data,
});
const directional_lights_data: []const DirectionalLight = &.{
.{
.directionWS = .{ 0, 0, -1 },
.color = .{ 0.2, 0.2, 0.2 },
},
};
try directional_lights.write(engine, .{
.header = @intCast(directional_lights_data.len),
.elements = directional_lights_data,
});
const object_count: u32 = blk: {
var objects: std.ArrayList(ObjectUniforms) = try .initCapacity(allocator, 289);
defer objects.deinit(allocator);
@@ -585,6 +657,9 @@ pub fn init(allocator: std.mem.Allocator, engine: *Engine, swapchain: *Swapchain
.index_buffer = index_buffer,
.global_uniforms = global_uniforms,
.global_uniforms_staging_buffer = global_uniforms_staging_buffer,
.global_uniforms_transfer_command_buffer = global_uniforms_transfer_command_buffer.handle,
.global_uniforms_transfer_semaphore = global_uniforms_transfer_semaphore,
.point_lights = point_lights,
.directional_lights = directional_lights,
.object_uniforms = object_uniforms,
@@ -597,14 +672,18 @@ pub fn init(allocator: std.mem.Allocator, engine: *Engine, swapchain: *Swapchain
}
pub fn deinit(self: *Game) void {
std.log.debug("Deinitializing {*}", .{self});
self.vertex_buffer.deinit(self.engine);
self.index_buffer.deinit(self.engine);
self.global_uniforms.deinit(self.engine);
self.global_uniforms_staging_buffer.deinit(self.engine);
self.point_lights.deinit(self.engine);
self.directional_lights.deinit(self.engine);
self.object_uniforms.deinit(self.engine);
self.engine.destroySemaphore(self.global_uniforms_transfer_semaphore);
self.engine.destroyDescriptorPool(self.descriptor_pool);
self.engine.destroySampler(self.sampler);
self.engine.destroyPipeline(self.pipeline);
@@ -618,12 +697,17 @@ pub fn deinit(self: *Game) void {
}
pub fn update(self: *Game, dt: f32) void {
var camera_d = Vector2.init(
@as(f32, @floatFromInt(@intFromBool(self.input_right))) - @as(f32, @floatFromInt(@intFromBool(self.input_left))),
@as(f32, @floatFromInt(@intFromBool(self.input_forwards))) - @as(f32, @floatFromInt(@intFromBool(self.input_backwards))),
).rotate(self.camera_yaw).mulScalar(player_speed * dt);
const camera_d = Vector2
.init(
@as(f32, @floatFromInt(@intFromBool(self.input_right))) - @as(f32, @floatFromInt(@intFromBool(self.input_left))),
@as(f32, @floatFromInt(@intFromBool(self.input_forwards))) - @as(f32, @floatFromInt(@intFromBool(self.input_backwards))),
)
.rotate(self.camera_yaw)
.mulScalar(player_horizontal_speed)
.asVector3(player_vertical_speed * (@as(f32, @floatFromInt(@intFromBool(self.input_up))) - @as(f32, @floatFromInt(@intFromBool(self.input_down)))))
.mulScalar(dt);
self.camera_position = Vector3.add(self.camera_position, camera_d.asVector3(0));
self.camera_position = Vector3.add(self.camera_position, camera_d);
const framebuffer_size = Vector2.init(
@floatFromInt(self.swapchain.extent.width),
@@ -654,58 +738,30 @@ pub fn update(self: *Game, dt: f32) void {
const ambient_light = Vector3.init(0.1, 0.1, 0.1);
self.global_uniforms.write(self.engine, .{
.header = .{
.matrixWStoVS = matrix_ws_to_vs.asArray(),
.matrixVStoCS = matrix_vs_to_cs.asArray(),
.ambientLight = ambient_light.asArray(),
},
}) catch |err| {
std.log.err("Failed to write global uniforms: {s}", .{@errorName(err)});
@panic("Frame update failed");
const global_uniforms_data: GlobalUniforms = .{
.matrixWStoVS = matrix_ws_to_vs.asArray(),
.matrixVStoCS = matrix_vs_to_cs.asArray(),
.ambientLight = ambient_light.asArray(),
};
const point_lights: []const PointLight = &.{
.{
.positionWS = .{ 0, 0, 1 },
.color = .{ 10, 10, 10 },
},
.{
.positionWS = .{ -7, 7, 1 },
.color = .{ 5, 0, 0 },
},
.{
.positionWS = .{ 7, 7, 1 },
.color = .{ 0, 0, 5 },
},
.{
.positionWS = .{ -7, -7, 1 },
.color = .{ 0, 5, 0 },
},
.{
.positionWS = .{ 7, -7, 1 },
.color = .{ 5, 5, 0 },
},
};
self.point_lights.write(self.engine, .{
.header = @intCast(point_lights.len),
.elements = point_lights,
}) catch |err| {
std.log.err("Failed to write point lights: {s}", .{@errorName(err)});
const staging_memory = self.global_uniforms_staging_buffer.map(self.engine) catch |err| {
std.log.err("Failed to map global uniforms staging buffer: {s}", .{@errorName(err)});
@panic("Frame update failed");
};
@memcpy(staging_memory, std.mem.asBytes(&global_uniforms_data));
self.global_uniforms_staging_buffer.unmap(self.engine);
const directional_lights: []const DirectionalLight = &.{
const submits = [_]vk.SubmitInfo{
.{
.directionWS = .{ 0, 0, -1 },
.color = .{ 0.2, 0.2, 0.2 },
.command_buffer_count = 1,
.p_command_buffers = @ptrCast(&self.global_uniforms_transfer_command_buffer),
.signal_semaphore_count = 1,
.p_signal_semaphores = @ptrCast(&self.global_uniforms_transfer_semaphore),
},
};
self.directional_lights.write(self.engine, .{
.header = @intCast(directional_lights.len),
.elements = directional_lights,
}) catch |err| {
std.log.err("Failed to write directional lights: {s}", .{@errorName(err)});
self.engine.device.queueSubmit(self.engine.transfer_queue.handle, submits.len, &submits, .null_handle) catch |err| {
std.log.err("Failed to submit global uniforms transfer: {s}", .{@errorName(err)});
@panic("Frame update failed");
};
@@ -738,6 +794,12 @@ pub fn onKeyDown(self: *Game, key_code: glfw.Key, mods: glfw.Mods) void {
self.input_right = true;
self.input_left = false;
}
if (key_code == .space) {
self.input_up = true;
}
if (key_code == .left_shift) {
self.input_down = true;
}
}
pub fn onKeyUp(self: *Game, key_code: glfw.Key, mods: glfw.Mods) void {
@@ -755,6 +817,12 @@ pub fn onKeyUp(self: *Game, key_code: glfw.Key, mods: glfw.Mods) void {
if (key_code == .d) {
self.input_right = false;
}
if (key_code == .space) {
self.input_up = false;
}
if (key_code == .left_shift) {
self.input_down = false;
}
}
pub fn onMouseMove(self: *Game, dx: f32, dy: f32) void {
@@ -820,7 +888,15 @@ fn render(self: *Game) !void {
}
try command_buffer.endCommandBuffer();
const res = try self.swapchain.present(self.engine, command_buffer.handle);
const res = try self.swapchain.present(self.engine, .{
.command_buffer = command_buffer.handle,
.wait_semaphores = &.{
.{
.semaphore = self.global_uniforms_transfer_semaphore,
.stage_flags = .{ .vertex_shader_bit = true },
},
},
});
_ = res;
}