NYXGFX/examples/imgui/imgui.zig

192 lines
5.6 KiB
Zig
Raw Permalink Normal View History

//! ----------------------------------------------------
//! SDL3 + Vulkan
//!
//! Used dear_bindings with docking imgui branch
//! https://mrscriptx.github.io/devlog/zig/2025/04/30/zig-linking-dear-imgui.html
//! ----------------------------------------------------
const im = @import("imgui");
const im_vk = @import("imgui_impl_vulkan");
const im_sdl = @import("imgui_impl_sdl3");
const std = @import("std");
const sdl = @import("sdl");
const Gfx = @import("gfx");
pub fn main(init: std.process.Init) !void {
//
// SDL
//
// --- # ---
if (!sdl.SDL_Init(sdl.SDL_INIT_VIDEO)) return error.FailedToInitSDL;
defer sdl.SDL_Quit();
// --- # ---
const window = sdl.SDL_CreateWindow("NYXGFX", 800, 600, sdl.SDL_WINDOW_VULKAN) orelse return error.FailedTomakeWindow;
defer sdl.SDL_DestroyWindow(window);
// --- # ---
const props = sdl.SDL_GetWindowProperties(window);
const display = sdl.SDL_GetPointerProperty(props, sdl.SDL_PROP_WINDOW_X11_DISPLAY_POINTER, null);
const xwindow = sdl.SDL_GetNumberProperty(props, sdl.SDL_PROP_WINDOW_X11_WINDOW_NUMBER, 0);
//
// GFX
//
2026-08-19 14:47:03 +01:00
var gfx: Gfx = try .init(init.gpa, init.io);
defer gfx.deinit();
const instance = try gfx.makeInstance(.{
.vulkan = .{},
});
const surface = try gfx.makeSurface(.{
2026-08-19 14:47:03 +01:00
.window = .{
.xlib = .{
.window = @intCast(xwindow),
.display = display.?,
},
},
2026-08-19 14:47:03 +01:00
.instance = instance,
});
const adapter = try gfx.makeAdapter(.{
.instance = instance,
});
const device = try gfx.makeDevice(.{
.instance = instance,
.adapter = adapter,
.surface = surface,
});
2026-08-19 14:47:03 +01:00
const swapchain = try gfx.makeSwapchain(.{
.format = .rgba8_unorm,
.surface = surface,
.adapter = adapter,
.device = device,
});
//
// IMGUI
//
// --- CREATE IMGUI CTX ---
const ctx = im.ImGui_CreateContext(null) orelse return error.FailedToCreateImGuiContext;
defer im.ImGui_DestroyContext(ctx);
// --- INIT IMGUI FOR SDL3 + VK ---
if (!im_sdl.cImGui_ImplSDL3_InitForVulkan(@ptrCast(window))) return error.FailedToImplImGuiForSDL;
defer im_sdl.cImGui_ImplSDL3_Shutdown();
// --- SET IO ---
const io = im.ImGui_GetIO() orelse return error.FailedToGetImGuiIO;
io.*.ConfigFlags |= im.ImGuiConfigFlags_NavEnableKeyboard;
io.*.ConfigFlags |= im.ImGuiConfigFlags_DockingEnable;
// --- GET VK RAW DEVICE ---
const raw_device = switch (try gfx.getRawDevice(device)) {
.vulkan => |v| v,
};
// --- GET VK RAW SWAPCHAIN ---
const raw_swapchain = try gfx.getRawSwapchain(swapchain);
// --- INIT IMGUI FOR VK ---
var color_format: im_vk.VkFormat = raw_swapchain.format;
var im_info: im_vk.ImGui_ImplVulkan_InitInfo = .{
.Instance = @ptrCast((try gfx.getRawInstance(instance)).vulkan),
.PhysicalDevice = blk: {
switch (try gfx.getRawAdapter(adapter)) {
.vulkan => |v| break :blk @ptrCast(v),
}
},
.Device = @ptrCast(raw_device.device),
.Queue = @ptrCast(raw_device.present_queue),
.DescriptorPoolSize = 1024,
.MinImageCount = 2,
.ImageCount = @intCast(raw_swapchain.images.len),
.PipelineInfoMain = .{
.MSAASamples = im_vk.VK_SAMPLE_COUNT_1_BIT,
.PipelineRenderingCreateInfo = .{
.sType = im_vk.VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR,
.colorAttachmentCount = 1,
.pColorAttachmentFormats = &color_format,
},
},
.UseDynamicRendering = true, // <--- vulkan implementation specific
};
if (!im_vk.cImGui_ImplVulkan_Init(&im_info)) return error.FailedToImplImGuiForVulkan;
defer {
_ = im_vk.vkDeviceWaitIdle(@ptrCast(raw_device.device));
im_vk.cImGui_ImplVulkan_Shutdown();
}
//
// MAIN LOOP
//
// --- MISC ---
var event: sdl.SDL_Event = undefined;
var running: bool = true;
while (running) {
// --- INPUTS ---
while (sdl.SDL_PollEvent(&event)) {
switch (event.type) {
sdl.SDL_EVENT_QUIT => running = false,
else => {},
}
_ = im_sdl.cImGui_ImplSDL3_ProcessEvent(@ptrCast(&event));
}
{ // IMGUI
// --- NEW IMGUI FRAME ---
im_sdl.cImGui_ImplSDL3_NewFrame();
im_vk.cImGui_ImplVulkan_NewFrame();
im.ImGui_NewFrame();
// --- UI ---
if (im.ImGui_Begin("Inspector", null, 0)) {
defer im.ImGui_End();
im.ImGui_Text("Hello World");
if (im.ImGui_Button("Click Me")) {}
}
// --- DEMO ---
im.ImGui_ShowDemoWindow(null);
// --- RENDER IMGUI ---
im.ImGui_Render();
}
// --- FRAME ---
try gfx.beginFrame(swapchain, device);
defer gfx.endFrame(swapchain, device) catch unreachable;
// --- NEW PASS ---
if (gfx.beginPass(swapchain, .{
.clear_color = .{ 0.01, 0.01, 0.01, 1.0 },
})) |pass| {
defer pass.end();
// --- RENDER IMGUI ---
switch (try gfx.getRawFrame()) {
.vulkan => |v| {
const draw_data = im.ImGui_GetDrawData() orelse return;
im_vk.cImGui_ImplVulkan_RenderDrawData(
@ptrCast(draw_data),
@ptrCast(v.cmd_buf),
);
},
}
}
}
}