2021-10-24 08:53:59 -07:00
# mach/glfw - Ziggified GLFW bindings [](https://github.com/hexops/mach-glfw/actions) <a href="https://hexops.com"><img align="right" alt="Hexops logo" src="https://raw.githubusercontent.com/hexops/media/main/readme.svg"></img></a>
2021-07-10 01:11:39 -07:00
2021-10-24 07:47:05 -07:00
Ziggified GLFW bindings that [Mach engine ](https://github.com/hexops/mach ) uses, with 100% API coverage, zero-fuss installation, cross compilation, and more.
2021-07-04 10:36:34 -07:00
2021-11-07 20:47:29 -07:00
This repository is a separate copy of the same library in the [main Mach repository ](https://github.com/hexops/mach ), and is automatically kept in sync, so that anyone can use this library in their own project / engine if they like!
2021-07-04 10:36:34 -07:00
2021-10-24 05:48:08 -07:00
## Zero fuss installation, cross compilation, and more
2021-07-18 13:50:53 -07:00
2021-10-24 05:50:56 -07:00
[Just as with Mach ](https://github.com/hexops/mach#zero-fuss-installation--cross-compilation ), you get zero fuss installation & cross compilation using these GLFW bindings. **only `zig` and `git` are needed to build from any OS and produce binaries for every OS.** No system dependencies at all.
2021-07-18 14:52:11 -07:00
2021-10-30 20:36:19 -07:00
## 100% API coverage, 130+ tests, etc.
2021-07-18 14:52:11 -07:00
2021-10-30 20:36:19 -07:00
These bindings have 100% API coverage of GLFW v3.3.4. Every function, type, constant, etc. has been wrapped in a ziggified API.
2021-07-18 14:52:11 -07:00
2021-10-30 20:36:19 -07:00
There are 130+ tests, and CI tests on all major platforms as well as cross-compilation between platforms:
[platform support table ](https://github.com/hexops/mach#supported-platforms )
2021-07-18 14:52:11 -07:00
2021-10-24 05:48:08 -07:00
## What does a ziggified GLFW API offer?
2021-07-18 14:52:45 -07:00
2021-10-30 20:36:19 -07:00
Why create a ziggified GLFW wrapper, instead of just using `@cImport` and interfacing with GLFW directly? You get:
2021-07-18 14:52:45 -07:00
2021-10-30 20:36:19 -07:00
* Errors as [zig errors ](https://ziglang.org/documentation/master/#Errors ) instead of via a callback function.
* `true` and `false` instead of `c.GLFW_TRUE` and `c.GLFW_FALSE` constants.
2021-10-24 05:48:08 -07:00
* Generics, so you can just use `window.hint` instead of `glfwWindowHint` , `glfwWindowHintString` , etc.
2021-10-30 20:36:19 -07:00
* **Enums**, always know what value a GLFW function can accept as everything is strictly typed. And use the nice Zig syntax to access enums, like `window.getKey(.escape)` instead of `c.glfwGetKey(window, c.GLFW_KEY_ESCAPE)`
2021-10-24 05:48:08 -07:00
* Slices instead of C pointers and lengths.
2021-10-30 20:36:19 -07:00
* [packed structs ](https://ziglang.org/documentation/master/#packed-struct ) represent bit masks, so you can use `if (joystick.down and joystick.right)` instead of `if (joystick & c.GLFW_HAT_DOWN and joystick & c.GLFW_HAT_RIGHT)` , etc.
* Methods, e.g. `my_window.hint(...)` instead of `glfwWindowHint(my_window, ...)`
2021-07-18 14:52:45 -07:00
2021-10-24 07:47:05 -07:00
## How do I use OpenGL, Vulkan, WebGPU, etc. with this?
You'll need to bring your own library for this. Some are:
* (Vulkan) https://github.com/Snektron/vulkan-zig (also see https://github.com/Avokadoen/zig_vulkan)
* (OpenGL) https://github.com/ziglibs/zgl
2021-10-31 01:14:46 -07:00
## Examples
A minimal Vulkan example can be found in the [mach-glfw-vulkan-example ](https://github.com/hexops/mach-glfw-vulkan-example ) repository:
< img width = "912" alt = "image" src = "https://user-images.githubusercontent.com/3173176/139573985-d862f35a-e78e-40c2-bc0c-9c4fb68d6ecd.png" >
2021-10-30 20:36:19 -07:00
## Getting started
In a `libs` subdirectory of the root of your project:
```sg
git clone https://github.com/hexops/mach-glfw
```
Then in your `build.zig` add:
```zig
const glfw = @import ("libs/mach-glfw/build.zig");
pub fn build(b: *Builder) void {
...
exe.addPackagePath("glfw", "libs/mach-glfw/src/main.zig");
glfw.link(b, exe, .{});
}
```
Now in your code you may import and use GLFW:
```zig
const glfw = @import ("glfw");
pub fn main() !void {
2021-11-10 11:39:13 +01:00
try glfw.init(.{});
2021-10-30 20:36:19 -07:00
defer glfw.terminate();
// Create our window
glfw: window hints rework (#71)
* glfw: make comments into doc comments
* glfw: Publicize Window.CursorPos, Window.Size, Window.Pos, and Window.FrameSize
* glfw: Make enum value name the same format as other enum value names
* glfw: Window hints rework patch
* glfw: Relegate `Window.hint` to testing; move it down to just above the tests to reflect this, add doc comment line
* glfw: handle error `Error.InvalidEnum` explicitly, for clear error message in this unlikely edge case
* glfw: instate `Hint.context_no_error` as a hint, as it actually is specified to be a Window creation hint by the docs, and affirm removal of `Hint.context_revision`, which isn't.
The docs don't seem to specify a default value for `Hints.context_no_error` to take on, so we could set it based on `std.debug.runtime_safety` like this.
* glfw: default `context_no_error` to `false`, and added a note of caution about its usage as suggested.
* glfw: Inline enum values of `ClientApi`, `ContextCreationApi`, `ContextRobustness`, `ContextReleaseBehavior`, and `OpenGlProfile` from consts.zig, and remove the now unused constants (replaced by aformentioned enum values).
* glfw: Reference `Window.Hint` enum instead of `Window.Hints` struct to ensure fields are the same
* glfw: add comment explaining default values of `Window.Hints`
* glfw: change `OpenGlProfile` to `OpenGLProfile` based on established naming convention
* glfw: Update actual declaration of `OpenGLProfile`
* glfw: call `Window.defaultHints` after window creation, not before
* glfw: remove 'consts.zig', and move `dont_care` directly into 'main.zig'; fix anything referencing it.
* glfw: put `Window.defaultHints` into defer statement to handle cleanup in all paths
* glfw: move `Hint.focused` to match position of `Hints.focused`
* glfw: do 'zig fmt glfw/src'
* glfw: Cull `Window.Hint` comments, polish remaining; match order entirely according to current GLFW docs
* glfw: Change `Window.Hints.*Api` to `Window.Hints.*API`
Co-authored-by: Stephen Gutekanst <stephen@hexops.com>
2021-11-16 02:41:16 +01:00
const window = try glfw.Window.create(640, 480, "Hello, mach-glfw!", null, null, .{});
2021-10-30 20:36:19 -07:00
defer window.destroy();
// Wait for the user to close the window.
while (!window.shouldClose()) {
2021-11-15 14:45:05 +03:30
try glfw.pollEvents();
2021-10-30 20:36:19 -07:00
}
}
```
## A warning about error handling
Unless the action you're performing is truly critical to your application continuing further, you should avoid using `try` .
This is because GLFW unfortunately must return errors for _a large portion_ of its functionality on some platforms, but especially for Wayland - so ideally your application is resiliant to such errors and merely e.g. logs failures that are not critical.
Instead of `try window.getPos()` for example, you may use:
```zig
const pos = window.getPos() catch |err| {
2021-11-04 05:13:39 +02:00
std.log.err("failed to get window position: error={}\n", .{err});
2021-10-30 20:36:19 -07:00
return;
2021-11-04 05:13:39 +02:00
};
2021-10-30 20:36:19 -07:00
```
Here is a rough list of functionality Wayland does not support:
* `Window.setIcon`
* `Window.setPos` , `Window.getPos`
* `Window.iconify` , `Window.focus`
* `Monitor.setGamma`
* `Monitor.getGammaRamp` , `Monitor.setGammaRamp`
2021-10-24 05:48:08 -07:00
## Issues
2021-07-18 14:52:45 -07:00
2021-10-24 05:48:08 -07:00
Issues are tracked in the [main Mach repository ](https://github.com/hexops/mach/issues?q=is%3Aissue+is%3Aopen+label%3Aglfw ).
## Contributing
2021-11-07 20:47:29 -07:00
Contributions are very welcome, but pull requests must be sent to [the main repository ](https://github.com/hexops/mach/tree/main/glfw ) to avoid some complex merge conflicts we'd get by accepting contributions in both repositories. Once the changes are merged there, they'll get sync'd to this repository automatically.
2021-10-24 05:48:08 -07:00
We track the latest stable release of GLFW, if you need a newer version we can start a development branch / figure that out - just open an issue.