Skip to content

Instantly share code, notes, and snippets.

@wilba
Last active October 7, 2025 09:24
Show Gist options
  • Select an option

  • Save wilba/b6405bbbde974bd7473fdbb719ca2b64 to your computer and use it in GitHub Desktop.

Select an option

Save wilba/b6405bbbde974bd7473fdbb719ca2b64 to your computer and use it in GitHub Desktop.
IMGUI WITH ZIG-SDL3

IMGUI WITH ZIG-SDL3

  imgui_demo.cpp
  imgui_draw.cpp
  imgui_internal.h
  imgui_tables.cpp
  imgui_widgets.cpp
  imgui.cpp
  imgui.h
  imstb_rectpack.h
  imstb_textedit.h
  imstb_truetype.h
  imconfig.h
  /backends/imgui_impl_sdl3.cpp
  /backends/imgui_impl_sdl3.h
  /backends/imgui_impl_sdlrenderer3.cpp
  /backends/imgui_impl_sdlrenderer3.h
  • copy Dear Bindings source files to /zig-sdl3-project/lib/imgui
  dcimgui.h
  dcimgui.cpp
  dcimgui_internal.h
  dcimgui_internal.cpp
  backends/dcimgui_impl_sdlrenderer3.h
  backends/dcimgui_impl_sdlrenderer3.cpp
  backends/dcimgui_impl_sdl3.h
  backends/dcimgui_impl_sdl3.cpp
  • change build.zon to add explicit dependency on SDL3, separate from zig-sdl3
    .dependencies = .{
        .sdl = .{
            .url = "git+https://github.com/castholm/SDL.git#1994ca5dbad5a3e3c670a9ab8533d86cfd97bdc0",
            .hash = "sdl-0.2.6+3.2.20-7uIn9NgjfwHH5a6HhyLHat2nHU3OP5B05QHhKJKuxEex",
        },
        .sdl3 = .{
            .url = "git+https://github.com/Gota7/zig-sdl3?ref=v0.1.1#694ffacd7c2c0b83aaa7a9bb1e279d7b39ea9aee",
            .hash = "sdl3-0.1.1-NmT1QwTgIADixpCS2g5pBBON5AEfnjOox94dU0dtT-tq",
        },
    },
  • change your project's build.zig to build the imgui source
const std = @import("std");

pub fn build(b: *std.Build) void {
    const target = b.standardTargetOptions(.{});
    const optimize = b.standardOptimizeOption(.{});

    const exe_mod = b.createModule(.{
        .root_source_file = b.path("src/main.zig"),
        .target = target,
        .optimize = optimize,
        .link_libcpp = true, // imgui needs this
    });
    const exe = b.addExecutable(.{
        .name = "your-project",
        .root_module = exe_mod,
    });

    const sdl3 = b.dependency("sdl3", .{
        .target = target,
        .optimize = optimize,
        .callbacks = true,
        .ext_image = true,
    });
    exe.root_module.addImport("sdl3", sdl3.module("sdl3"));
    b.installArtifact(exe);

    const imgui_c_srcs = .{
        "lib/imgui/dcimgui_impl_sdl3.cpp",
        "lib/imgui/dcimgui_impl_sdlrenderer3.cpp",
        "lib/imgui/dcimgui_internal.cpp",
        "lib/imgui/dcimgui.cpp",
        "lib/imgui/imgui_demo.cpp",
        "lib/imgui/imgui_draw.cpp",
        "lib/imgui/imgui_tables.cpp",
        "lib/imgui/imgui_widgets.cpp",
        "lib/imgui/imgui.cpp",
        "lib/imgui/imgui_impl_sdl3.cpp",
        "lib/imgui/imgui_impl_sdlrenderer3.cpp",
    };
    inline for (imgui_c_srcs) |src| {
        exe.root_module.addCSourceFile(.{ .file = b.path(src), .flags = &.{} });
    }
    exe.root_module.addIncludePath(b.path("lib/imgui"));

    // imgui (using SDL3 renderer) needs to include SDL3 headers and link to SDL3.
    // Note: this is *not* zig-sdl3
    const sdl_dep = b.dependency("sdl", .{
        .target = target,
        .optimize = optimize,
        .lto = optimize != .Debug,
    });
    exe.root_module.addIncludePath(sdl_dep.path("include"));

    const run_cmd = b.addRunArtifact(exe);
    run_cmd.step.dependOn(b.getInstallStep());

    if (b.args) |args| {
        run_cmd.addArgs(args);
    }

    const run_step = b.step("run", "Run the app");
    run_step.dependOn(&run_cmd.step);

    const exe_unit_tests = b.addTest(.{
        .root_module = exe_mod,
    });

    const run_exe_unit_tests = b.addRunArtifact(exe_unit_tests);

    const test_step = b.step("test", "Run unit tests");
    test_step.dependOn(&run_exe_unit_tests.step);
}
  • change your project's main.zig to integrate imgui

    Shown relative to the zig-sdl3 template.

    • include
    const im = @cImport({
        @cInclude("dcimgui.h");
        @cInclude("dcimgui_impl_sdl3.h");
        @cInclude("dcimgui_impl_sdlrenderer3.h");
    });
    • init()
    _ = im.ImGui_CreateContext(null);
    var io: *im.struct_ImGuiIO_t = im.ImGui_GetIO();
    io.ConfigFlags |= im.ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
    io.ConfigFlags |= im.ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
    im.ImGui_StyleColorsDark(null);
    _ = im.cImGui_ImplSDL3_InitForSDLRenderer(@ptrCast(window.value), @ptrCast(renderer.value));
    _ = im.cImGui_ImplSDLRenderer3_Init(@ptrCast(renderer.value));
    • iterate()
    im.cImGui_ImplSDLRenderer3_NewFrame();
    im.cImGui_ImplSDL3_NewFrame();
    im.ImGui_NewFrame();
    
    if (ui_show_demo_window) {
        im.ImGui_ShowDemoWindow(&ui_show_demo_window);
    }
    
    im.ImGui_Render();
    im.cImGui_ImplSDLRenderer3_RenderDrawData(
        im.ImGui_GetDrawData(),
        @ptrCast(app_state.renderer.value),
    );
    try app_state.renderer.present();
    • event()
    const _curr_event = curr_event.toSdl();
    _ = im.cImGui_ImplSDL3_ProcessEvent(@ptrCast(&_curr_event));
    
    const io: *im.struct_ImGuiIO_t = im.ImGui_GetIO();
    if (!io.WantCaptureMouse and !io.WantTextInput) {
        // Not hovered on ImGui, process mouse/keyboard
    }
    
    // process window resized, terminating, quit, etc.
    • quit()
    im.cImGui_ImplSDLRenderer3_Shutdown();
    im.cImGui_ImplSDL3_Shutdown();
    im.ImGui_DestroyContext(null);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment