git.s-ol.nu zig-imgui / master src / main.zig
master

Tree @master (Download .tar.gz)

main.zig @masterraw · history · blame

/// this is a port of cimgui/imgui/examples/example_glfw_opengl3/main.cpp
const c = @import("c.zig");
const std = @import("std");
const panic = std.debug.panic;
const debug_gl = @import("debug_gl.zig");
const glfw_impl = @import("glfw_impl.zig");
const gl3_impl = @import("gl3_impl.zig");

fn errorCallback(err: c_int, description: [*c]const u8) callconv(.C) void {
    _ = err;
    panic("Error: {s}\n", .{description});
}

pub usingnamespace c;

pub const Window = struct {
    window: *c.GLFWwindow,
    context: *c.ImGuiContext,

    pub fn init() Window {
        _ = c.glfwSetErrorCallback(errorCallback);

        if (c.glfwInit() == c.GL_FALSE) {
            panic("GLFW init failure\n", .{});
        }
        errdefer c.glfwTerminate();

        c.glfwWindowHint(c.GLFW_CONTEXT_VERSION_MAJOR, 3);
        c.glfwWindowHint(c.GLFW_CONTEXT_VERSION_MINOR, 2);
        c.glfwWindowHint(c.GLFW_OPENGL_FORWARD_COMPAT, c.GL_TRUE);
        c.glfwWindowHint(c.GLFW_OPENGL_DEBUG_CONTEXT, debug_gl.is_on);
        c.glfwWindowHint(c.GLFW_OPENGL_PROFILE, c.GLFW_OPENGL_CORE_PROFILE);
        // c.glfwWindowHint(c.GLFW_DEPTH_BITS, 0);
        // c.glfwWindowHint(c.GLFW_STENCIL_BITS, 8);
        c.glfwWindowHint(c.GLFW_RESIZABLE, c.GL_TRUE);

        const window_width = 640;
        const window_height = 480;
        const window = c.glfwCreateWindow(window_width, window_height, "ImGUI Test", null, null) orelse {
            panic("unable to create window\n", .{});
        };
        errdefer c.glfwDestroyWindow(window);

        c.glfwMakeContextCurrent(window);
        c.glfwSwapInterval(1);

        const context = c.igCreateContext(null) orelse panic("ImGui init failure\n", .{});
        errdefer c.igDestroyContext(context);

        const io = c.igGetIO();
        io.*.ConfigFlags |= c.ImGuiConfigFlags_NavEnableKeyboard;
        io.*.ConfigFlags |= c.ImGuiConfigFlags_DockingEnable;
        // io.*.ConfigFlags |= c.ImGuiConfigFlags_ViewportsEnable;

        const style = c.igGetStyle();
        c.igStyleColorsDark(style);

        if (io.*.ConfigFlags & c.ImGuiConfigFlags_ViewportsEnable != 0) {
            style.*.WindowRounding = 0.0;
            style.*.Colors[c.ImGuiCol_WindowBg].w = 1.0;
        }

        glfw_impl.Init(window, true, glfw_impl.ClientApi.OpenGL);
        errdefer glfw_impl.Shutdown();

        gl3_impl.Init();
        errdefer gl3_impl.Shutdown();

        return .{
            .window = window,
            .context = context,
        };
    }

    pub fn deinit(self: *const Window) void {
        gl3_impl.Shutdown();
        glfw_impl.Shutdown();
        c.igDestroyContext(self.context);
        c.glfwDestroyWindow(self.window);
        c.glfwTerminate();
    }

    pub fn shouldClose(self: *const Window) bool {
        return c.glfwWindowShouldClose(self.window) == c.GL_TRUE;
    }

    pub fn beginFrame(self: *const Window) !void {
        _ = self;

        c.glfwPollEvents();

        try gl3_impl.NewFrame();
        glfw_impl.NewFrame();
        c.igNewFrame();
    }

    pub fn endFrame(self: *const Window) void {
        c.igRender();
        var w: c_int = undefined;
        var h: c_int = undefined;
        c.glfwGetFramebufferSize(self.window, &w, &h);
        c.glViewport(0, 0, w, h);
        c.glClearColor(0.0, 0.0, 0.0, 0.0);
        c.glClear(c.GL_COLOR_BUFFER_BIT);
        gl3_impl.RenderDrawData(c.igGetDrawData());

        c.glfwSwapBuffers(self.window);
    }
};