126 lines
3.7 KiB
Zig
126 lines
3.7 KiB
Zig
//! all imgui code through this path
|
|
|
|
const std = @import("std");
|
|
|
|
const vk = @import("vk");
|
|
const nu = @import("../nu.zig");
|
|
const au = @import("Render/au.zig");
|
|
|
|
const Hook = @import("hooks.zig").Hook;
|
|
const Render = @import("Render.zig");
|
|
const Window = @import("Window.zig");
|
|
|
|
const im = @import("cimgui");
|
|
pub usingnamespace im;
|
|
|
|
pub const Options = struct {};
|
|
|
|
pub const Hooks = struct {
|
|
pub const Frame = Hook(fn () void);
|
|
frame: Frame,
|
|
};
|
|
|
|
pub fn loader_wrapper(procname: [*c]const u8, _: ?*anyopaque) callconv(.C) vk.PfnVoidFunction {
|
|
return au.glfwGetInstanceProcAddress(au.I.handle, procname);
|
|
}
|
|
|
|
var ctx: *im.ImGuiContext = undefined;
|
|
var descriptor_pool: vk.DescriptorPool = undefined;
|
|
|
|
pub var hooks: Hooks = undefined;
|
|
|
|
pub fn init(alloc: std.mem.Allocator) !void {
|
|
ctx = im.igCreateContext(null) orelse {
|
|
return error.igCreateContextFailed;
|
|
};
|
|
errdefer im.igDestroyContext(ctx);
|
|
|
|
if (!im.impl.ImGui_ImplVulkan_LoadFunctions(loader_wrapper, null)) {
|
|
return error.igVulkanLoadFunctionsFailed;
|
|
}
|
|
|
|
if (!im.impl.ImGui_ImplGlfw_InitForVulkan(@ptrCast(Window.handle), true)) {
|
|
return error.igGlfwInitFailed;
|
|
}
|
|
errdefer im.impl.ImGui_ImplGlfw_Shutdown();
|
|
|
|
descriptor_pool = try au.D.createDescriptorPool(&vk.DescriptorPoolCreateInfo{
|
|
.flags = .{ .free_descriptor_set_bit = true },
|
|
.pool_size_count = 1,
|
|
.p_pool_sizes = &.{vk.DescriptorPoolSize{
|
|
.descriptor_count = 32,
|
|
.type = .combined_image_sampler,
|
|
}},
|
|
.max_sets = 32,
|
|
}, null);
|
|
errdefer au.D.destroyDescriptorPool(descriptor_pool, null);
|
|
|
|
if (im.impl.ImGui_ImplVulkan_Init(@constCast(&im.impl.ImGui_ImplVulkan_InitInfo{
|
|
.Instance = @ptrFromInt(@intFromEnum(au.I.handle)),
|
|
.PhysicalDevice = @ptrFromInt(@intFromEnum(au.device_config.pdev)),
|
|
.Device = @ptrFromInt(@intFromEnum(au.D.handle)),
|
|
.QueueFamily = au.device_config.family,
|
|
.Queue = @ptrFromInt(@intFromEnum(au.Q.handle)),
|
|
.DescriptorPool = @ptrFromInt(@intFromEnum(descriptor_pool)),
|
|
.RenderPass = null,
|
|
.MinImageCount = 2,
|
|
.ImageCount = @intCast(nu.options.render.frames_in_flight),
|
|
.PipelineRenderingCreateInfo = @bitCast(vk.PipelineRenderingCreateInfo{
|
|
.view_mask = 0,
|
|
.depth_attachment_format = .undefined,
|
|
.stencil_attachment_format = .undefined,
|
|
.color_attachment_count = 1,
|
|
.p_color_attachment_formats = &.{au.device_config.format.format},
|
|
}),
|
|
.MSAASamples = 0,
|
|
.PipelineCache = null,
|
|
.Subpass = 0,
|
|
.UseDynamicRendering = true,
|
|
.Allocator = null,
|
|
})) != true) {
|
|
return error.igVulkanInitFailed;
|
|
}
|
|
errdefer im.impl.ImGui_ImplVulkan_Shutdown();
|
|
|
|
if (!im.impl.ImGui_ImplVulkan_CreateFontsTexture()) {
|
|
return error.igVulkanFontTextureFailed;
|
|
}
|
|
|
|
hooks = .{
|
|
.frame = Hooks.Frame.init(alloc),
|
|
};
|
|
errdefer hooks.frame.deinit();
|
|
}
|
|
|
|
pub fn deinit() void {
|
|
hooks.frame.deinit();
|
|
im.impl.ImGui_ImplVulkan_Shutdown();
|
|
au.D.destroyDescriptorPool(descriptor_pool, null);
|
|
im.impl.ImGui_ImplGlfw_Shutdown();
|
|
im.igDestroyContext(ctx);
|
|
}
|
|
|
|
pub fn connect() !void {
|
|
try nu.hooks.frame.register(nu_frame);
|
|
try Render.hooks.present.register(nu_render_present);
|
|
}
|
|
|
|
pub fn nu_frame() !void {
|
|
im.impl.ImGui_ImplGlfw_NewFrame();
|
|
im.impl.ImGui_ImplVulkan_NewFrame();
|
|
im.igNewFrame();
|
|
|
|
hooks.frame.invoke(.{});
|
|
|
|
im.igEndFrame();
|
|
im.igRender();
|
|
}
|
|
|
|
pub fn nu_render_present(cmd: au.CommandBufferProxy) void {
|
|
im.impl.ImGui_ImplVulkan_RenderDrawData(
|
|
@ptrCast(im.igGetDrawData()),
|
|
@ptrFromInt(@intFromEnum(cmd.handle)),
|
|
null,
|
|
);
|
|
}
|