switch from capy to sokol + imgui
This commit is contained in:
parent
10f3c25f80
commit
683756900c
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…
Reference in a new issue