Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Settings: add FPS cap #532

Merged
merged 15 commits into from
Jul 1, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/gui/windows/debug.zig
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ pub var window = GuiWindow {
pub fn render() void {
draw.setColor(0xffffffff);
var y: f32 = 0;
draw.print(" fps: {d:.0} Hz{s}", .{1.0/main.lastFrameTime.load(.monotonic), if(main.settings.vsync) @as([]const u8, " (vsync)") else ""}, 0, y, 8, .left);
draw.print(" fps: {d:.0} Hz{s}", .{1.0/main.lastDeltaTime.load(.monotonic), if(main.settings.vsync) @as([]const u8, " (vsync)") else ""}, 0, y, 8, .left);
IntegratedQuantum marked this conversation as resolved.
Show resolved Hide resolved
y += 8;
draw.print(" frameTime: {d:.1} ms", .{main.lastFrameTime.load(.monotonic)*1000.0}, 0, y, 8, .left);
y += 8;
Expand Down Expand Up @@ -57,4 +57,4 @@ pub fn render() void {
draw.print("Opaque faces: {}, Transparent faces: {}", .{main.renderer.chunk_meshing.quadsDrawn, main.renderer.chunk_meshing.transparentQuadsDrawn}, 0, y, 8, .left);
y += 8;
}
}
}
11 changes: 10 additions & 1 deletion src/gui/windows/graphics.zig
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ const anisotropy = [_]u8{1, 2, 4, 8, 16};

const resolutions = [_]u16{25, 50, 100};

fn fpsCapFormatter(allocator: main.utils.NeverFailingAllocator, value: f32) []const u8 {
return std.fmt.allocPrint(allocator.allocator, "#ffffffFPS Limit: {d:.0}", .{value}) catch unreachable;
}

fn fpsCapCallback(newValue: f32) void {
settings.fpsCap = if(newValue == 144.0) null else @intFromFloat(newValue);
IntegratedQuantum marked this conversation as resolved.
Show resolved Hide resolved
}

fn renderDistanceCallback(newValue: u16) void {
settings.renderDistance = newValue + renderDistances[0];
}
Expand Down Expand Up @@ -64,6 +72,7 @@ fn resolutionScaleCallback(newValue: u16) void {

pub fn onOpen() void {
const list = VerticalList.init(.{padding, 16 + padding}, 300, 16);
list.add(ContinuousSlider.init(.{0, 0}, 128, 10.0, 144.0, @floatFromInt(settings.fpsCap orelse 144), &fpsCapCallback, &fpsCapFormatter));
list.add(DiscreteSlider.init(.{0, 0}, 128, "#ffffffRender Distance: ", "{}", &renderDistances, settings.renderDistance - renderDistances[0], &renderDistanceCallback));
list.add(ContinuousSlider.init(.{0, 0}, 128, 40.0, 120.0, settings.fov, &fovCallback, &fovFormatter));
list.add(CheckBox.init(.{0, 0}, 128, "Bloom", settings.bloom, &bloomCallback));
Expand All @@ -80,4 +89,4 @@ pub fn onClose() void {
if(window.rootComponent) |*comp| {
comp.deinit();
}
}
}
31 changes: 22 additions & 9 deletions src/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,10 @@ pub const KeyBoard = struct {
}
};

/// Records gpu time per frame.
pub var lastFrameTime = std.atomic.Value(f64).init(0);
/// Measures time between different frames' beginnings.
pub var lastDeltaTime = std.atomic.Value(f64).init(0);

pub fn main() void {
seed = @bitCast(std.time.milliTimestamp());
Expand Down Expand Up @@ -426,7 +429,7 @@ pub fn main() void {
c.glDepthFunc(c.GL_LESS);
c.glBlendFunc(c.GL_SRC_ALPHA, c.GL_ONE_MINUS_SRC_ALPHA);
Window.GLFWCallbacks.framebufferSize(undefined, Window.width, Window.height);
var lastTime = std.time.nanoTimestamp();
var lastBeginRendering = std.time.nanoTimestamp();

if(settings.developerAutoEnterWorld.len != 0) {
// Speed up the dev process by entering the world directly.
Expand All @@ -446,17 +449,27 @@ pub fn main() void {
std.time.sleep(16_000_000);
}

const endRendering = std.time.nanoTimestamp();
const frameTime = @as(f64, @floatFromInt(endRendering -% lastBeginRendering))/1e9;
if(settings.developerGPUInfiniteLoopDetection and frameTime > 5) { // On linux a process that runs 10 seconds or longer on the GPU will get stopped. This allows detecting an infinite loop on the GPU.
std.log.err("Frame got too long with {} seconds. Infinite loop on GPU?", .{frameTime});
std.posix.exit(1);
}
lastFrameTime.store(frameTime, .monotonic);

if(settings.fpsCap) |fpsCap| {
const minFrameTime = @divFloor(1000*1000*1000, fpsCap);
const sleep = @min(minFrameTime, @max(0, minFrameTime - (endRendering -% lastBeginRendering)));
std.time.sleep(sleep);
}
const begin = std.time.nanoTimestamp();
const deltaTime = @as(f64, @floatFromInt(begin - lastBeginRendering))/1e9;
IntegratedQuantum marked this conversation as resolved.
Show resolved Hide resolved
lastDeltaTime.store(deltaTime, .monotonic);
lastBeginRendering = begin;

Window.handleEvents();
file_monitor.handleEvents();

const newTime = std.time.nanoTimestamp();
const deltaTime = @as(f64, @floatFromInt(newTime -% lastTime))/1e9;
if(settings.developerGPUInfiniteLoopDetection and deltaTime > 5) { // On linux a process that runs 10 seconds or longer on the GPU will get stopped. This allows detecting an infinite loop on the GPU.
std.log.err("Frame got too long with {} seconds. Infinite loop on GPU?", .{deltaTime});
std.posix.exit(1);
}
lastFrameTime.store(deltaTime, .monotonic);
lastTime = newTime;
if(game.world != null) { // Update the game
game.update(deltaTime);
}
Expand Down
2 changes: 2 additions & 0 deletions src/settings.zig
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ pub var cpuThreads: ?u64 = null;
pub var anisotropicFiltering: u8 = 4.0;


pub var fpsCap: ?u32 = null;

pub var fov: f32 = 70;

pub var mouseSensitivity: f32 = 1;
Expand Down
Loading