switch from capy to sokol + imgui
This commit is contained in:
		
							parent
							
								
									10f3c25f80
								
							
						
					
					
						commit
						683756900c
					
				
					 6 changed files with 252 additions and 44 deletions
				
			
		
							
								
								
									
										66
									
								
								3rd-party/cimgui/build.zig
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								3rd-party/cimgui/build.zig
									
										
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,66 @@
 | 
			
		|||
const std = @import("std");
 | 
			
		||||
const builtin = @import("builtin");
 | 
			
		||||
 | 
			
		||||
pub fn build(b: *std.Build) void {
 | 
			
		||||
    const target = b.standardTargetOptions(.{});
 | 
			
		||||
    const optimize = b.standardOptimizeOption(.{});
 | 
			
		||||
 | 
			
		||||
    const dep_cimgui = b.dependency("cimgui", .{});
 | 
			
		||||
    const dep_imgui = b.dependency("imgui", .{});
 | 
			
		||||
 | 
			
		||||
    // create file tree for cimgui and imgui
 | 
			
		||||
    const wf = b.addNamedWriteFiles("cimgui");
 | 
			
		||||
    _ = wf.addCopyDirectory(dep_cimgui.path(""), "", .{});
 | 
			
		||||
    _ = wf.addCopyDirectory(dep_imgui.path(""), "imgui", .{});
 | 
			
		||||
    const root = wf.getDirectory();
 | 
			
		||||
 | 
			
		||||
    // build cimgui as C/C++ library
 | 
			
		||||
    const lib_cimgui = b.addStaticLibrary(.{
 | 
			
		||||
        .name = "cimgui_clib",
 | 
			
		||||
        .target = target,
 | 
			
		||||
        .optimize = optimize,
 | 
			
		||||
        .link_libc = true,
 | 
			
		||||
    });
 | 
			
		||||
    lib_cimgui.linkLibCpp();
 | 
			
		||||
    lib_cimgui.addCSourceFiles(.{
 | 
			
		||||
        .root = root,
 | 
			
		||||
        .files = &.{
 | 
			
		||||
            b.pathJoin(&.{"cimgui.cpp"}),
 | 
			
		||||
            b.pathJoin(&.{ "imgui", "imgui.cpp" }),
 | 
			
		||||
            b.pathJoin(&.{ "imgui", "imgui_widgets.cpp" }),
 | 
			
		||||
            b.pathJoin(&.{ "imgui", "imgui_draw.cpp" }),
 | 
			
		||||
            b.pathJoin(&.{ "imgui", "imgui_tables.cpp" }),
 | 
			
		||||
            b.pathJoin(&.{ "imgui", "imgui_demo.cpp" }),
 | 
			
		||||
        },
 | 
			
		||||
    });
 | 
			
		||||
    lib_cimgui.addIncludePath(root);
 | 
			
		||||
 | 
			
		||||
    // make cimgui available as artifact, this then allows to inject
 | 
			
		||||
    // the Emscripten include path in another build.zig
 | 
			
		||||
    b.installArtifact(lib_cimgui);
 | 
			
		||||
 | 
			
		||||
    // lib compilation depends on file tree
 | 
			
		||||
    lib_cimgui.step.dependOn(&wf.step);
 | 
			
		||||
 | 
			
		||||
    // translate-c the cimgui.h file
 | 
			
		||||
    // NOTE: always run this with the host target, that way we don't need to inject
 | 
			
		||||
    // the Emscripten SDK include path into the translate-C step when building for WASM
 | 
			
		||||
    const cimgui_h = dep_cimgui.path("cimgui.h");
 | 
			
		||||
    const translateC = b.addTranslateC(.{
 | 
			
		||||
        .root_source_file = cimgui_h,
 | 
			
		||||
        .target = b.host,
 | 
			
		||||
        .optimize = optimize,
 | 
			
		||||
    });
 | 
			
		||||
    translateC.defineCMacroRaw("CIMGUI_DEFINE_ENUMS_AND_STRUCTS=\"\"");
 | 
			
		||||
    const entrypoint = translateC.getOutput();
 | 
			
		||||
 | 
			
		||||
    // build cimgui as a module with the header file as the entrypoint
 | 
			
		||||
    const mod_cimgui = b.addModule("cimgui", .{
 | 
			
		||||
        .root_source_file = entrypoint,
 | 
			
		||||
        .target = target,
 | 
			
		||||
        .optimize = optimize,
 | 
			
		||||
        .link_libc = true,
 | 
			
		||||
        .link_libcpp = true,
 | 
			
		||||
    });
 | 
			
		||||
    mod_cimgui.linkLibrary(lib_cimgui);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										18
									
								
								3rd-party/cimgui/build.zig.zon
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								3rd-party/cimgui/build.zig.zon
									
										
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,18 @@
 | 
			
		|||
.{
 | 
			
		||||
    .name = "cimgui",
 | 
			
		||||
    .version = "0.0.0",
 | 
			
		||||
 | 
			
		||||
    .dependencies = .{
 | 
			
		||||
        .cimgui = .{
 | 
			
		||||
            .url = "git+https://github.com/cimgui/cimgui.git#1.90.7",
 | 
			
		||||
            .hash = "1220d925a8374fbc3a21a5b46025fb867672d85b4099d2151bed607618e08b0cd71c",
 | 
			
		||||
        },
 | 
			
		||||
        .imgui = .{
 | 
			
		||||
            .url = "git+https://github.com/ocornut/imgui.git#v1.90.7",
 | 
			
		||||
            .hash = "122072b125179c7cbdbbee8fa81d22a1050a950ad61cfeefee8dc0dca5423b5d05b9",
 | 
			
		||||
        },
 | 
			
		||||
    },
 | 
			
		||||
    .paths = .{
 | 
			
		||||
        "",
 | 
			
		||||
    },
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										102
									
								
								build.zig
									
										
									
									
									
								
							
							
						
						
									
										102
									
								
								build.zig
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,30 +1,90 @@
 | 
			
		|||
const std = @import("std");
 | 
			
		||||
const capy = @import("capy");
 | 
			
		||||
const Build = std.Build;
 | 
			
		||||
const OptimizeMode = std.builtin.OptimizeMode;
 | 
			
		||||
const ResolvedTarget = Build.ResolvedTarget;
 | 
			
		||||
const Dependency = Build.Dependency;
 | 
			
		||||
const sokol = @import("sokol");
 | 
			
		||||
 | 
			
		||||
pub fn build(b: *std.Build) !void {
 | 
			
		||||
pub fn build(b: *Build) !void {
 | 
			
		||||
    const target = b.standardTargetOptions(.{});
 | 
			
		||||
    const mode = b.standardOptimizeOption(.{});
 | 
			
		||||
    const optimize = b.standardOptimizeOption(.{});
 | 
			
		||||
 | 
			
		||||
    const exe = b.addExecutable(.{
 | 
			
		||||
        .name = "doggo",
 | 
			
		||||
        .root_source_file = .{ .path = "src/main.zig" },
 | 
			
		||||
    // note that the sokol dependency is built with `.with_imgui_sokol = true`
 | 
			
		||||
    const dep_sokol = b.dependency("sokol", .{
 | 
			
		||||
        .target = target,
 | 
			
		||||
        .optimize = mode,
 | 
			
		||||
        .optimize = optimize,
 | 
			
		||||
        .with_sokol_imgui = true,
 | 
			
		||||
    });
 | 
			
		||||
    const dep_cimgui = b.dependency("cimgui", .{
 | 
			
		||||
        .target = target,
 | 
			
		||||
        .optimize = optimize,
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    b.installArtifact(exe);
 | 
			
		||||
    // inject the cimgui header search path into the sokol C library compile step
 | 
			
		||||
    const cimgui_root = dep_cimgui.namedWriteFiles("cimgui").getDirectory();
 | 
			
		||||
    dep_sokol.artifact("sokol_clib").addIncludePath(cimgui_root);
 | 
			
		||||
 | 
			
		||||
    const run_cmd = try capy.install(exe, .{ .args = b.args });
 | 
			
		||||
 | 
			
		||||
    const run_step = b.step("run", "Run the app");
 | 
			
		||||
    run_step.dependOn(run_cmd);
 | 
			
		||||
 | 
			
		||||
    const exe_tests = b.addTest(.{
 | 
			
		||||
        .root_source_file = .{ .path = "src/main.zig" },
 | 
			
		||||
        .target = target,
 | 
			
		||||
        .optimize = mode,
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    const test_step = b.step("test", "Run unit tests");
 | 
			
		||||
    test_step.dependOn(&exe_tests.step);
 | 
			
		||||
    // from here on different handling for native vs wasm builds
 | 
			
		||||
    if (target.result.isWasm()) {
 | 
			
		||||
        try buildWasm(b, target, optimize, dep_sokol, dep_cimgui);
 | 
			
		||||
    } else {
 | 
			
		||||
        try buildNative(b, target, optimize, dep_sokol, dep_cimgui);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn buildNative(b: *Build, target: ResolvedTarget, optimize: OptimizeMode, dep_sokol: *Dependency, dep_cimgui: *Dependency) !void {
 | 
			
		||||
    const demo = b.addExecutable(.{
 | 
			
		||||
        .name = "demo",
 | 
			
		||||
        .root_source_file = b.path("src/main.zig"),
 | 
			
		||||
        .target = target,
 | 
			
		||||
        .optimize = optimize,
 | 
			
		||||
    });
 | 
			
		||||
    demo.root_module.addImport("sokol", dep_sokol.module("sokol"));
 | 
			
		||||
    demo.root_module.addImport("cimgui", dep_cimgui.module("cimgui"));
 | 
			
		||||
    b.installArtifact(demo);
 | 
			
		||||
    b.step("run", "Run demo").dependOn(&b.addRunArtifact(demo).step);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn buildWasm(b: *Build, target: ResolvedTarget, optimize: OptimizeMode, dep_sokol: *Dependency, dep_cimgui: *Dependency) !void {
 | 
			
		||||
    // build the main file into a library, this is because the WASM 'exe'
 | 
			
		||||
    // needs to be linked in a separate build step with the Emscripten linker
 | 
			
		||||
    const demo = b.addStaticLibrary(.{
 | 
			
		||||
        .name = "demo",
 | 
			
		||||
        .root_source_file = b.path("src/main.zig"),
 | 
			
		||||
        .target = target,
 | 
			
		||||
        .optimize = optimize,
 | 
			
		||||
    });
 | 
			
		||||
    demo.root_module.addImport("sokol", dep_sokol.module("sokol"));
 | 
			
		||||
    demo.root_module.addImport("cimgui", dep_cimgui.module("cimgui"));
 | 
			
		||||
 | 
			
		||||
    // get the Emscripten SDK dependency from the sokol dependency
 | 
			
		||||
    const dep_emsdk = dep_sokol.builder.dependency("emsdk", .{});
 | 
			
		||||
 | 
			
		||||
    // need to inject the Emscripten system header include path into
 | 
			
		||||
    // the cimgui C library otherwise the C/C++ code won't find
 | 
			
		||||
    // C stdlib headers
 | 
			
		||||
    const emsdk_incl_path = dep_emsdk.path("upstream/emscripten/cache/sysroot/include");
 | 
			
		||||
    dep_cimgui.artifact("cimgui_clib").addSystemIncludePath(emsdk_incl_path);
 | 
			
		||||
 | 
			
		||||
    // all C libraries need to depend on the sokol library, when building for
 | 
			
		||||
    // WASM this makes sure that the Emscripten SDK has been setup before
 | 
			
		||||
    // C compilation is attempted (since the sokol C library depends on the
 | 
			
		||||
    // Emscripten SDK setup step)
 | 
			
		||||
    dep_cimgui.artifact("cimgui_clib").step.dependOn(&dep_sokol.artifact("sokol_clib").step);
 | 
			
		||||
 | 
			
		||||
    // create a build step which invokes the Emscripten linker
 | 
			
		||||
    const link_step = try sokol.emLinkStep(b, .{
 | 
			
		||||
        .lib_main = demo,
 | 
			
		||||
        .target = target,
 | 
			
		||||
        .optimize = optimize,
 | 
			
		||||
        .emsdk = dep_emsdk,
 | 
			
		||||
        .use_webgl2 = true,
 | 
			
		||||
        .use_emmalloc = true,
 | 
			
		||||
        .use_filesystem = false,
 | 
			
		||||
        .shell_file_path = dep_sokol.path("src/sokol/web/shell.html").getPath(b),
 | 
			
		||||
    });
 | 
			
		||||
    // ...and a special run step to start the web build output via 'emrun'
 | 
			
		||||
    const run = sokol.emRunStep(b, .{ .name = "demo", .emsdk = dep_emsdk });
 | 
			
		||||
    run.step.dependOn(&link_step.step);
 | 
			
		||||
    b.step("run", "Run demo").dependOn(&run.step);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,13 +7,12 @@
 | 
			
		|||
        "src",
 | 
			
		||||
    },
 | 
			
		||||
    .dependencies = .{
 | 
			
		||||
        .capy = .{
 | 
			
		||||
            .url = "https://github.com/ffreling/capy/archive/refs/heads/zig-0.12.0.tar.gz",
 | 
			
		||||
            .hash = "12207fd2f0d02eb929d1e8a05843de4dc3f4b362055e9e47a014fb6b806a592d9808",
 | 
			
		||||
        .sokol = .{
 | 
			
		||||
            .url = "git+https://github.com/floooh/sokol-zig.git#d9f3ef983b7021417cc91bd5788cd925ca06aa83",
 | 
			
		||||
            .hash = "12200a472b4f1a3a6db1002f39f10ae0cccf58ada45bf25ddc5fd48384dd187f55ea",
 | 
			
		||||
        },
 | 
			
		||||
        .zigimg = .{
 | 
			
		||||
            .url = "https://github.com/zigimg/zigimg/archive/8873f29fc449e1b63400e9f4ad86d3c76204f962.tar.gz",
 | 
			
		||||
            .hash = "122019f6439545235af116d0d8eb81fde1ff05fdb070da57c723772c557f84c5bf39",
 | 
			
		||||
        .cimgui = .{
 | 
			
		||||
            .path = "3rd-party/cimgui",
 | 
			
		||||
        },
 | 
			
		||||
    },
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										10
									
								
								flake.nix
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								flake.nix
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -12,7 +12,15 @@
 | 
			
		|||
            zls
 | 
			
		||||
          ];
 | 
			
		||||
          buildInputs = [
 | 
			
		||||
            gtk4
 | 
			
		||||
            alsa-lib
 | 
			
		||||
            xorg.libX11
 | 
			
		||||
            xorg.libXcursor
 | 
			
		||||
            xorg.libXi
 | 
			
		||||
            xorg.libXext
 | 
			
		||||
            xorg.libXrandr
 | 
			
		||||
            xorg.libXinerama
 | 
			
		||||
            libGL
 | 
			
		||||
            libGLU
 | 
			
		||||
          ];
 | 
			
		||||
        };
 | 
			
		||||
  };
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										89
									
								
								src/main.zig
									
										
									
									
									
								
							
							
						
						
									
										89
									
								
								src/main.zig
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,20 +1,77 @@
 | 
			
		|||
const std = @import("std");
 | 
			
		||||
const capy = @import("capy");
 | 
			
		||||
const ig = @import("cimgui");
 | 
			
		||||
const sokol = @import("sokol");
 | 
			
		||||
const slog = sokol.log;
 | 
			
		||||
const sg = sokol.gfx;
 | 
			
		||||
const sapp = sokol.app;
 | 
			
		||||
const sglue = sokol.glue;
 | 
			
		||||
const simgui = sokol.imgui;
 | 
			
		||||
 | 
			
		||||
// This is required for your app to build to WebAssembly and other particular architectures
 | 
			
		||||
pub usingnamespace capy.cross_platform;
 | 
			
		||||
const state = struct {
 | 
			
		||||
    var pass_action: sg.PassAction = .{};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub fn main() !void {
 | 
			
		||||
    try capy.backend.init();
 | 
			
		||||
export fn init() void {
 | 
			
		||||
    // initialize sokol-gfx
 | 
			
		||||
    sg.setup(.{
 | 
			
		||||
        .environment = sglue.environment(),
 | 
			
		||||
        .logger = .{ .func = slog.func },
 | 
			
		||||
    });
 | 
			
		||||
    // initialize sokol-imgui
 | 
			
		||||
    simgui.setup(.{
 | 
			
		||||
        .logger = .{ .func = slog.func },
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    var window = try capy.Window.init();
 | 
			
		||||
    try window.set(
 | 
			
		||||
        capy.label(.{ .text = "Hello, World", .alignment = .Center }),
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    window.setTitle("Hello");
 | 
			
		||||
    window.setPreferredSize(250, 100);
 | 
			
		||||
    window.show();
 | 
			
		||||
 | 
			
		||||
    capy.runEventLoop();
 | 
			
		||||
    // initial clear color
 | 
			
		||||
    state.pass_action.colors[0] = .{
 | 
			
		||||
        .load_action = .CLEAR,
 | 
			
		||||
        .clear_value = .{ .r = 0.0, .g = 0.5, .b = 1.0, .a = 1.0 },
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export fn frame() void {
 | 
			
		||||
    // call simgui.newFrame() before any ImGui calls
 | 
			
		||||
    simgui.newFrame(.{
 | 
			
		||||
        .width = sapp.width(),
 | 
			
		||||
        .height = sapp.height(),
 | 
			
		||||
        .delta_time = sapp.frameDuration(),
 | 
			
		||||
        .dpi_scale = sapp.dpiScale(),
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    //=== UI CODE STARTS HERE
 | 
			
		||||
    ig.igSetNextWindowPos(.{ .x = 10, .y = 10 }, ig.ImGuiCond_Once, .{ .x = 0, .y = 0 });
 | 
			
		||||
    ig.igSetNextWindowSize(.{ .x = 400, .y = 100 }, ig.ImGuiCond_Once);
 | 
			
		||||
    _ = ig.igBegin("Hello Dear ImGui!", 0, ig.ImGuiWindowFlags_None);
 | 
			
		||||
    _ = ig.igColorEdit3("Background", &state.pass_action.colors[0].clear_value.r, ig.ImGuiColorEditFlags_None);
 | 
			
		||||
    ig.igEnd();
 | 
			
		||||
    //=== UI CODE ENDS HERE
 | 
			
		||||
 | 
			
		||||
    // call simgui.render() inside a sokol-gfx pass
 | 
			
		||||
    sg.beginPass(.{ .action = state.pass_action, .swapchain = sglue.swapchain() });
 | 
			
		||||
    simgui.render();
 | 
			
		||||
    sg.endPass();
 | 
			
		||||
    sg.commit();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export fn cleanup() void {
 | 
			
		||||
    simgui.shutdown();
 | 
			
		||||
    sg.shutdown();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export fn event(ev: [*c]const sapp.Event) void {
 | 
			
		||||
    // forward input events to sokol-imgui
 | 
			
		||||
    _ = simgui.handleEvent(ev.*);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn main() void {
 | 
			
		||||
    sapp.run(.{
 | 
			
		||||
        .init_cb = init,
 | 
			
		||||
        .frame_cb = frame,
 | 
			
		||||
        .cleanup_cb = cleanup,
 | 
			
		||||
        .event_cb = event,
 | 
			
		||||
        .window_title = "sokol-zig + Dear Imgui",
 | 
			
		||||
        .width = 800,
 | 
			
		||||
        .height = 600,
 | 
			
		||||
        .icon = .{ .sokol_default = true },
 | 
			
		||||
        .logger = .{ .func = slog.func },
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue