-
-
Notifications
You must be signed in to change notification settings - Fork 98
Rewrite local README with updated startup instructions #44
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,19 +5,174 @@ | |
</picture> | ||
</a> | ||
|
||
Perfected GLFW bindings for Zig | ||
Perfected, community-maintained Zig bindings for GLFW | ||
|
||
## Features | ||
A previous version of this document can be found [here](https://machengine.org/v0.4/pkg/mach-glfw/). | ||
|
||
* Zero-fuss installation, cross-compilation at the flip of a switch, and broad platform support. | ||
* 100% API coverage. Every function, type, constant, etc. has been exposed in a ziggified API. | ||
## Features of this ziggified GLFW API | ||
- Zero-fuss installation | ||
- Simple cross-compiling over a broad range of platforms | ||
- 100% API coverage, including each function, type, and constant. | ||
|
||
See also: [What does a ziggified GLFW API offer?](https://machengine.org/pkg/mach-glfw/) | ||
- Strict typing on GLFW functions | ||
|
||
## Community maintained | ||
- Zig enums provide a pleasant syntax for the developer | ||
- `window.getKey(.escape)` vs `c.glfwGetKey(window, c.GLFW_KEY_ESCAPE)` | ||
|
||
The [Mach engine](https://machengine.org/) project no longer uses GLFW, and so this project is now community-maintained. Pull requests are welcome and will be reviewed. The project will still target [nominated Zig versions](https://machengine.org/about/zig-version/) but may not see regular updates as it is no longer a Mach project (see [hexops/mach#1166](https://github.com/hexops/mach/issues/1166)). | ||
- Zig API works with slices instead of C-style pointers and lengths | ||
|
||
- Generics provide a cleaner interface | ||
- allowing `window.hint` over `glfwWindowHint` or `glfwWindowHintString`, etc. | ||
|
||
- Zig's packed structs make working with bitmasks easier | ||
- `if (joystick.down and joystick.right)` with mach-glfw | ||
- `if (joystick & c.GLFW_HAT_DOWN and joystick & c.GLFW_HAT_RIGHT)` with standard Zig/C interfacing | ||
|
||
- Namespaced methods instead of long variable names | ||
- `my_window.hint(...)` vs `c.glfwWindowHint(my_window, ...)` | ||
|
||
- Native boolean support with `true` and `false` | ||
- No more `c.GLFW_TRUE` and `c.GLFW_FALSE` | ||
|
||
## Targeting | ||
This project was originally a part of the [Mach engine](https://machengine.org), but was dropped | ||
with the end of GLFW support in the project. It is now community-maintained. | ||
|
||
This project targets the latest `master` version of GLFW, allowing its authors to work | ||
with the GLFW author to fix integration hiccups. Following `master` means that new | ||
changes (such as runtime X11/Wayland switching) can be integrated seamlessly. | ||
|
||
This project additionally targets [nominated zig versions](https://machengine.org/about/zig-version/) | ||
but may not recieve as regular updates (see [hexops/mach#1166](https://github.com/hexops/mach/issues/1166)) | ||
|
||
## How-to-use OpenGL, Vulkan, WebGPU, etc | ||
This project can be used in conjunction with other libraries, as these authors have done: | ||
|
||
- WebGPU: [mach-gpu](https://machengine.org/v0.4/pkg/mach-gpu) - [example](https://github.com/hexops/mach-gpu) (deprecated) | ||
|
||
- Vulkan: [example](https://github.com/hexops/mach-glfw-vulkan-example) | ||
|
||
- [Snektron/vulkan-zig](https://github.com/Snektron/vulkan-zig) | ||
|
||
- [hexops/vulkan-zig-generated](https://github.com/hexops/vulkan-zig-generated) | ||
|
||
- OpenGL: [castholm/zigglegen](https://github.com/hexops/mach-glfw-opengl-example) - [example](https://github.com/hexops/mach-glfw-opengl-example) | ||
|
||
## Getting Started | ||
This project is best suited for development using native zig tooling. | ||
|
||
First run `zig init` to create a valid zig project. This will generate `build.zig` and | ||
`build.zig.zon` files, which you will need to modify in the following steps. | ||
|
||
### build.zig.zon | ||
The `zig` command-line tool supports a CLI for modifying your `build.zig.zon`. | ||
```sh | ||
zig fetch --save "https://pkg.machengine.org/mach-glfw/LATEST_COMMIT.tar.gz" | ||
``` | ||
The `zig fetch` command above will include this project in your dependency list. | ||
You will need to check the git repository in order to find the latest full commit hash. | ||
|
||
### build.zig | ||
A depedency step must be added in order for your project to build with mach-glfw. Below | ||
the line beginning with `const exe = b.addExecutable`, add the following snippet: | ||
```typescript | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should be |
||
const glfw_dep = b.dependency("mach-glfw", .{ | ||
.target = target, | ||
.optimize = optimize, | ||
}); | ||
exe.root_module.addImport("mach-glfw", glfw_dep.module("mach-glfw")); | ||
``` | ||
|
||
### src/main.zig | ||
Below follows an example program, to test your functionality: | ||
```typescript | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should be |
||
/// Default GLFW error handling callback | ||
fn errorCallback(error_code: glfw.ErrorCode, description: [:0]const u8) void { | ||
std.log.err("glfw: {}: {s}\n", .{ error_code, description }); | ||
} | ||
|
||
pub fn main() !void { | ||
glfw.setErrorCallback(errorCallback); | ||
if (!glfw.init(.{})) { | ||
std.log.err("failed to initialize GLFW: {?s}", .{glfw.getErrorString()}); | ||
std.process.exit(1); | ||
} | ||
defer glfw.terminate(); | ||
|
||
// Create our window | ||
const window = glfw.Window.create(640, 480, "Hello, mach-glfw!", null, null, .{}) orelse { | ||
std.log.err("failed to create GLFW window: {?s}", .{glfw.getErrorString()}); | ||
std.process.exit(1); | ||
}; | ||
defer window.destroy(); | ||
|
||
// Wait for the user to close the window. | ||
while (!window.shouldClose()) { | ||
window.swapBuffers(); | ||
glfw.pollEvents(); | ||
} | ||
} | ||
``` | ||
|
||
## Issues persisting? | ||
If you're manually configuring your `build.zig.zon`, verify that this structure exists: | ||
```typescript | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should be |
||
.{ | ||
// ... .name, .version, etc | ||
.dependencies = .{ | ||
// ... other dependencies of yours | ||
.@"mach-glfw" = .{ | ||
.url = "https://pkg.machengine.org/mach-glfw/FULL_HASH_LATEST_COMMIT.tar.gz", | ||
.hash = "" // place anything here--zig build will error and give you the correct hash | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove this line, as it being present makes Zig assume the hash should be |
||
}, | ||
}, | ||
// ... .paths is down here | ||
} | ||
``` | ||
|
||
You may need to modify the `.url` or `.hash` fields for accuracy. | ||
|
||
## Developer's Notes | ||
|
||
**TLDR: Unless your intended action is truly critical to your intended functionality, you should avoid terminating on GLFW errors.** | ||
|
||
For some platforms, a large portion of GLFW's functionality will return errors. | ||
For Wayland on Linux in particular, errors should probably be logged instead of crashing. | ||
|
||
Wayland does not support the following functionality: | ||
- `Window.setIcon` | ||
- `Window.setPos`, `Window.getPos` | ||
- `Window.iconify`, `Window.focus` | ||
- `Monitor.setGamma` | ||
- `Monitor.getGammaRamp`, `Monitor.setGammaRamp` | ||
|
||
Non-critical errors (such as the failure of `Window.getPos`) can still be caught and handled: | ||
```typescript | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should be |
||
const pos = window.getPos(); // always returns x=0, y=0 on Wayland | ||
|
||
// Option 1: GLFW error -> Zig error | ||
glfw.getErrorCode() catch |err| { | ||
std.log.err("Failed to get window position: error={}", .{err}); | ||
return err; // or fall back to other code | ||
}; | ||
|
||
// Option 2: Log the error, without failing | ||
if (glfw.getErrorString()) |description| { | ||
std.log.err("Failed to get window position: {s}", .{description}); | ||
} | ||
|
||
// Option 3: A combination of both, using zig constructs | ||
if (glfw.getError()) |err| { | ||
const error_code = err.error_code; | ||
const description = err.description; | ||
std.log.err("Failed to get window position: error={}: {s}", .{error_code, description}); | ||
} | ||
``` | ||
|
||
It is of note that these options rely on GLFW's saved error being empty; otherwise, | ||
previously emitted errors can be mistaked for a `Window.getPos` error. | ||
|
||
If your application frequently ignores errors, `glfw.clearError()` or `defer glfw.clearError()` | ||
will ensure a clean slate for future error handling. | ||
|
||
Note: [hexops/glfw]() | ||
|
||
Some old documentation is available at https://machengine.org/v0.4/pkg/mach-glfw/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not a link to zigglegen
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be
https://github.com/castholm/zigglgen