diff --git a/examples/fractal-cube/main.zig b/examples/fractal-cube/main.zig index 05ef551f..15af6ff5 100755 --- a/examples/fractal-cube/main.zig +++ b/examples/fractal-cube/main.zig @@ -22,7 +22,7 @@ const UniformBufferObject = struct { mat: zm.Mat, }; -var timer: std.time.Timer = undefined; +var timer: mach.Timer = undefined; pipeline: gpu.RenderPipeline, queue: gpu.Queue, @@ -38,7 +38,7 @@ sampler: gpu.Sampler, bgl: gpu.BindGroupLayout, pub fn init(app: *App, engine: *mach.Engine) !void { - timer = try std.time.Timer.start(); + timer = try mach.Timer.start(); engine.core.setKeyCallback(struct { fn callback(_: *App, eng: *mach.Engine, key: mach.Key, action: mach.Action) void { @@ -269,7 +269,7 @@ pub fn update(app: *App, engine: *mach.Engine) !bool { }; { - const time = @intToFloat(f32, timer.read()) / @as(f32, std.time.ns_per_s); + const time = timer.read(); const model = zm.mul(zm.rotationX(time * (std.math.pi / 2.0)), zm.rotationZ(time * (std.math.pi / 2.0))); const view = zm.lookAtRh( zm.f32x4(0, -4, 0, 1), diff --git a/examples/instanced-cube/main.zig b/examples/instanced-cube/main.zig index 47aac605..b562a18d 100755 --- a/examples/instanced-cube/main.zig +++ b/examples/instanced-cube/main.zig @@ -10,7 +10,7 @@ const UniformBufferObject = struct { mat: zm.Mat, }; -var timer: std.time.Timer = undefined; +var timer: mach.Timer = undefined; pipeline: gpu.RenderPipeline, queue: gpu.Queue, @@ -21,7 +21,7 @@ bind_group: gpu.BindGroup, const App = @This(); pub fn init(app: *App, engine: *mach.Engine) !void { - timer = try std.time.Timer.start(); + timer = try mach.Timer.start(); engine.core.setKeyCallback(struct { fn callback(_: *App, eng: *mach.Engine, key: mach.Key, action: mach.Action) void { @@ -171,7 +171,7 @@ pub fn update(app: *App, engine: *mach.Engine) !bool { ); var ubos: [16]UniformBufferObject = undefined; - const time = @intToFloat(f32, timer.read()) / @as(f32, std.time.ns_per_s); + const time = timer.read(); const step: f32 = 4.0; var m: u8 = 0; var x: u8 = 0; diff --git a/examples/rotating-cube/main.zig b/examples/rotating-cube/main.zig index 82abb27a..520edf1c 100755 --- a/examples/rotating-cube/main.zig +++ b/examples/rotating-cube/main.zig @@ -12,7 +12,7 @@ const UniformBufferObject = struct { mat: zm.Mat, }; -var timer: std.time.Timer = undefined; +var timer: mach.Timer = undefined; pipeline: gpu.RenderPipeline, queue: gpu.Queue, @@ -21,7 +21,7 @@ uniform_buffer: gpu.Buffer, bind_group: gpu.BindGroup, pub fn init(app: *App, engine: *mach.Engine) !void { - timer = try std.time.Timer.start(); + timer = try mach.Timer.start(); // TODO: higher level input handlers engine.core.setKeyCallback(struct { @@ -173,7 +173,7 @@ pub fn update(app: *App, engine: *mach.Engine) !bool { }; { - const time = @intToFloat(f32, timer.read()) / @as(f32, std.time.ns_per_s); + const time = timer.read(); const model = zm.mul(zm.rotationX(time * (std.math.pi / 2.0)), zm.rotationZ(time * (std.math.pi / 2.0))); const view = zm.lookAtRh( zm.f32x4(0, 4, 2, 1), diff --git a/examples/textured-cube/main.zig b/examples/textured-cube/main.zig index d280e6db..2205c970 100644 --- a/examples/textured-cube/main.zig +++ b/examples/textured-cube/main.zig @@ -11,7 +11,7 @@ const UniformBufferObject = struct { mat: zm.Mat, }; -var timer: std.time.Timer = undefined; +var timer: mach.Timer = undefined; pipeline: gpu.RenderPipeline, queue: gpu.Queue, @@ -24,7 +24,7 @@ depth_size: mach.Size, const App = @This(); pub fn init(app: *App, engine: *mach.Engine) !void { - timer = try std.time.Timer.start(); + timer = try mach.Timer.start(); engine.core.setKeyCallback(struct { fn callback(_: *App, eng: *mach.Engine, key: mach.Key, action: mach.Action) void { @@ -239,7 +239,7 @@ pub fn update(app: *App, engine: *mach.Engine) !bool { }; { - const time = @intToFloat(f32, timer.read()) / @as(f32, std.time.ns_per_s); + const time = timer.read(); const model = zm.mul(zm.rotationX(time * (std.math.pi / 2.0)), zm.rotationZ(time * (std.math.pi / 2.0))); const view = zm.lookAtRh( zm.f32x4(0, 4, 2, 1), diff --git a/examples/two-cubes/main.zig b/examples/two-cubes/main.zig index a4b9307f..c4d82ac2 100755 --- a/examples/two-cubes/main.zig +++ b/examples/two-cubes/main.zig @@ -10,7 +10,7 @@ const UniformBufferObject = struct { mat: zm.Mat, }; -var timer: std.time.Timer = undefined; +var timer: mach.Timer = undefined; pipeline: gpu.RenderPipeline, queue: gpu.Queue, @@ -22,7 +22,7 @@ bind_group2: gpu.BindGroup, const App = @This(); pub fn init(app: *App, engine: *mach.Engine) !void { - timer = try std.time.Timer.start(); + timer = try mach.Timer.start(); engine.core.setKeyCallback(struct { fn callback(_: *App, eng: *mach.Engine, key: mach.Key, action: mach.Action) void { @@ -189,7 +189,7 @@ pub fn update(app: *App, engine: *mach.Engine) !bool { }; { - const time = @intToFloat(f32, timer.read()) / @as(f32, std.time.ns_per_s); + const time = timer.read(); const rotation1 = zm.mul(zm.rotationX(time * (std.math.pi / 2.0)), zm.rotationZ(time * (std.math.pi / 2.0))); const rotation2 = zm.mul(zm.rotationZ(time * (std.math.pi / 2.0)), zm.rotationX(time * (std.math.pi / 2.0))); const model1 = zm.mul(rotation1, zm.translation(-2, 0, 0)); diff --git a/src/Engine.zig b/src/Engine.zig index 08744d08..85ad47dc 100644 --- a/src/Engine.zig +++ b/src/Engine.zig @@ -5,6 +5,7 @@ const gpu = @import("gpu"); const App = @import("app"); const structs = @import("structs.zig"); const enums = @import("enums.zig"); +const Timer = @import("Timer.zig"); const Engine = @This(); @@ -23,9 +24,9 @@ options: structs.Options, /// For example, if you are animating a cube which should rotate 360 degrees every second, /// instead of writing (360.0 / 60.0) and assuming the frame rate is 60hz, write /// (360.0 * engine.delta_time) -delta_time: f64 = 0, +delta_time: f32 = 0, delta_time_ns: u64 = 0, -timer: std.time.Timer, +timer: Timer, pub const Core = struct { internal: GetCoreInternalType(), @@ -64,7 +65,7 @@ pub fn init(allocator: std.mem.Allocator, options: structs.Options) !Engine { var engine = Engine{ .allocator = allocator, .options = options, - .timer = try std.time.Timer.start(), + .timer = try Timer.start(), .core = undefined, .gpu_driver = undefined, }; diff --git a/src/Timer.zig b/src/Timer.zig new file mode 100644 index 00000000..c02fc6d9 --- /dev/null +++ b/src/Timer.zig @@ -0,0 +1,41 @@ +const std = @import("std"); +const builtin = @import("builtin"); + +const Timer = @This(); + +backing_timer: BackingTimerType = undefined, + +// TODO: verify declarations and its signatures +const BackingTimerType = if (builtin.cpu.arch == .wasm32) void else std.time.Timer; + +/// Initialize the timer. +pub fn start() !Timer { + return Timer{ + .backing_timer = try BackingTimerType.start(), + }; +} + +/// Reads the timer value since start or the last reset in nanoseconds. +pub fn readPrecise(timer: *Timer) u64 { + return timer.backing_timer.read(); +} + +/// Reads the timer value since start or the last reset in seconds. +pub fn read(timer: *Timer) f32 { + return @intToFloat(f32, timer.readPrecise()) / @intToFloat(f32, std.time.ns_per_s); +} + +/// Resets the timer value to 0/now. +pub fn reset(timer: *Timer) void { + timer.backing_timer.reset(); +} + +/// Returns the current value of the timer in nanoseconds, then resets it. +pub fn lapPrecise(timer: *Timer) u64 { + return timer.backing_timer.lap(); +} + +/// Returns the current value of the timer in seconds, then resets it. +pub fn lap(timer: *Timer) f32 { + return @intToFloat(f32, timer.lapPrecise()) / @intToFloat(f32, std.time.ns_per_s); +} diff --git a/src/main.zig b/src/main.zig index 9afeded3..cd3f80d6 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1,3 +1,4 @@ pub usingnamespace @import("structs.zig"); pub usingnamespace @import("enums.zig"); pub const Engine = @import("Engine.zig"); +pub const Timer = @import("Timer.zig"); diff --git a/src/native.zig b/src/native.zig index 8379f2ef..c762ab50 100644 --- a/src/native.zig +++ b/src/native.zig @@ -387,8 +387,8 @@ pub fn main() !void { while (!window.shouldClose()) { try glfw.pollEvents(); - engine.delta_time_ns = engine.timer.lap(); - engine.delta_time = @intToFloat(f64, engine.delta_time_ns) / @intToFloat(f64, std.time.ns_per_s); + engine.delta_time_ns = engine.timer.lapPrecise(); + engine.delta_time = @intToFloat(f32, engine.delta_time_ns) / @intToFloat(f32, std.time.ns_per_s); var framebuffer_size = try window.getFramebufferSize(); engine.gpu_driver.target_desc.width = framebuffer_size.width;