Port old pipeline logic
This commit is contained in:
11
src/Log.zig
Normal file
11
src/Log.zig
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
level: std.log.Level,
|
||||||
|
message: []const u8,
|
||||||
|
|
||||||
|
pub fn init(level: std.log.Level, message: []const u8) @This() {
|
||||||
|
return .{
|
||||||
|
.level = level,
|
||||||
|
.message = message,
|
||||||
|
};
|
||||||
|
}
|
||||||
49
src/Samplers.zig
Normal file
49
src/Samplers.zig
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
const sokol = @import("sokol");
|
||||||
|
|
||||||
|
const sg = sokol.gfx;
|
||||||
|
|
||||||
|
const main = @import("main.zig");
|
||||||
|
|
||||||
|
pub var sampler_cache: std.AutoHashMapUnmanaged(Descriptor, sg.Sampler) = .{};
|
||||||
|
|
||||||
|
pub const Descriptor = struct {
|
||||||
|
wrap_u: sg.Wrap = .REPEAT,
|
||||||
|
wrap_v: sg.Wrap = .REPEAT,
|
||||||
|
wrap_w: sg.Wrap = .REPEAT,
|
||||||
|
min_filter: sg.Filter = .LINEAR,
|
||||||
|
mag_filter: sg.Filter = .LINEAR,
|
||||||
|
mipmap_filter: sg.Filter = .LINEAR,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn getOrCreateSampler(descriptor: Descriptor) !sg.Sampler {
|
||||||
|
const entry = try sampler_cache.getOrPut(main.allocator, descriptor);
|
||||||
|
|
||||||
|
if (entry.found_existing) {
|
||||||
|
return entry.value_ptr.*;
|
||||||
|
} else {
|
||||||
|
const sampler = sg.makeSampler(.{
|
||||||
|
.wrap_u = descriptor.wrap_u,
|
||||||
|
.wrap_v = descriptor.wrap_v,
|
||||||
|
.wrap_w = descriptor.wrap_w,
|
||||||
|
.min_filter = descriptor.min_filter,
|
||||||
|
.mag_filter = descriptor.mag_filter,
|
||||||
|
.mipmap_filter = descriptor.mipmap_filter,
|
||||||
|
});
|
||||||
|
|
||||||
|
entry.key_ptr.* = descriptor;
|
||||||
|
entry.value_ptr.* = sampler;
|
||||||
|
|
||||||
|
return sampler;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deinit() void {
|
||||||
|
var sampler_cache_it = sampler_cache.valueIterator();
|
||||||
|
while (sampler_cache_it.next()) |sampler| {
|
||||||
|
sg.destroySampler(sampler.*);
|
||||||
|
}
|
||||||
|
|
||||||
|
sampler_cache.deinit(main.allocator);
|
||||||
|
}
|
||||||
252
src/game.zig
Normal file
252
src/game.zig
Normal file
@@ -0,0 +1,252 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
const ig = @import("cimgui");
|
||||||
|
const shader = @import("shader");
|
||||||
|
const sokol = @import("sokol");
|
||||||
|
|
||||||
|
const sapp = sokol.app;
|
||||||
|
const sg = sokol.gfx;
|
||||||
|
const sglue = sokol.glue;
|
||||||
|
|
||||||
|
const main = @import("main.zig");
|
||||||
|
const Samplers = @import("Samplers.zig");
|
||||||
|
|
||||||
|
var show_console: bool = false;
|
||||||
|
var show_demo_window: bool = false;
|
||||||
|
|
||||||
|
var vertex_buffer: sg.Buffer = undefined;
|
||||||
|
var index_buffer: sg.Buffer = undefined;
|
||||||
|
|
||||||
|
var pipeline: sg.Pipeline = undefined;
|
||||||
|
|
||||||
|
var point_light_buffer: sg.Buffer = undefined;
|
||||||
|
var directional_light_buffer: sg.Buffer = undefined;
|
||||||
|
var sampler: sg.Sampler = undefined;
|
||||||
|
var base_color_texture: sg.Image = undefined;
|
||||||
|
var occlusion_roughness_metallic_texture: sg.Image = undefined;
|
||||||
|
var normal_texture: sg.Image = undefined;
|
||||||
|
|
||||||
|
var bindings: sg.Bindings = undefined;
|
||||||
|
|
||||||
|
pub fn init() void {
|
||||||
|
vertex_buffer = sg.makeBuffer(.{
|
||||||
|
.data = sg.asRange(&[_]f32{
|
||||||
|
// positionOS texCoord normalOS tangentOS
|
||||||
|
-0.5, -0.5, 0, 0, 1, 0, 0, 1, 1, 0, 0, -1,
|
||||||
|
0.5, -0.5, 0, 1, 1, 0, 0, 1, 1, 0, 0, -1,
|
||||||
|
-0.5, 0.5, 0, 0, 0, 0, 0, 1, 1, 0, 0, -1,
|
||||||
|
0.5, 0.5, 0, 1, 0, 0, 0, 1, 1, 0, 0, -1,
|
||||||
|
}),
|
||||||
|
.usage = .{
|
||||||
|
.immutable = true,
|
||||||
|
.vertex_buffer = true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
index_buffer = sg.makeBuffer(.{
|
||||||
|
.data = sg.asRange(&[_]u16{ 0, 1, 2, 2, 1, 3 }),
|
||||||
|
.usage = .{
|
||||||
|
.immutable = true,
|
||||||
|
.index_buffer = true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
pipeline = sg.makePipeline(.{
|
||||||
|
.shader = sg.makeShader(shader.programShaderDesc(sg.queryBackend())),
|
||||||
|
.layout = blk: {
|
||||||
|
var ret: sg.VertexLayoutState = .{};
|
||||||
|
ret.attrs[shader.ATTR_program_positionOS].format = .FLOAT3;
|
||||||
|
ret.attrs[shader.ATTR_program_texCoord].format = .FLOAT2;
|
||||||
|
ret.attrs[shader.ATTR_program_normalOS].format = .FLOAT3;
|
||||||
|
ret.attrs[shader.ATTR_program_tangentOS].format = .FLOAT4;
|
||||||
|
break :blk ret;
|
||||||
|
},
|
||||||
|
.primitive_type = .TRIANGLES,
|
||||||
|
.index_type = .UINT16,
|
||||||
|
.cull_mode = .BACK,
|
||||||
|
.face_winding = .CCW,
|
||||||
|
});
|
||||||
|
|
||||||
|
point_light_buffer = sg.makeBuffer(.{
|
||||||
|
.size = @sizeOf([4]shader.PointLight),
|
||||||
|
.usage = .{
|
||||||
|
.stream_update = true,
|
||||||
|
.storage_buffer = true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
directional_light_buffer = sg.makeBuffer(.{
|
||||||
|
.size = @sizeOf([4]shader.DirectionalLight),
|
||||||
|
.usage = .{
|
||||||
|
.stream_update = true,
|
||||||
|
.storage_buffer = true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
sampler = Samplers.getOrCreateSampler(.{
|
||||||
|
.wrap_u = .REPEAT,
|
||||||
|
.wrap_v = .REPEAT,
|
||||||
|
.wrap_w = .REPEAT,
|
||||||
|
.min_filter = .LINEAR,
|
||||||
|
.mag_filter = .LINEAR,
|
||||||
|
.mipmap_filter = .LINEAR,
|
||||||
|
}) catch unreachable;
|
||||||
|
|
||||||
|
base_color_texture = sg.makeImage(.{
|
||||||
|
.type = .ARRAY,
|
||||||
|
.usage = .{ .immutable = true },
|
||||||
|
.width = 16,
|
||||||
|
.height = 16,
|
||||||
|
.num_slices = 16,
|
||||||
|
.pixel_format = .RGBA8,
|
||||||
|
.data = blk: {
|
||||||
|
var ret: sg.ImageData = .{};
|
||||||
|
ret.mip_levels[0] = sg.asRange(&[_]u8{ 255, 255, 255, 255 } ** (16 * 16 * 16));
|
||||||
|
break :blk ret;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
occlusion_roughness_metallic_texture = sg.makeImage(.{
|
||||||
|
.type = .ARRAY,
|
||||||
|
.usage = .{ .immutable = true },
|
||||||
|
.width = 1,
|
||||||
|
.height = 1,
|
||||||
|
.num_slices = 16,
|
||||||
|
.pixel_format = .RGBA8,
|
||||||
|
.data = blk: {
|
||||||
|
var ret: sg.ImageData = .{};
|
||||||
|
ret.mip_levels[0] = sg.asRange(&[_]u8{ 255, 255, 0, 255 } ** (1 * 1 * 16));
|
||||||
|
break :blk ret;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
normal_texture = sg.makeImage(.{
|
||||||
|
.type = .ARRAY,
|
||||||
|
.usage = .{ .immutable = true },
|
||||||
|
.width = 128,
|
||||||
|
.height = 128,
|
||||||
|
.num_slices = 16,
|
||||||
|
.pixel_format = .RGBA8,
|
||||||
|
.data = blk: {
|
||||||
|
var ret: sg.ImageData = .{};
|
||||||
|
ret.mip_levels[0] = sg.asRange(&[_]u8{ 127, 127, 255, 255 } ** (128 * 128 * 16));
|
||||||
|
break :blk ret;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
bindings = .{};
|
||||||
|
|
||||||
|
bindings.vertex_buffers[0] = vertex_buffer;
|
||||||
|
bindings.index_buffer = index_buffer;
|
||||||
|
|
||||||
|
bindings.views[shader.VIEW_Point_Lights] = sg.makeView(.{
|
||||||
|
.storage_buffer = .{ .buffer = point_light_buffer },
|
||||||
|
});
|
||||||
|
bindings.views[shader.VIEW_Directional_Lights] = sg.makeView(.{
|
||||||
|
.storage_buffer = .{ .buffer = directional_light_buffer },
|
||||||
|
});
|
||||||
|
bindings.views[shader.VIEW__BaseColorTexture] = sg.makeView(.{
|
||||||
|
.texture = .{ .image = base_color_texture },
|
||||||
|
});
|
||||||
|
bindings.views[shader.VIEW__OcclusionRoughnessMetallicTexture] = sg.makeView(.{
|
||||||
|
.texture = .{ .image = occlusion_roughness_metallic_texture },
|
||||||
|
});
|
||||||
|
bindings.views[shader.VIEW__NormalTexture] = sg.makeView(.{
|
||||||
|
.texture = .{ .image = normal_texture },
|
||||||
|
});
|
||||||
|
|
||||||
|
bindings.samplers[0] = sampler;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deinit() void {}
|
||||||
|
|
||||||
|
pub fn update(dt: f64) void {
|
||||||
|
_ = dt;
|
||||||
|
|
||||||
|
if (show_console) {
|
||||||
|
showConsole();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (show_demo_window) {
|
||||||
|
ig.igShowDemoWindow(&show_demo_window);
|
||||||
|
}
|
||||||
|
|
||||||
|
sg.beginPass(.{
|
||||||
|
.action = blk: {
|
||||||
|
var ret: sg.PassAction = .{};
|
||||||
|
|
||||||
|
ret.colors[0] = .{
|
||||||
|
.load_action = .CLEAR,
|
||||||
|
.store_action = .STORE,
|
||||||
|
.clear_value = .{ .r = 0, .g = 0, .b = 0, .a = 1 },
|
||||||
|
};
|
||||||
|
|
||||||
|
ret.depth = .{
|
||||||
|
.load_action = .CLEAR,
|
||||||
|
.store_action = .STORE,
|
||||||
|
.clear_value = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
break :blk ret;
|
||||||
|
},
|
||||||
|
.swapchain = sglue.swapchain(),
|
||||||
|
});
|
||||||
|
|
||||||
|
sg.applyPipeline(pipeline);
|
||||||
|
sg.applyBindings(bindings);
|
||||||
|
|
||||||
|
sg.applyUniforms(shader.UB_Global_Uniforms_Vertex, sg.asRange(&shader.GlobalUniformsVertex{
|
||||||
|
._MatrixVStoCS = .{ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 },
|
||||||
|
._MatrixWStoVS = .{ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 },
|
||||||
|
}));
|
||||||
|
|
||||||
|
sg.applyUniforms(shader.UB_Object_Uniforms, sg.asRange(&shader.ObjectUniforms{
|
||||||
|
._MatrixOStoWS = .{ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 },
|
||||||
|
._MatrixOStoWSNormal = .{ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 },
|
||||||
|
}));
|
||||||
|
|
||||||
|
sg.applyUniforms(shader.UB_Global_Uniforms_Fragment, sg.asRange(&shader.GlobalUniformsFragment{
|
||||||
|
._MatrixWStoVS = .{ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 },
|
||||||
|
._AmbientLight = .{ 0.1, 0.1, 0.1 },
|
||||||
|
._PointLightCount = 0,
|
||||||
|
._DirectionalLightCount = 0,
|
||||||
|
}));
|
||||||
|
|
||||||
|
sg.applyUniforms(shader.UB_Material_Uniforms, sg.asRange(&shader.MaterialUniforms{
|
||||||
|
._TextureIndex = 0,
|
||||||
|
}));
|
||||||
|
|
||||||
|
sg.draw(0, 6, 1);
|
||||||
|
sg.endPass();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn onKeyDown(key_code: sapp.Keycode, mods: u32) void {
|
||||||
|
const no_mods = mods == 0;
|
||||||
|
|
||||||
|
if (key_code == .GRAVE_ACCENT and no_mods) {
|
||||||
|
show_console = !show_console;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key_code == .F1 and no_mods) {
|
||||||
|
show_demo_window = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn showConsole() void {
|
||||||
|
const display_size = ig.igGetIO().*.DisplaySize;
|
||||||
|
ig.igSetNextWindowPos(.{ .x = 0, .y = 0 }, 0);
|
||||||
|
ig.igSetNextWindowSize(.{ .x = display_size.x, .y = main.min_window_height }, ig.ImGuiCond_Once);
|
||||||
|
if (ig.igBegin("Console", null, ig.ImGuiWindowFlags_NoTitleBar | ig.ImGuiWindowFlags_NoResize | ig.ImGuiWindowFlags_NoMove | ig.ImGuiWindowFlags_NoCollapse)) {
|
||||||
|
for (main.logs.items) |log| {
|
||||||
|
ig.igPushStyleColorImVec4(ig.ImGuiCol_Text, switch (log.level) {
|
||||||
|
.err => .{ .x = 1, .y = 0, .z = 0, .w = 1 },
|
||||||
|
.warn => .{ .x = 1, .y = 1, .z = 0, .w = 1 },
|
||||||
|
.info => .{ .x = 1, .y = 1, .z = 1, .w = 1 },
|
||||||
|
.debug => .{ .x = 0.5, .y = 0.5, .z = 0.5, .w = 1 },
|
||||||
|
});
|
||||||
|
ig.igTextUnformattedEx(log.message.ptr, log.message.ptr + log.message.len);
|
||||||
|
ig.igPopStyleColor();
|
||||||
|
}
|
||||||
|
ig.igEnd();
|
||||||
|
}
|
||||||
|
}
|
||||||
192
src/main.zig
192
src/main.zig
@@ -1,3 +1,5 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
|
||||||
const ig = @import("cimgui");
|
const ig = @import("cimgui");
|
||||||
const shader = @import("shader");
|
const shader = @import("shader");
|
||||||
const sokol = @import("sokol");
|
const sokol = @import("sokol");
|
||||||
@@ -6,19 +8,24 @@ const sapp = sokol.app;
|
|||||||
const sg = sokol.gfx;
|
const sg = sokol.gfx;
|
||||||
const sglue = sokol.glue;
|
const sglue = sokol.glue;
|
||||||
const simgui = sokol.imgui;
|
const simgui = sokol.imgui;
|
||||||
const slog = sokol.log;
|
|
||||||
|
|
||||||
var show_demo_window = true;
|
const game = @import("game.zig");
|
||||||
|
const Log = @import("Log.zig");
|
||||||
|
|
||||||
const main_action = blk: {
|
pub const min_framerate = 30.0;
|
||||||
var ret: sg.PassAction = .{};
|
pub const min_frametime = 1.0 / min_framerate;
|
||||||
|
pub const min_window_height = 360;
|
||||||
|
pub const min_window_width = 640;
|
||||||
|
pub const temp_allocator_capacity = 16 * 1024 * 1024;
|
||||||
|
pub const window_title = "voxel-game";
|
||||||
|
|
||||||
ret.colors[0] = .{
|
pub var allocator: std.mem.Allocator = undefined;
|
||||||
.load_action = .CLEAR,
|
pub var temp_allocator: std.mem.Allocator = undefined;
|
||||||
.clear_value = .{ .r = 0.0, .g = 0.0, .b = 0.0, .a = 1.0 },
|
|
||||||
};
|
|
||||||
|
|
||||||
break :blk ret;
|
pub var logs: std.ArrayListUnmanaged(Log) = .empty;
|
||||||
|
|
||||||
|
pub const std_options: std.Options = .{
|
||||||
|
.logFn = logFn,
|
||||||
};
|
};
|
||||||
|
|
||||||
const imgui_action = blk: {
|
const imgui_action = blk: {
|
||||||
@@ -31,72 +38,38 @@ const imgui_action = blk: {
|
|||||||
break :blk ret;
|
break :blk ret;
|
||||||
};
|
};
|
||||||
|
|
||||||
var bindings: sg.Bindings = .{};
|
|
||||||
var pipeline: sg.Pipeline = .{};
|
|
||||||
|
|
||||||
fn init() callconv(.c) void {
|
fn init() callconv(.c) void {
|
||||||
sg.setup(.{
|
sg.setup(.{
|
||||||
.environment = sglue.environment(),
|
.environment = sglue.environment(),
|
||||||
.logger = .{ .func = slog.func },
|
.logger = .{ .func = sokolLogFn },
|
||||||
});
|
});
|
||||||
|
|
||||||
simgui.setup(.{
|
simgui.setup(.{
|
||||||
.logger = .{ .func = slog.func },
|
.logger = .{ .func = sokolLogFn },
|
||||||
});
|
});
|
||||||
|
|
||||||
bindings.vertex_buffers[0] = sg.makeBuffer(.{
|
game.init();
|
||||||
.data = sg.asRange(&[_]f32{
|
|
||||||
// positionOS texCoord normalOS tangentOS
|
|
||||||
0.0, 0.5, 0.5, 0.5, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0,
|
|
||||||
0.5, -0.5, 0.5, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0,
|
|
||||||
-0.5, -0.5, 0.5, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0,
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
pipeline = sg.makePipeline(.{
|
|
||||||
.shader = sg.makeShader(shader.programShaderDesc(sg.queryBackend())),
|
|
||||||
.layout = blk: {
|
|
||||||
var ret: sg.VertexLayoutState = .{};
|
|
||||||
ret.attrs[shader.ATTR_program_positionOS].format = .FLOAT3;
|
|
||||||
ret.attrs[shader.ATTR_program_texCoord].format = .FLOAT2;
|
|
||||||
ret.attrs[shader.ATTR_program_normalOS].format = .FLOAT3;
|
|
||||||
ret.attrs[shader.ATTR_program_tangentOS].format = .FLOAT4;
|
|
||||||
break :blk ret;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deinit() callconv(.c) void {
|
fn deinit() callconv(.c) void {
|
||||||
|
game.deinit();
|
||||||
simgui.shutdown();
|
simgui.shutdown();
|
||||||
sg.shutdown();
|
sg.shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn frame() callconv(.c) void {
|
fn frame() callconv(.c) void {
|
||||||
|
const dt = sapp.frameDuration();
|
||||||
|
|
||||||
simgui.newFrame(.{
|
simgui.newFrame(.{
|
||||||
.width = sapp.width(),
|
.width = sapp.width(),
|
||||||
.height = sapp.height(),
|
.height = sapp.height(),
|
||||||
.delta_time = sapp.frameDuration(),
|
.delta_time = dt,
|
||||||
.dpi_scale = sapp.dpiScale(),
|
.dpi_scale = sapp.dpiScale(),
|
||||||
});
|
});
|
||||||
|
|
||||||
// --- UPDATE ---
|
game.update(dt);
|
||||||
|
|
||||||
if (show_demo_window) {
|
// --- BEGIN IMGUI PASS ---
|
||||||
ig.igShowDemoWindow(&show_demo_window);
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- MAIN PASS ---
|
|
||||||
|
|
||||||
sg.beginPass(.{
|
|
||||||
.action = main_action,
|
|
||||||
.swapchain = sglue.swapchain(),
|
|
||||||
});
|
|
||||||
sg.applyPipeline(pipeline);
|
|
||||||
sg.applyBindings(bindings);
|
|
||||||
sg.draw(0, 3, 1);
|
|
||||||
sg.endPass();
|
|
||||||
|
|
||||||
// --- IMGUI PASS ---
|
|
||||||
|
|
||||||
sg.beginPass(.{
|
sg.beginPass(.{
|
||||||
.action = imgui_action,
|
.action = imgui_action,
|
||||||
@@ -105,16 +78,40 @@ fn frame() callconv(.c) void {
|
|||||||
simgui.render();
|
simgui.render();
|
||||||
sg.endPass();
|
sg.endPass();
|
||||||
|
|
||||||
// ---
|
// --- END IMGUI PASS ---
|
||||||
|
|
||||||
sg.commit();
|
sg.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn event(ev: [*c]const sapp.Event) callconv(.c) void {
|
fn event(_ev: [*c]const sapp.Event) callconv(.c) void {
|
||||||
_ = simgui.handleEvent(ev.*);
|
const ev: *const sapp.Event = @ptrCast(_ev);
|
||||||
|
const ig_capture_keyboard = simgui.handleEvent(ev.*);
|
||||||
|
|
||||||
|
if (!ig_capture_keyboard) {
|
||||||
|
if (ev.type == .KEY_DOWN and !ev.key_repeat) {
|
||||||
|
game.onKeyDown(ev.key_code, ev.modifiers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn main() !void {
|
||||||
|
var gpa: std.heap.GeneralPurposeAllocator(.{}) = .init;
|
||||||
|
defer _ = gpa.deinit();
|
||||||
|
|
||||||
|
var fba: std.heap.FixedBufferAllocator = .init(&struct {
|
||||||
|
pub var buffer: [temp_allocator_capacity]u8 = undefined;
|
||||||
|
}.buffer);
|
||||||
|
|
||||||
|
allocator = gpa.allocator();
|
||||||
|
temp_allocator = fba.threadSafeAllocator();
|
||||||
|
|
||||||
|
defer {
|
||||||
|
for (logs.items) |log| {
|
||||||
|
allocator.free(log.message);
|
||||||
|
}
|
||||||
|
logs.deinit(allocator);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn main() void {
|
|
||||||
sapp.run(.{
|
sapp.run(.{
|
||||||
.init_cb = &init,
|
.init_cb = &init,
|
||||||
.cleanup_cb = &deinit,
|
.cleanup_cb = &deinit,
|
||||||
@@ -124,6 +121,87 @@ pub fn main() void {
|
|||||||
.width = 1280,
|
.width = 1280,
|
||||||
.height = 720,
|
.height = 720,
|
||||||
.icon = .{ .sokol_default = true },
|
.icon = .{ .sokol_default = true },
|
||||||
.logger = .{ .func = slog.func },
|
.logger = .{ .func = sokolLogFn },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn sokolLogFn(
|
||||||
|
maybe_tag: ?[*:0]const u8,
|
||||||
|
log_level: u32,
|
||||||
|
log_item: u32,
|
||||||
|
maybe_message: ?[*:0]const u8,
|
||||||
|
line_nr: u32,
|
||||||
|
maybe_filename: ?[*:0]const u8,
|
||||||
|
user_data: ?*anyopaque,
|
||||||
|
) callconv(.c) void {
|
||||||
|
defer {
|
||||||
|
if (log_level == 0) {
|
||||||
|
const message = std.mem.span(maybe_message) orelse "";
|
||||||
|
@panic(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const _SLOG_LINE_LENGTH = 512;
|
||||||
|
|
||||||
|
_ = user_data;
|
||||||
|
|
||||||
|
var line_buf: [_SLOG_LINE_LENGTH]u8 = undefined;
|
||||||
|
var writer = std.Io.Writer.fixed(&line_buf);
|
||||||
|
|
||||||
|
if (maybe_tag) |tag| {
|
||||||
|
writer.print("[{s}]", .{tag}) catch return;
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.print("[{s}]", .{switch (log_level) {
|
||||||
|
0 => "panic",
|
||||||
|
1 => "error",
|
||||||
|
2 => "warning",
|
||||||
|
else => "info",
|
||||||
|
}}) catch return;
|
||||||
|
|
||||||
|
writer.print("[id:{d}]", .{log_item}) catch return;
|
||||||
|
|
||||||
|
if (maybe_filename) |filename| {
|
||||||
|
writer.print(" {s}:{d}:0: ", .{ filename, line_nr }) catch return;
|
||||||
|
} else {
|
||||||
|
writer.print("[line:{d}]", .{line_nr}) catch return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (maybe_message) |message| {
|
||||||
|
writer.print("\n\t{s}", .{message}) catch return;
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.print("\n\n", .{}) catch return;
|
||||||
|
|
||||||
|
if (log_level == 0) {
|
||||||
|
writer.print("ABORTING because of [panic]\n", .{}) catch return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const level: std.log.Level = switch (log_level) {
|
||||||
|
0, 1 => .err,
|
||||||
|
2 => .warn,
|
||||||
|
else => .info,
|
||||||
|
};
|
||||||
|
|
||||||
|
const full_message = allocator.dupe(u8, writer.buffered()) catch return;
|
||||||
|
|
||||||
|
std.debug.print("{s}", .{full_message});
|
||||||
|
|
||||||
|
logs.append(allocator, .init(level, full_message)) catch {
|
||||||
|
allocator.free(full_message);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn logFn(
|
||||||
|
comptime level: std.log.Level,
|
||||||
|
comptime _: @Type(.enum_literal),
|
||||||
|
comptime fmt: []const u8,
|
||||||
|
args: anytype,
|
||||||
|
) void {
|
||||||
|
const message = std.fmt.allocPrint(allocator, fmt, args) catch return;
|
||||||
|
logs.append(allocator, .init(level, message)) catch {
|
||||||
|
allocator.free(message);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user