LibGLFW Bindings for The PHP GLFW Extension

Maintainers

Package info

github.com/microscrap/glfw

Homepage

pkg:composer/microscrap/glfw

Transparency log

Statistics

Installs: 1

Dependents: 1

Suggesters: 0

Stars: 0

Open Issues: 0

0.5.1 2026-07-19 14:25 UTC

This package is not auto-updated.

Last update: 2026-07-20 12:50:49 UTC


README

PHP library that wraps the glfw extension with global helpers, enums, and data objects. Every helper delegates to a static wrapper class under Microscrap\Bindings\GLFW.

The package covers the entire extension surface (124 GLFWAPI methods + a small OpenGL convenience set across 8 extension classes): init, error, windows, monitors, input/joysticks/gamepads, context, Vulkan, and minimal GL clear/viewport helpers for visual proofs.

Highlights

  • Two calling styles — exact C names (glfwCreateWindow(...)) or static wrapper classes (Window::createWindow(...))
  • Opaque GLFW handles wrapped in typed final readonly data objects (GlfwWindow, GlfwMonitor, GlfwCursor)
  • Enum layer transcribed from glfw3.h — keys, hints, actions, joysticks/gamepads, context/client API tokens, plus a few GL enums used by the convenience layer
  • C-style error handling: no exceptions in src/; details via glfwGetError()
  • Coverage drift guard: a Pest test reflects the extension and fails if any extension method lacks a wrapper method or helper function

Requirements

Installation

Confirm ext-glfw is loaded:

php -m | grep glfw
composer require microscrap/glfw

Composer autoloads all helper files in src/Helpers/, registering the global glfw* / gl* functions when the package is installed. Helpers are only defined if the name is not already taken (function_exists guard).

The two calling styles

C-ish — global functions with exact GLFW C names:

use Microscrap\Bindings\GLFW\Enums\TrueFalse;
use Microscrap\Bindings\GLFW\Enums\WindowHint;

glfwInit();
glfwWindowHint(WindowHint::GLFW_VISIBLE, TrueFalse::GLFW_FALSE->value);
$window = glfwCreateWindow(640, 480, 'hello');
glfwDestroyWindow($window);
glfwTerminate();

OO-ish — static wrapper classes, same behavior:

use Microscrap\Bindings\GLFW\Init;
use Microscrap\Bindings\GLFW\Window;
use Microscrap\Bindings\GLFW\Enums\TrueFalse;
use Microscrap\Bindings\GLFW\Enums\WindowHint;

Init::init();
Window::windowHint(WindowHint::GLFW_VISIBLE, TrueFalse::GLFW_FALSE->value);
$window = Window::createWindow(640, 480, 'hello');
Window::destroyWindow($window);
Init::terminate();

Helpers never touch the extension directly; they delegate one-to-one to the wrapper classes, which are the only layer calling Glfw\GLFW\*. Both styles accept and return the same data objects, and every flag/enum parameter takes EnumType|int.

Name transforms

  • Wrapper methods drop the glfw prefix: glfwCreateWindowWindow::createWindow().
  • The GL class drops the gl prefix: glClearColorGL::clearColor().
  • Helpers use the exact C / extension method name (glfwCreateWindow(), glClear()).

macOS note: data objects are named GlfwWindow / GlfwMonitor / GlfwCursor (not GLFWwindow) so they do not collide with the extension classes GLFWWindow / GLFWMonitor on case-insensitive filesystems.

Wrapper classes

Class Wraps Methods Subsystem
Init Glfw\GLFW\GLFW 10 init/terminate, version, platform, error callback
Error GLFWError 1 glfwGetError
Window Window\GLFWWindow 47 windows, hints, attributes, event loop
Monitor Monitor\GLFWMonitor 15 monitors, video modes, gamma
Input Input\GLFWInput 40 keys, mouse, cursors, joystick/gamepad, clipboard, time
Context Context\GLFWContext 6 make current, swap, proc address
Vulkan Vulkan\GLFWVulkan 5 Vulkan support + surface
GL GL\GLFWGL 8 minimal OpenGL for visual demos

Data objects live under Microscrap\Bindings\GLFW\DataObjects. Enums live under Microscrap\Bindings\GLFW\Enums (case names match the C macros exactly; TrueFalse holds GLFW_TRUE / GLFW_FALSE because Bool is reserved in PHP).

Examples

Hidden window (init smoke)

use Microscrap\Bindings\GLFW\Enums\TrueFalse;
use Microscrap\Bindings\GLFW\Enums\WindowHint;

glfwInit();
glfwWindowHint(WindowHint::GLFW_VISIBLE, TrueFalse::GLFW_FALSE->value);

$window = glfwCreateWindow(320, 240, 'demo');
if (is_null($window)) {
    [$code, $description] = glfwGetError();
    throw new RuntimeException($description ?: "glfw error {$code}");
}

while (! glfwWindowShouldClose($window)) {
    glfwPollEvents();
    glfwSetWindowShouldClose($window, TrueFalse::GLFW_TRUE->value);
}

glfwDestroyWindow($window);
glfwTerminate();

OpenGL clear (needs a display)

use Microscrap\Bindings\GLFW\Context;
use Microscrap\Bindings\GLFW\GL;
use Microscrap\Bindings\GLFW\Init;
use Microscrap\Bindings\GLFW\Window;
use Microscrap\Bindings\GLFW\Enums\ClearBufferMask;

Init::init();
$window = Window::createWindow(640, 480, 'clear');
Context::makeContextCurrent($window);

GL::clearColor(0.1, 0.2, 0.3, 1.0);
GL::clear(ClearBufferMask::GL_COLOR_BUFFER_BIT);
Context::swapBuffers($window);

Window::destroyWindow($window);
Init::terminate();

Error handling

Nothing in src/ throws. The package keeps GLFW's C conventions:

  • creation functions return null on failure (?GlfwWindow, ?GlfwCursor, …)
  • call glfwGetError() for [code, description]

Note: the underlying extension itself may throw RuntimeException from a handful of calls (e.g. failed glfwCreateWindow). Those propagate as-is.

Testing

./vendor/bin/pest
  • tests/Unit runs without the extension: coverage drift guard (against a committed 0.5.0 method snapshot), style audit (no class constants, no throws, guarded helpers, backed enums, uppercase cases).
  • tests/Feature is gated on extension_loaded('glfw') and smokes init/version/platform.

License

MIT. See LICENSE.