From 62dab73ae6be801d37261322bd235ea1db1911e2 Mon Sep 17 00:00:00 2001 From: Interrupt Date: Sat, 12 Apr 2025 11:04:54 -0700 Subject: [PATCH 1/3] Adding ability to make imgui image ids from textures / materials --- src/examples/imgui.zig | 64 ++++++++++++++++++++++++++++- src/framework/platform/graphics.zig | 13 ++++++ 2 files changed, 76 insertions(+), 1 deletion(-) diff --git a/src/examples/imgui.zig b/src/examples/imgui.zig index 2ad59f57..8e5ba6ce 100644 --- a/src/examples/imgui.zig +++ b/src/examples/imgui.zig @@ -1,9 +1,17 @@ const delve = @import("delve"); const app = delve.app; +const graphics = delve.platform.graphics; const std = @import("std"); const imgui = delve.imgui; +const test_image_asset = @embedFile("static/test.png"); +var test_texture: graphics.Texture = undefined; +var test_material: graphics.Material = undefined; + +var imgui_texture_1: ?*anyopaque = undefined; +var imgui_texture_2: ?*anyopaque = undefined; + var gpa = std.heap.GeneralPurposeAllocator(.{}){}; // This example shows how to use Dear Imgui! @@ -13,6 +21,7 @@ const imgui_module = delve.modules.Module{ .init_fn = on_init, .tick_fn = on_tick, .draw_fn = on_draw, + .cleanup_fn = on_cleanup, }; var bg_color: [4]f32 = [4]f32{ 0.25, 0.85, 0.55, 1.0 }; @@ -40,6 +49,32 @@ pub fn registerModule() !void { pub fn on_init() !void { delve.debug.log("Imgui Example Initializing.", .{}); + + // load an image + var test_image = try delve.images.loadBytes(test_image_asset); + defer test_image.deinit(); + + // make a texture from it + test_texture = graphics.Texture.init(test_image); + + // make an imgui texture for it + imgui_texture_1 = test_texture.makeImguiTexture(); + + // make a material to use a different sampler mode + test_material = try delve.platform.graphics.Material.init(.{ + .shader = delve.platform.graphics.getDefaultShader(), + .texture_0 = test_texture, + .samplers = &[_]graphics.FilterMode{.NEAREST}, + }); + + // and make an imgui texture out of our material + imgui_texture_2 = test_material.makeImguiTexture(); +} + +fn on_cleanup() !void { + delve.debug.log("Imgui example cleaning up", .{}); + test_texture.destroy(); + test_material.deinit(); } pub fn on_tick(delta: f32) void { @@ -52,9 +87,36 @@ pub fn on_tick(delta: f32) void { delve.platform.app.startImguiFrame(); imgui.igSetNextWindowPos(.{ .x = 40, .y = 60 }, imgui.ImGuiCond_Once, .{ .x = 0, .y = 0 }); - imgui.igSetNextWindowSize(.{ .x = 400, .y = 100 }, imgui.ImGuiCond_Once); + imgui.igSetNextWindowSize(.{ .x = 400, .y = 300 }, imgui.ImGuiCond_Once); + + // start a window _ = imgui.igBegin("Hello Dear ImGui!", 0, imgui.ImGuiWindowFlags_None); + _ = imgui.igColorEdit3("Background", &bg_color[0], imgui.ImGuiColorEditFlags_None); + + _ = imgui.igSpacing(); + + _ = imgui.igImage( + imgui_texture_1, + .{ .x = 80, .y = 80 }, // size + .{ .x = 0, .y = 0 }, // u + .{ .x = 1.0, .y = 1.0 }, // v + .{ .x = 1.0, .y = 1.0, .z = 1.0, .w = 1.0 }, // tint color + .{ .x = 1.0, .y = 1.0, .z = 1.0, .w = 1.0 }, // border color + ); + + _ = imgui.igSpacing(); + + _ = imgui.igImage( + imgui_texture_2, + .{ .x = 140, .y = 140 }, // size + .{ .x = 0, .y = 0 }, // u + .{ .x = 1.0, .y = 1.0 }, // v + .{ .x = 1.0, .y = 1.0, .z = 1.0, .w = 1.0 }, // tint color + .{ .x = 1.0, .y = 1.0, .z = 1.0, .w = 1.0 }, // border color + ); + + // end the window imgui.igEnd(); delve.platform.graphics.setClearColor(delve.colors.Color.fromArray(bg_color)); diff --git a/src/framework/platform/graphics.zig b/src/framework/platform/graphics.zig index 89f96ced..b1ead430 100644 --- a/src/framework/platform/graphics.zig +++ b/src/framework/platform/graphics.zig @@ -10,6 +10,7 @@ const sokol_gfx_backend = @import("backends/sokol/graphics.zig"); const shaders = @import("../graphics/shaders.zig"); const sokol = @import("sokol"); +const simgui = sokol.imgui; const slog = sokol.log; const sg = sokol.gfx; const sapp = sokol.app; @@ -517,6 +518,12 @@ pub const Texture = struct { sg.destroyImage(self.sokol_image.?); self.sokol_image = null; } + + /// Returns an Imgui Texture ID that can be used with Imgui + pub fn makeImguiTexture(self: *const Texture) ?*anyopaque { + const img = simgui.makeImage(.{ .image = self.sokol_image.?, .sampler = state.debug_material.state.sokol_samplers[0].? }); + return simgui.imtextureid(img); + } }; pub const RenderPassConfig = struct { @@ -1040,6 +1047,12 @@ pub const Material = struct { self.state.shader.applyUniformBlockByName(.FS, "fs_params", asAnything(data.bytes.items)); } } + + /// Returns an Imgui Texture ID from Texture 0 and Sampler 0 that can be used with Imgui + pub fn makeImguiTexture(self: *const Material) ?*anyopaque { + const img = simgui.makeImage(.{ .image = self.state.textures[0].?.sokol_image.?, .sampler = self.state.sokol_samplers[0].? }); + return simgui.imtextureid(img); + } }; pub const state = struct { From d21f44ab06db06e1d708a3670119c8d5b8b0151c Mon Sep 17 00:00:00 2001 From: Interrupt Date: Sat, 12 Apr 2025 11:06:35 -0700 Subject: [PATCH 2/3] Some cleanup in imgui example --- src/examples/imgui.zig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/examples/imgui.zig b/src/examples/imgui.zig index 8e5ba6ce..c65823e9 100644 --- a/src/examples/imgui.zig +++ b/src/examples/imgui.zig @@ -61,8 +61,8 @@ pub fn on_init() !void { imgui_texture_1 = test_texture.makeImguiTexture(); // make a material to use a different sampler mode - test_material = try delve.platform.graphics.Material.init(.{ - .shader = delve.platform.graphics.getDefaultShader(), + test_material = try graphics.Material.init(.{ + .shader = graphics.getDefaultShader(), .texture_0 = test_texture, .samplers = &[_]graphics.FilterMode{.NEAREST}, }); @@ -119,7 +119,7 @@ pub fn on_tick(delta: f32) void { // end the window imgui.igEnd(); - delve.platform.graphics.setClearColor(delve.colors.Color.fromArray(bg_color)); + graphics.setClearColor(delve.colors.Color.fromArray(bg_color)); } pub fn on_draw() void { From 09e873ddcb23d0cc1bf548eea7c607e7df5bf362 Mon Sep 17 00:00:00 2001 From: Interrupt Date: Sat, 12 Apr 2025 11:13:16 -0700 Subject: [PATCH 3/3] Adding support to get other textures / samplers from a material when making an imgui image --- src/examples/imgui.zig | 7 +++++-- src/framework/platform/graphics.zig | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/examples/imgui.zig b/src/examples/imgui.zig index c65823e9..c7eee139 100644 --- a/src/examples/imgui.zig +++ b/src/examples/imgui.zig @@ -67,8 +67,11 @@ pub fn on_init() !void { .samplers = &[_]graphics.FilterMode{.NEAREST}, }); - // and make an imgui texture out of our material - imgui_texture_2 = test_material.makeImguiTexture(); + // make an imgui image out of our material + // materials have more than one texture / sampler, have to pick which to use + const img_idx: usize = 0; + const sampler_idx: usize = 0; + imgui_texture_2 = test_material.makeImguiTexture(img_idx, sampler_idx); } fn on_cleanup() !void { diff --git a/src/framework/platform/graphics.zig b/src/framework/platform/graphics.zig index b1ead430..14964221 100644 --- a/src/framework/platform/graphics.zig +++ b/src/framework/platform/graphics.zig @@ -1049,8 +1049,11 @@ pub const Material = struct { } /// Returns an Imgui Texture ID from Texture 0 and Sampler 0 that can be used with Imgui - pub fn makeImguiTexture(self: *const Material) ?*anyopaque { - const img = simgui.makeImage(.{ .image = self.state.textures[0].?.sokol_image.?, .sampler = self.state.sokol_samplers[0].? }); + pub fn makeImguiTexture(self: *const Material, texture_idx: usize, sampler_idx: usize) ?*anyopaque { + const img = simgui.makeImage(.{ + .image = self.state.textures[texture_idx].?.sokol_image.?, + .sampler = self.state.sokol_samplers[sampler_idx].?, + }); return simgui.imtextureid(img); } };