Compare commits

..

2 Commits

Author SHA1 Message Date
ca27a47224 chore: add necessary imgui files for opengl3
feat: add glfw+opengl3 backend option to build.zig

feat: add backend impl for glfw+opengl3

chore: combine render() and draw() in backend

chore: handle all cases of enum

feat: add sdl2-opengl3 backend impl

fix: vcpkg stores SDL.h under SDL2 folder

macOS and Linux seem to not, so in order to get CI working again I
should make use of the preprocessor.

FIXME: I think this makes vcpkg a **hard** requirement which perhaps
isn't ideal if I want ZBA to be as easy to build as possible. I should
try ensuring that building w/out vcpkg works as well

chore: explicitly link SDL2

TODO: What happens on Windows? macOS?

feat: prefer SDL.h instead of SDL/SDL.h on all supported platforms

fix: restore import for glfw w/ opengl3 backend

rebase unalived that specific line. Whoops

fix: ensure that main.zig is removed

chore: Update to Zig v0.11.0
2023-10-07 02:59:02 -05:00
cb1cc16c8f chore: update to zgui 4f14a690fe8fbfce37a50dcf666e2293a19abbba 2023-10-07 02:53:20 -05:00
16 changed files with 443 additions and 1005 deletions

View File

@@ -11,21 +11,18 @@ Easy to use, hand-crafted API with default arguments, named parameters and Zig s
## Getting started ## Getting started
Copy `zgui` folder to a `libs` subdirectory of the root of your project and add the following to your `build.zig.zon` .dependencies: Copy `zgui` folder to a `libs` subdirectory of the root of your project.
```zig
.zgui = .{ .path = "libs/zgui" },
```
To get glfw/wgpu rendering backend working also copy `zgpu`, `zglfw`, `zpool` and `system-sdk` folders and add the depenency paths (see [zgpu](https://github.com/zig-gamedev/zig-gamedev/tree/main/libs/zgpu) for the details). Alternatively, you can provide your own rendering backend by specifying `.no_backend` in the package options. To get glfw/wgpu rendering backend working also copy `zgpu`, `zglfw`, `zpool` and `system-sdk` folders (see [zgpu](https://github.com/michal-z/zig-gamedev/tree/main/libs/zgpu) for the details). Alternatively, you can provide your own rendering backend, see: [backend_glfw_wgpu.zig](src/backend_glfw_wgpu.zig) for an example.
Then in your `build.zig` add: Then in your `build.zig` add:
```zig ```zig
const zgui = @import("zgui"); const zgui = @import("libs/zgui/build.zig");
// Needed for glfw/wgpu rendering backend // Needed for glfw/wgpu rendering backend
const zglfw = @import("zglfw"); const zglfw = @import("libs/zglfw/build.zig");
const zgpu = @import("zgpu"); const zgpu = @import("libs/zgpu/build.zig");
const zpool = @import("zpool"); const zpool = @import("libs/zpool/build.zig");
pub fn build(b: *std.Build) void { pub fn build(b: *std.Build) void {
... ...
@@ -49,28 +46,7 @@ pub fn build(b: *std.Build) void {
zgpu_pkg.link(exe); zgpu_pkg.link(exe);
} }
``` ```
You may also include zgui without bundled imgui or implot:
```zig
// In build.zig
const pkg = zgui.package(b, exe.target, .ReleaseSafe, .{
.options = .{
.backend = .no_backend,
.with_imgui = false,
.with_implot = false,
},
});
const lib = pkg.zgui_c_cpp;
lib.defineCMacro("IMGUI_USER_CONFIG",
\\"../imconfig_custom.h"
);
lib.addIncludePath("lib/imgui");
```
Now in your code you may import and use `zgui`: Now in your code you may import and use `zgui`:
```zig ```zig
const zgui = @import("zgui"); const zgui = @import("zgui");
@@ -82,7 +58,6 @@ zgui.backend.init(
window, window,
demo.gctx.device, demo.gctx.device,
@enumToInt(swapchain_format), @enumToInt(swapchain_format),
@enumToInt(depth_format),
); );
``` ```

172
build.zig
View File

@@ -3,42 +3,35 @@ const std = @import("std");
pub const Backend = enum { pub const Backend = enum {
no_backend, no_backend,
glfw_wgpu, glfw_wgpu,
glfw_opengl3,
win32_dx12, win32_dx12,
glfw_opengl3,
sdl2_opengl3, sdl2_opengl3,
}; };
const default_options = struct {
const shared = false;
const with_imgui = true;
const with_implot = true;
};
pub const Options = struct { pub const Options = struct {
backend: Backend, backend: Backend,
shared: bool = default_options.shared, shared: bool = false,
/// use bundled imgui source /// use bundled imgui source
with_imgui: bool = default_options.with_imgui, with_imgui: bool = true,
/// use bundled implot source /// use bundled implot source
with_implot: bool = default_options.with_implot, with_implot: bool = true,
}; };
pub const Package = struct { pub const Package = struct {
options: Options, options: Options,
zgui: *std.Build.Module, zgui: *std.Build.Module,
zgui_options: *std.Build.Module, zgui_options: *std.Build.Module,
zgui_c_cpp: *std.Build.Step.Compile, zgui_c_cpp: *std.Build.CompileStep,
pub fn link(pkg: Package, exe: *std.Build.Step.Compile) void { pub fn link(pkg: Package, exe: *std.Build.CompileStep) void {
exe.linkLibrary(pkg.zgui_c_cpp); exe.linkLibrary(pkg.zgui_c_cpp);
exe.root_module.addImport("zgui", pkg.zgui); exe.addModule("zgui", pkg.zgui);
exe.root_module.addImport("zgui_options", pkg.zgui_options);
} }
}; };
pub fn package( pub fn package(
b: *std.Build, b: *std.Build,
target: std.Build.ResolvedTarget, target: std.zig.CrossTarget,
optimize: std.builtin.Mode, optimize: std.builtin.Mode,
args: struct { args: struct {
options: Options, options: Options,
@@ -50,9 +43,9 @@ pub fn package(
const zgui_options = step.createModule(); const zgui_options = step.createModule();
const zgui = b.addModule("zgui", .{ const zgui = b.createModule(.{
.root_source_file = .{ .path = thisDir() ++ "/src/gui.zig" }, .source_file = .{ .path = thisDir() ++ "/src/gui.zig" },
.imports = &.{ .dependencies = &.{
.{ .name = "zgui_options", .module = zgui_options }, .{ .name = "zgui_options", .module = zgui_options },
}, },
}); });
@@ -65,16 +58,12 @@ pub fn package(
}); });
b.installArtifact(lib); b.installArtifact(lib);
if (target.result.os.tag == .windows) { if (target.isWindows()) {
lib.defineCMacro("IMGUI_API", "__declspec(dllexport)"); lib.defineCMacro("IMGUI_API", "__declspec(dllexport)");
lib.defineCMacro("IMPLOT_API", "__declspec(dllexport)"); lib.defineCMacro("IMPLOT_API", "__declspec(dllexport)");
lib.defineCMacro("ZGUI_API", "__declspec(dllexport)"); lib.defineCMacro("ZGUI_API", "__declspec(dllexport)");
} }
if (target.result.os.tag == .macos) {
lib.linker_allow_shlib_undefined = true;
}
break :blk lib; break :blk lib;
} else b.addStaticLibrary(.{ } else b.addStaticLibrary(.{
.name = "zgui", .name = "zgui",
@@ -85,7 +74,7 @@ pub fn package(
zgui_c_cpp.addIncludePath(.{ .path = thisDir() ++ "/libs" }); zgui_c_cpp.addIncludePath(.{ .path = thisDir() ++ "/libs" });
zgui_c_cpp.addIncludePath(.{ .path = thisDir() ++ "/libs/imgui" }); zgui_c_cpp.addIncludePath(.{ .path = thisDir() ++ "/libs/imgui" });
const abi = target.result.abi; const abi = (std.zig.system.NativeTargetInfo.detect(target) catch unreachable).target.abi;
zgui_c_cpp.linkLibC(); zgui_c_cpp.linkLibC();
if (abi != .msvc) if (abi != .msvc)
zgui_c_cpp.linkLibCpp(); zgui_c_cpp.linkLibCpp();
@@ -98,77 +87,75 @@ pub fn package(
}); });
if (args.options.with_imgui) { if (args.options.with_imgui) {
zgui_c_cpp.addCSourceFiles(.{ zgui_c_cpp.addCSourceFiles(&.{
.files = &.{
thisDir() ++ "/libs/imgui/imgui.cpp", thisDir() ++ "/libs/imgui/imgui.cpp",
thisDir() ++ "/libs/imgui/imgui_widgets.cpp", thisDir() ++ "/libs/imgui/imgui_widgets.cpp",
thisDir() ++ "/libs/imgui/imgui_tables.cpp", thisDir() ++ "/libs/imgui/imgui_tables.cpp",
thisDir() ++ "/libs/imgui/imgui_draw.cpp", thisDir() ++ "/libs/imgui/imgui_draw.cpp",
thisDir() ++ "/libs/imgui/imgui_demo.cpp", thisDir() ++ "/libs/imgui/imgui_demo.cpp",
}, }, cflags);
.flags = cflags,
});
} }
if (args.options.with_implot) { if (args.options.with_implot) {
zgui_c_cpp.defineCMacro("ZGUI_IMPLOT", "1"); zgui_c_cpp.addCSourceFiles(&.{
zgui_c_cpp.addCSourceFiles(.{
.files = &.{
thisDir() ++ "/libs/imgui/implot_demo.cpp", thisDir() ++ "/libs/imgui/implot_demo.cpp",
thisDir() ++ "/libs/imgui/implot.cpp", thisDir() ++ "/libs/imgui/implot.cpp",
thisDir() ++ "/libs/imgui/implot_items.cpp", thisDir() ++ "/libs/imgui/implot_items.cpp",
}, }, cflags);
.flags = cflags,
});
} else {
zgui_c_cpp.defineCMacro("ZGUI_IMPLOT", "0");
} }
switch (args.options.backend) { switch (args.options.backend) {
.glfw_wgpu => { .glfw_wgpu => {
const zglfw = b.dependency("zglfw", .{}); zgui_c_cpp.addIncludePath(.{ .path = thisDir() ++ "/../zglfw/libs/glfw/include" });
const zgpu = b.dependency("zgpu", .{}); zgui_c_cpp.addIncludePath(.{ .path = thisDir() ++ "/../zgpu/libs/dawn/include" });
zgui_c_cpp.addIncludePath(.{ .path = zglfw.path("libs/glfw/include").getPath(b) }); zgui_c_cpp.addCSourceFiles(&.{
zgui_c_cpp.addIncludePath(.{ .path = zgpu.path("libs/dawn/include").getPath(b) });
zgui_c_cpp.addCSourceFiles(.{
.files = &.{
thisDir() ++ "/libs/imgui/backends/imgui_impl_glfw.cpp", thisDir() ++ "/libs/imgui/backends/imgui_impl_glfw.cpp",
thisDir() ++ "/libs/imgui/backends/imgui_impl_wgpu.cpp", thisDir() ++ "/libs/imgui/backends/imgui_impl_wgpu.cpp",
}, }, cflags);
.flags = cflags,
});
}, },
.glfw_opengl3 => { .glfw_opengl3 => {
const zglfw = b.dependency("zglfw", .{}); zgui_c_cpp.addCSourceFiles(&.{
zgui_c_cpp.addIncludePath(.{ .path = zglfw.path("libs/glfw/include").getPath(b) });
zgui_c_cpp.addCSourceFiles(.{
.files = &.{
thisDir() ++ "/libs/imgui/backends/imgui_impl_glfw.cpp", thisDir() ++ "/libs/imgui/backends/imgui_impl_glfw.cpp",
thisDir() ++ "/libs/imgui/backends/imgui_impl_opengl3.cpp", thisDir() ++ "/libs/imgui/backends/imgui_impl_opengl3.cpp",
}, }, cflags);
.flags = &(cflags.* ++ .{"-DIMGUI_IMPL_OPENGL_LOADER_CUSTOM"}),
});
},
.sdl2_opengl3 => {
zgui_c_cpp.addCSourceFiles(.{
.files = &.{
thisDir() ++ "/libs/imgui/backends/imgui_impl_sdl.cpp",
thisDir() ++ "/libs/imgui/backends/imgui_impl_opengl3.cpp",
thisDir() ++ "/libs/imgui/backends/imgui_impl_opengl3_loader.h",
},
.flags = cflags,
});
}, },
.win32_dx12 => { .win32_dx12 => {
zgui_c_cpp.addCSourceFiles(.{ zgui_c_cpp.addCSourceFiles(&.{
.files = &.{
thisDir() ++ "/libs/imgui/backends/imgui_impl_win32.cpp", thisDir() ++ "/libs/imgui/backends/imgui_impl_win32.cpp",
thisDir() ++ "/libs/imgui/backends/imgui_impl_dx12.cpp", thisDir() ++ "/libs/imgui/backends/imgui_impl_dx12.cpp",
}, cflags);
zgui_c_cpp.linkSystemLibraryName("d3dcompiler_47");
zgui_c_cpp.linkSystemLibraryName("dwmapi");
}, },
.flags = cflags, .sdl2_opengl3 => {
}); if (target.isWindows()) blk: {
zgui_c_cpp.linkSystemLibrary("d3dcompiler_47"); // see: https://github.com/MasterQ32/SDL.zig/blob/37f4ba9e31bea895fa19ef8b90d1f51111e52e67/Sdk.zig#L182-L199
zgui_c_cpp.linkSystemLibrary("dwmapi");
zgui_c_cpp.addVcpkgPaths(if (args.options.shared) .dynamic else .static) catch break :blk;
const vcpkg_triplet = zgui_c_cpp.target.vcpkgTriplet(b.allocator, if (args.options.shared) .Dynamic else .Static) catch |e| {
std.debug.panic("failed to determing vcpkg triplet: {}", .{e});
};
defer b.allocator.free(vcpkg_triplet);
const include_path = b.pathJoin(&.{ b.vcpkg_root.found, "installed", vcpkg_triplet, "include", "SDL2" });
// What's the difference between a IncludeDir "path" and "path_system"?
zgui_c_cpp.include_dirs.append(.{ .path = .{ .path = include_path } }) catch @panic("out of memory");
const bin_path = zgui_c_cpp.vcpkg_bin_path orelse @panic("vcpkg paths were found, so vcpkg_bin_path should be set ");
const dll_path = std.fs.path.join(b.allocator, &.{ bin_path, "SDL2.dll" }) catch @panic("out of memory");
std.fs.cwd().access(dll_path, .{}) catch break :blk;
b.installBinFile(dll_path, "SDL2.dll");
}
zgui_c_cpp.linkSystemLibrary("SDL2");
zgui_c_cpp.addCSourceFiles(&.{
thisDir() ++ "/libs/imgui/backends/imgui_impl_sdl.cpp",
thisDir() ++ "/libs/imgui/backends/imgui_impl_opengl3.cpp",
}, cflags);
}, },
.no_backend => {}, .no_backend => {},
} }
@@ -181,52 +168,7 @@ pub fn package(
}; };
} }
pub fn build(b: *std.Build) void { pub fn build(_: *std.Build) void {}
const optimize = b.standardOptimizeOption(.{});
const target = b.standardTargetOptions(.{});
_ = package(b, target, optimize, .{
.options = .{
.backend = b.option(Backend, "backend", "Select backend") orelse .no_backend,
.shared = b.option(
bool,
"shared",
"Bulid as a shared library",
) orelse default_options.shared,
.with_imgui = b.option(
bool,
"with_imgui",
"Build with bundled imgui source",
) orelse default_options.with_imgui,
.with_implot = b.option(
bool,
"with_implot",
"Build with bundled implot source",
) orelse default_options.with_implot,
},
});
const test_step = b.step("test", "Run zgui tests");
test_step.dependOn(runTests(b, optimize, target));
}
pub fn runTests(
b: *std.Build,
optimize: std.builtin.OptimizeMode,
target: std.Build.ResolvedTarget,
) *std.Build.Step {
const gui_tests = b.addTest(.{
.name = "gui-tests",
.root_source_file = .{ .path = thisDir() ++ "/src/gui.zig" },
.target = target,
.optimize = optimize,
});
const pkg = package(b, target, optimize, .{
.options = .{ .backend = .no_backend },
});
pkg.link(gui_tests);
return &b.addRunArtifact(gui_tests).step;
}
inline fn thisDir() []const u8 { inline fn thisDir() []const u8 {
return comptime std.fs.path.dirname(@src().file) orelse "."; return comptime std.fs.path.dirname(@src().file) orelse ".";

View File

@@ -1,15 +0,0 @@
.{
.name = "zgui",
.version = "1.89.6",
.paths = .{
"build.zig",
"build.zig.zon",
"libs",
"src",
"README.md",
},
.dependencies = .{
.zglfw = .{ .path = "../zglfw" },
.zgpu = .{ .path = "../zgpu" },
},
}

View File

@@ -5,12 +5,7 @@
// Implemented features: // Implemented features:
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID! // [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID!
// [x] Renderer: Large meshes support (64k+ vertices) with 16-bit indices (Desktop OpenGL only). // [x] Renderer: Desktop GL only: Support for large meshes (64k+ vertices) with 16-bit indices.
// About WebGL/ES:
// - You need to '#define IMGUI_IMPL_OPENGL_ES2' or '#define IMGUI_IMPL_OPENGL_ES3' to use WebGL or OpenGL ES.
// - This is done automatically on iOS, Android and Emscripten targets.
// - For other targets, the define needs to be visible from the imgui_impl_opengl3.cpp compilation unit. If unsure, define globally or in imconfig.h.
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
@@ -19,17 +14,11 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2023-06-20: OpenGL: Fixed erroneous use glGetIntegerv(GL_CONTEXT_PROFILE_MASK) on contexts lower than 3.2. (#6539, #6333)
// 2023-05-09: OpenGL: Support for glBindSampler() backup/restore on ES3. (#6375)
// 2023-04-18: OpenGL: Restore front and back polygon mode separately when supported by context. (#6333)
// 2023-03-23: OpenGL: Properly restoring "no shader program bound" if it was the case prior to running the rendering function. (#6267, #6220, #6224)
// 2023-03-15: OpenGL: Fixed GL loader crash when GL_VERSION returns NULL. (#6154, #4445, #3530)
// 2023-03-06: OpenGL: Fixed restoration of a potentially deleted OpenGL program, by calling glIsProgram(). (#6220, #6224)
// 2022-11-09: OpenGL: Reverted use of glBufferSubData(), too many corruptions issues + old issues seemingly can't be reproed with Intel drivers nowadays (revert 2021-12-15 and 2022-05-23 changes). // 2022-11-09: OpenGL: Reverted use of glBufferSubData(), too many corruptions issues + old issues seemingly can't be reproed with Intel drivers nowadays (revert 2021-12-15 and 2022-05-23 changes).
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11. // 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
// 2022-09-27: OpenGL: Added ability to '#define IMGUI_IMPL_OPENGL_DEBUG'. // 2022-09-27: OpenGL: Added ability to '#define IMGUI_IMPL_OPENGL_DEBUG'.
// 2022-05-23: OpenGL: Reworking 2021-12-15 "Using buffer orphaning" so it only happens on Intel GPU, seems to cause problems otherwise. (#4468, #4825, #4832, #5127). // 2022-05-23: OpenGL: Reworking 2021-12-15 "Using buffer orphaning" so it only happens on Intel GPU, seems to cause problems otherwise. (#4468, #4825, #4832, #5127).
// 2022-05-13: OpenGL: Fixed state corruption on OpenGL ES 2.0 due to not preserving GL_ELEMENT_ARRAY_BUFFER_BINDING and vertex attribute states. // 2022-05-13: OpenGL: Fix state corruption on OpenGL ES 2.0 due to not preserving GL_ELEMENT_ARRAY_BUFFER_BINDING and vertex attribute states.
// 2021-12-15: OpenGL: Using buffer orphaning + glBufferSubData(), seems to fix leaks with multi-viewports with some Intel HD drivers. // 2021-12-15: OpenGL: Using buffer orphaning + glBufferSubData(), seems to fix leaks with multi-viewports with some Intel HD drivers.
// 2021-08-23: OpenGL: Fixed ES 3.0 shader ("#version 300 es") use normal precision floats to avoid wobbly rendering at HD resolutions. // 2021-08-23: OpenGL: Fixed ES 3.0 shader ("#version 300 es") use normal precision floats to avoid wobbly rendering at HD resolutions.
// 2021-08-19: OpenGL: Embed and use our own minimal GL loader (imgui_impl_opengl3_loader.h), removing requirement and support for third-party loader. // 2021-08-19: OpenGL: Embed and use our own minimal GL loader (imgui_impl_opengl3_loader.h), removing requirement and support for third-party loader.
@@ -103,30 +92,27 @@
#define _CRT_SECURE_NO_WARNINGS #define _CRT_SECURE_NO_WARNINGS
#endif #endif
#ifndef IMGUI_DISABLE
#include "imgui.h" #include "imgui.h"
#include "imgui_impl_opengl3.h" #include "imgui_impl_opengl3.h"
#include <stdio.h> #include <stdio.h>
#if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier
#include <stddef.h> // intptr_t
#else
#include <stdint.h> // intptr_t #include <stdint.h> // intptr_t
#endif
#if defined(__APPLE__) #if defined(__APPLE__)
#include <TargetConditionals.h> #include <TargetConditionals.h>
#endif #endif
// Clang/GCC warnings with -Weverything // Clang warnings with -Weverything
#if defined(__clang__) #if defined(__clang__)
#pragma clang diagnostic push #pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast #pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast
#pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness #pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness
#pragma clang diagnostic ignored "-Wunused-macros" // warning: macro is not used
#pragma clang diagnostic ignored "-Wnonportable-system-include-path"
#pragma clang diagnostic ignored "-Wcast-function-type" // warning: cast between incompatible function types (for loader)
#endif #endif
#if defined(__GNUC__) #if defined(__GNUC__)
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind #pragma GCC diagnostic ignored "-Wcast-function-type" // warning: cast between incompatible function types
#pragma GCC diagnostic ignored "-Wunknown-warning-option" // warning: unknown warning group 'xxx'
#pragma GCC diagnostic ignored "-Wcast-function-type" // warning: cast between incompatible function types (for loader)
#endif #endif
// GL includes // GL includes
@@ -158,10 +144,6 @@
// Changes to this backend using new APIs should be accompanied by a regenerated stripped loader version. // Changes to this backend using new APIs should be accompanied by a regenerated stripped loader version.
#define IMGL3W_IMPL #define IMGL3W_IMPL
#include "imgui_impl_opengl3_loader.h" #include "imgui_impl_opengl3_loader.h"
#else // zig-gamedev: added gl decls
extern "C" {
#include "opengl-decls.h"
}
#endif #endif
// Vertex arrays are not supported on ES2/WebGL1 unless Emscripten which uses an extension // Vertex arrays are not supported on ES2/WebGL1 unless Emscripten which uses an extension
@@ -185,8 +167,8 @@ extern "C" {
#define IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET #define IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET
#endif #endif
// Desktop GL 3.3+ and GL ES 3.0+ have glBindSampler() // Desktop GL 3.3+ has glBindSampler()
#if !defined(IMGUI_IMPL_OPENGL_ES2) && (defined(IMGUI_IMPL_OPENGL_ES3) || defined(GL_VERSION_3_3)) #if !defined(IMGUI_IMPL_OPENGL_ES2) && !defined(IMGUI_IMPL_OPENGL_ES3) && defined(GL_VERSION_3_3)
#define IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER #define IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER
#endif #endif
@@ -214,10 +196,6 @@ struct ImGui_ImplOpenGL3_Data
{ {
GLuint GlVersion; // Extracted at runtime using GL_MAJOR_VERSION, GL_MINOR_VERSION queries (e.g. 320 for GL 3.2) GLuint GlVersion; // Extracted at runtime using GL_MAJOR_VERSION, GL_MINOR_VERSION queries (e.g. 320 for GL 3.2)
char GlslVersionString[32]; // Specified by user or detected based on compile time GL settings. char GlslVersionString[32]; // Specified by user or detected based on compile time GL settings.
bool GlProfileIsES2;
bool GlProfileIsES3;
bool GlProfileIsCompat;
GLint GlProfileMask;
GLuint FontTexture; GLuint FontTexture;
GLuint ShaderHandle; GLuint ShaderHandle;
GLint AttribLocationTex; // Uniforms location GLint AttribLocationTex; // Uniforms location
@@ -272,13 +250,13 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!"); IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
// Initialize our loader // Initialize our loader
#if !defined(IMGUI_IMPL_OPENGL_ES2) && !defined(IMGUI_IMPL_OPENGL_ES3) && !defined(IMGUI_IMPL_OPENGL_LOADER_CUSTOM) #if !defined(IMGUI_IMPL_OPENGL_ES2) && !defined(IMGUI_IMPL_OPENGL_ES3) && !defined(IMGUI_IMPL_OPENGL_LOADER_CUSTOM)
if (imgl3wInit() != 0) if (imgl3wInit() != 0)
{ {
fprintf(stderr, "Failed to initialize OpenGL loader!\n"); fprintf(stderr, "Failed to initialize OpenGL loader!\n");
return false; return false;
} }
#endif #endif
// Setup backend capabilities flags // Setup backend capabilities flags
ImGui_ImplOpenGL3_Data* bd = IM_NEW(ImGui_ImplOpenGL3_Data)(); ImGui_ImplOpenGL3_Data* bd = IM_NEW(ImGui_ImplOpenGL3_Data)();
@@ -286,12 +264,7 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
io.BackendRendererName = "imgui_impl_opengl3"; io.BackendRendererName = "imgui_impl_opengl3";
// Query for GL version (e.g. 320 for GL 3.2) // Query for GL version (e.g. 320 for GL 3.2)
#if defined(IMGUI_IMPL_OPENGL_ES2) #if !defined(IMGUI_IMPL_OPENGL_ES2)
// GLES 2
bd->GlVersion = 200;
bd->GlProfileIsES2 = true;
#else
// Desktop or GLES 3
GLint major = 0; GLint major = 0;
GLint minor = 0; GLint minor = 0;
glGetIntegerv(GL_MAJOR_VERSION, &major); glGetIntegerv(GL_MAJOR_VERSION, &major);
@@ -303,15 +276,6 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
sscanf(gl_version, "%d.%d", &major, &minor); sscanf(gl_version, "%d.%d", &major, &minor);
} }
bd->GlVersion = (GLuint)(major * 100 + minor * 10); bd->GlVersion = (GLuint)(major * 100 + minor * 10);
#if defined(GL_CONTEXT_PROFILE_MASK)
if (bd->GlVersion >= 320)
glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &bd->GlProfileMask);
bd->GlProfileIsCompat = (bd->GlProfileMask & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT) != 0;
#endif
#if defined(IMGUI_IMPL_OPENGL_ES3)
bd->GlProfileIsES3 = true;
#endif
bd->UseBufferSubData = false; bd->UseBufferSubData = false;
/* /*
@@ -322,10 +286,12 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
bd->UseBufferSubData = true; bd->UseBufferSubData = true;
#endif #endif
*/ */
#else
bd->GlVersion = 200; // GLES 2
#endif #endif
#ifdef IMGUI_IMPL_OPENGL_DEBUG #ifdef IMGUI_IMPL_OPENGL_DEBUG
printf("GlVersion = %d\nGlProfileIsCompat = %d\nGlProfileMask = 0x%X\nGlProfileIsES2 = %d, GlProfileIsES3 = %d\nGL_VENDOR = '%s'\nGL_RENDERER = '%s'\n", bd->GlVersion, bd->GlProfileIsCompat, bd->GlProfileMask, bd->GlProfileIsES2, bd->GlProfileIsES3, (const char*)glGetString(GL_VENDOR), (const char*)glGetString(GL_RENDERER)); // [DEBUG] printf("GL_MAJOR_VERSION = %d\nGL_MINOR_VERSION = %d\nGL_VENDOR = '%s'\nGL_RENDERER = '%s'\n", major, minor, (const char*)glGetString(GL_VENDOR), (const char*)glGetString(GL_RENDERER)); // [DEBUG]
#endif #endif
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET #ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_VTX_OFFSET
@@ -381,7 +347,6 @@ void ImGui_ImplOpenGL3_Shutdown()
ImGui_ImplOpenGL3_DestroyDeviceObjects(); ImGui_ImplOpenGL3_DestroyDeviceObjects();
io.BackendRendererName = nullptr; io.BackendRendererName = nullptr;
io.BackendRendererUserData = nullptr; io.BackendRendererUserData = nullptr;
io.BackendFlags &= ~ImGuiBackendFlags_RendererHasVtxOffset;
IM_DELETE(bd); IM_DELETE(bd);
} }
@@ -447,8 +412,8 @@ static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_wid
glUniformMatrix4fv(bd->AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); glUniformMatrix4fv(bd->AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]);
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER #ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER
if (bd->GlVersion >= 330 || bd->GlProfileIsES3) if (bd->GlVersion >= 330)
glBindSampler(0, 0); // We use combined texture/sampler state. Applications using GL 3.3 and GL ES 3.0 may set that otherwise. glBindSampler(0, 0); // We use combined texture/sampler state. Applications using GL 3.3 may set that otherwise.
#endif #endif
(void)vertex_array_object; (void)vertex_array_object;
@@ -486,7 +451,7 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
GLuint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, (GLint*)&last_program); GLuint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, (GLint*)&last_program);
GLuint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, (GLint*)&last_texture); GLuint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, (GLint*)&last_texture);
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER #ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER
GLuint last_sampler; if (bd->GlVersion >= 330 || bd->GlProfileIsES3) { glGetIntegerv(GL_SAMPLER_BINDING, (GLint*)&last_sampler); } else { last_sampler = 0; } GLuint last_sampler; if (bd->GlVersion >= 330) { glGetIntegerv(GL_SAMPLER_BINDING, (GLint*)&last_sampler); } else { last_sampler = 0; }
#endif #endif
GLuint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, (GLint*)&last_array_buffer); GLuint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, (GLint*)&last_array_buffer);
#ifndef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY #ifndef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY
@@ -609,11 +574,10 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
#endif #endif
// Restore modified GL state // Restore modified GL state
// This "glIsProgram()" check is required because if the program is "pending deletion" at the time of binding backup, it will have been deleted by now and will cause an OpenGL error. See #6220. glUseProgram(last_program);
if (last_program == 0 || glIsProgram(last_program)) glUseProgram(last_program);
glBindTexture(GL_TEXTURE_2D, last_texture); glBindTexture(GL_TEXTURE_2D, last_texture);
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER #ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER
if (bd->GlVersion >= 330 || bd->GlProfileIsES3) if (bd->GlVersion >= 330)
glBindSampler(0, last_sampler); glBindSampler(0, last_sampler);
#endif #endif
glActiveTexture(last_active_texture); glActiveTexture(last_active_texture);
@@ -639,18 +603,8 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
#endif #endif
#ifdef IMGUI_IMPL_HAS_POLYGON_MODE #ifdef IMGUI_IMPL_HAS_POLYGON_MODE
// Desktop OpenGL 3.0 and OpenGL 3.1 had separate polygon draw modes for front-facing and back-facing faces of polygons
if (bd->GlVersion <= 310 || bd->GlProfileIsCompat)
{
glPolygonMode(GL_FRONT, (GLenum)last_polygon_mode[0]);
glPolygonMode(GL_BACK, (GLenum)last_polygon_mode[1]);
}
else
{
glPolygonMode(GL_FRONT_AND_BACK, (GLenum)last_polygon_mode[0]); glPolygonMode(GL_FRONT_AND_BACK, (GLenum)last_polygon_mode[0]);
} #endif
#endif // IMGUI_IMPL_HAS_POLYGON_MODE
glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]);
glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3]); glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3]);
(void)bd; // Not all compilation paths use this (void)bd; // Not all compilation paths use this
@@ -935,13 +889,9 @@ void ImGui_ImplOpenGL3_DestroyDeviceObjects()
ImGui_ImplOpenGL3_DestroyFontsTexture(); ImGui_ImplOpenGL3_DestroyFontsTexture();
} }
//-----------------------------------------------------------------------------
#if defined(__GNUC__) #if defined(__GNUC__)
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#endif #endif
#if defined(__clang__) #if defined(__clang__)
#pragma clang diagnostic pop #pragma clang diagnostic pop
#endif #endif
#endif // #ifndef IMGUI_DISABLE

View File

@@ -5,12 +5,7 @@
// Implemented features: // Implemented features:
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID! // [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID!
// [x] Renderer: Large meshes support (64k+ vertices) with 16-bit indices (Desktop OpenGL only). // [x] Renderer: Desktop GL only: Support for large meshes (64k+ vertices) with 16-bit indices.
// About WebGL/ES:
// - You need to '#define IMGUI_IMPL_OPENGL_ES2' or '#define IMGUI_IMPL_OPENGL_ES3' to use WebGL or OpenGL ES.
// - This is done automatically on iOS, Android and Emscripten targets.
// - For other targets, the define needs to be visible from the imgui_impl_opengl3.cpp compilation unit. If unsure, define globally or in imconfig.h.
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
@@ -24,22 +19,19 @@
#pragma once #pragma once
#include "imgui.h" // IMGUI_IMPL_API #include "imgui.h" // IMGUI_IMPL_API
#ifndef IMGUI_DISABLE
extern "C" { extern "C" {
// Backend API
IMGUI_IMPL_API bool ImGui_ImplOpenGL3_Init(const char* glsl_version = nullptr);
IMGUI_IMPL_API void ImGui_ImplOpenGL3_Shutdown();
IMGUI_IMPL_API void ImGui_ImplOpenGL3_NewFrame();
IMGUI_IMPL_API void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data);
// Backend API // (Optional) Called by Init/NewFrame/Shutdown
IMGUI_IMPL_API bool ImGui_ImplOpenGL3_Init(const char* glsl_version = nullptr); IMGUI_IMPL_API bool ImGui_ImplOpenGL3_CreateFontsTexture();
IMGUI_IMPL_API void ImGui_ImplOpenGL3_Shutdown(); IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyFontsTexture();
IMGUI_IMPL_API void ImGui_ImplOpenGL3_NewFrame(); IMGUI_IMPL_API bool ImGui_ImplOpenGL3_CreateDeviceObjects();
IMGUI_IMPL_API void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data); IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyDeviceObjects();
// (Optional) Called by Init/NewFrame/Shutdown
IMGUI_IMPL_API bool ImGui_ImplOpenGL3_CreateFontsTexture();
IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyFontsTexture();
IMGUI_IMPL_API bool ImGui_ImplOpenGL3_CreateDeviceObjects();
IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyDeviceObjects();
} }
// Specific OpenGL ES versions // Specific OpenGL ES versions
@@ -63,5 +55,3 @@ IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyDeviceObjects();
#endif #endif
#endif #endif
#endif // #ifndef IMGUI_DISABLE

View File

@@ -154,8 +154,6 @@ typedef khronos_uint8_t GLubyte;
#define GL_ONE 1 #define GL_ONE 1
#define GL_SRC_ALPHA 0x0302 #define GL_SRC_ALPHA 0x0302
#define GL_ONE_MINUS_SRC_ALPHA 0x0303 #define GL_ONE_MINUS_SRC_ALPHA 0x0303
#define GL_FRONT 0x0404
#define GL_BACK 0x0405
#define GL_FRONT_AND_BACK 0x0408 #define GL_FRONT_AND_BACK 0x0408
#define GL_POLYGON_MODE 0x0B40 #define GL_POLYGON_MODE 0x0B40
#define GL_CULL_FACE 0x0B44 #define GL_CULL_FACE 0x0B44
@@ -311,7 +309,6 @@ typedef void (APIENTRYP PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSi
typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar *name); typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar *name);
typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVPROC) (GLuint index, GLenum pname, GLint *params); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVPROC) (GLuint index, GLenum pname, GLint *params);
typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVPROC) (GLuint index, GLenum pname, void **pointer); typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVPROC) (GLuint index, GLenum pname, void **pointer);
typedef GLboolean (APIENTRYP PFNGLISPROGRAMPROC) (GLuint program);
typedef void (APIENTRYP PFNGLLINKPROGRAMPROC) (GLuint program); typedef void (APIENTRYP PFNGLLINKPROGRAMPROC) (GLuint program);
typedef void (APIENTRYP PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length); typedef void (APIENTRYP PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length);
typedef void (APIENTRYP PFNGLUSEPROGRAMPROC) (GLuint program); typedef void (APIENTRYP PFNGLUSEPROGRAMPROC) (GLuint program);
@@ -337,7 +334,6 @@ GLAPI void APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufSize, GLsizei
GLAPI GLint APIENTRY glGetUniformLocation (GLuint program, const GLchar *name); GLAPI GLint APIENTRY glGetUniformLocation (GLuint program, const GLchar *name);
GLAPI void APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint *params); GLAPI void APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint *params);
GLAPI void APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, void **pointer); GLAPI void APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, void **pointer);
GLAPI GLboolean APIENTRY glIsProgram (GLuint program);
GLAPI void APIENTRY glLinkProgram (GLuint program); GLAPI void APIENTRY glLinkProgram (GLuint program);
GLAPI void APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length); GLAPI void APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length);
GLAPI void APIENTRY glUseProgram (GLuint program); GLAPI void APIENTRY glUseProgram (GLuint program);
@@ -375,8 +371,6 @@ GLAPI void APIENTRY glGenVertexArrays (GLsizei n, GLuint *arrays);
typedef struct __GLsync *GLsync; typedef struct __GLsync *GLsync;
typedef khronos_uint64_t GLuint64; typedef khronos_uint64_t GLuint64;
typedef khronos_int64_t GLint64; typedef khronos_int64_t GLint64;
#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002
#define GL_CONTEXT_PROFILE_MASK 0x9126
typedef void (APIENTRYP PFNGLDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex); typedef void (APIENTRYP PFNGLDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex);
typedef void (APIENTRYP PFNGLGETINTEGER64I_VPROC) (GLenum target, GLuint index, GLint64 *data); typedef void (APIENTRYP PFNGLGETINTEGER64I_VPROC) (GLenum target, GLuint index, GLint64 *data);
#ifdef GL_GLEXT_PROTOTYPES #ifdef GL_GLEXT_PROTOTYPES
@@ -467,8 +461,8 @@ GL3W_API int imgl3wIsSupported(int major, int minor);
GL3W_API GL3WglProc imgl3wGetProcAddress(const char *proc); GL3W_API GL3WglProc imgl3wGetProcAddress(const char *proc);
/* gl3w internal state */ /* gl3w internal state */
union ImGL3WProcs { union GL3WProcs {
GL3WglProc ptr[59]; GL3WglProc ptr[58];
struct { struct {
PFNGLACTIVETEXTUREPROC ActiveTexture; PFNGLACTIVETEXTUREPROC ActiveTexture;
PFNGLATTACHSHADERPROC AttachShader; PFNGLATTACHSHADERPROC AttachShader;
@@ -515,7 +509,6 @@ union ImGL3WProcs {
PFNGLGETVERTEXATTRIBPOINTERVPROC GetVertexAttribPointerv; PFNGLGETVERTEXATTRIBPOINTERVPROC GetVertexAttribPointerv;
PFNGLGETVERTEXATTRIBIVPROC GetVertexAttribiv; PFNGLGETVERTEXATTRIBIVPROC GetVertexAttribiv;
PFNGLISENABLEDPROC IsEnabled; PFNGLISENABLEDPROC IsEnabled;
PFNGLISPROGRAMPROC IsProgram;
PFNGLLINKPROGRAMPROC LinkProgram; PFNGLLINKPROGRAMPROC LinkProgram;
PFNGLPIXELSTOREIPROC PixelStorei; PFNGLPIXELSTOREIPROC PixelStorei;
PFNGLPOLYGONMODEPROC PolygonMode; PFNGLPOLYGONMODEPROC PolygonMode;
@@ -532,7 +525,7 @@ union ImGL3WProcs {
} gl; } gl;
}; };
GL3W_API extern union ImGL3WProcs imgl3wProcs; GL3W_API extern union GL3WProcs imgl3wProcs;
/* OpenGL functions */ /* OpenGL functions */
#define glActiveTexture imgl3wProcs.gl.ActiveTexture #define glActiveTexture imgl3wProcs.gl.ActiveTexture
@@ -580,7 +573,6 @@ GL3W_API extern union ImGL3WProcs imgl3wProcs;
#define glGetVertexAttribPointerv imgl3wProcs.gl.GetVertexAttribPointerv #define glGetVertexAttribPointerv imgl3wProcs.gl.GetVertexAttribPointerv
#define glGetVertexAttribiv imgl3wProcs.gl.GetVertexAttribiv #define glGetVertexAttribiv imgl3wProcs.gl.GetVertexAttribiv
#define glIsEnabled imgl3wProcs.gl.IsEnabled #define glIsEnabled imgl3wProcs.gl.IsEnabled
#define glIsProgram imgl3wProcs.gl.IsProgram
#define glLinkProgram imgl3wProcs.gl.LinkProgram #define glLinkProgram imgl3wProcs.gl.LinkProgram
#define glPixelStorei imgl3wProcs.gl.PixelStorei #define glPixelStorei imgl3wProcs.gl.PixelStorei
#define glPolygonMode imgl3wProcs.gl.PolygonMode #define glPolygonMode imgl3wProcs.gl.PolygonMode
@@ -608,7 +600,7 @@ extern "C" {
#include <stdlib.h> #include <stdlib.h>
#define GL3W_ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#if defined(_WIN32) #if defined(_WIN32)
#ifndef WIN32_LEAN_AND_MEAN #ifndef WIN32_LEAN_AND_MEAN
@@ -666,12 +658,7 @@ static GL3WglProc (*glx_get_proc_address)(const GLubyte *);
static int open_libgl(void) static int open_libgl(void)
{ {
// While most systems use libGL.so.1, NetBSD seems to use that libGL.so.3. See https://github.com/ocornut/imgui/issues/6983
libgl = dlopen("libGL.so", RTLD_LAZY | RTLD_LOCAL);
if (!libgl)
libgl = dlopen("libGL.so.1", RTLD_LAZY | RTLD_LOCAL); libgl = dlopen("libGL.so.1", RTLD_LAZY | RTLD_LOCAL);
if (!libgl)
libgl = dlopen("libGL.so.3", RTLD_LAZY | RTLD_LOCAL);
if (!libgl) if (!libgl)
return GL3W_ERROR_LIBRARY_OPEN; return GL3W_ERROR_LIBRARY_OPEN;
*(void **)(&glx_get_proc_address) = dlsym(libgl, "glXGetProcAddressARB"); *(void **)(&glx_get_proc_address) = dlsym(libgl, "glXGetProcAddressARB");
@@ -698,13 +685,7 @@ static int parse_version(void)
return GL3W_ERROR_INIT; return GL3W_ERROR_INIT;
glGetIntegerv(GL_MAJOR_VERSION, &version.major); glGetIntegerv(GL_MAJOR_VERSION, &version.major);
glGetIntegerv(GL_MINOR_VERSION, &version.minor); glGetIntegerv(GL_MINOR_VERSION, &version.minor);
if (version.major == 0 && version.minor == 0) if (version.major < 3)
{
// Query GL_VERSION in desktop GL 2.x, the string will start with "<major>.<minor>"
if (const char* gl_version = (const char*)glGetString(GL_VERSION))
sscanf(gl_version, "%d.%d", &version.major, &version.minor);
}
if (version.major < 2)
return GL3W_ERROR_OPENGL_VERSION; return GL3W_ERROR_OPENGL_VERSION;
return GL3W_OK; return GL3W_OK;
} }
@@ -728,7 +709,7 @@ int imgl3wInit2(GL3WGetProcAddressProc proc)
int imgl3wIsSupported(int major, int minor) int imgl3wIsSupported(int major, int minor)
{ {
if (major < 2) if (major < 3)
return 0; return 0;
if (version.major == major) if (version.major == major)
return version.minor >= minor; return version.minor >= minor;
@@ -783,7 +764,6 @@ static const char *proc_names[] = {
"glGetVertexAttribPointerv", "glGetVertexAttribPointerv",
"glGetVertexAttribiv", "glGetVertexAttribiv",
"glIsEnabled", "glIsEnabled",
"glIsProgram",
"glLinkProgram", "glLinkProgram",
"glPixelStorei", "glPixelStorei",
"glPolygonMode", "glPolygonMode",
@@ -799,12 +779,12 @@ static const char *proc_names[] = {
"glViewport", "glViewport",
}; };
GL3W_API union ImGL3WProcs imgl3wProcs; GL3W_API union GL3WProcs imgl3wProcs;
static void load_procs(GL3WGetProcAddressProc proc) static void load_procs(GL3WGetProcAddressProc proc)
{ {
size_t i; size_t i;
for (i = 0; i < GL3W_ARRAY_SIZE(proc_names); i++) for (i = 0; i < ARRAY_SIZE(proc_names); i++)
imgl3wProcs.ptr[i] = proc(proc_names[i]); imgl3wProcs.ptr[i] = proc(proc_names[i]);
} }

View File

@@ -1,12 +1,10 @@
// zig-gamedev changes marked with `FIX(zig-gamedev)`
// dear imgui: Renderer for WebGPU // dear imgui: Renderer for WebGPU
// This needs to be used along with a Platform Binding (e.g. GLFW) // This needs to be used along with a Platform Binding (e.g. GLFW)
// (Please note that WebGPU is currently experimental, will not run on non-beta browsers, and may break.) // (Please note that WebGPU is currently experimental, will not run on non-beta browsers, and may break.)
// Implemented features: // Implemented features:
// [X] Renderer: User texture binding. Use 'WGPUTextureView' as ImTextureID. Read the FAQ about ImTextureID! // [X] Renderer: User texture binding. Use 'WGPUTextureView' as ImTextureID. Read the FAQ about ImTextureID!
// [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices. // [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices.
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
@@ -15,14 +13,9 @@
// CHANGELOG // CHANGELOG
// (minor and older changes stripped away, please see git history for details) // (minor and older changes stripped away, please see git history for details)
// 2023-04-11: Align buffer sizes. Use WGSL shaders instead of precompiled SPIR-V. // 2022-10-11: Using 'nullptr' instead of 'nullptr' as per our switch to C++11.
// 2023-04-11: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
// 2023-01-25: Revert automatic pipeline layout generation (see https://github.com/gpuweb/gpuweb/issues/2470)
// 2022-11-24: Fixed validation error with default depth buffer settings.
// 2022-11-10: Fixed rendering when a depth buffer is enabled. Added 'WGPUTextureFormat depth_format' parameter to ImGui_ImplWGPU_Init().
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
// 2021-11-29: Passing explicit buffer sizes to wgpuRenderPassEncoderSetVertexBuffer()/wgpuRenderPassEncoderSetIndexBuffer(). // 2021-11-29: Passing explicit buffer sizes to wgpuRenderPassEncoderSetVertexBuffer()/wgpuRenderPassEncoderSetIndexBuffer().
// 2021-08-24: Fixed for latest specs. // 2021-08-24: Fix for latest specs.
// 2021-05-24: Add support for draw_data->FramebufferScale. // 2021-05-24: Add support for draw_data->FramebufferScale.
// 2021-05-19: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement) // 2021-05-19: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
// 2021-05-16: Update to latest WebGPU specs (compatible with Emscripten 2.0.20 and Chrome Canary 92). // 2021-05-16: Update to latest WebGPU specs (compatible with Emscripten 2.0.20 and Chrome Canary 92).
@@ -33,36 +26,52 @@
#include <limits.h> #include <limits.h>
#include <webgpu/webgpu.h> #include <webgpu/webgpu.h>
#define HAS_EMSCRIPTEN_VERSION(major, minor, tiny) (__EMSCRIPTEN_major__ > (major) || (__EMSCRIPTEN_major__ == (major) && __EMSCRIPTEN_minor__ > (minor)) || (__EMSCRIPTEN_major__ == (major) && __EMSCRIPTEN_minor__ == (minor) && __EMSCRIPTEN_tiny__ >= (tiny)))
#if defined(__EMSCRIPTEN__) && !HAS_EMSCRIPTEN_VERSION(2, 0, 20)
#error "Requires at least emscripten 2.0.20"
#endif
// Dear ImGui prototypes from imgui_internal.h // Dear ImGui prototypes from imgui_internal.h
extern ImGuiID ImHashData(const void* data_p, size_t data_size, ImU32 seed = 0); extern ImGuiID ImHashData(const void* data_p, size_t data_size, ImU32 seed = 0);
#define MEMALIGN(_SIZE,_ALIGN) (((_SIZE) + ((_ALIGN) - 1)) & ~((_ALIGN) - 1)) // Memory align (copied from IM_ALIGN() macro).
// FIX(zig-gamedev): We removed header file and declare all our external functions here. // mziulek: We removed header file and declare all our external functions here.
extern "C" { extern "C" {
IMGUI_IMPL_API bool ImGui_ImplWGPU_Init(WGPUDevice device, int num_frames_in_flight, WGPUTextureFormat rt_format, WGPUTextureFormat depth_format = WGPUTextureFormat_Undefined); struct Config
IMGUI_IMPL_API void ImGui_ImplWGPU_Shutdown(void); {
IMGUI_IMPL_API void ImGui_ImplWGPU_NewFrame(void); unsigned int pipeline_multisample_count;
IMGUI_IMPL_API void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder pass_encoder); unsigned int texture_filter_mode;
};
bool ImGui_ImplWGPU_Init(WGPUDevice device, int num_frames_in_flight, WGPUTextureFormat rt_format, const Config* config);
void ImGui_ImplWGPU_Shutdown(void);
void ImGui_ImplWGPU_NewFrame(void);
void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder pass_encoder);
// Use if you want to reset your rendering device without losing Dear ImGui state. // Use if you want to reset your rendering device without losing Dear ImGui state.
IMGUI_IMPL_API void ImGui_ImplWGPU_InvalidateDeviceObjects(void); void ImGui_ImplWGPU_InvalidateDeviceObjects(void);
IMGUI_IMPL_API bool ImGui_ImplWGPU_CreateDeviceObjects(void); bool ImGui_ImplWGPU_CreateDeviceObjects(void);
} // extern "C" } // extern "C"
// WebGPU data // WebGPU data
static WGPUDevice g_wgpuDevice = nullptr;
static WGPUQueue g_defaultQueue = nullptr;
static WGPUTextureFormat g_renderTargetFormat = WGPUTextureFormat_Undefined;
static WGPURenderPipeline g_pipelineState = nullptr;
struct RenderResources struct RenderResources
{ {
WGPUTexture FontTexture = nullptr; // Font texture WGPUTexture FontTexture; // Font texture
WGPUTextureView FontTextureView = nullptr; // Texture view for font texture WGPUTextureView FontTextureView; // Texture view for font texture
WGPUSampler Sampler = nullptr; // Sampler for the font texture WGPUSampler Sampler; // Sampler for the font texture
WGPUBuffer Uniforms = nullptr; // Shader uniforms WGPUBuffer Uniforms; // Shader uniforms
WGPUBindGroup CommonBindGroup = nullptr; // Resources bind-group to bind the common resources to pipeline WGPUBindGroup CommonBindGroup; // Resources bind-group to bind the common resources to pipeline
ImGuiStorage ImageBindGroups; // Resources bind-group to bind the font/image resources to pipeline (this is a key->value map) ImGuiStorage ImageBindGroups; // Resources bind-group to bind the font/image resources to pipeline (this is a key->value map)
WGPUBindGroup ImageBindGroup = nullptr; // Default font-resource of Dear ImGui WGPUBindGroup ImageBindGroup; // Default font-resource of Dear ImGui
WGPUBindGroupLayout ImageBindGroupLayout = nullptr; // Cache layout used for the image bind group. Avoids allocating unnecessary JS objects when working with WebASM WGPUBindGroupLayout ImageBindGroupLayout; // Cache layout used for the image bind group. Avoids allocating unnecessary JS objects when working with WebASM
}; };
static RenderResources g_resources;
struct FrameResources struct FrameResources
{ {
@@ -73,91 +82,129 @@ struct FrameResources
int IndexBufferSize; int IndexBufferSize;
int VertexBufferSize; int VertexBufferSize;
}; };
static FrameResources* g_pFrameResources = nullptr;
static unsigned int g_numFramesInFlight = 0;
static unsigned int g_frameIndex = UINT_MAX;
struct Uniforms struct Uniforms
{ {
float MVP[4][4]; float MVP[4][4];
float Gamma;
}; };
struct ImGui_ImplWGPU_Data
{
WGPUDevice wgpuDevice = nullptr;
WGPUQueue defaultQueue = nullptr;
WGPUTextureFormat renderTargetFormat = WGPUTextureFormat_Undefined;
WGPUTextureFormat depthStencilFormat = WGPUTextureFormat_Undefined;
WGPURenderPipeline pipelineState = nullptr;
RenderResources renderResources; static Config g_config;
FrameResources* pFrameResources = nullptr;
unsigned int numFramesInFlight = 0;
unsigned int frameIndex = UINT_MAX;
};
// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts
// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts.
static ImGui_ImplWGPU_Data* ImGui_ImplWGPU_GetBackendData()
{
return ImGui::GetCurrentContext() ? (ImGui_ImplWGPU_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// SHADERS // SHADERS
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static const char __shader_vert_wgsl[] = R"( // glsl_shader.vert, compiled with:
struct VertexInput { // # glslangValidator -V -x -o glsl_shader.vert.u32 glsl_shader.vert
@location(0) position: vec2<f32>, /*
@location(1) uv: vec2<f32>, #version 450 core
@location(2) color: vec4<f32>, layout(location = 0) in vec2 aPos;
}; layout(location = 1) in vec2 aUV;
layout(location = 2) in vec4 aColor;
layout(set=0, binding = 0) uniform transform { mat4 mvp; };
struct VertexOutput { out gl_PerVertex { vec4 gl_Position; };
@builtin(position) position: vec4<f32>, layout(location = 0) out struct { vec4 Color; vec2 UV; } Out;
@location(0) color: vec4<f32>,
@location(1) uv: vec2<f32>,
};
struct Uniforms { void main()
mvp: mat4x4<f32>, {
gamma: f32, Out.Color = aColor;
}; Out.UV = aUV;
gl_Position = mvp * vec4(aPos, 0, 1);
@group(0) @binding(0) var<uniform> uniforms: Uniforms;
@vertex
fn main(in: VertexInput) -> VertexOutput {
var out: VertexOutput;
out.position = uniforms.mvp * vec4<f32>(in.position, 0.0, 1.0);
out.color = in.color;
out.uv = in.uv;
return out;
} }
)"; */
static uint32_t __glsl_shader_vert_spv[] =
static const char __shader_frag_wgsl[] = R"( {
struct VertexOutput { 0x07230203,0x00010000,0x00080007,0x0000002c,0x00000000,0x00020011,0x00000001,0x0006000b,
@builtin(position) position: vec4<f32>, 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001,
@location(0) color: vec4<f32>, 0x000a000f,0x00000000,0x00000004,0x6e69616d,0x00000000,0x0000000b,0x0000000f,0x00000015,
@location(1) uv: vec2<f32>, 0x0000001b,0x00000023,0x00030003,0x00000002,0x000001c2,0x00040005,0x00000004,0x6e69616d,
0x00000000,0x00030005,0x00000009,0x00000000,0x00050006,0x00000009,0x00000000,0x6f6c6f43,
0x00000072,0x00040006,0x00000009,0x00000001,0x00005655,0x00030005,0x0000000b,0x0074754f,
0x00040005,0x0000000f,0x6c6f4361,0x0000726f,0x00030005,0x00000015,0x00565561,0x00060005,
0x00000019,0x505f6c67,0x65567265,0x78657472,0x00000000,0x00060006,0x00000019,0x00000000,
0x505f6c67,0x7469736f,0x006e6f69,0x00030005,0x0000001b,0x00000000,0x00050005,0x0000001d,
0x6e617274,0x726f6673,0x0000006d,0x00040006,0x0000001d,0x00000000,0x0070766d,0x00030005,
0x0000001f,0x00000000,0x00040005,0x00000023,0x736f5061,0x00000000,0x00040047,0x0000000b,
0x0000001e,0x00000000,0x00040047,0x0000000f,0x0000001e,0x00000002,0x00040047,0x00000015,
0x0000001e,0x00000001,0x00050048,0x00000019,0x00000000,0x0000000b,0x00000000,0x00030047,
0x00000019,0x00000002,0x00040048,0x0000001d,0x00000000,0x00000005,0x00050048,0x0000001d,
0x00000000,0x00000023,0x00000000,0x00050048,0x0000001d,0x00000000,0x00000007,0x00000010,
0x00030047,0x0000001d,0x00000002,0x00040047,0x0000001f,0x00000022,0x00000000,0x00040047,
0x0000001f,0x00000021,0x00000000,0x00040047,0x00000023,0x0000001e,0x00000000,0x00020013,
0x00000002,0x00030021,0x00000003,0x00000002,0x00030016,0x00000006,0x00000020,0x00040017,
0x00000007,0x00000006,0x00000004,0x00040017,0x00000008,0x00000006,0x00000002,0x0004001e,
0x00000009,0x00000007,0x00000008,0x00040020,0x0000000a,0x00000003,0x00000009,0x0004003b,
0x0000000a,0x0000000b,0x00000003,0x00040015,0x0000000c,0x00000020,0x00000001,0x0004002b,
0x0000000c,0x0000000d,0x00000000,0x00040020,0x0000000e,0x00000001,0x00000007,0x0004003b,
0x0000000e,0x0000000f,0x00000001,0x00040020,0x00000011,0x00000003,0x00000007,0x0004002b,
0x0000000c,0x00000013,0x00000001,0x00040020,0x00000014,0x00000001,0x00000008,0x0004003b,
0x00000014,0x00000015,0x00000001,0x00040020,0x00000017,0x00000003,0x00000008,0x0003001e,
0x00000019,0x00000007,0x00040020,0x0000001a,0x00000003,0x00000019,0x0004003b,0x0000001a,
0x0000001b,0x00000003,0x00040018,0x0000001c,0x00000007,0x00000004,0x0003001e,0x0000001d,
0x0000001c,0x00040020,0x0000001e,0x00000002,0x0000001d,0x0004003b,0x0000001e,0x0000001f,
0x00000002,0x00040020,0x00000020,0x00000002,0x0000001c,0x0004003b,0x00000014,0x00000023,
0x00000001,0x0004002b,0x00000006,0x00000025,0x00000000,0x0004002b,0x00000006,0x00000026,
0x3f800000,0x00050036,0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005,
0x0004003d,0x00000007,0x00000010,0x0000000f,0x00050041,0x00000011,0x00000012,0x0000000b,
0x0000000d,0x0003003e,0x00000012,0x00000010,0x0004003d,0x00000008,0x00000016,0x00000015,
0x00050041,0x00000017,0x00000018,0x0000000b,0x00000013,0x0003003e,0x00000018,0x00000016,
0x00050041,0x00000020,0x00000021,0x0000001f,0x0000000d,0x0004003d,0x0000001c,0x00000022,
0x00000021,0x0004003d,0x00000008,0x00000024,0x00000023,0x00050051,0x00000006,0x00000027,
0x00000024,0x00000000,0x00050051,0x00000006,0x00000028,0x00000024,0x00000001,0x00070050,
0x00000007,0x00000029,0x00000027,0x00000028,0x00000025,0x00000026,0x00050091,0x00000007,
0x0000002a,0x00000022,0x00000029,0x00050041,0x00000011,0x0000002b,0x0000001b,0x0000000d,
0x0003003e,0x0000002b,0x0000002a,0x000100fd,0x00010038
}; };
struct Uniforms { // glsl_shader.frag, compiled with:
mvp: mat4x4<f32>, // # glslangValidator -V -x -o glsl_shader.frag.u32 glsl_shader.frag
gamma: f32, /*
}; #version 450 core
layout(location = 0) out vec4 fColor;
@group(0) @binding(0) var<uniform> uniforms: Uniforms; layout(set=0, binding=1) uniform sampler s;
@group(0) @binding(1) var s: sampler; layout(set=1, binding=0) uniform texture2D t;
@group(1) @binding(0) var t: texture_2d<f32>; layout(location = 0) in struct { vec4 Color; vec2 UV; } In;
void main()
@fragment {
fn main(in: VertexOutput) -> @location(0) vec4<f32> { fColor = In.Color * texture(sampler2D(t, s), In.UV.st);
let color = in.color * textureSample(t, s, in.uv);
let corrected_color = pow(color.rgb, vec3<f32>(uniforms.gamma));
return vec4<f32>(corrected_color, color.a);
} }
)"; */
static uint32_t __glsl_shader_frag_spv[] =
{
0x07230203,0x00010000,0x00080007,0x00000023,0x00000000,0x00020011,0x00000001,0x0006000b,
0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001,
0x0007000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x00000009,0x0000000d,0x00030010,
0x00000004,0x00000007,0x00030003,0x00000002,0x000001c2,0x00040005,0x00000004,0x6e69616d,
0x00000000,0x00040005,0x00000009,0x6c6f4366,0x0000726f,0x00030005,0x0000000b,0x00000000,
0x00050006,0x0000000b,0x00000000,0x6f6c6f43,0x00000072,0x00040006,0x0000000b,0x00000001,
0x00005655,0x00030005,0x0000000d,0x00006e49,0x00030005,0x00000015,0x00000074,0x00030005,
0x00000019,0x00000073,0x00040047,0x00000009,0x0000001e,0x00000000,0x00040047,0x0000000d,
0x0000001e,0x00000000,0x00040047,0x00000015,0x00000022,0x00000001,0x00040047,0x00000015,
0x00000021,0x00000000,0x00040047,0x00000019,0x00000022,0x00000000,0x00040047,0x00000019,
0x00000021,0x00000001,0x00020013,0x00000002,0x00030021,0x00000003,0x00000002,0x00030016,
0x00000006,0x00000020,0x00040017,0x00000007,0x00000006,0x00000004,0x00040020,0x00000008,
0x00000003,0x00000007,0x0004003b,0x00000008,0x00000009,0x00000003,0x00040017,0x0000000a,
0x00000006,0x00000002,0x0004001e,0x0000000b,0x00000007,0x0000000a,0x00040020,0x0000000c,
0x00000001,0x0000000b,0x0004003b,0x0000000c,0x0000000d,0x00000001,0x00040015,0x0000000e,
0x00000020,0x00000001,0x0004002b,0x0000000e,0x0000000f,0x00000000,0x00040020,0x00000010,
0x00000001,0x00000007,0x00090019,0x00000013,0x00000006,0x00000001,0x00000000,0x00000000,
0x00000000,0x00000001,0x00000000,0x00040020,0x00000014,0x00000000,0x00000013,0x0004003b,
0x00000014,0x00000015,0x00000000,0x0002001a,0x00000017,0x00040020,0x00000018,0x00000000,
0x00000017,0x0004003b,0x00000018,0x00000019,0x00000000,0x0003001b,0x0000001b,0x00000013,
0x0004002b,0x0000000e,0x0000001d,0x00000001,0x00040020,0x0000001e,0x00000001,0x0000000a,
0x00050036,0x00000002,0x00000004,0x00000000,0x00000003,0x000200f8,0x00000005,0x00050041,
0x00000010,0x00000011,0x0000000d,0x0000000f,0x0004003d,0x00000007,0x00000012,0x00000011,
0x0004003d,0x00000013,0x00000016,0x00000015,0x0004003d,0x00000017,0x0000001a,0x00000019,
0x00050056,0x0000001b,0x0000001c,0x00000016,0x0000001a,0x00050041,0x0000001e,0x0000001f,
0x0000000d,0x0000001d,0x0004003d,0x0000000a,0x00000020,0x0000001f,0x00050057,0x00000007,
0x00000021,0x0000001c,0x00000020,0x00050085,0x00000007,0x00000022,0x00000012,0x00000021,
0x0003003e,0x00000009,0x00000022,0x000100fd,0x00010038
};
static void SafeRelease(ImDrawIdx*& res) static void SafeRelease(ImDrawIdx*& res)
{ {
@@ -239,40 +286,35 @@ static void SafeRelease(FrameResources& res)
SafeRelease(res.VertexBufferHost); SafeRelease(res.VertexBufferHost);
} }
static WGPUProgrammableStageDescriptor ImGui_ImplWGPU_CreateShaderModule(const char* wgsl_source) static WGPUProgrammableStageDescriptor ImGui_ImplWGPU_CreateShaderModule(uint32_t* binary_data, uint32_t binary_data_size)
{ {
ImGui_ImplWGPU_Data* bd = ImGui_ImplWGPU_GetBackendData(); WGPUShaderModuleSPIRVDescriptor spirv_desc = {};
spirv_desc.chain.sType = WGPUSType_ShaderModuleSPIRVDescriptor;
WGPUShaderModuleWGSLDescriptor wgsl_desc = {}; spirv_desc.codeSize = binary_data_size;
wgsl_desc.chain.sType = WGPUSType_ShaderModuleWGSLDescriptor; spirv_desc.code = binary_data;
// FiX(zig-gamedev): `.source` renamed to `.code`
wgsl_desc.code = wgsl_source;
WGPUShaderModuleDescriptor desc = {}; WGPUShaderModuleDescriptor desc = {};
desc.nextInChain = reinterpret_cast<WGPUChainedStruct*>(&wgsl_desc); desc.nextInChain = reinterpret_cast<WGPUChainedStruct*>(&spirv_desc);
WGPUProgrammableStageDescriptor stage_desc = {}; WGPUProgrammableStageDescriptor stage_desc = {};
stage_desc.module = wgpuDeviceCreateShaderModule(bd->wgpuDevice, &desc); stage_desc.module = wgpuDeviceCreateShaderModule(g_wgpuDevice, &desc);
stage_desc.entryPoint = "main"; stage_desc.entryPoint = "main";
return stage_desc; return stage_desc;
} }
static WGPUBindGroup ImGui_ImplWGPU_CreateImageBindGroup(WGPUBindGroupLayout layout, WGPUTextureView texture) static WGPUBindGroup ImGui_ImplWGPU_CreateImageBindGroup(WGPUBindGroupLayout layout, WGPUTextureView texture)
{ {
ImGui_ImplWGPU_Data* bd = ImGui_ImplWGPU_GetBackendData();
WGPUBindGroupEntry image_bg_entries[] = { { nullptr, 0, 0, 0, 0, 0, texture } }; WGPUBindGroupEntry image_bg_entries[] = { { nullptr, 0, 0, 0, 0, 0, texture } };
WGPUBindGroupDescriptor image_bg_descriptor = {}; WGPUBindGroupDescriptor image_bg_descriptor = {};
image_bg_descriptor.layout = layout; image_bg_descriptor.layout = layout;
image_bg_descriptor.entryCount = sizeof(image_bg_entries) / sizeof(WGPUBindGroupEntry); image_bg_descriptor.entryCount = sizeof(image_bg_entries) / sizeof(WGPUBindGroupEntry);
image_bg_descriptor.entries = image_bg_entries; image_bg_descriptor.entries = image_bg_entries;
return wgpuDeviceCreateBindGroup(bd->wgpuDevice, &image_bg_descriptor); return wgpuDeviceCreateBindGroup(g_wgpuDevice, &image_bg_descriptor);
} }
static void ImGui_ImplWGPU_SetupRenderState(ImDrawData* draw_data, WGPURenderPassEncoder ctx, FrameResources* fr) static void ImGui_ImplWGPU_SetupRenderState(ImDrawData* draw_data, WGPURenderPassEncoder ctx, FrameResources* fr)
{ {
ImGui_ImplWGPU_Data* bd = ImGui_ImplWGPU_GetBackendData();
// Setup orthographic projection matrix into our constant buffer // Setup orthographic projection matrix into our constant buffer
// Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). // Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right).
{ {
@@ -287,38 +329,7 @@ static void ImGui_ImplWGPU_SetupRenderState(ImDrawData* draw_data, WGPURenderPas
{ 0.0f, 0.0f, 0.5f, 0.0f }, { 0.0f, 0.0f, 0.5f, 0.0f },
{ (R+L)/(L-R), (T+B)/(B-T), 0.5f, 1.0f }, { (R+L)/(L-R), (T+B)/(B-T), 0.5f, 1.0f },
}; };
wgpuQueueWriteBuffer(bd->defaultQueue, bd->renderResources.Uniforms, offsetof(Uniforms, MVP), mvp, sizeof(Uniforms::MVP)); wgpuQueueWriteBuffer(g_defaultQueue, g_resources.Uniforms, 0, mvp, sizeof(mvp));
float gamma;
switch (bd->renderTargetFormat)
{
case WGPUTextureFormat_ASTC10x10UnormSrgb:
case WGPUTextureFormat_ASTC10x5UnormSrgb:
case WGPUTextureFormat_ASTC10x6UnormSrgb:
case WGPUTextureFormat_ASTC10x8UnormSrgb:
case WGPUTextureFormat_ASTC12x10UnormSrgb:
case WGPUTextureFormat_ASTC12x12UnormSrgb:
case WGPUTextureFormat_ASTC4x4UnormSrgb:
case WGPUTextureFormat_ASTC5x5UnormSrgb:
case WGPUTextureFormat_ASTC6x5UnormSrgb:
case WGPUTextureFormat_ASTC6x6UnormSrgb:
case WGPUTextureFormat_ASTC8x5UnormSrgb:
case WGPUTextureFormat_ASTC8x6UnormSrgb:
case WGPUTextureFormat_ASTC8x8UnormSrgb:
case WGPUTextureFormat_BC1RGBAUnormSrgb:
case WGPUTextureFormat_BC2RGBAUnormSrgb:
case WGPUTextureFormat_BC3RGBAUnormSrgb:
case WGPUTextureFormat_BC7RGBAUnormSrgb:
case WGPUTextureFormat_BGRA8UnormSrgb:
case WGPUTextureFormat_ETC2RGB8A1UnormSrgb:
case WGPUTextureFormat_ETC2RGB8UnormSrgb:
case WGPUTextureFormat_ETC2RGBA8UnormSrgb:
case WGPUTextureFormat_RGBA8UnormSrgb:
gamma = 2.2f;
break;
default:
gamma = 1.0f;
}
wgpuQueueWriteBuffer(bd->defaultQueue, bd->renderResources.Uniforms, offsetof(Uniforms, Gamma), &gamma, sizeof(Uniforms::Gamma));
} }
// Setup viewport // Setup viewport
@@ -327,8 +338,8 @@ static void ImGui_ImplWGPU_SetupRenderState(ImDrawData* draw_data, WGPURenderPas
// Bind shader and vertex buffers // Bind shader and vertex buffers
wgpuRenderPassEncoderSetVertexBuffer(ctx, 0, fr->VertexBuffer, 0, fr->VertexBufferSize * sizeof(ImDrawVert)); wgpuRenderPassEncoderSetVertexBuffer(ctx, 0, fr->VertexBuffer, 0, fr->VertexBufferSize * sizeof(ImDrawVert));
wgpuRenderPassEncoderSetIndexBuffer(ctx, fr->IndexBuffer, sizeof(ImDrawIdx) == 2 ? WGPUIndexFormat_Uint16 : WGPUIndexFormat_Uint32, 0, fr->IndexBufferSize * sizeof(ImDrawIdx)); wgpuRenderPassEncoderSetIndexBuffer(ctx, fr->IndexBuffer, sizeof(ImDrawIdx) == 2 ? WGPUIndexFormat_Uint16 : WGPUIndexFormat_Uint32, 0, fr->IndexBufferSize * sizeof(ImDrawIdx));
wgpuRenderPassEncoderSetPipeline(ctx, bd->pipelineState); wgpuRenderPassEncoderSetPipeline(ctx, g_pipelineState);
wgpuRenderPassEncoderSetBindGroup(ctx, 0, bd->renderResources.CommonBindGroup, 0, nullptr); wgpuRenderPassEncoderSetBindGroup(ctx, 0, g_resources.CommonBindGroup, 0, nullptr);
// Setup blend factor // Setup blend factor
WGPUColor blend_color = { 0.f, 0.f, 0.f, 0.f }; WGPUColor blend_color = { 0.f, 0.f, 0.f, 0.f };
@@ -345,9 +356,8 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
// FIXME: Assuming that this only gets called once per frame! // FIXME: Assuming that this only gets called once per frame!
// If not, we can't just re-allocate the IB or VB, we'll have to do a proper allocator. // If not, we can't just re-allocate the IB or VB, we'll have to do a proper allocator.
ImGui_ImplWGPU_Data* bd = ImGui_ImplWGPU_GetBackendData(); g_frameIndex = g_frameIndex + 1;
bd->frameIndex = bd->frameIndex + 1; FrameResources* fr = &g_pFrameResources[g_frameIndex % g_numFramesInFlight];
FrameResources* fr = &bd->pFrameResources[bd->frameIndex % bd->numFramesInFlight];
// Create and grow vertex/index buffers if needed // Create and grow vertex/index buffers if needed
if (fr->VertexBuffer == nullptr || fr->VertexBufferSize < draw_data->TotalVtxCount) if (fr->VertexBuffer == nullptr || fr->VertexBufferSize < draw_data->TotalVtxCount)
@@ -365,10 +375,10 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
nullptr, nullptr,
"Dear ImGui Vertex buffer", "Dear ImGui Vertex buffer",
WGPUBufferUsage_CopyDst | WGPUBufferUsage_Vertex, WGPUBufferUsage_CopyDst | WGPUBufferUsage_Vertex,
MEMALIGN(fr->VertexBufferSize * sizeof(ImDrawVert), 4), fr->VertexBufferSize * sizeof(ImDrawVert),
false false
}; };
fr->VertexBuffer = wgpuDeviceCreateBuffer(bd->wgpuDevice, &vb_desc); fr->VertexBuffer = wgpuDeviceCreateBuffer(g_wgpuDevice, &vb_desc);
if (!fr->VertexBuffer) if (!fr->VertexBuffer)
return; return;
@@ -389,10 +399,10 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
nullptr, nullptr,
"Dear ImGui Index buffer", "Dear ImGui Index buffer",
WGPUBufferUsage_CopyDst | WGPUBufferUsage_Index, WGPUBufferUsage_CopyDst | WGPUBufferUsage_Index,
MEMALIGN(fr->IndexBufferSize * sizeof(ImDrawIdx), 4), fr->IndexBufferSize * sizeof(ImDrawIdx),
false false
}; };
fr->IndexBuffer = wgpuDeviceCreateBuffer(bd->wgpuDevice, &ib_desc); fr->IndexBuffer = wgpuDeviceCreateBuffer(g_wgpuDevice, &ib_desc);
if (!fr->IndexBuffer) if (!fr->IndexBuffer)
return; return;
@@ -410,10 +420,10 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
vtx_dst += cmd_list->VtxBuffer.Size; vtx_dst += cmd_list->VtxBuffer.Size;
idx_dst += cmd_list->IdxBuffer.Size; idx_dst += cmd_list->IdxBuffer.Size;
} }
int64_t vb_write_size = MEMALIGN((char*)vtx_dst - (char*)fr->VertexBufferHost, 4); int64_t vb_write_size = ((char*)vtx_dst - (char*)fr->VertexBufferHost + 3) & ~3;
int64_t ib_write_size = MEMALIGN((char*)idx_dst - (char*)fr->IndexBufferHost, 4); int64_t ib_write_size = ((char*)idx_dst - (char*)fr->IndexBufferHost + 3) & ~3;
wgpuQueueWriteBuffer(bd->defaultQueue, fr->VertexBuffer, 0, fr->VertexBufferHost, vb_write_size); wgpuQueueWriteBuffer(g_defaultQueue, fr->VertexBuffer, 0, fr->VertexBufferHost, vb_write_size);
wgpuQueueWriteBuffer(bd->defaultQueue, fr->IndexBuffer, 0, fr->IndexBufferHost, ib_write_size); wgpuQueueWriteBuffer(g_defaultQueue, fr->IndexBuffer, 0, fr->IndexBufferHost, ib_write_size);
// Setup desired render state // Setup desired render state
ImGui_ImplWGPU_SetupRenderState(draw_data, pass_encoder, fr); ImGui_ImplWGPU_SetupRenderState(draw_data, pass_encoder, fr);
@@ -444,15 +454,15 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
// Bind custom texture // Bind custom texture
ImTextureID tex_id = pcmd->GetTexID(); ImTextureID tex_id = pcmd->GetTexID();
ImGuiID tex_id_hash = ImHashData(&tex_id, sizeof(tex_id)); ImGuiID tex_id_hash = ImHashData(&tex_id, sizeof(tex_id));
auto bind_group = bd->renderResources.ImageBindGroups.GetVoidPtr(tex_id_hash); auto bind_group = g_resources.ImageBindGroups.GetVoidPtr(tex_id_hash);
if (bind_group) if (bind_group)
{ {
wgpuRenderPassEncoderSetBindGroup(pass_encoder, 1, (WGPUBindGroup)bind_group, 0, nullptr); wgpuRenderPassEncoderSetBindGroup(pass_encoder, 1, (WGPUBindGroup)bind_group, 0, nullptr);
} }
else else
{ {
WGPUBindGroup image_bind_group = ImGui_ImplWGPU_CreateImageBindGroup(bd->renderResources.ImageBindGroupLayout, (WGPUTextureView)tex_id); WGPUBindGroup image_bind_group = ImGui_ImplWGPU_CreateImageBindGroup(g_resources.ImageBindGroupLayout, (WGPUTextureView)tex_id);
bd->renderResources.ImageBindGroups.SetVoidPtr(tex_id_hash, image_bind_group); g_resources.ImageBindGroups.SetVoidPtr(tex_id_hash, image_bind_group);
wgpuRenderPassEncoderSetBindGroup(pass_encoder, 1, image_bind_group, 0, nullptr); wgpuRenderPassEncoderSetBindGroup(pass_encoder, 1, image_bind_group, 0, nullptr);
} }
@@ -462,7 +472,7 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y) if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
continue; continue;
// FIX(zig-gamedev): Fixes 'Popups and Modal windows->Modals->Stacked modals..' from showDemoWindow(). // mziulek: Fixes 'Popups and Modal windows->Modals->Stacked modals..' from showDemoWindow().
if (clip_min.x < 0.0f) clip_min.x = 0.0f; if (clip_min.x < 0.0f) clip_min.x = 0.0f;
if (clip_min.y < 0.0f) clip_min.y = 0.0f; if (clip_min.y < 0.0f) clip_min.y = 0.0f;
if (clip_max.x > draw_data->DisplaySize.x) clip_max.x = draw_data->DisplaySize.x; if (clip_max.x > draw_data->DisplaySize.x) clip_max.x = draw_data->DisplaySize.x;
@@ -481,7 +491,6 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
static void ImGui_ImplWGPU_CreateFontsTexture() static void ImGui_ImplWGPU_CreateFontsTexture()
{ {
// Build texture atlas // Build texture atlas
ImGui_ImplWGPU_Data* bd = ImGui_ImplWGPU_GetBackendData();
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
unsigned char* pixels; unsigned char* pixels;
int width, height, size_pp; int width, height, size_pp;
@@ -499,7 +508,7 @@ static void ImGui_ImplWGPU_CreateFontsTexture()
tex_desc.format = WGPUTextureFormat_RGBA8Unorm; tex_desc.format = WGPUTextureFormat_RGBA8Unorm;
tex_desc.mipLevelCount = 1; tex_desc.mipLevelCount = 1;
tex_desc.usage = WGPUTextureUsage_CopyDst | WGPUTextureUsage_TextureBinding; tex_desc.usage = WGPUTextureUsage_CopyDst | WGPUTextureUsage_TextureBinding;
bd->renderResources.FontTexture = wgpuDeviceCreateTexture(bd->wgpuDevice, &tex_desc); g_resources.FontTexture = wgpuDeviceCreateTexture(g_wgpuDevice, &tex_desc);
WGPUTextureViewDescriptor tex_view_desc = {}; WGPUTextureViewDescriptor tex_view_desc = {};
tex_view_desc.format = WGPUTextureFormat_RGBA8Unorm; tex_view_desc.format = WGPUTextureFormat_RGBA8Unorm;
@@ -509,13 +518,13 @@ static void ImGui_ImplWGPU_CreateFontsTexture()
tex_view_desc.baseArrayLayer = 0; tex_view_desc.baseArrayLayer = 0;
tex_view_desc.arrayLayerCount = 1; tex_view_desc.arrayLayerCount = 1;
tex_view_desc.aspect = WGPUTextureAspect_All; tex_view_desc.aspect = WGPUTextureAspect_All;
bd->renderResources.FontTextureView = wgpuTextureCreateView(bd->renderResources.FontTexture, &tex_view_desc); g_resources.FontTextureView = wgpuTextureCreateView(g_resources.FontTexture, &tex_view_desc);
} }
// Upload texture data // Upload texture data
{ {
WGPUImageCopyTexture dst_view = {}; WGPUImageCopyTexture dst_view = {};
dst_view.texture = bd->renderResources.FontTexture; dst_view.texture = g_resources.FontTexture;
dst_view.mipLevel = 0; dst_view.mipLevel = 0;
dst_view.origin = { 0, 0, 0 }; dst_view.origin = { 0, 0, 0 };
dst_view.aspect = WGPUTextureAspect_All; dst_view.aspect = WGPUTextureAspect_All;
@@ -524,49 +533,50 @@ static void ImGui_ImplWGPU_CreateFontsTexture()
layout.bytesPerRow = width * size_pp; layout.bytesPerRow = width * size_pp;
layout.rowsPerImage = height; layout.rowsPerImage = height;
WGPUExtent3D size = { (uint32_t)width, (uint32_t)height, 1 }; WGPUExtent3D size = { (uint32_t)width, (uint32_t)height, 1 };
wgpuQueueWriteTexture(bd->defaultQueue, &dst_view, pixels, (uint32_t)(width * size_pp * height), &layout, &size); wgpuQueueWriteTexture(g_defaultQueue, &dst_view, pixels, (uint32_t)(width * size_pp * height), &layout, &size);
} }
// Create the associated sampler // Create the associated sampler
// (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling) // (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)
{ {
const WGPUMipmapFilterMode mipmap_filter_mode = g_config.texture_filter_mode == 1 ? WGPUMipmapFilterMode_Linear : WGPUMipmapFilterMode_Nearest;
const WGPUFilterMode filter_mode = g_config.texture_filter_mode == 1 ? WGPUFilterMode_Linear : WGPUFilterMode_Nearest;
WGPUSamplerDescriptor sampler_desc = {}; WGPUSamplerDescriptor sampler_desc = {};
sampler_desc.minFilter = WGPUFilterMode_Linear; sampler_desc.minFilter = filter_mode;
sampler_desc.magFilter = WGPUFilterMode_Linear; sampler_desc.magFilter = filter_mode;
// FIX(zig-gamedev): WGPUFilterMode_Linear should be WGPUMipmapFilterMode_Linear sampler_desc.mipmapFilter = mipmap_filter_mode;
sampler_desc.mipmapFilter = WGPUMipmapFilterMode_Linear;
sampler_desc.addressModeU = WGPUAddressMode_Repeat; sampler_desc.addressModeU = WGPUAddressMode_Repeat;
sampler_desc.addressModeV = WGPUAddressMode_Repeat; sampler_desc.addressModeV = WGPUAddressMode_Repeat;
sampler_desc.addressModeW = WGPUAddressMode_Repeat; sampler_desc.addressModeW = WGPUAddressMode_Repeat;
sampler_desc.maxAnisotropy = 1; sampler_desc.maxAnisotropy = 1;
bd->renderResources.Sampler = wgpuDeviceCreateSampler(bd->wgpuDevice, &sampler_desc); g_resources.Sampler = wgpuDeviceCreateSampler(g_wgpuDevice, &sampler_desc);
} }
// Store our identifier // Store our identifier
static_assert(sizeof(ImTextureID) >= sizeof(bd->renderResources.FontTexture), "Can't pack descriptor handle into TexID, 32-bit not supported yet."); static_assert(sizeof(ImTextureID) >= sizeof(g_resources.FontTexture), "Can't pack descriptor handle into TexID, 32-bit not supported yet.");
io.Fonts->SetTexID((ImTextureID)bd->renderResources.FontTextureView); io.Fonts->SetTexID((ImTextureID)g_resources.FontTextureView);
} }
static void ImGui_ImplWGPU_CreateUniformBuffer() static void ImGui_ImplWGPU_CreateUniformBuffer()
{ {
ImGui_ImplWGPU_Data* bd = ImGui_ImplWGPU_GetBackendData();
WGPUBufferDescriptor ub_desc = WGPUBufferDescriptor ub_desc =
{ {
nullptr, nullptr,
"Dear ImGui Uniform buffer", "Dear ImGui Uniform buffer",
WGPUBufferUsage_CopyDst | WGPUBufferUsage_Uniform, WGPUBufferUsage_CopyDst | WGPUBufferUsage_Uniform,
MEMALIGN(sizeof(Uniforms), 16), sizeof(Uniforms),
false false
}; };
bd->renderResources.Uniforms = wgpuDeviceCreateBuffer(bd->wgpuDevice, &ub_desc); g_resources.Uniforms = wgpuDeviceCreateBuffer(g_wgpuDevice, &ub_desc);
} }
bool ImGui_ImplWGPU_CreateDeviceObjects() bool ImGui_ImplWGPU_CreateDeviceObjects(void)
{ {
ImGui_ImplWGPU_Data* bd = ImGui_ImplWGPU_GetBackendData(); if (!g_wgpuDevice)
if (!bd->wgpuDevice)
return false; return false;
if (bd->pipelineState) if (g_pipelineState)
ImGui_ImplWGPU_InvalidateDeviceObjects(); ImGui_ImplWGPU_InvalidateDeviceObjects();
// Create render pipeline // Create render pipeline
@@ -575,44 +585,13 @@ bool ImGui_ImplWGPU_CreateDeviceObjects()
graphics_pipeline_desc.primitive.stripIndexFormat = WGPUIndexFormat_Undefined; graphics_pipeline_desc.primitive.stripIndexFormat = WGPUIndexFormat_Undefined;
graphics_pipeline_desc.primitive.frontFace = WGPUFrontFace_CW; graphics_pipeline_desc.primitive.frontFace = WGPUFrontFace_CW;
graphics_pipeline_desc.primitive.cullMode = WGPUCullMode_None; graphics_pipeline_desc.primitive.cullMode = WGPUCullMode_None;
graphics_pipeline_desc.multisample.count = 1; graphics_pipeline_desc.multisample.count = g_config.pipeline_multisample_count;
graphics_pipeline_desc.multisample.mask = UINT_MAX; graphics_pipeline_desc.multisample.mask = UINT_MAX;
graphics_pipeline_desc.multisample.alphaToCoverageEnabled = false; graphics_pipeline_desc.multisample.alphaToCoverageEnabled = false;
graphics_pipeline_desc.layout = nullptr; // Use automatic layout generation
// Bind group layouts
WGPUBindGroupLayoutEntry common_bg_layout_entries[2] = {};
common_bg_layout_entries[0].binding = 0;
common_bg_layout_entries[0].visibility = WGPUShaderStage_Vertex | WGPUShaderStage_Fragment;
common_bg_layout_entries[0].buffer.type = WGPUBufferBindingType_Uniform;
common_bg_layout_entries[1].binding = 1;
common_bg_layout_entries[1].visibility = WGPUShaderStage_Fragment;
common_bg_layout_entries[1].sampler.type = WGPUSamplerBindingType_Filtering;
WGPUBindGroupLayoutEntry image_bg_layout_entries[1] = {};
image_bg_layout_entries[0].binding = 0;
image_bg_layout_entries[0].visibility = WGPUShaderStage_Fragment;
image_bg_layout_entries[0].texture.sampleType = WGPUTextureSampleType_Float;
image_bg_layout_entries[0].texture.viewDimension = WGPUTextureViewDimension_2D;
WGPUBindGroupLayoutDescriptor common_bg_layout_desc = {};
common_bg_layout_desc.entryCount = 2;
common_bg_layout_desc.entries = common_bg_layout_entries;
WGPUBindGroupLayoutDescriptor image_bg_layout_desc = {};
image_bg_layout_desc.entryCount = 1;
image_bg_layout_desc.entries = image_bg_layout_entries;
WGPUBindGroupLayout bg_layouts[2];
bg_layouts[0] = wgpuDeviceCreateBindGroupLayout(bd->wgpuDevice, &common_bg_layout_desc);
bg_layouts[1] = wgpuDeviceCreateBindGroupLayout(bd->wgpuDevice, &image_bg_layout_desc);
WGPUPipelineLayoutDescriptor layout_desc = {};
layout_desc.bindGroupLayoutCount = 2;
layout_desc.bindGroupLayouts = bg_layouts;
graphics_pipeline_desc.layout = wgpuDeviceCreatePipelineLayout(bd->wgpuDevice, &layout_desc);
// Create the vertex shader // Create the vertex shader
WGPUProgrammableStageDescriptor vertex_shader_desc = ImGui_ImplWGPU_CreateShaderModule(__shader_vert_wgsl); WGPUProgrammableStageDescriptor vertex_shader_desc = ImGui_ImplWGPU_CreateShaderModule(__glsl_shader_vert_spv, sizeof(__glsl_shader_vert_spv) / sizeof(uint32_t));
graphics_pipeline_desc.vertex.module = vertex_shader_desc.module; graphics_pipeline_desc.vertex.module = vertex_shader_desc.module;
graphics_pipeline_desc.vertex.entryPoint = vertex_shader_desc.entryPoint; graphics_pipeline_desc.vertex.entryPoint = vertex_shader_desc.entryPoint;
@@ -634,7 +613,7 @@ bool ImGui_ImplWGPU_CreateDeviceObjects()
graphics_pipeline_desc.vertex.buffers = buffer_layouts; graphics_pipeline_desc.vertex.buffers = buffer_layouts;
// Create the pixel shader // Create the pixel shader
WGPUProgrammableStageDescriptor pixel_shader_desc = ImGui_ImplWGPU_CreateShaderModule(__shader_frag_wgsl); WGPUProgrammableStageDescriptor pixel_shader_desc = ImGui_ImplWGPU_CreateShaderModule(__glsl_shader_frag_spv, sizeof(__glsl_shader_frag_spv) / sizeof(uint32_t));
// Create the blending setup // Create the blending setup
WGPUBlendState blend_state = {}; WGPUBlendState blend_state = {};
@@ -646,7 +625,7 @@ bool ImGui_ImplWGPU_CreateDeviceObjects()
blend_state.color.dstFactor = WGPUBlendFactor_OneMinusSrcAlpha; blend_state.color.dstFactor = WGPUBlendFactor_OneMinusSrcAlpha;
WGPUColorTargetState color_state = {}; WGPUColorTargetState color_state = {};
color_state.format = bd->renderTargetFormat; color_state.format = g_renderTargetFormat;
color_state.blend = &blend_state; color_state.blend = &blend_state;
color_state.writeMask = WGPUColorWriteMask_All; color_state.writeMask = WGPUColorWriteMask_All;
@@ -660,37 +639,39 @@ bool ImGui_ImplWGPU_CreateDeviceObjects()
// Create depth-stencil State // Create depth-stencil State
WGPUDepthStencilState depth_stencil_state = {}; WGPUDepthStencilState depth_stencil_state = {};
depth_stencil_state.format = bd->depthStencilFormat; depth_stencil_state.depthBias = 0;
depth_stencil_state.depthWriteEnabled = false; depth_stencil_state.depthBiasClamp = 0;
depth_stencil_state.depthCompare = WGPUCompareFunction_Always; depth_stencil_state.depthBiasSlopeScale = 0;
depth_stencil_state.stencilFront.compare = WGPUCompareFunction_Always;
depth_stencil_state.stencilBack.compare = WGPUCompareFunction_Always;
// Configure disabled depth-stencil state // Configure disabled depth-stencil state
graphics_pipeline_desc.depthStencil = (bd->depthStencilFormat == WGPUTextureFormat_Undefined) ? nullptr : &depth_stencil_state; graphics_pipeline_desc.depthStencil = nullptr;
bd->pipelineState = wgpuDeviceCreateRenderPipeline(bd->wgpuDevice, &graphics_pipeline_desc); g_pipelineState = wgpuDeviceCreateRenderPipeline(g_wgpuDevice, &graphics_pipeline_desc);
ImGui_ImplWGPU_CreateFontsTexture(); ImGui_ImplWGPU_CreateFontsTexture();
ImGui_ImplWGPU_CreateUniformBuffer(); ImGui_ImplWGPU_CreateUniformBuffer();
// Create resource bind group // Create resource bind group
WGPUBindGroupLayout bg_layouts[2];
bg_layouts[0] = wgpuRenderPipelineGetBindGroupLayout(g_pipelineState, 0);
bg_layouts[1] = wgpuRenderPipelineGetBindGroupLayout(g_pipelineState, 1);
WGPUBindGroupEntry common_bg_entries[] = WGPUBindGroupEntry common_bg_entries[] =
{ {
{ nullptr, 0, bd->renderResources.Uniforms, 0, MEMALIGN(sizeof(Uniforms), 16), 0, 0 }, { nullptr, 0, g_resources.Uniforms, 0, sizeof(Uniforms), 0, 0 },
{ nullptr, 1, 0, 0, 0, bd->renderResources.Sampler, 0 }, { nullptr, 1, 0, 0, 0, g_resources.Sampler, 0 },
}; };
WGPUBindGroupDescriptor common_bg_descriptor = {}; WGPUBindGroupDescriptor common_bg_descriptor = {};
common_bg_descriptor.layout = bg_layouts[0]; common_bg_descriptor.layout = bg_layouts[0];
common_bg_descriptor.entryCount = sizeof(common_bg_entries) / sizeof(WGPUBindGroupEntry); common_bg_descriptor.entryCount = sizeof(common_bg_entries) / sizeof(WGPUBindGroupEntry);
common_bg_descriptor.entries = common_bg_entries; common_bg_descriptor.entries = common_bg_entries;
bd->renderResources.CommonBindGroup = wgpuDeviceCreateBindGroup(bd->wgpuDevice, &common_bg_descriptor); g_resources.CommonBindGroup = wgpuDeviceCreateBindGroup(g_wgpuDevice, &common_bg_descriptor);
WGPUBindGroup image_bind_group = ImGui_ImplWGPU_CreateImageBindGroup(bg_layouts[1], bd->renderResources.FontTextureView); WGPUBindGroup image_bind_group = ImGui_ImplWGPU_CreateImageBindGroup(bg_layouts[1], g_resources.FontTextureView);
bd->renderResources.ImageBindGroup = image_bind_group; g_resources.ImageBindGroup = image_bind_group;
bd->renderResources.ImageBindGroupLayout = bg_layouts[1]; g_resources.ImageBindGroupLayout = bg_layouts[1];
bd->renderResources.ImageBindGroups.SetVoidPtr(ImHashData(&bd->renderResources.FontTextureView, sizeof(ImTextureID)), image_bind_group); g_resources.ImageBindGroups.SetVoidPtr(ImHashData(&g_resources.FontTextureView, sizeof(ImTextureID)), image_bind_group);
SafeRelease(vertex_shader_desc.module); SafeRelease(vertex_shader_desc.module);
SafeRelease(pixel_shader_desc.module); SafeRelease(pixel_shader_desc.module);
@@ -699,54 +680,50 @@ bool ImGui_ImplWGPU_CreateDeviceObjects()
return true; return true;
} }
void ImGui_ImplWGPU_InvalidateDeviceObjects() void ImGui_ImplWGPU_InvalidateDeviceObjects(void)
{ {
ImGui_ImplWGPU_Data* bd = ImGui_ImplWGPU_GetBackendData(); if (!g_wgpuDevice)
if (!bd->wgpuDevice)
return; return;
SafeRelease(bd->pipelineState); SafeRelease(g_pipelineState);
SafeRelease(bd->renderResources); SafeRelease(g_resources);
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
io.Fonts->SetTexID(0); // We copied g_pFontTextureView to io.Fonts->TexID so let's clear that as well. io.Fonts->SetTexID(nullptr); // We copied g_pFontTextureView to io.Fonts->TexID so let's clear that as well.
for (unsigned int i = 0; i < bd->numFramesInFlight; i++) for (unsigned int i = 0; i < g_numFramesInFlight; i++)
SafeRelease(bd->pFrameResources[i]); SafeRelease(g_pFrameResources[i]);
} }
bool ImGui_ImplWGPU_Init(WGPUDevice device, int num_frames_in_flight, WGPUTextureFormat rt_format, WGPUTextureFormat depth_format) bool ImGui_ImplWGPU_Init(WGPUDevice device, int num_frames_in_flight, WGPUTextureFormat rt_format, const Config* config)
{ {
ImGuiIO& io = ImGui::GetIO(); g_config = *config;
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
// Setup backend capabilities flags // Setup backend capabilities flags
ImGui_ImplWGPU_Data* bd = IM_NEW(ImGui_ImplWGPU_Data)(); ImGuiIO& io = ImGui::GetIO();
io.BackendRendererUserData = (void*)bd;
io.BackendRendererName = "imgui_impl_webgpu"; io.BackendRendererName = "imgui_impl_webgpu";
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes. io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
bd->wgpuDevice = device; g_wgpuDevice = device;
bd->defaultQueue = wgpuDeviceGetQueue(bd->wgpuDevice); g_defaultQueue = wgpuDeviceGetQueue(g_wgpuDevice);
bd->renderTargetFormat = rt_format; g_renderTargetFormat = rt_format;
bd->depthStencilFormat = depth_format; g_pFrameResources = new FrameResources[num_frames_in_flight];
bd->numFramesInFlight = num_frames_in_flight; g_numFramesInFlight = num_frames_in_flight;
bd->frameIndex = UINT_MAX; g_frameIndex = UINT_MAX;
bd->renderResources.FontTexture = nullptr; g_resources.FontTexture = nullptr;
bd->renderResources.FontTextureView = nullptr; g_resources.FontTextureView = nullptr;
bd->renderResources.Sampler = nullptr; g_resources.Sampler = nullptr;
bd->renderResources.Uniforms = nullptr; g_resources.Uniforms = nullptr;
bd->renderResources.CommonBindGroup = nullptr; g_resources.CommonBindGroup = nullptr;
bd->renderResources.ImageBindGroups.Data.reserve(100); g_resources.ImageBindGroups.Data.reserve(100);
bd->renderResources.ImageBindGroup = nullptr; g_resources.ImageBindGroup = nullptr;
bd->renderResources.ImageBindGroupLayout = nullptr; g_resources.ImageBindGroupLayout = nullptr;
// Create buffers with a default size (they will later be grown as needed) // Create buffers with a default size (they will later be grown as needed)
bd->pFrameResources = new FrameResources[num_frames_in_flight];
for (int i = 0; i < num_frames_in_flight; i++) for (int i = 0; i < num_frames_in_flight; i++)
{ {
FrameResources* fr = &bd->pFrameResources[i]; FrameResources* fr = &g_pFrameResources[i];
fr->IndexBuffer = nullptr; fr->IndexBuffer = nullptr;
fr->VertexBuffer = nullptr; fr->VertexBuffer = nullptr;
fr->IndexBufferHost = nullptr; fr->IndexBufferHost = nullptr;
@@ -758,29 +735,22 @@ bool ImGui_ImplWGPU_Init(WGPUDevice device, int num_frames_in_flight, WGPUTextur
return true; return true;
} }
void ImGui_ImplWGPU_Shutdown() void ImGui_ImplWGPU_Shutdown(void)
{ {
ImGui_ImplWGPU_Data* bd = ImGui_ImplWGPU_GetBackendData(); // mziulek: Explicitly release the memory reserved in ImGui_ImplWGPU_Init().
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?"); g_resources.ImageBindGroups.Clear();
ImGuiIO& io = ImGui::GetIO();
ImGui_ImplWGPU_InvalidateDeviceObjects(); ImGui_ImplWGPU_InvalidateDeviceObjects();
delete[] bd->pFrameResources; delete[] g_pFrameResources;
bd->pFrameResources = nullptr; g_pFrameResources = nullptr;
wgpuQueueRelease(bd->defaultQueue); wgpuQueueRelease(g_defaultQueue);
bd->wgpuDevice = nullptr; g_wgpuDevice = nullptr;
bd->numFramesInFlight = 0; g_numFramesInFlight = 0;
bd->frameIndex = UINT_MAX; g_frameIndex = UINT_MAX;
io.BackendRendererName = nullptr;
io.BackendRendererUserData = nullptr;
io.BackendFlags &= ~ImGuiBackendFlags_RendererHasVtxOffset;
IM_DELETE(bd);
} }
void ImGui_ImplWGPU_NewFrame() void ImGui_ImplWGPU_NewFrame(void)
{ {
ImGui_ImplWGPU_Data* bd = ImGui_ImplWGPU_GetBackendData(); if (!g_pipelineState)
if (!bd->pipelineState)
ImGui_ImplWGPU_CreateDeviceObjects(); ImGui_ImplWGPU_CreateDeviceObjects();
} }

View File

@@ -1,318 +0,0 @@
// Adapted from KHR/khrplatform.h to avoid including entire file.
#ifndef __khrplatform_h_
typedef float khronos_float_t;
typedef signed char khronos_int8_t;
typedef unsigned char khronos_uint8_t;
typedef signed short int khronos_int16_t;
typedef unsigned short int khronos_uint16_t;
#ifdef _WIN64
typedef signed long long int khronos_intptr_t;
typedef signed long long int khronos_ssize_t;
#else
typedef signed long int khronos_intptr_t;
typedef signed long int khronos_ssize_t;
#endif
#if defined(_MSC_VER) && !defined(__clang__)
typedef signed __int64 khronos_int64_t;
typedef unsigned __int64 khronos_uint64_t;
#elif (defined(__clang__) || defined(__GNUC__)) && (__cplusplus < 201100)
#include <stdint.h>
typedef int64_t khronos_int64_t;
typedef uint64_t khronos_uint64_t;
#else
typedef signed long long khronos_int64_t;
typedef unsigned long long khronos_uint64_t;
#endif
#endif // __khrplatform_h_
#ifndef APIENTRY
#define APIENTRY
#endif
#ifndef APIENTRYP
#define APIENTRYP APIENTRY *
#endif
#ifndef GLAPI
#define GLAPI extern
#endif
#ifndef GL_VERSION_1_0
typedef void GLvoid;
typedef unsigned int GLenum;
typedef khronos_float_t GLfloat;
typedef int GLint;
typedef int GLsizei;
typedef unsigned int GLbitfield;
typedef double GLdouble;
typedef unsigned int GLuint;
typedef unsigned char GLboolean;
typedef khronos_uint8_t GLubyte;
#define GL_COLOR_BUFFER_BIT 0x00004000
#define GL_FALSE 0
#define GL_TRUE 1
#define GL_TRIANGLES 0x0004
#define GL_ONE 1
#define GL_SRC_ALPHA 0x0302
#define GL_ONE_MINUS_SRC_ALPHA 0x0303
#define GL_FRONT 0x0404
#define GL_BACK 0x0405
#define GL_FRONT_AND_BACK 0x0408
#define GL_POLYGON_MODE 0x0B40
#define GL_CULL_FACE 0x0B44
#define GL_DEPTH_TEST 0x0B71
#define GL_STENCIL_TEST 0x0B90
#define GL_VIEWPORT 0x0BA2
#define GL_BLEND 0x0BE2
#define GL_SCISSOR_BOX 0x0C10
#define GL_SCISSOR_TEST 0x0C11
#define GL_UNPACK_ROW_LENGTH 0x0CF2
#define GL_PACK_ALIGNMENT 0x0D05
#define GL_TEXTURE_2D 0x0DE1
#define GL_UNSIGNED_BYTE 0x1401
#define GL_UNSIGNED_SHORT 0x1403
#define GL_UNSIGNED_INT 0x1405
#define GL_FLOAT 0x1406
#define GL_RGBA 0x1908
#define GL_FILL 0x1B02
#define GL_VENDOR 0x1F00
#define GL_RENDERER 0x1F01
#define GL_VERSION 0x1F02
#define GL_EXTENSIONS 0x1F03
#define GL_LINEAR 0x2601
#define GL_TEXTURE_MAG_FILTER 0x2800
#define GL_TEXTURE_MIN_FILTER 0x2801
typedef void (APIENTRYP PFNGLPOLYGONMODEPROC) (GLenum face, GLenum mode);
typedef void (APIENTRYP PFNGLSCISSORPROC) (GLint x, GLint y, GLsizei width, GLsizei height);
typedef void (APIENTRYP PFNGLTEXPARAMETERIPROC) (GLenum target, GLenum pname, GLint param);
typedef void (APIENTRYP PFNGLTEXIMAGE2DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels);
typedef void (APIENTRYP PFNGLCLEARPROC) (GLbitfield mask);
typedef void (APIENTRYP PFNGLCLEARCOLORPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
typedef void (APIENTRYP PFNGLDISABLEPROC) (GLenum cap);
typedef void (APIENTRYP PFNGLENABLEPROC) (GLenum cap);
typedef void (APIENTRYP PFNGLFLUSHPROC) (void);
typedef void (APIENTRYP PFNGLPIXELSTOREIPROC) (GLenum pname, GLint param);
typedef void (APIENTRYP PFNGLREADPIXELSPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels);
typedef GLenum (APIENTRYP PFNGLGETERRORPROC) (void);
typedef void (APIENTRYP PFNGLGETINTEGERVPROC) (GLenum pname, GLint *data);
typedef const GLubyte *(APIENTRYP PFNGLGETSTRINGPROC) (GLenum name);
typedef GLboolean (APIENTRYP PFNGLISENABLEDPROC) (GLenum cap);
typedef void (APIENTRYP PFNGLVIEWPORTPROC) (GLint x, GLint y, GLsizei width, GLsizei height);
GLAPI PFNGLPOLYGONMODEPROC glPolygonMode;
GLAPI PFNGLSCISSORPROC glScissor;
GLAPI PFNGLTEXPARAMETERIPROC glTexParameteri;
GLAPI PFNGLTEXIMAGE2DPROC glTexImage2D;
GLAPI PFNGLCLEARPROC glClear;
GLAPI PFNGLCLEARCOLORPROC glClearColor;
GLAPI PFNGLDISABLEPROC glDisable;
GLAPI PFNGLENABLEPROC glEnable;
GLAPI PFNGLFLUSHPROC glFlush;
GLAPI PFNGLPIXELSTOREIPROC glPixelStorei;
GLAPI PFNGLREADPIXELSPROC glReadPixels;
GLAPI PFNGLGETERRORPROC glGetError;
GLAPI PFNGLGETINTEGERVPROC glGetIntegerv;
GLAPI PFNGLGETSTRINGPROC glGetString;
GLAPI PFNGLISENABLEDPROC glIsEnabled;
GLAPI PFNGLVIEWPORTPROC glViewport;
#endif /* GL_VERSION_1_0 */
#ifndef GL_VERSION_1_1
typedef khronos_float_t GLclampf;
typedef double GLclampd;
#define GL_TEXTURE_BINDING_2D 0x8069
typedef void (APIENTRYP PFNGLDRAWELEMENTSPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices);
typedef void (APIENTRYP PFNGLBINDTEXTUREPROC) (GLenum target, GLuint texture);
typedef void (APIENTRYP PFNGLDELETETEXTURESPROC) (GLsizei n, const GLuint *textures);
typedef void (APIENTRYP PFNGLGENTEXTURESPROC) (GLsizei n, GLuint *textures);
GLAPI PFNGLDRAWELEMENTSPROC glDrawElements;
GLAPI PFNGLBINDTEXTUREPROC glBindTexture;
GLAPI PFNGLDELETETEXTURESPROC glDeleteTextures;
GLAPI PFNGLGENTEXTURESPROC glGenTextures;
#endif /* GL_VERSION_1_1 */
#ifndef GL_VERSION_1_3
#define GL_TEXTURE0 0x84C0
#define GL_ACTIVE_TEXTURE 0x84E0
typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture);
GLAPI PFNGLACTIVETEXTUREPROC glActiveTexture;
#endif /* GL_VERSION_1_3 */
#ifndef GL_VERSION_1_4
#define GL_BLEND_DST_RGB 0x80C8
#define GL_BLEND_SRC_RGB 0x80C9
#define GL_BLEND_DST_ALPHA 0x80CA
#define GL_BLEND_SRC_ALPHA 0x80CB
#define GL_FUNC_ADD 0x8006
typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
typedef void (APIENTRYP PFNGLBLENDEQUATIONPROC) (GLenum mode);
GLAPI PFNGLBLENDFUNCSEPARATEPROC glBlendFuncSeparate;
GLAPI PFNGLBLENDEQUATIONPROC glBlendEquation;
#endif /* GL_VERSION_1_4 */
#ifndef GL_VERSION_1_5
typedef khronos_ssize_t GLsizeiptr;
typedef khronos_intptr_t GLintptr;
#define GL_ARRAY_BUFFER 0x8892
#define GL_ELEMENT_ARRAY_BUFFER 0x8893
#define GL_ARRAY_BUFFER_BINDING 0x8894
#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895
#define GL_STREAM_DRAW 0x88E0
typedef void (APIENTRYP PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer);
typedef void (APIENTRYP PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint *buffers);
typedef void (APIENTRYP PFNGLGENBUFFERSPROC) (GLsizei n, GLuint *buffers);
typedef void (APIENTRYP PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const void *data, GLenum usage);
typedef void (APIENTRYP PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const void *data);
GLAPI PFNGLBINDBUFFERPROC glBindBuffer;
GLAPI PFNGLDELETEBUFFERSPROC glDeleteBuffers;
GLAPI PFNGLGENBUFFERSPROC glGenBuffers;
GLAPI PFNGLBUFFERDATAPROC glBufferData;
GLAPI PFNGLBUFFERSUBDATAPROC glBufferSubData;
#endif /* GL_VERSION_1_5 */
#ifndef GL_VERSION_2_0
typedef char GLchar;
typedef khronos_int16_t GLshort;
typedef khronos_int8_t GLbyte;
typedef khronos_uint16_t GLushort;
#define GL_BLEND_EQUATION_RGB 0x8009
#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622
#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623
#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624
#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625
#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645
#define GL_BLEND_EQUATION_ALPHA 0x883D
#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A
#define GL_FRAGMENT_SHADER 0x8B30
#define GL_VERTEX_SHADER 0x8B31
#define GL_COMPILE_STATUS 0x8B81
#define GL_LINK_STATUS 0x8B82
#define GL_INFO_LOG_LENGTH 0x8B84
#define GL_CURRENT_PROGRAM 0x8B8D
#define GL_UPPER_LEFT 0x8CA2
typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum modeRGB, GLenum modeAlpha);
typedef void (APIENTRYP PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader);
typedef void (APIENTRYP PFNGLCOMPILESHADERPROC) (GLuint shader);
typedef GLuint (APIENTRYP PFNGLCREATEPROGRAMPROC) (void);
typedef GLuint (APIENTRYP PFNGLCREATESHADERPROC) (GLenum type);
typedef void (APIENTRYP PFNGLDELETEPROGRAMPROC) (GLuint program);
typedef void (APIENTRYP PFNGLDELETESHADERPROC) (GLuint shader);
typedef void (APIENTRYP PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader);
typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint index);
typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index);
typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar *name);
typedef void (APIENTRYP PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint *params);
typedef void (APIENTRYP PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
typedef void (APIENTRYP PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint *params);
typedef void (APIENTRYP PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar *name);
typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVPROC) (GLuint index, GLenum pname, GLint *params);
typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVPROC) (GLuint index, GLenum pname, void **pointer);
typedef GLboolean (APIENTRYP PFNGLISPROGRAMPROC) (GLuint program);
typedef void (APIENTRYP PFNGLLINKPROGRAMPROC) (GLuint program);
typedef void (APIENTRYP PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length);
typedef void (APIENTRYP PFNGLUSEPROGRAMPROC) (GLuint program);
typedef void (APIENTRYP PFNGLUNIFORM1IPROC) (GLint location, GLint v0);
typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer);
GLAPI PFNGLBLENDEQUATIONSEPARATEPROC glBlendEquationSeparate;
GLAPI PFNGLATTACHSHADERPROC glAttachShader;
GLAPI PFNGLCOMPILESHADERPROC glCompileShader;
GLAPI PFNGLCREATEPROGRAMPROC glCreateProgram;
GLAPI PFNGLCREATESHADERPROC glCreateShader;
GLAPI PFNGLDELETEPROGRAMPROC glDeleteProgram;
GLAPI PFNGLDELETESHADERPROC glDeleteShader;
GLAPI PFNGLDETACHSHADERPROC glDetachShader;
GLAPI PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray;
GLAPI PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray;
GLAPI PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation;
GLAPI PFNGLGETPROGRAMIVPROC glGetProgramiv;
GLAPI PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog;
GLAPI PFNGLGETSHADERIVPROC glGetShaderiv;
GLAPI PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog;
GLAPI PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation;
GLAPI PFNGLGETVERTEXATTRIBIVPROC glGetVertexAttribiv;
GLAPI PFNGLGETVERTEXATTRIBPOINTERVPROC glGetVertexAttribPointerv;
GLAPI PFNGLISPROGRAMPROC glIsProgram;
GLAPI PFNGLLINKPROGRAMPROC glLinkProgram;
GLAPI PFNGLSHADERSOURCEPROC glShaderSource;
GLAPI PFNGLUSEPROGRAMPROC glUseProgram;
GLAPI PFNGLUNIFORM1IPROC glUniform1i;
GLAPI PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv;
GLAPI PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer;
#endif /* GL_VERSION_2_0 */
#ifndef GL_VERSION_3_0
typedef khronos_uint16_t GLhalf;
#define GL_MAJOR_VERSION 0x821B
#define GL_MINOR_VERSION 0x821C
#define GL_NUM_EXTENSIONS 0x821D
#define GL_FRAMEBUFFER_SRGB 0x8DB9
#define GL_VERTEX_ARRAY_BINDING 0x85B5
typedef void (APIENTRYP PFNGLGETBOOLEANI_VPROC) (GLenum target, GLuint index, GLboolean *data);
typedef void (APIENTRYP PFNGLGETINTEGERI_VPROC) (GLenum target, GLuint index, GLint *data);
typedef const GLubyte *(APIENTRYP PFNGLGETSTRINGIPROC) (GLenum name, GLuint index);
typedef void (APIENTRYP PFNGLBINDVERTEXARRAYPROC) (GLuint array);
typedef void (APIENTRYP PFNGLDELETEVERTEXARRAYSPROC) (GLsizei n, const GLuint *arrays);
typedef void (APIENTRYP PFNGLGENVERTEXARRAYSPROC) (GLsizei n, GLuint *arrays);
GLAPI PFNGLGETSTRINGIPROC glGetStringi;
GLAPI PFNGLBINDVERTEXARRAYPROC glBindVertexArray;
GLAPI PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays;
GLAPI PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;
#endif /* GL_VERSION_3_0 */
#ifndef GL_VERSION_3_1
#define GL_VERSION_3_1 1
#define GL_PRIMITIVE_RESTART 0x8F9D
#endif /* GL_VERSION_3_1 */
#ifndef GL_VERSION_3_2
#define GL_VERSION_3_2 1
typedef struct __GLsync *GLsync;
typedef khronos_uint64_t GLuint64;
typedef khronos_int64_t GLint64;
typedef void (APIENTRYP PFNGLDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex);
typedef void (APIENTRYP PFNGLGETINTEGER64I_VPROC) (GLenum target, GLuint index, GLint64 *data);
GLAPI PFNGLDRAWELEMENTSBASEVERTEXPROC glDrawElementsBaseVertex;
#endif /* GL_VERSION_3_2 */
#ifndef GL_VERSION_3_3
#define GL_VERSION_3_3 1
#define GL_SAMPLER_BINDING 0x8919
typedef void (APIENTRYP PFNGLBINDSAMPLERPROC) (GLuint unit, GLuint sampler);
GLAPI PFNGLBINDSAMPLERPROC glBindSampler;
#endif /* GL_VERSION_3_3 */
#ifndef GL_VERSION_4_1
typedef void (APIENTRYP PFNGLGETFLOATI_VPROC) (GLenum target, GLuint index, GLfloat *data);
typedef void (APIENTRYP PFNGLGETDOUBLEI_VPROC) (GLenum target, GLuint index, GLdouble *data);
#endif /* GL_VERSION_4_1 */
#ifndef GL_VERSION_4_3
typedef void (APIENTRY *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam);
#endif /* GL_VERSION_4_3 */
#ifndef GL_VERSION_4_5
#define GL_CLIP_ORIGIN 0x935C
typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKI_VPROC) (GLuint xfb, GLenum pname, GLuint index, GLint *param);
typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKI64_VPROC) (GLuint xfb, GLenum pname, GLuint index, GLint64 *param);
#endif /* GL_VERSION_4_5 */
#ifndef GL_ARB_bindless_texture
typedef khronos_uint64_t GLuint64EXT;
#endif /* GL_ARB_bindless_texture */
#ifndef GL_ARB_cl_event
struct _cl_context;
struct _cl_event;
#endif /* GL_ARB_cl_event */
#ifndef GL_ARB_clip_control
#define GL_ARB_clip_control 1
#endif /* GL_ARB_clip_control */
#ifndef GL_ARB_debug_output
typedef void (APIENTRY *GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam);
#endif /* GL_ARB_debug_output */
#ifndef GL_EXT_EGL_image_storage
typedef void *GLeglImageOES;
#endif /* GL_EXT_EGL_image_storage */
#ifndef GL_EXT_direct_state_access
typedef void (APIENTRYP PFNGLGETFLOATI_VEXTPROC) (GLenum pname, GLuint index, GLfloat *params);
typedef void (APIENTRYP PFNGLGETDOUBLEI_VEXTPROC) (GLenum pname, GLuint index, GLdouble *params);
typedef void (APIENTRYP PFNGLGETPOINTERI_VEXTPROC) (GLenum pname, GLuint index, void **params);
typedef void (APIENTRYP PFNGLGETVERTEXARRAYINTEGERI_VEXTPROC) (GLuint vaobj, GLuint index, GLenum pname, GLint *param);
typedef void (APIENTRYP PFNGLGETVERTEXARRAYPOINTERI_VEXTPROC) (GLuint vaobj, GLuint index, GLenum pname, void **param);
#endif /* GL_EXT_direct_state_access */
#ifndef GL_NV_draw_vulkan_image
typedef void (APIENTRY *GLVULKANPROCNV)(void);
#endif /* GL_NV_draw_vulkan_image */
#ifndef GL_NV_gpu_shader5
typedef khronos_int64_t GLint64EXT;
#endif /* GL_NV_gpu_shader5 */
#ifndef GL_NV_vertex_buffer_unified_memory
typedef void (APIENTRYP PFNGLGETINTEGERUI64I_VNVPROC) (GLenum value, GLuint index, GLuint64EXT *result);
#endif /* GL_NV_vertex_buffer_unified_memory */

View File

@@ -1,46 +0,0 @@
const gui = @import("gui.zig");
pub fn initWithGlSlVersion(
window: *const anyopaque, // zglfw.Window
glsl_version: ?[:0]const u8, // e.g. "#version 130"
) void {
if (!ImGui_ImplGlfw_InitForOpenGL(window, true)) {
unreachable;
}
ImGui_ImplOpenGL3_Init(@ptrCast(glsl_version));
}
pub fn init(
window: *const anyopaque, // zglfw.Window
) void {
initWithGlSlVersion(window, null);
}
pub fn deinit() void {
ImGui_ImplGlfw_Shutdown();
ImGui_ImplOpenGL3_Shutdown();
}
pub fn newFrame(fb_width: u32, fb_height: u32) void {
ImGui_ImplGlfw_NewFrame();
ImGui_ImplOpenGL3_NewFrame();
gui.io.setDisplaySize(@as(f32, @floatFromInt(fb_width)), @as(f32, @floatFromInt(fb_height)));
gui.io.setDisplayFramebufferScale(1.0, 1.0);
gui.newFrame();
}
pub fn draw() void {
gui.render();
ImGui_ImplOpenGL3_RenderDrawData(gui.getDrawData());
}
extern fn ImGui_ImplGlfw_InitForOpenGL(window: *const anyopaque, install_callbacks: bool) bool;
extern fn ImGui_ImplGlfw_NewFrame() void;
extern fn ImGui_ImplGlfw_Shutdown() void;
extern fn ImGui_ImplOpenGL3_Init(glsl_version: [*c]const u8) void;
extern fn ImGui_ImplOpenGL3_Shutdown() void;
extern fn ImGui_ImplOpenGL3_NewFrame() void;
extern fn ImGui_ImplOpenGL3_RenderDrawData(data: *const anyopaque) void;

View File

@@ -0,0 +1,35 @@
const zgui = @import("gui.zig");
pub fn init(window: *anyopaque, glsl_version: []const u8) void {
if (!ImGui_ImplGlfw_InitForOpenGL(window, true)) unreachable;
if (!ImGui_ImplOpenGL3_Init(glsl_version.ptr)) unreachable;
}
pub fn deinit() void {
ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplGlfw_Shutdown();
}
pub fn newFrame(width: f32, height: f32) void {
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
zgui.io.setDisplaySize(width, height);
zgui.io.setDisplayFramebufferScale(1.0, 1.0);
zgui.newFrame();
}
pub fn draw() void {
zgui.render();
ImGui_ImplOpenGL3_RenderDrawData(zgui.getDrawData());
}
extern fn ImGui_ImplGlfw_InitForOpenGL(window: *anyopaque, install_callbacks: bool) bool;
extern fn ImGui_ImplGlfw_Shutdown() void;
extern fn ImGui_ImplGlfw_NewFrame() void;
extern fn ImGui_ImplOpenGL3_Init(glsl_version: [*]const u8) bool;
extern fn ImGui_ImplOpenGL3_Shutdown() void;
extern fn ImGui_ImplOpenGL3_NewFrame() void;
extern fn ImGui_ImplOpenGL3_RenderDrawData(draw_data: *anyopaque) void; // ImDrawData

View File

@@ -1,23 +1,37 @@
const gui = @import("gui.zig"); const gui = @import("gui.zig");
pub const TextureFilterMode = enum(u32) {
nearest,
linear,
};
pub const Config = extern struct {
pipeline_multisample_count: u32 = 1,
texture_filter_mode: TextureFilterMode = .linear,
};
// This call will install GLFW callbacks to handle GUI interactions. // This call will install GLFW callbacks to handle GUI interactions.
// Those callbacks will chain-call user's previously installed callbacks, if any. // Those callbacks will chain-call user's previously installed callbacks, if any.
// This means that custom user's callbacks need to be installed *before* calling zgpu.gui.init(). // This means that custom user's callbacks need to be installed *before* calling zgpu.gui.init().
pub fn init( pub fn initWithConfig(
window: *const anyopaque, // zglfw.Window window: *const anyopaque, // zglfw.Window
wgpu_device: *const anyopaque, // WGPUDevice wgpu_device: *const anyopaque, // wgpu.Device
wgpu_swap_chain_format: u32, // WGPUTextureFormat wgpu_swap_chain_format: u32, // wgpu.TextureFormat
wgpu_depth_format: u32, // WGPUTextureFormat config: Config,
) void { ) void {
if (!ImGui_ImplGlfw_InitForOther(window, true)) { if (!ImGui_ImplGlfw_InitForOther(window, true)) {
unreachable; unreachable;
} }
if (!ImGui_ImplWGPU_Init(wgpu_device, 1, wgpu_swap_chain_format, wgpu_depth_format)) { if (!ImGui_ImplWGPU_Init(wgpu_device, 1, wgpu_swap_chain_format, &config)) {
unreachable; unreachable;
} }
} }
pub fn init(window: *const anyopaque, wgpu_device: *const anyopaque, wgpu_swap_chain_format: u32) void {
initWithConfig(window, wgpu_device, wgpu_swap_chain_format, .{});
}
pub fn deinit() void { pub fn deinit() void {
ImGui_ImplWGPU_Shutdown(); ImGui_ImplWGPU_Shutdown();
ImGui_ImplGlfw_Shutdown(); ImGui_ImplGlfw_Shutdown();
@@ -44,10 +58,10 @@ extern fn ImGui_ImplGlfw_InitForOther(window: *const anyopaque, install_callback
extern fn ImGui_ImplGlfw_NewFrame() void; extern fn ImGui_ImplGlfw_NewFrame() void;
extern fn ImGui_ImplGlfw_Shutdown() void; extern fn ImGui_ImplGlfw_Shutdown() void;
extern fn ImGui_ImplWGPU_Init( extern fn ImGui_ImplWGPU_Init(
device: *const anyopaque, // WGPUDevice device: *const anyopaque,
num_frames_in_flight: u32, num_frames_in_flight: u32,
rt_format: u32, // WGPUTextureFormat rt_format: u32,
wgpu_depth_format: u32, // WGPUTextureFormat config: *const Config,
) bool; ) bool;
extern fn ImGui_ImplWGPU_NewFrame() void; extern fn ImGui_ImplWGPU_NewFrame() void;
extern fn ImGui_ImplWGPU_RenderDrawData(draw_data: *const anyopaque, pass_encoder: *const anyopaque) void; extern fn ImGui_ImplWGPU_RenderDrawData(draw_data: *const anyopaque, pass_encoder: *const anyopaque) void;

View File

@@ -4,11 +4,13 @@
// named parameters and Zig style text formatting. // named parameters and Zig style text formatting.
// //
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
pub const version = @import("std").SemanticVersion{ .major = 1, .minor = 89, .patch = 6 };
pub const plot = @import("plot.zig"); pub const plot = @import("plot.zig");
pub const backend = switch (@import("zgui_options").backend) { pub const backend = switch (@import("zgui_options").backend) {
.glfw_wgpu => @import("backend_glfw_wgpu.zig"), .glfw_wgpu => @import("backend_glfw_wgpu.zig"),
.glfw_opengl3 => @import("backend_glfw_opengl.zig"), .glfw_opengl3 => @import("backend_glfw_opengl3.zig"),
.sdl2_opengl3 => @import("backend_sdl2_opengl.zig"), .sdl2_opengl3 => @import("backend_sdl2_opengl3.zig"),
.win32_dx12 => .{}, // TODO: .win32_dx12 => .{}, // TODO:
.no_backend => .{}, .no_backend => .{},
}; };
@@ -1476,7 +1478,7 @@ pub fn comboFromEnum(
.Enum => |e| { .Enum => |e| {
comptime var str: [:0]const u8 = ""; comptime var str: [:0]const u8 = "";
for (e.fields) |f| { inline for (e.fields) |f| {
str = str ++ f.name ++ "\x00"; str = str ++ f.name ++ "\x00";
} }
break :lbl str; break :lbl str;
@@ -3086,14 +3088,12 @@ pub fn colorConvertFloat3ToU32(in: [3]f32) u32 {
pub fn colorConvertRgbToHsv(r: f32, g: f32, b: f32) [3]f32 { pub fn colorConvertRgbToHsv(r: f32, g: f32, b: f32) [3]f32 {
var hsv: [3]f32 = undefined; var hsv: [3]f32 = undefined;
zguiColorConvertRGBtoHSV(r, g, b, &hsv[0], &hsv[1], &hsv[2]); return zguiColorConvertRGBtoHSV(r, g, b, &hsv[0], &hsv[1], &hsv[2]);
return hsv;
} }
pub fn colorConvertHsvToRgb(h: f32, s: f32, v: f32) [3]f32 { pub fn colorConvertHsvToRgb(h: f32, s: f32, v: f32) [3]f32 {
var rgb: [3]f32 = undefined; var rgb: [3]f32 = undefined;
zguiColorConvertHSVtoRGB(h, s, v, &rgb[0], &rgb[1], &rgb[2]); return zguiColorConvertHSVtoRGB(h, s, v, &rgb[0], &rgb[1], &rgb[2]);
return rgb;
} }
extern fn zguiColorConvertU32ToFloat4(in: u32, rgba: *[4]f32) void; extern fn zguiColorConvertU32ToFloat4(in: u32, rgba: *[4]f32) void;
@@ -3467,32 +3467,19 @@ pub const DrawList = *opaque {
pub const getVertexBufferLength = zguiDrawList_GetVertexBufferLength; pub const getVertexBufferLength = zguiDrawList_GetVertexBufferLength;
extern fn zguiDrawList_GetVertexBufferLength(draw_list: DrawList) i32; extern fn zguiDrawList_GetVertexBufferLength(draw_list: DrawList) i32;
pub const getVertexBufferData = zguiDrawList_GetVertexBufferData; pub const getVertexBufferData = zguiDrawList_GetVertexBufferData;
extern fn zguiDrawList_GetVertexBufferData(draw_list: DrawList) [*]DrawVert; extern fn zguiDrawList_GetVertexBufferData(draw_list: DrawList) [*]const DrawVert;
pub fn getVertexBuffer(draw_list: DrawList) []DrawVert {
const len: usize = @intCast(draw_list.getVertexBufferLength());
return draw_list.getVertexBufferData()[0..len];
}
pub const getIndexBufferLength = zguiDrawList_GetIndexBufferLength; pub const getIndexBufferLength = zguiDrawList_GetIndexBufferLength;
extern fn zguiDrawList_GetIndexBufferLength(draw_list: DrawList) i32; extern fn zguiDrawList_GetIndexBufferLength(draw_list: DrawList) i32;
pub const getIndexBufferData = zguiDrawList_GetIndexBufferData; pub const getIndexBufferData = zguiDrawList_GetIndexBufferData;
extern fn zguiDrawList_GetIndexBufferData(draw_list: DrawList) [*]DrawIdx; extern fn zguiDrawList_GetIndexBufferData(draw_list: DrawList) [*]const DrawIdx;
pub fn getIndexBuffer(draw_list: DrawList) []DrawIdx {
const len: usize = @intCast(draw_list.getIndexBufferLength());
return draw_list.getIndexBufferData()[0..len];
}
pub const getCurrentIndex = zguiDrawList_GetCurrentIndex; pub const getCurrentIndex = zguiDrawList_GetCurrentIndex;
extern fn zguiDrawList_GetCurrentIndex(draw_list: DrawList) u32; extern fn zguiDrawList_GetCurrentIndex(draw_list: DrawList) u32;
pub const getCmdBufferLength = zguiDrawList_GetCmdBufferLength; pub const getCmdBufferLength = zguiDrawList_GetCmdBufferLength;
extern fn zguiDrawList_GetCmdBufferLength(draw_list: DrawList) i32; extern fn zguiDrawList_GetCmdBufferLength(draw_list: DrawList) i32;
pub const getCmdBufferData = zguiDrawList_GetCmdBufferData; pub const getCmdBufferData = zguiDrawList_GetCmdBufferData;
extern fn zguiDrawList_GetCmdBufferData(draw_list: DrawList) [*]DrawCmd; extern fn zguiDrawList_GetCmdBufferData(draw_list: DrawList) [*]const DrawCmd;
pub fn getCmdBuffer(draw_list: DrawList) []DrawCmd {
const len: usize = @intCast(draw_list.getCmdBufferLength());
return draw_list.getCmdBufferData()[0..len];
}
pub const DrawListFlags = packed struct(u32) { pub const DrawListFlags = packed struct(u32) {
anti_aliased_lines: bool = false, anti_aliased_lines: bool = false,
@@ -4238,7 +4225,3 @@ pub const DrawList = *opaque {
} }
extern fn zguiDrawList_AddResetRenderStateCallback(draw_list: DrawList) void; extern fn zguiDrawList_AddResetRenderStateCallback(draw_list: DrawList) void;
}; };
test {
std.testing.refAllDeclsRecursive(@This());
}

View File

@@ -1,16 +0,0 @@
//--------------------------------------------------------------------------------------------------
//
// Zig bindings for 'dear imgui' library. Easy to use, hand-crafted API with default arguments,
// named parameters and Zig style text formatting.
//
//--------------------------------------------------------------------------------------------------
pub const version = @import("std").SemanticVersion{ .major = 0, .minor = 9, .patch = 6 };
pub usingnamespace @import("gui.zig");
pub const plot = @import("plot.zig");
pub const backend = switch (@import("zgui_options").backend) {
.glfw_wgpu => @import("backend_glfw_wgpu.zig"),
.sdl2_opengl3 => @import("backend_sdl2_opengl.zig"),
.win32_dx12 => .{}, // TODO:
.no_backend => .{},
};

View File

@@ -574,17 +574,17 @@ const PlotText = struct {
pix_offset: [2]f32 = .{ 0, 0 }, pix_offset: [2]f32 = .{ 0, 0 },
flags: PlotTextFlags = .{}, flags: PlotTextFlags = .{},
}; };
pub fn plotText(text: [*:0]const u8, args: PlotText) void { pub fn plotText(text: [*:0]const u8, args:PlotText) void {
zguiPlot_PlotText(text, args.x, args.y, &args.pix_offset, args.flags); zguiPlot_PlotText(text, args.x, args.y, &args.pix_offset, args.flags);
} }
extern fn zguiPlot_PlotText( extern fn zguiPlot_PlotText(
text: [*:0]const u8, text:[*:0]const u8,
x: f64, x:f64, y:f64,
y: f64,
pix_offset: *const [2]f32, pix_offset: *const [2]f32,
flags: PlotTextFlags, flags: PlotTextFlags,
) void; ) void;
//---------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------
/// `pub fn showDemoWindow(popen: ?*bool) void` /// `pub fn showDemoWindow(popen: ?*bool) void`
pub const showDemoWindow = zguiPlot_ShowDemoWindow; pub const showDemoWindow = zguiPlot_ShowDemoWindow;

View File

@@ -1,8 +1,5 @@
#include "imgui.h" #include "./imgui/imgui.h"
#include "./imgui/implot.h"
#if ZGUI_IMPLOT
#include "implot.h"
#endif
#ifndef ZGUI_API #ifndef ZGUI_API
#define ZGUI_API #define ZGUI_API
@@ -2158,8 +2155,6 @@ ZGUI_API void zguiViewport_GetWorkSize(ImGuiViewport* viewport, float p[2]) {
p[0] = sz.x; p[0] = sz.x;
p[1] = sz.y; p[1] = sz.y;
} }
#if ZGUI_IMPLOT
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
// //
// ImPlot // ImPlot
@@ -2420,7 +2415,6 @@ ZGUI_API void zguiPlot_PlotText(
const ImVec2 p(pix_offset[0], pix_offset[1]); const ImVec2 p(pix_offset[0], pix_offset[1]);
ImPlot::PlotText(text, x, y, p, flags); ImPlot::PlotText(text, x, y, p, flags);
} }
#endif /* #ifdef ZGUI_IMPLOT */
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
} /* extern "C" */ } /* extern "C" */