mirror of
https://github.com/PixelGuys/Cubyz.git
synced 2025-09-08 03:29:48 -04:00
Add debug overlay and performance graph.
This commit is contained in:
parent
9dee31ccbe
commit
914be9cf63
@ -7,7 +7,7 @@ uniform vec2 screen;
|
|||||||
uniform int points;
|
uniform int points;
|
||||||
uniform int offset;
|
uniform int offset;
|
||||||
|
|
||||||
layout(std430, binding = 4) buffer _data
|
layout(std430, binding = 5) buffer _data
|
||||||
{
|
{
|
||||||
float data[];
|
float data[];
|
||||||
};
|
};
|
||||||
|
@ -380,6 +380,12 @@ pub const draw = struct {
|
|||||||
pub fn text(_text: []const u8, x: f32, y: f32, fontSize: f32, alignment: TextBuffer.Alignment) !void {
|
pub fn text(_text: []const u8, x: f32, y: f32, fontSize: f32, alignment: TextBuffer.Alignment) !void {
|
||||||
try TextRendering.renderText(_text, x, y, fontSize, .{.color = @truncate(u24, @bitCast(u32, color))}, alignment);
|
try TextRendering.renderText(_text, x, y, fontSize, .{.color = @truncate(u24, @bitCast(u32, color))}, alignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn print(comptime format: []const u8, args: anytype, x: f32, y: f32, fontSize: f32, alignment: TextBuffer.Alignment) !void {
|
||||||
|
const string = try std.fmt.allocPrint(main.threadAllocator, format, args);
|
||||||
|
defer main.threadAllocator.free(string);
|
||||||
|
try text(string, x, y ,fontSize, alignment);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const TextBuffer = struct {
|
pub const TextBuffer = struct {
|
||||||
|
@ -241,6 +241,26 @@ pub fn openWindow(id: []const u8) Allocator.Error!void {
|
|||||||
std.log.warn("Could not find window with id {s}.", .{id});
|
std.log.warn("Could not find window with id {s}.", .{id});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn toggleWindow(id: []const u8) Allocator.Error!void {
|
||||||
|
defer updateWindowPositions();
|
||||||
|
for(windowList.items) |window| {
|
||||||
|
if(std.mem.eql(u8, window.id, id)) {
|
||||||
|
for(openWindows.items, 0..) |_openWindow, i| {
|
||||||
|
if(_openWindow == window) {
|
||||||
|
_ = openWindows.swapRemove(i);
|
||||||
|
selectedWindow = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try openWindows.append(window);
|
||||||
|
try window.onOpenFn();
|
||||||
|
selectedWindow = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std.log.warn("Could not find window with id {s}.", .{id});
|
||||||
|
}
|
||||||
|
|
||||||
pub fn openHud() Allocator.Error!void {
|
pub fn openHud() Allocator.Error!void {
|
||||||
for(windowList.items) |window| {
|
for(windowList.items) |window| {
|
||||||
if(window.isHud) {
|
if(window.isHud) {
|
||||||
|
@ -4,6 +4,7 @@ pub const chat = @import("chat.zig");
|
|||||||
pub const controls = @import("controls.zig");
|
pub const controls = @import("controls.zig");
|
||||||
pub const creative = @import("creative.zig");
|
pub const creative = @import("creative.zig");
|
||||||
pub const crosshair = @import("crosshair.zig");
|
pub const crosshair = @import("crosshair.zig");
|
||||||
|
pub const debug = @import("debug.zig");
|
||||||
pub const graphics = @import("graphics.zig");
|
pub const graphics = @import("graphics.zig");
|
||||||
pub const healthbar = @import("healthbar.zig");
|
pub const healthbar = @import("healthbar.zig");
|
||||||
pub const hotbar = @import("hotbar.zig");
|
pub const hotbar = @import("hotbar.zig");
|
||||||
@ -11,6 +12,7 @@ pub const inventory = @import("inventory.zig");
|
|||||||
pub const inventory_crafting = @import("inventory_crafting.zig");
|
pub const inventory_crafting = @import("inventory_crafting.zig");
|
||||||
pub const main = @import("main.zig");
|
pub const main = @import("main.zig");
|
||||||
pub const multiplayer = @import("multiplayer.zig");
|
pub const multiplayer = @import("multiplayer.zig");
|
||||||
|
pub const performance_graph = @import("performance_graph.zig");
|
||||||
pub const settings = @import("settings.zig");
|
pub const settings = @import("settings.zig");
|
||||||
pub const sound = @import("sound.zig");
|
pub const sound = @import("sound.zig");
|
||||||
pub const workbench = @import("workbench.zig");
|
pub const workbench = @import("workbench.zig");
|
51
src/gui/windows/debug.zig
Normal file
51
src/gui/windows/debug.zig
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
const Allocator = std.mem.Allocator;
|
||||||
|
|
||||||
|
const main = @import("root");
|
||||||
|
const graphics = main.graphics;
|
||||||
|
const draw = graphics.draw;
|
||||||
|
const Texture = graphics.Texture;
|
||||||
|
const Vec2f = main.vec.Vec2f;
|
||||||
|
|
||||||
|
const gui = @import("../gui.zig");
|
||||||
|
const GuiWindow = gui.GuiWindow;
|
||||||
|
const GuiComponent = gui.GuiComponent;
|
||||||
|
|
||||||
|
pub var window = GuiWindow {
|
||||||
|
.contentSize = Vec2f{128, 16},
|
||||||
|
.title = "Debug",
|
||||||
|
.id = "cubyz:debug",
|
||||||
|
.isHud = false,
|
||||||
|
.showTitleBar = false,
|
||||||
|
.hasBackground = false,
|
||||||
|
};
|
||||||
|
|
||||||
|
fn flawedRender() !void {
|
||||||
|
draw.setColor(0xffffffff);
|
||||||
|
var y: f32 = 0;
|
||||||
|
try 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);
|
||||||
|
y += 8;
|
||||||
|
try draw.print(" frameTime: {d:.1} ms", .{main.lastFrameTime.load(.Monotonic)*1000.0}, 0, y, 8, .left);
|
||||||
|
y += 8;
|
||||||
|
try draw.print("window size: {}×{}", .{main.Window.width, main.Window.height}, 0, y, 8, .left);
|
||||||
|
y += 8;
|
||||||
|
if (main.game.world != null) {
|
||||||
|
try draw.print("Pos: {d:.1}", .{main.game.Player.getPosBlocking()}, 0, y, 8, .left);
|
||||||
|
y += 8;
|
||||||
|
try draw.print("Game Time: {}", .{main.game.world.?.gameTime.load(.Monotonic)}, 0, y, 8, .left);
|
||||||
|
y += 8;
|
||||||
|
try draw.print("Queue size: {}", .{main.threadPool.loadList.size}, 0, y, 8, .left);
|
||||||
|
y += 8;
|
||||||
|
// TODO: biome
|
||||||
|
y += 8;
|
||||||
|
// TODO: packet loss
|
||||||
|
y += 8;
|
||||||
|
// TODO: Protocl statistics(maybe?)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn render() Allocator.Error!void {
|
||||||
|
flawedRender() catch |err| {
|
||||||
|
std.log.err("Encountered error while drawing debug window: {s}", .{@errorName(err)});
|
||||||
|
};
|
||||||
|
}
|
84
src/gui/windows/performance_graph.zig
Normal file
84
src/gui/windows/performance_graph.zig
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
const Allocator = std.mem.Allocator;
|
||||||
|
|
||||||
|
const main = @import("root");
|
||||||
|
const graphics = main.graphics;
|
||||||
|
const draw = graphics.draw;
|
||||||
|
const Texture = graphics.Texture;
|
||||||
|
const Vec2f = main.vec.Vec2f;
|
||||||
|
|
||||||
|
const gui = @import("../gui.zig");
|
||||||
|
const GuiWindow = gui.GuiWindow;
|
||||||
|
const GuiComponent = gui.GuiComponent;
|
||||||
|
|
||||||
|
pub var window = GuiWindow {
|
||||||
|
.contentSize = Vec2f{128, 64},
|
||||||
|
.title = "Performance Graph",
|
||||||
|
.id = "cubyz:performance_graph",
|
||||||
|
.isHud = false,
|
||||||
|
.showTitleBar = false,
|
||||||
|
.hasBackground = false,
|
||||||
|
};
|
||||||
|
|
||||||
|
var lastFrameTime: [2048]f32 = undefined;
|
||||||
|
var index: u31 = 0;
|
||||||
|
var ssbo: graphics.SSBO = undefined;
|
||||||
|
var shader: graphics.Shader = undefined;
|
||||||
|
const border: f32 = 8;
|
||||||
|
|
||||||
|
var uniforms: struct {
|
||||||
|
start: c_int,
|
||||||
|
dimension: c_int,
|
||||||
|
screen: c_int,
|
||||||
|
points: c_int,
|
||||||
|
offset: c_int,
|
||||||
|
lineColor: c_int,
|
||||||
|
} = undefined;
|
||||||
|
|
||||||
|
pub fn init() !void {
|
||||||
|
ssbo = graphics.SSBO.init();
|
||||||
|
shader = try graphics.Shader.initAndGetUniforms("assets/cubyz/shaders/graphics/graph.vs", "assets/cubyz/shaders/graphics/graph.fs", &uniforms);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deinit() void {
|
||||||
|
ssbo.deinit();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn flawedRender() !void {
|
||||||
|
lastFrameTime[index] = @floatCast(f32, main.lastFrameTime.load(.Monotonic)*1000.0);
|
||||||
|
index = (index + 1)%@intCast(u31, lastFrameTime.len);
|
||||||
|
draw.setColor(0xffffffff);
|
||||||
|
try draw.text("32 ms", 0, 16, 8, .left);
|
||||||
|
try draw.text("16 ms", 0, 32, 8, .left);
|
||||||
|
try draw.text("00 ms", 0, 48, 8, .left);
|
||||||
|
draw.setColor(0x80ffffff);
|
||||||
|
draw.line(.{border, 24}, .{window.contentSize[0] - border, 24});
|
||||||
|
draw.line(.{border, 40}, .{window.contentSize[0] - border, 40});
|
||||||
|
draw.line(.{border, 56}, .{window.contentSize[0] - border, 56});
|
||||||
|
draw.setColor(0xffffffff);
|
||||||
|
shader.bind();
|
||||||
|
graphics.c.glUniform1i(uniforms.points, lastFrameTime.len);
|
||||||
|
graphics.c.glUniform1i(uniforms.offset, index);
|
||||||
|
graphics.c.glUniform3f(uniforms.lineColor, 1, 1, 1);
|
||||||
|
var pos = Vec2f{border, border};
|
||||||
|
var dim = window.contentSize - @splat(2, 2*border);
|
||||||
|
pos *= @splat(2, draw.setScale(1));
|
||||||
|
pos += draw.setTranslation(.{0, 0});
|
||||||
|
dim *= @splat(2, draw.setScale(1));
|
||||||
|
pos = @floor(pos);
|
||||||
|
dim = @ceil(dim);
|
||||||
|
pos[1] += dim[1];
|
||||||
|
|
||||||
|
graphics.c.glUniform2f(uniforms.screen, @intToFloat(f32, main.Window.width), @intToFloat(f32, main.Window.height));
|
||||||
|
graphics.c.glUniform2f(uniforms.start, pos[0], pos[1]);
|
||||||
|
graphics.c.glUniform2f(uniforms.dimension, dim[0], draw.setScale(1));
|
||||||
|
ssbo.bufferData(f32, &lastFrameTime);
|
||||||
|
ssbo.bind(5);
|
||||||
|
graphics.c.glDrawArrays(graphics.c.GL_LINE_STRIP, 0, lastFrameTime.len);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn render() Allocator.Error!void {
|
||||||
|
flawedRender() catch |err| {
|
||||||
|
std.log.err("Encountered error while drawing debug window: {s}", .{@errorName(err)});
|
||||||
|
};
|
||||||
|
}
|
23
src/main.zig
23
src/main.zig
@ -188,6 +188,16 @@ fn takeBackgroundImageFn() void {
|
|||||||
std.log.err("Got error while recording the background image: {s}", .{@errorName(err)});
|
std.log.err("Got error while recording the background image: {s}", .{@errorName(err)});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
fn toggleDebugOverlay() void {
|
||||||
|
gui.toggleWindow("cubyz:debug") catch |err| {
|
||||||
|
std.log.err("Got error while opening the debug overlay: {s}", .{@errorName(err)});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
fn togglePerformanceOverlay() void {
|
||||||
|
gui.toggleWindow("cubyz:performance_graph") catch |err| {
|
||||||
|
std.log.err("Got error while opening the performance_graph overlay: {s}", .{@errorName(err)});
|
||||||
|
};
|
||||||
|
}
|
||||||
pub var keyboard: struct {
|
pub var keyboard: struct {
|
||||||
// Gameplay:
|
// Gameplay:
|
||||||
forward: Key = Key{.key = c.GLFW_KEY_W},
|
forward: Key = Key{.key = c.GLFW_KEY_W},
|
||||||
@ -221,6 +231,10 @@ pub var keyboard: struct {
|
|||||||
textPaste: Key = Key{.key = c.GLFW_KEY_V, .repeatAction = &gui.textCallbacks.paste},
|
textPaste: Key = Key{.key = c.GLFW_KEY_V, .repeatAction = &gui.textCallbacks.paste},
|
||||||
textCut: Key = Key{.key = c.GLFW_KEY_X, .repeatAction = &gui.textCallbacks.cut},
|
textCut: Key = Key{.key = c.GLFW_KEY_X, .repeatAction = &gui.textCallbacks.cut},
|
||||||
textNewline: Key = Key{.key = c.GLFW_KEY_ENTER, .repeatAction = &gui.textCallbacks.newline},
|
textNewline: Key = Key{.key = c.GLFW_KEY_ENTER, .repeatAction = &gui.textCallbacks.newline},
|
||||||
|
|
||||||
|
// debug:
|
||||||
|
debugOverlay: Key = Key{.key = c.GLFW_KEY_F3, .releaseAction = &toggleDebugOverlay},
|
||||||
|
performanceOverlay: Key = Key{.key = c.GLFW_KEY_F4, .releaseAction = &togglePerformanceOverlay},
|
||||||
} = .{};
|
} = .{};
|
||||||
|
|
||||||
pub const Window = struct {
|
pub const Window = struct {
|
||||||
@ -464,6 +478,8 @@ pub const Window = struct {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub var lastFrameTime = std.atomic.Atomic(f64).init(0);
|
||||||
|
|
||||||
pub fn main() !void {
|
pub fn main() !void {
|
||||||
seed = @bitCast(u64, std.time.milliTimestamp());
|
seed = @bitCast(u64, std.time.milliTimestamp());
|
||||||
var gpa = std.heap.GeneralPurposeAllocator(.{.thread_safe=false}){};
|
var gpa = std.heap.GeneralPurposeAllocator(.{.thread_safe=false}){};
|
||||||
@ -539,7 +555,7 @@ pub fn main() !void {
|
|||||||
c.glEnable(c.GL_BLEND);
|
c.glEnable(c.GL_BLEND);
|
||||||
c.glBlendFunc(c.GL_SRC_ALPHA, c.GL_ONE_MINUS_SRC_ALPHA);
|
c.glBlendFunc(c.GL_SRC_ALPHA, c.GL_ONE_MINUS_SRC_ALPHA);
|
||||||
Window.GLFWCallbacks.framebufferSize(undefined, Window.width, Window.height);
|
Window.GLFWCallbacks.framebufferSize(undefined, Window.width, Window.height);
|
||||||
var lastTime = std.time.milliTimestamp();
|
var lastTime = std.time.nanoTimestamp();
|
||||||
|
|
||||||
while(c.glfwWindowShouldClose(Window.window) == 0) {
|
while(c.glfwWindowShouldClose(Window.window) == 0) {
|
||||||
{ // Check opengl errors:
|
{ // Check opengl errors:
|
||||||
@ -552,8 +568,9 @@ pub fn main() !void {
|
|||||||
Window.handleEvents();
|
Window.handleEvents();
|
||||||
c.glClearColor(0.5, 1, 1, 1);
|
c.glClearColor(0.5, 1, 1, 1);
|
||||||
c.glClear(c.GL_DEPTH_BUFFER_BIT | c.GL_STENCIL_BUFFER_BIT | c.GL_COLOR_BUFFER_BIT);
|
c.glClear(c.GL_DEPTH_BUFFER_BIT | c.GL_STENCIL_BUFFER_BIT | c.GL_COLOR_BUFFER_BIT);
|
||||||
var newTime = std.time.milliTimestamp();
|
var newTime = std.time.nanoTimestamp();
|
||||||
var deltaTime = @intToFloat(f64, newTime -% lastTime)/1000.0;
|
var deltaTime = @intToFloat(f64, newTime -% lastTime)/1e9;
|
||||||
|
lastFrameTime.store(deltaTime, .Monotonic);
|
||||||
lastTime = newTime;
|
lastTime = newTime;
|
||||||
if(game.world != null) { // Update the game
|
if(game.world != null) { // Update the game
|
||||||
try game.update(deltaTime);
|
try game.update(deltaTime);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user