// Graphics Framework for Zig // Copyright (C) 2021-2023, 2025 Nguyễn Gia Phong // // This file is part of gfz. // // gfz is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published // by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // gfz is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with gfz. If not, see . const c = @import("cimport.zig"); const input = @import("input.zig"); pub const Error = error{ /// GLFW has not been initialized. NotInitialized, /// No context is current for this thread. NoCurrentContext, /// One of the arguments to the function was an invalid enum value. InvalidEnum, /// One of the arguments to the function was an invalid value. InvalidValue, /// A memory allocation failed. OutOfMemory, /// GLFW could not find support for the requested API on the system. ApiUnavailable, /// The requested OpenGL or OpenGL ES version is not available. VersionUnavailable, /// A platform-specific error occurred /// that does not match any of the more specific categories. PlatformError, /// The requested format is not supported or available. FormatUnavailable, /// The specified window does not have an OpenGL or OpenGL ES context. NoWindowContext, /// The specified cursor shape is not available. CursorUnavailable, /// The requested feature is not provided by the platform. FeatureUnavailable, /// The requested feature is not implemented for the platform. FeatureUnimplemented, /// Platform unavailable or no matching platform was found. PlatformUnavailable, }; /// Return and clear the error code of the last error /// that occurred on the calling thread if any. pub fn checkError() Error!void { return switch (c.glfwGetError(null)) { c.GLFW_NO_ERROR => {}, c.GLFW_NOT_INITIALIZED => Error.NotInitialized, c.GLFW_NO_CURRENT_CONTEXT => Error.NoCurrentContext, c.GLFW_INVALID_ENUM => Error.InvalidEnum, c.GLFW_INVALID_VALUE => Error.InvalidValue, c.GLFW_OUT_OF_MEMORY => Error.OutOfMemory, c.GLFW_API_UNAVAILABLE => Error.ApiUnavailable, c.GLFW_VERSION_UNAVAILABLE => Error.VersionUnavailable, c.GLFW_PLATFORM_ERROR => Error.PlatformError, c.GLFW_FORMAT_UNAVAILABLE => Error.FormatUnavailable, c.GLFW_NO_WINDOW_CONTEXT => Error.NoWindowContext, c.GLFW_CURSOR_UNAVAILABLE => Error.CursorUnavailable, c.GLFW_FEATURE_UNAVAILABLE => Error.FeatureUnavailable, c.GLFW_FEATURE_UNIMPLEMENTED => Error.FeatureUnimplemented, c.GLFW_PLATFORM_UNAVAILABLE => Error.PlatformUnavailable, else => unreachable, }; } /// Return and clear the last error for the calling thread. pub fn getError() Error { return if (checkError()) |_| unreachable else |err| err; } /// Initialize the GLFW library. /// /// Before most GLFW functions can be used, GLFW must be initialized, /// and before an application terminates GLFW should be terminated /// in order to free any resources allocated during or after initialization. /// /// If this function fails, it calls `glfwTerminate` before returning. /// If it succeeds, you should call `deinit` before the application exits. /// /// Additional calls to this function after successful initialization /// but before termination will return immediately. pub fn init() Error!void { if (c.glfwInit() != c.GLFW_TRUE) return getError(); } /// Destroy all remaining windows and cursors, restore any modified gamma ramps /// and frees any other allocated resources. /// /// Once this function is called, you must again call `init` successfully /// before you will be able to use most GLFW functions. /// /// If GLFW has been successfully initialized, this function should be called /// before the application exits. If initialization fails, there is no need /// to call this function, as it is called by `init` before it returns failure. /// /// This function has no effect if GLFW is not initialized. pub fn deinit() Error!void { c.glfwTerminate(); try checkError(); } /// Set the swap interval for the current context. pub fn swapInterval(interval: c_int) Error!void { c.glfwSwapInterval(interval); try checkError(); } /// Process all pending events. pub fn pollEvents() Error!void { c.glfwPollEvents(); try checkError(); } /// Return the GLFW time, in seconds. pub fn getTime() Error!f64 { const time = c.glfwGetTime(); return if (time == 0) getError() else time; } /// Set the GLFW time, in seconds. pub fn setTime(time: f64) Error!void { c.glfwSetTime(time); try checkError(); } /// Return whether raw mouse motion is supported. pub fn rawMouseMotionSupported() Error!bool { const result = c.glfwRawMouseMotionSupported(); try checkError(); return result == c.GLFW_TRUE; } pub const Window = @import("Window.zig"); pub const Key = input.Key; pub const KeyAction = input.KeyAction; pub const Mods = input.Mods; pub const MouseButton = input.MouseButton; test { try init(); defer deinit() catch unreachable; const window = try Window.create(800, 600, "Hello, World!", .{}, .{}); try window.makeCurrent(); while (!try window.shouldClose()) { try window.swapBuffers(); try pollEvents(); } }