Intro
RGFW is a cross-platform single-header framework that abstracts creating and managing windows. RGFW is simple to use, letting you focus on programming your game or application rather than dealing with complex low-level windowing APIs, libraries with a lot of overhead, or supporting platform-specific APIs. RGFW handles the low-level APIs for you without getting in your way. It currently supports X11 (Linux), Windows (XP +), Emscripten (HTML5), and MacOS.
While creating a window, RGFW initializes a graphics context of your choosing. The options include OpenGL (including variants), DirectX, direct software rendering, or no graphics API. There is also a separate header for Vulkan support although it's recommended to make your Vulkan context yourself.
Design
RGFW is also flexible by design. For example, you can use an event loop system or an event call-back system. (See more in examples/events/main.c and examples/callbacks/main.c in the RGFW repo).
while (RGFW_window_checkEvent(win)) {
switch (win->event.type) {
case RGFW_quit:
break;
case RGFW_keyPressed:
break;
case RGFW_mousePosChanged:
break;
...
}
}
void mouseposfunc(RGFW_window* win, RGFW_point point) {
}
void keyfunc(RGFW_window* win, u32 keycode, char keyName[16], u8 lockState, u8 pressed) {
}
void windowquitfunc(RGFW_window* win) {
}
RGFW_setMousePosCallback(mouseposfunc);
RGFW_setKeyCallback(keyfunc);
RGFW_setWindowQuitCallback(windowquitfunc);
RGFW vs GLFW
RGFW is designed as an alternative to GLFW. This is because GLFW's codebase is not lightweight and is missing some flexibility.
There is a GitHub repository that takes all of GLFW's source code and puts it in one big single-header library. This GLFW.h file is 10.7 megabytes and cannot be viewed on GitHub. RGFW can be viewed on GitHub because it is 244 kilobytes and the RGFW binaries are also generally around a third of the size of GLFW's binaries. RGFW also tends to use less RAM than GLFW.
If RGFW is significantly more lightweight than GLFW does that mean that RGFW is lacking features? No, RGFW has nearly the same features as GLFW. If you're interested in knowing the differences, there is a table included in the RGFW repository that compares RGFW to GLFW.
Using/compiling RGFW
To use RGFW you need to add this line to one of your source files.
#define RGFW_IMPLEMENTATION
This allows the RGFW source defines to be included.
You can also compile RGFW like any other library.
cc -x c -c RGFW.h -D RGFW_IMPLEMENTATION -fPIC -D
RGFW_EXPORT
(Linux):
cc -shared RGFW.o -lX11 -lXrandr -lm -lGL
(window mingw):
cc -shared RGFW.o -lgdi32 -lopengl32 -lwinmm -lm
(macOS)
cc -shared RGFW.o -framework Foundation -framework AppKit -framework OpenGL -framework CoreVideo -lm
RGFW example
To create a window and initialize RGFW, if it's the first window, you use RGFW_createWindow(const char* name, RGFW_rect, u16 args)
For example, to create a window in the center of the screen that cannot be resized
RGFW_window* win = RGFW_createWindow("Window", RGFW_RECT(0, 0, 200, 200) RGFW_CENTER | RGFW_NO_RESIZE);
... // do software stuff
RGFW_window_close(win); // close window now that we're done
After you finish rendering, you need to swap the window buffer.
RGFW_window_swapBuffers(RGFW_window* win);
If you're using an unsupported API, you'll need to handle the function yourself.
Now here's a full RGFW example:
#define RGFW_IMPLEMENTATION
#include "RGFW.h"
u8 icon[4 * 3 * 3] = {0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF};
void keyfunc(RGFW_window* win, u32 keycode, char keyName[16], u8 lockState, u8 pressed) {
printf("this is probably early\n");
}
int main() {
RGFW_window* win = RGFW_createWindow("name", RGFW_RECT(500, 500, 500, 500), (u64)RGFW_CENTER);
RGFW_window_setIcon(win, icon, RGFW_AREA(3, 3), 4);
RGFW_setKeyCallback(keyfunc); // you can use callbacks like this if you want
i32 running = 1;
while (running) {
while (RGFW_window_checkEvent(win)) { // or RGFW_window_checkEvents(); if you only want callbacks
if (win->event.type == RGFW_quit || RGFW_isPressed(win, RGFW_Escape)) {
running = 0;
break;
}
if (win->event.type == RGFW_keyPressed) // this is the 'normal' way of handling an event
printf("This is probably late\n");
}
glClearColor(0xFF, 0XFF, 0xFF, 0xFF);
glClear(GL_COLOR_BUFFER_BIT);
RGFW_window_swapBuffers(win);
}
RGFW_window_close(win);
}
Final notes
A screenshot of the RGFW examples and PureDoom-RGFWMore example codes and information about RGFW can be found in the repository. The examples can also be run with HTML5 on the RGFW examples site. If RGFW interests you, feel free to check out the RGFW repository, star it, or ask me any questions you have about RGFW. I am also open to any criticism, advice, or feature requests you may have.
Although RGFW is significantly more lightweight than GLFW, that doesn’t mean you should it over GLFW. Ultimately, the choice is up to you. RGFW is more lightweight but it's also newer and has a tiny community. So there's less support and it hasn't yet been tested in a production-ready project.
If you find RGFW interesting, please check out the repository. One way you can support RGFW is by starring it.
Top comments (0)