It works!
This commit is contained in:
128
src/Game.zig
128
src/Game.zig
@@ -104,7 +104,7 @@ swapchain: *Swapchain,
|
|||||||
global_descriptor_set_layout: vk.DescriptorSetLayout,
|
global_descriptor_set_layout: vk.DescriptorSetLayout,
|
||||||
per_batch_descriptor_set_layout: vk.DescriptorSetLayout,
|
per_batch_descriptor_set_layout: vk.DescriptorSetLayout,
|
||||||
descriptor_pool: vk.DescriptorPool,
|
descriptor_pool: vk.DescriptorPool,
|
||||||
/// [0] GLOBAL, [1] PER OBJECT
|
/// [0] GLOBAL, [1] PER BATCH
|
||||||
descriptor_sets: [2]vk.DescriptorSet,
|
descriptor_sets: [2]vk.DescriptorSet,
|
||||||
pipeline_layout: vk.PipelineLayout,
|
pipeline_layout: vk.PipelineLayout,
|
||||||
pipeline: vk.Pipeline,
|
pipeline: vk.Pipeline,
|
||||||
@@ -117,6 +117,7 @@ point_lights: PointLightBuffer,
|
|||||||
directional_lights: DirectionalLightBuffer,
|
directional_lights: DirectionalLightBuffer,
|
||||||
object_uniforms: ObjectUniformsBuffer,
|
object_uniforms: ObjectUniformsBuffer,
|
||||||
sampler: vk.Sampler,
|
sampler: vk.Sampler,
|
||||||
|
object_count: u32,
|
||||||
|
|
||||||
materials: Materials,
|
materials: Materials,
|
||||||
textures: Textures,
|
textures: Textures,
|
||||||
@@ -254,25 +255,25 @@ pub fn init(allocator: std.mem.Allocator, engine: *Engine, swapchain: *Swapchain
|
|||||||
.init(
|
.init(
|
||||||
.init(-0.5, -0.5, 0),
|
.init(-0.5, -0.5, 0),
|
||||||
.init(0, 1),
|
.init(0, 1),
|
||||||
.init(1, 0, 0),
|
.init(0, 0, 1),
|
||||||
.init(1, 0, 0, -1),
|
.init(1, 0, 0, -1),
|
||||||
),
|
),
|
||||||
.init(
|
.init(
|
||||||
.init(0.5, -0.5, 0),
|
.init(0.5, -0.5, 0),
|
||||||
.init(1, 1),
|
.init(1, 1),
|
||||||
.init(1, 0, 0),
|
.init(0, 0, 1),
|
||||||
.init(1, 0, 0, -1),
|
.init(1, 0, 0, -1),
|
||||||
),
|
),
|
||||||
.init(
|
.init(
|
||||||
.init(-0.5, 0.5, 0),
|
.init(-0.5, 0.5, 0),
|
||||||
.init(0, 0),
|
.init(0, 0),
|
||||||
.init(1, 0, 0),
|
.init(0, 0, 1),
|
||||||
.init(1, 0, 0, -1),
|
.init(1, 0, 0, -1),
|
||||||
),
|
),
|
||||||
.init(
|
.init(
|
||||||
.init(0.5, 0.5, 0),
|
.init(0.5, 0.5, 0),
|
||||||
.init(1, 0),
|
.init(1, 0),
|
||||||
.init(1, 0, 0),
|
.init(0, 0, 1),
|
||||||
.init(1, 0, 0, -1),
|
.init(1, 0, 0, -1),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
@@ -549,6 +550,26 @@ pub fn init(allocator: std.mem.Allocator, engine: *Engine, swapchain: *Swapchain
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const object_count: u32 = blk: {
|
||||||
|
var objects: std.ArrayList(ObjectUniforms) = try .initCapacity(allocator, 289);
|
||||||
|
defer objects.deinit(allocator);
|
||||||
|
|
||||||
|
var it = Iterator3.init(.init(-8, -8, 0), .init(8, 8, 0), .one);
|
||||||
|
while (it.next()) |pos| {
|
||||||
|
const material: Materials.Id = @enumFromInt(engine.random.uintLessThan(u16, @intFromEnum(materials.next_id)));
|
||||||
|
const matrix_os_to_ws = Matrix4x4.initTranslation(pos);
|
||||||
|
const matrix_os_to_ws_normal = Matrix4x4.inverseTransposeAffine(matrix_os_to_ws);
|
||||||
|
objects.appendAssumeCapacity(.{
|
||||||
|
.matrixOStoWS = matrix_os_to_ws.asArray(),
|
||||||
|
.matrixOStoWSNormal = matrix_os_to_ws_normal.asArray(),
|
||||||
|
.material = material,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
try object_uniforms.write(engine, .{ .elements = objects.items });
|
||||||
|
|
||||||
|
break :blk @intCast(objects.items.len);
|
||||||
|
};
|
||||||
|
|
||||||
return .{
|
return .{
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
.engine = engine,
|
.engine = engine,
|
||||||
@@ -568,6 +589,7 @@ pub fn init(allocator: std.mem.Allocator, engine: *Engine, swapchain: *Swapchain
|
|||||||
.directional_lights = directional_lights,
|
.directional_lights = directional_lights,
|
||||||
.object_uniforms = object_uniforms,
|
.object_uniforms = object_uniforms,
|
||||||
.sampler = sampler,
|
.sampler = sampler,
|
||||||
|
.object_count = object_count,
|
||||||
|
|
||||||
.materials = materials,
|
.materials = materials,
|
||||||
.textures = textures,
|
.textures = textures,
|
||||||
@@ -623,14 +645,14 @@ pub fn update(self: *Game, dt: f32) void {
|
|||||||
|
|
||||||
// zig fmt: off
|
// zig fmt: off
|
||||||
const matrix_vs_to_cs = Matrix4x4.init(
|
const matrix_vs_to_cs = Matrix4x4.init(
|
||||||
camera_xscale, 0, 0, 0,
|
camera_xscale, 0, 0, 0,
|
||||||
0, 0, camera_near_plane, 1,
|
0, 0, camera_near_plane, 1,
|
||||||
0, camera_yscale, 0, 0,
|
0, -camera_yscale, 0, 0,
|
||||||
0, 0, 0, 0,
|
0, 0, 0, 0,
|
||||||
);
|
);
|
||||||
// zig fmt: on
|
// zig fmt: on
|
||||||
|
|
||||||
const ambient_light = Vector3.init(0.3, 0.3, 0.3);
|
const ambient_light = Vector3.init(0.1, 0.1, 0.1);
|
||||||
|
|
||||||
self.global_uniforms.write(self.engine, .{
|
self.global_uniforms.write(self.engine, .{
|
||||||
.header = .{
|
.header = .{
|
||||||
@@ -649,19 +671,19 @@ pub fn update(self: *Game, dt: f32) void {
|
|||||||
.color = .{ 10, 10, 10 },
|
.color = .{ 10, 10, 10 },
|
||||||
},
|
},
|
||||||
.{
|
.{
|
||||||
.positionWS = .{ -10, 10, 1 },
|
.positionWS = .{ -7, 7, 1 },
|
||||||
.color = .{ 5, 0, 0 },
|
.color = .{ 5, 0, 0 },
|
||||||
},
|
},
|
||||||
.{
|
.{
|
||||||
.positionWS = .{ 10, 10, 1 },
|
.positionWS = .{ 7, 7, 1 },
|
||||||
.color = .{ 0, 0, 5 },
|
.color = .{ 0, 0, 5 },
|
||||||
},
|
},
|
||||||
.{
|
.{
|
||||||
.positionWS = .{ -10, -10, 1 },
|
.positionWS = .{ -7, -7, 1 },
|
||||||
.color = .{ 0, 5, 0 },
|
.color = .{ 0, 5, 0 },
|
||||||
},
|
},
|
||||||
.{
|
.{
|
||||||
.positionWS = .{ 10, -10, 1 },
|
.positionWS = .{ 7, -7, 1 },
|
||||||
.color = .{ 5, 5, 0 },
|
.color = .{ 5, 5, 0 },
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -747,51 +769,10 @@ fn render(self: *Game) !void {
|
|||||||
const engine = self.engine;
|
const engine = self.engine;
|
||||||
const extent = self.swapchain.extent;
|
const extent = self.swapchain.extent;
|
||||||
|
|
||||||
const object_count: u32 = blk: {
|
|
||||||
var objects: std.ArrayList(ObjectUniforms) = try .initCapacity(self.engine.vk_allocator.allocator, 289);
|
|
||||||
defer objects.deinit(self.engine.vk_allocator.allocator);
|
|
||||||
|
|
||||||
var it = Iterator3.init(.init(-8, -8, 0), .init(8, 8, 0), .one);
|
|
||||||
var material: u16 = 0;
|
|
||||||
while (it.next()) |pos| : (material = (material + 1) % @intFromEnum(self.materials.next_id)) {
|
|
||||||
const matrix_os_to_ws = Matrix4x4.initTranslation(pos);
|
|
||||||
const matrix_os_to_ws_normal = Matrix4x4.inverseTransposeAffine(matrix_os_to_ws);
|
|
||||||
objects.appendAssumeCapacity(.{
|
|
||||||
.matrixOStoWS = matrix_os_to_ws.asArray(),
|
|
||||||
.matrixOStoWSNormal = matrix_os_to_ws_normal.asArray(),
|
|
||||||
.material = @enumFromInt(material),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
try self.object_uniforms.write(self.engine, .{ .elements = objects.items });
|
|
||||||
|
|
||||||
break :blk @intCast(objects.items.len);
|
|
||||||
};
|
|
||||||
|
|
||||||
const command_buffer = try engine.allocateGraphicsCommandBuffer();
|
const command_buffer = try engine.allocateGraphicsCommandBuffer();
|
||||||
// NOTE Do not free command buffer yet
|
// NOTE Do not free command buffer yet
|
||||||
|
|
||||||
try command_buffer.beginCommandBuffer(&.{ .flags = .{ .one_time_submit_bit = true } });
|
try command_buffer.beginCommandBuffer(&.{ .flags = .{ .one_time_submit_bit = true } });
|
||||||
|
|
||||||
const viewports = [_]vk.Viewport{
|
|
||||||
.{
|
|
||||||
.x = 0,
|
|
||||||
.y = 0,
|
|
||||||
.width = @floatFromInt(extent.width),
|
|
||||||
.height = @floatFromInt(extent.height),
|
|
||||||
.min_depth = 0,
|
|
||||||
.max_depth = 1,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
command_buffer.setViewport(0, viewports.len, &viewports);
|
|
||||||
|
|
||||||
const scissors = [_]vk.Rect2D{
|
|
||||||
.{
|
|
||||||
.offset = .{ .x = 0, .y = 0 },
|
|
||||||
.extent = extent,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
command_buffer.setScissor(0, scissors.len, &scissors);
|
|
||||||
|
|
||||||
{
|
{
|
||||||
const clear_values = [_]vk.ClearValue{
|
const clear_values = [_]vk.ClearValue{
|
||||||
.{ .color = .{ .float_32 = .{ 0, 0, 0, 1 } } },
|
.{ .color = .{ .float_32 = .{ 0, 0, 0, 1 } } },
|
||||||
@@ -799,7 +780,7 @@ fn render(self: *Game) !void {
|
|||||||
|
|
||||||
command_buffer.beginRenderPass(&.{
|
command_buffer.beginRenderPass(&.{
|
||||||
.render_pass = self.swapchain.render_pass,
|
.render_pass = self.swapchain.render_pass,
|
||||||
.framebuffer = self.swapchain.swapchain_images[0].framebuffer,
|
.framebuffer = self.swapchain.swapchain_images[self.swapchain.image_index].framebuffer,
|
||||||
.render_area = .{
|
.render_area = .{
|
||||||
.offset = .{ .x = 0, .y = 0 },
|
.offset = .{ .x = 0, .y = 0 },
|
||||||
.extent = extent,
|
.extent = extent,
|
||||||
@@ -809,25 +790,36 @@ fn render(self: *Game) !void {
|
|||||||
}, .@"inline");
|
}, .@"inline");
|
||||||
defer command_buffer.endRenderPass();
|
defer command_buffer.endRenderPass();
|
||||||
|
|
||||||
|
const viewports = [_]vk.Viewport{
|
||||||
|
.{
|
||||||
|
.x = 0,
|
||||||
|
.y = 0,
|
||||||
|
.width = @floatFromInt(extent.width),
|
||||||
|
.height = @floatFromInt(extent.height),
|
||||||
|
.min_depth = 0,
|
||||||
|
.max_depth = 1,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
command_buffer.setViewport(0, viewports.len, &viewports);
|
||||||
|
|
||||||
|
const scissors = [_]vk.Rect2D{
|
||||||
|
.{
|
||||||
|
.offset = .{ .x = 0, .y = 0 },
|
||||||
|
.extent = extent,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
command_buffer.setScissor(0, scissors.len, &scissors);
|
||||||
|
|
||||||
command_buffer.bindPipeline(.graphics, self.pipeline);
|
command_buffer.bindPipeline(.graphics, self.pipeline);
|
||||||
|
|
||||||
command_buffer.bindVertexBuffers(0, 1, @ptrCast(&self.vertex_buffer.buffer), &.{0});
|
command_buffer.bindVertexBuffers(0, 1, @ptrCast(&self.vertex_buffer.buffer), &.{0});
|
||||||
command_buffer.bindIndexBuffer(self.index_buffer.buffer, 0, .uint16);
|
command_buffer.bindIndexBuffer(self.index_buffer.buffer, 0, .uint16);
|
||||||
|
command_buffer.bindDescriptorSets(.graphics, self.pipeline_layout, 0, self.descriptor_sets.len, &self.descriptor_sets, 0, null);
|
||||||
|
|
||||||
command_buffer.bindDescriptorSets(
|
command_buffer.drawIndexed(@intCast(self.index_buffer.array_capacity), self.object_count, 0, 0, 0);
|
||||||
.graphics,
|
|
||||||
self.pipeline_layout,
|
|
||||||
0,
|
|
||||||
self.descriptor_sets.len,
|
|
||||||
&self.descriptor_sets,
|
|
||||||
0,
|
|
||||||
null,
|
|
||||||
);
|
|
||||||
|
|
||||||
command_buffer.drawIndexed(@intCast(self.index_buffer.array_capacity), object_count, 0, 0, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try command_buffer.endCommandBuffer();
|
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.handle);
|
||||||
|
|
||||||
_ = res;
|
_ = res;
|
||||||
|
|||||||
@@ -170,6 +170,11 @@ fn loadTexture(engine: *Engine, filename: []const u8, usage: Texture.Usage, temp
|
|||||||
var img = try stbi.Image.loadFromMemory(file_buf, usage.samplesPerTexel());
|
var img = try stbi.Image.loadFromMemory(file_buf, usage.samplesPerTexel());
|
||||||
defer img.deinit();
|
defer img.deinit();
|
||||||
std.debug.assert(img.num_components == usage.samplesPerTexel());
|
std.debug.assert(img.num_components == usage.samplesPerTexel());
|
||||||
|
if (usage == .normal) {
|
||||||
|
for (img.data) |*sample| {
|
||||||
|
sample.* = sample.* +% 128;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var texture = try Texture.init(engine, .{
|
var texture = try Texture.init(engine, .{
|
||||||
.width = img.width,
|
.width = img.width,
|
||||||
|
|||||||
@@ -104,6 +104,9 @@ graphics_command_pool: vk.CommandPool,
|
|||||||
compute_command_pool: vk.CommandPool,
|
compute_command_pool: vk.CommandPool,
|
||||||
transfer_command_pool: vk.CommandPool,
|
transfer_command_pool: vk.CommandPool,
|
||||||
|
|
||||||
|
prng_ptr: *std.Random.Pcg,
|
||||||
|
random: std.Random,
|
||||||
|
|
||||||
const debug = @import("builtin").mode == .Debug;
|
const debug = @import("builtin").mode == .Debug;
|
||||||
|
|
||||||
const vk_application_info: vk.ApplicationInfo = .{
|
const vk_application_info: vk.ApplicationInfo = .{
|
||||||
@@ -164,7 +167,7 @@ pub fn init(allocator: std.mem.Allocator, maybe_window: ?*glfw.Window) !Engine {
|
|||||||
|
|
||||||
break :blk try base.createInstance(&.{
|
break :blk try base.createInstance(&.{
|
||||||
.p_application_info = &vk_application_info,
|
.p_application_info = &vk_application_info,
|
||||||
.enabled_layer_count = enabled_layers.len,
|
.enabled_layer_count = 0, //enabled_layers.len,
|
||||||
.pp_enabled_layer_names = enabled_layers.ptr,
|
.pp_enabled_layer_names = enabled_layers.ptr,
|
||||||
.enabled_extension_count = @intCast(enabled_extensions.items.len),
|
.enabled_extension_count = @intCast(enabled_extensions.items.len),
|
||||||
.pp_enabled_extension_names = enabled_extensions.items.ptr,
|
.pp_enabled_extension_names = enabled_extensions.items.ptr,
|
||||||
@@ -345,6 +348,15 @@ pub fn init(allocator: std.mem.Allocator, maybe_window: ?*glfw.Window) !Engine {
|
|||||||
const transfer_queue: Queue = .initAllocation(device, queue_allocations.transfer_queue);
|
const transfer_queue: Queue = .initAllocation(device, queue_allocations.transfer_queue);
|
||||||
const presentation_queue: Queue = if (maybe_window != null) .initAllocation(device, queue_allocations.presentation_queue) else undefined;
|
const presentation_queue: Queue = if (maybe_window != null) .initAllocation(device, queue_allocations.presentation_queue) else undefined;
|
||||||
|
|
||||||
|
// --- CREATE AND SEED RNG -------------------------------------------------
|
||||||
|
|
||||||
|
const prng_ptr = try allocator.create(std.Random.Pcg);
|
||||||
|
errdefer allocator.destroy(prng_ptr);
|
||||||
|
|
||||||
|
const timestamp: u128 = @bitCast(std.time.nanoTimestamp());
|
||||||
|
prng_ptr.* = .init(@truncate(timestamp));
|
||||||
|
const random = prng_ptr.random();
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
|
|
||||||
return .{
|
return .{
|
||||||
@@ -371,12 +383,17 @@ pub fn init(allocator: std.mem.Allocator, maybe_window: ?*glfw.Window) !Engine {
|
|||||||
.graphics_command_pool = graphics_command_pool,
|
.graphics_command_pool = graphics_command_pool,
|
||||||
.compute_command_pool = compute_command_pool,
|
.compute_command_pool = compute_command_pool,
|
||||||
.transfer_command_pool = transfer_command_pool,
|
.transfer_command_pool = transfer_command_pool,
|
||||||
|
|
||||||
|
.prng_ptr = prng_ptr,
|
||||||
|
.random = random,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *Engine) void {
|
pub fn deinit(self: *Engine) void {
|
||||||
const allocator = self.vk_allocator.allocator;
|
const allocator = self.vk_allocator.allocator;
|
||||||
|
|
||||||
|
allocator.destroy(self.prng_ptr);
|
||||||
|
|
||||||
self.device.destroyCommandPool(self.graphics_command_pool, &self.vk_allocator.interface);
|
self.device.destroyCommandPool(self.graphics_command_pool, &self.vk_allocator.interface);
|
||||||
self.device.destroyCommandPool(self.compute_command_pool, &self.vk_allocator.interface);
|
self.device.destroyCommandPool(self.compute_command_pool, &self.vk_allocator.interface);
|
||||||
self.device.destroyCommandPool(self.transfer_command_pool, &self.vk_allocator.interface);
|
self.device.destroyCommandPool(self.transfer_command_pool, &self.vk_allocator.interface);
|
||||||
|
|||||||
@@ -195,16 +195,12 @@ pub fn recreate(self: *Swapchain, engine: *Engine) !void {
|
|||||||
self.swapchain_images = new_swapchain_images;
|
self.swapchain_images = new_swapchain_images;
|
||||||
self.image_index = res.image_index;
|
self.image_index = res.image_index;
|
||||||
self.semaphore_image_acquired = semaphore_image_acquired;
|
self.semaphore_image_acquired = semaphore_image_acquired;
|
||||||
|
|
||||||
std.log.debug("Swapchain recreated.", .{});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn present(self: *Swapchain, engine: *Engine, command_buffer: vk.CommandBuffer) !PresentResult {
|
pub fn present(self: *Swapchain, engine: *Engine, command_buffer: vk.CommandBuffer) !PresentResult {
|
||||||
const device = engine.device;
|
const device = engine.device;
|
||||||
const mode = &engine.mode.surface;
|
const mode = &engine.mode.surface;
|
||||||
|
|
||||||
std.log.debug("Presenting command buffer {X}.", .{@intFromEnum(command_buffer)});
|
|
||||||
|
|
||||||
// --- WAIT FOR CURRENT FRAME TO FINISH ------------------------------------
|
// --- WAIT FOR CURRENT FRAME TO FINISH ------------------------------------
|
||||||
|
|
||||||
const current_swapchain_image = &self.swapchain_images[self.image_index];
|
const current_swapchain_image = &self.swapchain_images[self.image_index];
|
||||||
|
|||||||
73
src/main.zig
73
src/main.zig
@@ -11,20 +11,11 @@ const Engine = @import("engine/Engine.zig");
|
|||||||
const Swapchain = @import("engine/Swapchain.zig");
|
const Swapchain = @import("engine/Swapchain.zig");
|
||||||
const Game = @import("Game.zig");
|
const Game = @import("Game.zig");
|
||||||
|
|
||||||
pub var allocator: std.mem.Allocator = undefined;
|
|
||||||
pub var temp_allocator: std.mem.Allocator = undefined;
|
|
||||||
pub var window: *glfw.Window = undefined;
|
|
||||||
|
|
||||||
pub fn main() !void {
|
pub fn main() !void {
|
||||||
var gpa: std.heap.GeneralPurposeAllocator(.{}) = .init;
|
var gpa: std.heap.GeneralPurposeAllocator(.{}) = .init;
|
||||||
defer _ = gpa.deinit();
|
defer _ = gpa.deinit();
|
||||||
|
|
||||||
var fba: std.heap.FixedBufferAllocator = .init(&struct {
|
const allocator = gpa.allocator();
|
||||||
pub var buffer: [c.temp_allocator_capacity]u8 = undefined;
|
|
||||||
}.buffer);
|
|
||||||
|
|
||||||
allocator = gpa.allocator();
|
|
||||||
temp_allocator = fba.threadSafeAllocator();
|
|
||||||
|
|
||||||
atoms.init(allocator);
|
atoms.init(allocator);
|
||||||
defer atoms.deinit();
|
defer atoms.deinit();
|
||||||
@@ -44,13 +35,20 @@ pub fn main() !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
glfw.windowHint(.client_api, .no_api);
|
glfw.windowHint(.client_api, .no_api);
|
||||||
window = glfw.Window.create(c.default_window_width, c.default_window_height, c.window_title, null) catch |err| {
|
var window = glfw.Window.create(c.default_window_width, c.default_window_height, c.window_title, null) catch |err| {
|
||||||
std.log.err("Could not create window", .{});
|
std.log.err("Could not create window", .{});
|
||||||
return err;
|
return err;
|
||||||
};
|
};
|
||||||
defer window.destroy();
|
defer window.destroy();
|
||||||
|
|
||||||
window.setSizeLimits(c.min_window_width, c.min_window_height, -1, -1);
|
window.setSizeLimits(c.min_window_width, c.min_window_height, -1, -1);
|
||||||
|
window.setInputMode(.cursor, .disabled) catch {};
|
||||||
|
if (glfw.rawMouseMotionSupported()) {
|
||||||
|
window.setInputMode(.raw_mouse_motion, true) catch {};
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = window.setKeyCallback(keyCallback);
|
||||||
|
_ = window.setCursorPosCallback(cursorPosCallback);
|
||||||
|
|
||||||
var engine = try Engine.init(allocator, window);
|
var engine = try Engine.init(allocator, window);
|
||||||
defer engine.deinit();
|
defer engine.deinit();
|
||||||
@@ -59,7 +57,19 @@ pub fn main() !void {
|
|||||||
defer swapchain.deinit(&engine);
|
defer swapchain.deinit(&engine);
|
||||||
|
|
||||||
var game = try Game.init(allocator, &engine, &swapchain);
|
var game = try Game.init(allocator, &engine, &swapchain);
|
||||||
defer game.deinit();
|
var callback_context: CallbackContext = blk: {
|
||||||
|
const cursor_last_xpos, const cursor_last_ypos = window.getCursorPos();
|
||||||
|
break :blk .{
|
||||||
|
.game = &game,
|
||||||
|
.cursor_last_xpos = cursor_last_xpos,
|
||||||
|
.cursor_last_ypos = cursor_last_ypos,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
window.setUserPointer(&callback_context);
|
||||||
|
defer {
|
||||||
|
window.setUserPointer(null);
|
||||||
|
game.deinit();
|
||||||
|
}
|
||||||
|
|
||||||
var t1 = glfw.getTime();
|
var t1 = glfw.getTime();
|
||||||
while (!window.shouldClose()) {
|
while (!window.shouldClose()) {
|
||||||
@@ -73,3 +83,42 @@ pub fn main() !void {
|
|||||||
std.Thread.sleep(1 * std.time.ns_per_ms);
|
std.Thread.sleep(1 * std.time.ns_per_ms);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const CallbackContext = struct {
|
||||||
|
game: *Game,
|
||||||
|
cursor_last_xpos: f64,
|
||||||
|
cursor_last_ypos: f64,
|
||||||
|
};
|
||||||
|
|
||||||
|
fn keyCallback(window: *glfw.Window, key_code: glfw.Key, _: c_int, action: glfw.Action, mods: glfw.Mods) callconv(.c) void {
|
||||||
|
const maybe_ctx = window.getUserPointer(CallbackContext);
|
||||||
|
|
||||||
|
if (key_code == .escape and action == .press and (window.getInputMode(.cursor) catch .normal) == .disabled) {
|
||||||
|
window.setInputMode(.cursor, .normal) catch {};
|
||||||
|
if (maybe_ctx) |ctx| {
|
||||||
|
const cursor_last_xpos, const cursor_last_ypos = window.getCursorPos();
|
||||||
|
ctx.cursor_last_xpos = cursor_last_xpos;
|
||||||
|
ctx.cursor_last_ypos = cursor_last_ypos;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (maybe_ctx) |ctx| {
|
||||||
|
switch (action) {
|
||||||
|
.press => ctx.game.onKeyDown(key_code, mods),
|
||||||
|
.release => ctx.game.onKeyUp(key_code, mods),
|
||||||
|
.repeat => {},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn cursorPosCallback(window: *glfw.Window, cursor_xpos: f64, cursor_ypos: f64) callconv(.c) void {
|
||||||
|
const maybe_ctx = window.getUserPointer(CallbackContext);
|
||||||
|
if (maybe_ctx) |ctx| {
|
||||||
|
const dx: f32 = @floatCast(cursor_xpos - ctx.cursor_last_xpos);
|
||||||
|
const dy: f32 = @floatCast(cursor_ypos - ctx.cursor_last_ypos);
|
||||||
|
ctx.game.onMouseMove(dx, dy);
|
||||||
|
ctx.cursor_last_xpos = cursor_xpos;
|
||||||
|
ctx.cursor_last_ypos = cursor_ypos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -122,7 +122,8 @@ pub const Vector2 = extern struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn normalize(self: Vector2) Vector2 {
|
pub inline fn normalize(self: Vector2) Vector2 {
|
||||||
return .{ .vector = self.vector / @sqrt(@reduce(.Add, self.vector * self.vector)) };
|
const len_vector: Vector = @splat(@sqrt(@reduce(.Add, self.vector * self.vector)));
|
||||||
|
return .{ .vector = self.vector / len_vector };
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn dot(self: Vector2, other: Vector2) f32 {
|
pub inline fn dot(self: Vector2, other: Vector2) f32 {
|
||||||
|
|||||||
@@ -132,7 +132,8 @@ pub const Vector3 = extern struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn normalize(self: Vector3) Vector3 {
|
pub inline fn normalize(self: Vector3) Vector3 {
|
||||||
return .{ .vector = self.vector / @sqrt(@reduce(.Add, self.vector * self.vector)) };
|
const len_vector: Vector = @splat(@sqrt(@reduce(.Add, self.vector * self.vector)));
|
||||||
|
return .{ .vector = self.vector / len_vector };
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn dot(self: Vector3, other: Vector3) f32 {
|
pub inline fn dot(self: Vector3, other: Vector3) f32 {
|
||||||
|
|||||||
@@ -140,7 +140,8 @@ pub const Vector4 = extern struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn normalize(self: Vector4) Vector4 {
|
pub inline fn normalize(self: Vector4) Vector4 {
|
||||||
return .{ .vector = self.vector / @sqrt(@reduce(.Add, self.vector * self.vector)) };
|
const len_vector: Vector = @splat(@sqrt(@reduce(.Add, self.vector * self.vector)));
|
||||||
|
return .{ .vector = self.vector / len_vector };
|
||||||
}
|
}
|
||||||
|
|
||||||
pub inline fn dot(self: Vector4, other: Vector4) f32 {
|
pub inline fn dot(self: Vector4, other: Vector4) f32 {
|
||||||
|
|||||||
Reference in New Issue
Block a user