diff --git a/build.zig b/build.zig index 3ea2aa8..e7d7b71 100644 --- a/build.zig +++ b/build.zig @@ -3,6 +3,7 @@ const zig_version = @import ("builtin").zig_version; const glfw = @import ("build/glfw.zig"); const vk = @import ("build/vk.zig"); +const imgui = @import ("build/imgui.zig"); const shaders = @import ("build/shaders.zig"); const utils = @import ("build/utils.zig"); @@ -20,8 +21,10 @@ pub fn build (builder: *std.Build) !void fn requirements () !void { - if (zig_version.order (try std.SemanticVersion.parse (zon.min_zig_version)) == .lt) - std.debug.panic ("{s} needs at least Zig {s} to be build", .{ zon.name, zon.min_zig_version, }); + if (zig_version.order ( + try std.SemanticVersion.parse (zon.min_zig_version)) == .lt) + std.debug.panic ("{s} needs at least Zig {s} to be build", + .{ zon.name, zon.min_zig_version, }); } fn turbo (builder: *std.Build, profile: *Profile) !void @@ -29,15 +32,18 @@ fn turbo (builder: *std.Build, profile: *Profile) !void profile.optimize = .ReleaseFast; profile.variables.addOption ([] const u8, "log_dir", ""); profile.variables.addOption (u8, "log_level", 0); - profile.variables.addOption ([] const [] const [] const u8, "vk_optional_extensions", &.{}); - profile.command = &.{ "glslc", "-O", try std.fmt.allocPrint (builder.allocator, "--target-env=vulkan1.{s}", .{ profile.options.vkminor, }), }; + profile.variables.addOption ([] const [] const [] const u8, + "vk_optional_extensions", &.{}); + profile.command = &.{ "glslc", "-O", try std.fmt.allocPrint ( + builder.allocator, "--target-env=vulkan1.{s}", + .{ profile.options.vkminor, }), }; } -fn verbose (builder: *std.Build, profile: *Profile) !void +fn dev (builder: *std.Build, profile: *Profile) !void { const log_dir = "log"; - // Make log directory if not present only in verbose mode + // Make log directory if not present only in dev mode builder.build_root.handle.makeDir (log_dir) catch |err| { // Do not return error if log directory already exists @@ -45,14 +51,17 @@ fn verbose (builder: *std.Build, profile: *Profile) !void }; profile.optimize = .Debug; - profile.variables.addOption ([] const u8, "log_dir", try builder.build_root.join (builder.allocator, &.{ log_dir, })); + profile.variables.addOption ([] const u8, "log_dir", + try builder.build_root.join (builder.allocator, &.{ log_dir, })); profile.variables.addOption (u8, "log_level", 2); - profile.variables.addOption ([] const [] const [] const u8, "vk_optional_extensions", &.{ - &.{ "EXT", "DEVICE_ADDRESS_BINDING_REPORT", }, - &.{ "EXT", "VALIDATION_FEATURES", }, - &.{ "KHR", "SHADER_NON_SEMANTIC_INFO", }, - }); - profile.command = &.{ "glslc", try std.fmt.allocPrint (builder.allocator, "--target-env=vulkan1.{s}", .{ profile.options.vkminor, }), }; + profile.variables.addOption ([] const [] const [] const u8, + "vk_optional_extensions", &.{ + &.{ "EXT", "DEVICE_ADDRESS_BINDING_REPORT", }, + &.{ "EXT", "VALIDATION_FEATURES", }, + &.{ "KHR", "SHADER_NON_SEMANTIC_INFO", }, + }); + profile.command = &.{ "glslc", try std.fmt.allocPrint (builder.allocator, + "--target-env=vulkan1.{s}", .{ profile.options.vkminor, }), }; } fn default (builder: *std.Build, profile: *Profile) !void @@ -60,42 +69,64 @@ fn default (builder: *std.Build, profile: *Profile) !void profile.optimize = builder.standardOptimizeOption (.{}); profile.variables.addOption ([] const u8, "log_dir", profile.options.logdir); profile.variables.addOption (u8, "log_level", 1); - profile.variables.addOption ([] const [] const [] const u8, "vk_optional_extensions", &.{ - &.{ "EXT", "DEVICE_ADDRESS_BINDING_REPORT", }, - }); - profile.command = &.{ "glslc", try std.fmt.allocPrint (builder.allocator, "--target-env=vulkan1.{s}", .{ profile.options.vkminor, }), }; + profile.variables.addOption ([] const [] const [] const u8, + "vk_optional_extensions", &.{ + &.{ "EXT", "DEVICE_ADDRESS_BINDING_REPORT", }, + }); + profile.command = &.{ "glslc", try std.fmt.allocPrint (builder.allocator, + "--target-env=vulkan1.{s}", .{ profile.options.vkminor, }), }; } fn parse_options (builder: *std.Build) !Profile { const options = Options { - .verbose = builder.option (bool, std.meta.fieldInfo (Options, .verbose).name, "Build " ++ zon.name ++ " with full logging features. Default: " ++ (if (@field (Options.default, std.meta.fieldInfo (Options, .verbose).name)) "enabled" else "disabled") ++ ".") - orelse @field (Options.default, std.meta.fieldInfo (Options, .verbose).name), - .turbo = builder.option (bool, std.meta.fieldInfo (Options, .turbo).name, "Build " ++ zon.name ++ " with optimized features. Default: " ++ (if (@field (Options.default, std.meta.fieldInfo (Options, .turbo).name)) "enabled" else "disabled") ++ ".") + .dev = builder.option (bool, std.meta.fieldInfo (Options, .dev).name, + "Build " ++ zon.name ++ " with full logging features. Default: " ++ + (if (@field (Options.default, std.meta.fieldInfo (Options, .dev).name)) + "enabled" else "disabled") ++ ".") + orelse @field (Options.default, std.meta.fieldInfo (Options, .dev).name), + .turbo = builder.option (bool, std.meta.fieldInfo (Options, .turbo).name, + "Build " ++ zon.name ++ " with optimized features. Default: " ++ + (if (@field (Options.default, std.meta.fieldInfo (Options, .turbo).name)) + "enabled" else "disabled") ++ ".") orelse @field (Options.default, std.meta.fieldInfo (Options, .turbo).name), - .logdir = builder.option ([] const u8, std.meta.fieldInfo (Options, .logdir).name, "Absolute path to log directory. If not specified, logs are not registered in a file.") + .logdir = builder.option ([] const u8, + std.meta.fieldInfo (Options, .logdir).name, + "Absolute path to log directory. If not specified, logs are not registered in a file.") orelse @field (Options.default, std.meta.fieldInfo (Options, .logdir).name), - .vkminor = builder.option ([] const u8, std.meta.fieldInfo (Options, .vkminor).name, "Vulkan minor version to use: Possible values: 0, 1, 2 or 3. Default value: " ++ @field (Options.default, std.meta.fieldInfo (Options, .vkminor).name) ++ ".") + .vkminor = builder.option ([] const u8, + std.meta.fieldInfo (Options, .vkminor).name, + "Vulkan minor version to use: Possible values: 0, 1, 2 or 3. Default value: " ++ + @field (Options.default, std.meta.fieldInfo (Options, .vkminor).name) ++ ".") orelse @field (Options.default, std.meta.fieldInfo (Options, .vkminor).name), }; - _ = std.fmt.parseInt (u2, options.vkminor, 10) catch std.debug.panic ("-D{s} value should be 0, 1, 2 or 3", .{ std.meta.fieldInfo (Options, .vkminor).name, }); + _ = std.fmt.parseInt (u2, options.vkminor, 10) catch + std.debug.panic ("-D{s} value should be 0, 1, 2 or 3", + .{ std.meta.fieldInfo (Options, .vkminor).name, }); - if (options.turbo and options.verbose) - std.debug.panic ("-D{s} and -D{s} can not be used together", .{ std.meta.fieldInfo (Options, .turbo).name, std.meta.fieldInfo (Options, .verbose).name, }) + if (options.turbo and options.dev) + std.debug.panic ("-D{s} and -D{s} can not be used together", + .{ std.meta.fieldInfo (Options, .turbo).name, + std.meta.fieldInfo (Options, .dev).name, }) else if (options.turbo and options.logdir.len > 0) - std.debug.panic ("-D{s} and -D{s} can not be used together", .{ std.meta.fieldInfo (Options, .turbo).name, std.meta.fieldInfo (Options, .logdir).name, }); + std.debug.panic ("-D{s} and -D{s} can not be used together", + .{ std.meta.fieldInfo (Options, .turbo).name, + std.meta.fieldInfo (Options, .logdir).name, }); var profile: Profile = undefined; profile.target = builder.standardTargetOptions (.{}); profile.options = options; profile.variables = builder.addOptions (); - profile.variables.addOption ([] const u8, std.meta.fieldInfo (@TypeOf (zon), .name).name, zon.name); - profile.variables.addOption ([] const u8, std.meta.fieldInfo (@TypeOf (zon), .version).name, zon.version); - profile.variables.addOption ([] const u8, "vk_minor", profile.options.vkminor); + profile.variables.addOption ([] const u8, + std.meta.fieldInfo (@TypeOf (zon), .name).name, zon.name); + profile.variables.addOption ([] const u8, + std.meta.fieldInfo (@TypeOf (zon), .version).name, zon.version); + profile.variables.addOption ([] const u8, "vk_minor", + profile.options.vkminor); if (profile.options.turbo) try turbo (builder, &profile) - else if (profile.options.verbose) try verbose (builder, &profile) + else if (profile.options.dev) try dev (builder, &profile) else try default (builder, &profile); return profile; @@ -112,7 +143,8 @@ fn link (builder: *std.Build, profile: *const Profile) !*std.Build.Module const cimgui = imgui_dep.artifact ("cimgui"); const c = builder.createModule (.{ - .root_source_file = .{ .path = try builder.build_root.join (builder.allocator, &.{ "src", "binding", "raw.zig", }), }, + .root_source_file = .{ .path = try builder.build_root.join ( + builder.allocator, &.{ "src", "binding", "raw.zig", }), }, .target = profile.target, .optimize = profile.optimize, }); @@ -123,7 +155,8 @@ fn link (builder: *std.Build, profile: *const Profile) !*std.Build.Module return c; } -fn import (builder: *std.Build, exe: *std.Build.Step.Compile, profile: *const Profile) !void +fn import (builder: *std.Build, exe: *std.Build.Step.Compile, + profile: *const Profile) !void { const datetime_dep = builder.dependency ("zig-datetime", .{ .target = profile.target, @@ -135,19 +168,13 @@ fn import (builder: *std.Build, exe: *std.Build.Step.Compile, profile: *const Pr const c = try link (builder, profile); const glfw_module = try glfw.import (builder, profile, c); const vk_module = try vk.import (builder, profile, c); - - const imgui = builder.createModule (.{ - .root_source_file = .{ .path = try builder.build_root.join (builder.allocator, &.{ "src", "binding", "imgui.zig", }), }, - .target = profile.target, - .optimize = profile.optimize, - }); - imgui.addImport ("c", c); - imgui.addImport ("glfw", glfw_module); - imgui.addImport ("vk", vk_module); + const imgui_module = + try imgui.import (builder, profile, c, glfw_module, vk_module); const build_options = profile.variables.createModule (); const logger = builder.createModule (.{ - .root_source_file = .{ .path = try builder.build_root.join (builder.allocator, &.{ "src", "logger.zig", }), }, + .root_source_file = .{ .path = try builder.build_root.join ( + builder.allocator, &.{ "src", "logger.zig", }), }, .target = profile.target, .optimize = profile.optimize, }); @@ -155,8 +182,9 @@ fn import (builder: *std.Build, exe: *std.Build.Step.Compile, profile: *const Pr logger.addImport ("datetime", datetime); const instance = builder.createModule (.{ - .root_source_file = .{ .path = try builder.build_root.join (builder.allocator, - &.{ "src", "vk", "instance", if (profile.options.turbo) "turbo.zig" else "default.zig", }), }, + .root_source_file = .{ .path = try builder.build_root.join ( + builder.allocator, &.{ "src", "vk", "instance", + if (profile.options.turbo) "turbo.zig" else "default.zig", }), }, .target = profile.target, .optimize = profile.optimize, }); @@ -164,9 +192,12 @@ fn import (builder: *std.Build, exe: *std.Build.Step.Compile, profile: *const Pr instance.addImport ("vk", vk_module); for ([_] struct { name: [] const u8, ptr: *std.Build.Module, } { - .{ .name = "datetime", .ptr = datetime, }, .{ .name = "shader", .ptr = shaders_module, }, - .{ .name = "glfw", .ptr = glfw_module, }, .{ .name = "vk", .ptr = vk_module, }, - .{ .name = "imgui", .ptr = imgui, }, .{ .name = "logger", .ptr = logger, }, + .{ .name = "datetime", .ptr = datetime, }, + .{ .name = "shader", .ptr = shaders_module, }, + .{ .name = "glfw", .ptr = glfw_module, }, + .{ .name = "vk", .ptr = vk_module, }, + .{ .name = "imgui", .ptr = imgui_module, }, + .{ .name = "logger", .ptr = logger, }, .{ .name = "instance", .ptr = instance, }, }) |module| exe.root_module.addImport (module.name, module.ptr); } @@ -175,7 +206,8 @@ fn run_exe (builder: *std.Build, profile: *const Profile) !void { const exe = builder.addExecutable (.{ .name = zon.name, - .root_source_file = .{ .path = try builder.build_root.join (builder.allocator, &.{ "src", "main.zig", }), }, + .root_source_file = .{ .path = try builder.build_root.join ( + builder.allocator, &.{ "src", "main.zig", }), }, .target = profile.target, .optimize = profile.optimize, }); @@ -196,8 +228,10 @@ fn run_test (builder: *std.Build, profile: *const Profile) !void const unit_tests = builder.addTest (.{ .target = profile.target, .optimize = profile.optimize, - .test_runner = try builder.build_root.join (builder.allocator, &.{ "test", "runner.zig", }), - .root_source_file = .{ .path = try builder.build_root.join (builder.allocator, &.{ "test", "main.zig", }), }, + .test_runner = try builder.build_root.join (builder.allocator, + &.{ "test", "runner.zig", }), + .root_source_file = .{ .path = try builder.build_root.join ( + builder.allocator, &.{ "test", "main.zig", }), }, }); unit_tests.step.dependOn (builder.getInstallStep ()); diff --git a/build/glfw.zig b/build/glfw.zig index aba5f67..3350b1b 100644 --- a/build/glfw.zig +++ b/build/glfw.zig @@ -2,9 +2,11 @@ const std = @import ("std"); const Profile = @import ("utils.zig").Profile; -pub fn import (builder: *std.Build, profile: *const Profile, c: *std.Build.Module) !*std.Build.Module +pub fn import (builder: *std.Build, profile: *const Profile, + c: *std.Build.Module) !*std.Build.Module { - const path = try builder.build_root.join (builder.allocator, &.{ "src", "binding", "glfw", }); + const path = try builder.build_root.join (builder.allocator, + &.{ "src", "binding", "glfw", }); var modules = std.ArrayList (*std.Build.Module).init (builder.allocator); @@ -17,22 +19,24 @@ pub fn import (builder: *std.Build, profile: *const Profile, c: *std.Build.Modul switch (entry.kind) { .file => { - if (!std.mem.eql (u8, entry.name, "glfw.zig")) - { - try modules.append (builder.createModule (.{ - .root_source_file = .{ .path = try std.fs.path.join (builder.allocator, &.{ path, entry.name, }), }, - .target = profile.target, - .optimize = profile.optimize, - })); - modules.items [modules.items.len - 1].addImport ("c", c); - } - }, + if (!std.mem.eql (u8, entry.name, "glfw.zig")) + { + try modules.append (builder.createModule (.{ + .root_source_file = .{ .path = try std.fs.path.join ( + builder.allocator, &.{ path, entry.name, }), }, + .target = profile.target, + .optimize = profile.optimize, + })); + modules.items [modules.items.len - 1].addImport ("c", c); + } + }, else => {}, } } const glfw = builder.createModule (.{ - .root_source_file = .{ .path = try std.fs.path.join (builder.allocator, &.{ path, "glfw.zig", }), }, + .root_source_file = .{ .path = try std.fs.path.join (builder.allocator, + &.{ path, "glfw.zig", }), }, .target = profile.target, .optimize = profile.optimize, }); @@ -40,12 +44,14 @@ pub fn import (builder: *std.Build, profile: *const Profile, c: *std.Build.Modul for (modules.items) |module| { - const name = std.fs.path.stem (std.fs.path.basename (module.root_source_file.?.getPath (builder))); + const name = std.fs.path.stem ( + std.fs.path.basename (module.root_source_file.?.getPath (builder))); glfw.addImport (name, module); module.addImport ("glfw", glfw); for (modules.items) |other| { - const other_name = std.fs.path.stem (std.fs.path.basename (other.root_source_file.?.getPath (builder))); + const other_name = std.fs.path.stem ( + std.fs.path.basename (other.root_source_file.?.getPath (builder))); if (std.mem.eql (u8, name, other_name)) continue; module.addImport (other_name, other); } @@ -54,7 +60,8 @@ pub fn import (builder: *std.Build, profile: *const Profile, c: *std.Build.Modul return glfw; } -pub fn lib (builder: *std.Build, profile: *const Profile) *std.Build.Step.Compile +pub fn lib (builder: *std.Build, + profile: *const Profile) *std.Build.Step.Compile { const dep = builder.dependency ("glfw", .{ .target = profile.target, diff --git a/build/imgui.zig b/build/imgui.zig new file mode 100644 index 0000000..be4081d --- /dev/null +++ b/build/imgui.zig @@ -0,0 +1,64 @@ +const std = @import ("std"); + +const Profile = @import ("utils.zig").Profile; + +pub fn import (builder: *std.Build, profile: *const Profile, + c: *std.Build.Module, glfw: *std.Build.Module, + vk: *std.Build.Module) !*std.Build.Module +{ + const path = try builder.build_root.join (builder.allocator, + &.{ "src", "binding", "imgui", }); + + var modules = std.ArrayList (*std.Build.Module).init (builder.allocator); + + var dir = try builder.build_root.handle.openDir (path, .{ .iterate = true, }); + defer dir.close (); + + var it = dir.iterate (); + while (try it.next ()) |entry| + { + switch (entry.kind) + { + .file => { + if (!std.mem.eql (u8, entry.name, "imgui.zig")) + { + try modules.append (builder.createModule (.{ + .root_source_file = .{ .path = try std.fs.path.join ( + builder.allocator, &.{ path, entry.name, }), }, + .target = profile.target, + .optimize = profile.optimize, + })); + modules.items [modules.items.len - 1].addImport ("c", c); + modules.items [modules.items.len - 1].addImport ("glfw", glfw); + modules.items [modules.items.len - 1].addImport ("vk", vk); + } + }, + else => {}, + } + } + + const imgui = builder.createModule (.{ + .root_source_file = .{ .path = try std.fs.path.join (builder.allocator, + &.{ path, "imgui.zig", }), }, + .target = profile.target, + .optimize = profile.optimize, + }); + imgui.addImport ("c", c); + + for (modules.items) |module| + { + const name = std.fs.path.stem ( + std.fs.path.basename (module.root_source_file.?.getPath (builder))); + imgui.addImport (name, module); + module.addImport ("imgui", imgui); + for (modules.items) |other| + { + const other_name = std.fs.path.stem ( + std.fs.path.basename (other.root_source_file.?.getPath (builder))); + if (std.mem.eql (u8, name, other_name)) continue; + module.addImport (other_name, other); + } + } + + return imgui; +} diff --git a/build/utils.zig b/build/utils.zig index 903a05a..d770a6b 100644 --- a/build/utils.zig +++ b/build/utils.zig @@ -4,7 +4,7 @@ pub const zon = .{ .name = "spaceporn", .version = "0.1.0", .min_zig_version = " pub const Options = struct { - verbose: bool = false, + dev: bool = false, turbo: bool = false, logdir: [] const u8 = "", vkminor: [] const u8 = "2", diff --git a/src/binding/imgui.zig b/src/binding/imgui.zig deleted file mode 100644 index afa5ce7..0000000 --- a/src/binding/imgui.zig +++ /dev/null @@ -1,260 +0,0 @@ -const std = @import ("std"); -const c = @import ("c"); - -const binding = struct -{ - const glfw = @import ("glfw"); - const vk = @import ("vk"); -}; - -const imgui = @This (); - -pub const vk = struct -{ - pub const DrawData = struct - { - pub const Ex = struct - { - pub fn render (draw_data: *c.ImDrawData, command_buffer: binding.vk.Command.Buffer, pipeline: binding.vk.Pipeline) void - { - c.cImGui_ImplVulkan_RenderDrawDataEx (draw_data, @ptrFromInt (@intFromEnum (command_buffer)), @ptrFromInt (@intFromEnum (pipeline))); - } - }; - }; - - pub const FontsTexture = struct - { - pub fn create () !void - { - if (!c.cImGui_ImplVulkan_CreateFontsTexture ()) return error.ImGuiVulkanCreateFontsTexture; - } - }; - - pub const Frame = struct - { - pub fn new () void - { - c.cImGui_ImplVulkan_NewFrame (); - } - }; - - pub const InitInfo = struct - { - Instance: binding.vk.Instance, - PhysicalDevice: binding.vk.PhysicalDevice, - Device: binding.vk.Device, - QueueFamily: u32, - Queue: binding.vk.Queue, - PipelineCache: binding.vk.Pipeline.Cache, - DescriptorPool: binding.vk.Descriptor.Pool, - Subpass: u32, - MinImageCount: u32, - ImageCount: u32, - MSAASamples: c_uint, - UseDynamicRendering: bool, - ColorAttachmentFormat: i32, - Allocator: [*c] const binding.vk.AllocationCallbacks, - CheckVkResultFn: ?*const fn (c_int) callconv (binding.vk.call_conv) void, - }; - - fn loader (function_name: [*c] const u8, instance: ?*anyopaque) callconv (binding.vk.call_conv) ?*const fn () callconv (binding.vk.call_conv) void - { - return c.glfwGetInstanceProcAddress (if (instance) |v| @as (c.VkInstance, @ptrCast (v)) else null, function_name); - } - - pub fn load () !void - { - if (!c.cImGui_ImplVulkan_LoadFunctions (loader)) return error.ImGuiVulkanLoadFunctionsFailure; - } - - pub fn init (init_info: *imgui.vk.InitInfo) !void - { - if (!c.cImGui_ImplVulkan_Init (@ptrCast (init_info))) return error.ImGuiVulkanInitFailure; - } - - pub fn shutdown () void - { - c.cImGui_ImplVulkan_Shutdown (); - } -}; - -pub const glfw = struct -{ - pub const Frame = struct - { - pub fn new () void - { - c.cImGui_ImplGlfw_NewFrame (); - } - }; - - pub fn init () !void - { - const window = try binding.glfw.Context.get (); - if (!c.cImGui_ImplGlfw_InitForVulkan (@ptrCast (window), true)) return error.ImGuiGlfwInitForVulkanFailure; - } - - pub fn shutdown () void - { - c.cImGui_ImplGlfw_Shutdown (); - } -}; - -pub const Cond = c.ImGuiCond; - -pub const Context = struct -{ - pub fn create () !void - { - if (c.ImGui_CreateContext (null) == null) return error.ImGuiCreateContextFailure; - } - - pub fn destroy () void - { - c.ImGui_DestroyContext (null); - } -}; - -pub const Col = struct -{ - pub const WindowBg = c.ImGuiCol_WindowBg; -}; - -pub const DrawData = struct -{ - pub fn get () *c.ImDrawData - { - return &(c.ImGui_GetDrawData ().*); - } -}; - -pub const Ex = struct -{ - pub fn button (label: [] const u8, size: imgui.Vec2) bool - { - return c.ImGui_ButtonEx (label.ptr, size); - } - - pub fn sameline (offset_from_start_x: f32, spacing: f32) void - { - c.ImGui_SameLineEx (offset_from_start_x, spacing); - } -}; - -pub const Frame = struct -{ - pub fn new () void - { - c.ImGui_NewFrame (); - } -}; - -pub const IO = struct -{ - pub fn get () *const c.ImGuiIO - { - return &(c.ImGui_GetIO ().*); - } -}; - -pub const NextWindow = struct -{ - pub const Pos = struct - { - pub const Ex = struct - { - pub fn set (pos: imgui.Vec2, cond: imgui.Cond, pivot: imgui.Vec2) void - { - c.ImGui_SetNextWindowPosEx (pos, cond, pivot); - } - }; - }; - - pub const Size = struct - { - pub fn set (size: imgui.Vec2, cond: imgui.Cond) void - { - c.ImGui_SetNextWindowSize (size, cond); - } - }; -}; - -pub const Style = struct -{ - pub fn colorsDark () void - { - c.ImGui_StyleColorsDark (null); - } - - const SetterTag = enum - { - colors, - window_rounding, - }; - - const Setter = union (SetterTag) - { - colors: struct { index: usize, channel: [] const u8, value: usize, }, - window_rounding: usize, - }; - - fn zig_to_c_name (setter: Setter) [] const u8 - { - return switch (setter) - { - .colors => "Colors", - .window_rounding => "WindowRounding", - }; - } - - pub fn set (comptime setters: [] const Setter) void - { - const style = c.ImGui_GetStyle (); - - inline for (setters) |setter| - { - switch (setter) - { - .colors => |colors| @field (@field (style.*, "Colors") [colors.index], colors.channel) = colors.value, - else => |active| @field (style.*, zig_to_c_name (setter)) = @field (setter, @tagName (active)), - } - } - } -}; - -pub const Vec2 = c.ImVec2; - -pub const Window = struct -{ - //pub const Flags = c.ImGuiWindowFlags_; - pub const Flags = i32; - - pub const Bit = enum (imgui.Window.Flags) - { - NO_COLLAPSE = c.ImGuiWindowFlags_NoCollapse, - NO_MOVE = c.ImGuiWindowFlags_NoMove, - NO_RESIZE = c.ImGuiWindowFlags_NoResize, - NO_TITLE_BAR = c.ImGuiWindowFlags_NoTitleBar, - }; -}; - -pub fn begin (name: [] const u8, p_open: ?*bool, flags: imgui.Window.Flags) !void -{ - if (!c.ImGui_Begin (name.ptr, p_open, flags)) return error.ImGuiBeginFailure; -} - -pub fn end () void -{ - c.ImGui_End (); -} - -pub fn render () void -{ - c.ImGui_Render (); -} - -pub fn text (allocator: std.mem.Allocator, comptime fmt: [] const u8, args: anytype) !void -{ - const str = try std.fmt.allocPrint (allocator, fmt, args); - c.ImGui_Text (str.ptr); -} diff --git a/src/binding/imgui/glfw.zig b/src/binding/imgui/glfw.zig new file mode 100644 index 0000000..d90e3d4 --- /dev/null +++ b/src/binding/imgui/glfw.zig @@ -0,0 +1,22 @@ +const std = @import ("std"); +const c = @import ("c"); +const glfw = @import ("glfw"); + +pub const Frame = struct +{ + pub fn new () void + { + c.cImGui_ImplGlfw_NewFrame (); + } +}; + +pub fn init () !void +{ + const window = try glfw.Context.get (); + if (!c.cImGui_ImplGlfw_InitForVulkan (@ptrCast (window), true)) return error.ImGuiGlfwInitForVulkanFailure; +} + +pub fn shutdown () void +{ + c.cImGui_ImplGlfw_Shutdown (); +} diff --git a/src/binding/imgui/imgui.zig b/src/binding/imgui/imgui.zig new file mode 100644 index 0000000..99b3fa7 --- /dev/null +++ b/src/binding/imgui/imgui.zig @@ -0,0 +1,125 @@ +const std = @import ("std"); +const c = @import ("c"); + +const imgui = @This (); + +pub const glfw = @import ("glfw"); +pub const vk = @import ("vk"); + +pub const Cond = c.ImGuiCond; + +pub const Context = struct +{ + pub fn create () !void + { + if (c.ImGui_CreateContext (null) == null) return error.ImGuiCreateContextFailure; + } + + pub fn destroy () void + { + c.ImGui_DestroyContext (null); + } +}; + +pub const Col = struct +{ + pub const WindowBg = c.ImGuiCol_WindowBg; +}; + +pub const DrawData = struct +{ + pub fn get () *c.ImDrawData + { + return &(c.ImGui_GetDrawData ().*); + } +}; + +pub const Ex = struct +{ + pub fn button (label: [] const u8, size: imgui.Vec2) bool + { + return c.ImGui_ButtonEx (label.ptr, size); + } + + pub fn sameline (offset_from_start_x: f32, spacing: f32) void + { + c.ImGui_SameLineEx (offset_from_start_x, spacing); + } +}; + +pub const Frame = struct +{ + pub fn new () void + { + c.ImGui_NewFrame (); + } +}; + +pub const IO = struct +{ + pub fn get () *const c.ImGuiIO + { + return &(c.ImGui_GetIO ().*); + } +}; + +pub const NextWindow = struct +{ + pub const Pos = struct + { + pub const Ex = struct + { + pub fn set (pos: imgui.Vec2, cond: imgui.Cond, pivot: imgui.Vec2) void + { + c.ImGui_SetNextWindowPosEx (pos, cond, pivot); + } + }; + }; + + pub const Size = struct + { + pub fn set (size: imgui.Vec2, cond: imgui.Cond) void + { + c.ImGui_SetNextWindowSize (size, cond); + } + }; +}; + +pub const Style = @import ("style").Style; + +pub const Vec2 = c.ImVec2; + +pub const Window = struct +{ + //pub const Flags = c.ImGuiWindowFlags_; + pub const Flags = i32; + + pub const Bit = enum (imgui.Window.Flags) + { + NO_COLLAPSE = c.ImGuiWindowFlags_NoCollapse, + NO_MOVE = c.ImGuiWindowFlags_NoMove, + NO_RESIZE = c.ImGuiWindowFlags_NoResize, + NO_TITLE_BAR = c.ImGuiWindowFlags_NoTitleBar, + }; +}; + +pub fn begin (name: [] const u8, p_open: ?*bool, flags: imgui.Window.Flags) !void +{ + if (!c.ImGui_Begin (name.ptr, p_open, flags)) return error.ImGuiBeginFailure; +} + +pub fn end () void +{ + c.ImGui_End (); +} + +pub fn render () void +{ + c.ImGui_Render (); +} + +pub fn text (allocator: std.mem.Allocator, comptime fmt: [] const u8, args: anytype) !void +{ + const str = try std.fmt.allocPrint (allocator, fmt, args); + c.ImGui_Text (str.ptr); +} diff --git a/src/binding/imgui/style.zig b/src/binding/imgui/style.zig new file mode 100644 index 0000000..4289386 --- /dev/null +++ b/src/binding/imgui/style.zig @@ -0,0 +1,45 @@ +const std = @import ("std"); +const c = @import ("c"); + +pub const Style = struct +{ + pub fn colorsDark () void + { + c.ImGui_StyleColorsDark (null); + } + + const SetterTag = enum + { + colors, + window_rounding, + }; + + const Setter = union (SetterTag) + { + colors: struct { index: usize, channel: [] const u8, value: usize, }, + window_rounding: usize, + }; + + fn zig_to_c_name (setter: Setter) [] const u8 + { + return switch (setter) + { + .colors => "Colors", + .window_rounding => "WindowRounding", + }; + } + + pub fn set (comptime setters: [] const Setter) void + { + const style = c.ImGui_GetStyle (); + + inline for (setters) |setter| + { + switch (setter) + { + .colors => |colors| @field (@field (style.*, "Colors") [colors.index], colors.channel) = colors.value, + else => |active| @field (style.*, zig_to_c_name (setter)) = @field (setter, @tagName (active)), + } + } + } +}; diff --git a/src/binding/imgui/vk.zig b/src/binding/imgui/vk.zig new file mode 100644 index 0000000..dcc7e57 --- /dev/null +++ b/src/binding/imgui/vk.zig @@ -0,0 +1,77 @@ +const std = @import ("std"); +const c = @import ("c"); +const vk = @import ("vk"); +const imgui = @import ("imgui"); + +pub const DrawData = struct +{ + pub const Ex = struct + { + pub fn render (draw_data: *c.ImDrawData, + command_buffer: vk.Command.Buffer, pipeline: vk.Pipeline) void + { + c.cImGui_ImplVulkan_RenderDrawDataEx (draw_data, + @ptrFromInt (@intFromEnum (command_buffer)), + @ptrFromInt (@intFromEnum (pipeline))); + } + }; +}; + +pub const FontsTexture = struct +{ + pub fn create () !void + { + if (!c.cImGui_ImplVulkan_CreateFontsTexture ()) return error.ImGuiVulkanCreateFontsTexture; + } +}; + +pub const Frame = struct +{ + pub fn new () void + { + c.cImGui_ImplVulkan_NewFrame (); + } +}; + +pub const InitInfo = struct +{ + Instance: vk.Instance, + PhysicalDevice: vk.PhysicalDevice, + Device: vk.Device, + QueueFamily: u32, + Queue: vk.Queue, + PipelineCache: vk.Pipeline.Cache, + DescriptorPool: vk.Descriptor.Pool, + Subpass: u32, + MinImageCount: u32, + ImageCount: u32, + MSAASamples: c_uint, + UseDynamicRendering: bool, + ColorAttachmentFormat: i32, + Allocator: [*c] const vk.AllocationCallbacks, + CheckVkResultFn: ?*const fn (c_int) callconv (vk.call_conv) void, +}; + +fn loader (function_name: [*c] const u8, instance: ?*anyopaque) + callconv (vk.call_conv) ?*const fn () callconv (vk.call_conv) void +{ + return c.glfwGetInstanceProcAddress (if (instance) |v| @as (c.VkInstance, + @ptrCast (v)) else null, function_name); +} + +pub fn load () !void +{ + if (!c.cImGui_ImplVulkan_LoadFunctions (loader)) + return error.ImGuiVulkanLoadFunctionsFailure; +} + +pub fn init (init_info: *imgui.vk.InitInfo) !void +{ + if (!c.cImGui_ImplVulkan_Init (@ptrCast (init_info))) + return error.ImGuiVulkanInitFailure; +} + +pub fn shutdown () void +{ + c.cImGui_ImplVulkan_Shutdown (); +} diff --git a/src/logger.zig b/src/logger.zig index 5362476..356bd51 100644 --- a/src/logger.zig +++ b/src/logger.zig @@ -79,6 +79,7 @@ pub const Logger = struct if (Logger.build.profile.gt (.TURBO)) { + std.debug.print ("{s}\n", .{Logger.build.path}); try create_file (Logger.build.path); self.file = try std.fs.openFileAbsolute (Logger.build.path, .{ .mode = .write_only, });