GLFW

Language: C

CLI/Utils

GLFW was created by Camilla Löwy to provide a simple, cross-platform API for creating windows and managing input in graphics applications. It abstracts platform-specific details and integrates smoothly with OpenGL, making it a popular choice for developers building real-time graphics, games, and simulations.

GLFW is an open-source library for creating windows, contexts, and handling input and events in OpenGL, OpenGL ES, and Vulkan applications. It is designed to be simple, portable, and lightweight, ideal for graphics and game development.

Installation

linux: sudo apt install libglfw3-dev
mac: brew install glfw
windows: Download precompiled binaries or build from source from https://www.glfw.org/

Usage

GLFW provides functions to create windows, handle keyboard and mouse input, manage OpenGL or Vulkan contexts, and handle events. It supports multiple monitors, full-screen modes, and high-DPI scaling.

Creating a simple window

#include <GLFW/glfw3.h>
#include <iostream>

int main() {
    if (!glfwInit()) {
        std::cerr << "Failed to initialize GLFW" << std::endl;
        return -1;
    }

    GLFWwindow* window = glfwCreateWindow(640, 480, "Hello GLFW", nullptr, nullptr);
    if (!window) {
        glfwTerminate();
        return -1;
    }

    glfwMakeContextCurrent(window);

    while (!glfwWindowShouldClose(window)) {
        glClear(GL_COLOR_BUFFER_BIT);
        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    glfwDestroyWindow(window);
    glfwTerminate();
    return 0;
}

Initializes GLFW, creates a 640x480 window, and enters a loop to handle events and update the window until it is closed.

Handling keyboard input

void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) {
    if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
        glfwSetWindowShouldClose(window, true);
}

int main() {
    glfwInit();
    GLFWwindow* window = glfwCreateWindow(640, 480, "Input Example", nullptr, nullptr);
    glfwMakeContextCurrent(window);
    glfwSetKeyCallback(window, key_callback);

    while (!glfwWindowShouldClose(window)) {
        glfwSwapBuffers(window);
        glfwPollEvents();
    }
    glfwDestroyWindow(window);
    glfwTerminate();
    return 0;
}

Registers a keyboard callback to close the window when the Escape key is pressed.

Mouse input handling

void mouse_callback(GLFWwindow* window, double xpos, double ypos) {
    std::cout << "Mouse moved to: (" << xpos << ", " << ypos << ")" << std::endl;
}

int main() {
    glfwInit();
    GLFWwindow* window = glfwCreateWindow(640, 480, "Mouse Example", nullptr, nullptr);
    glfwMakeContextCurrent(window);
    glfwSetCursorPosCallback(window, mouse_callback);

    while (!glfwWindowShouldClose(window)) {
        glfwSwapBuffers(window);
        glfwPollEvents();
    }
    glfwDestroyWindow(window);
    glfwTerminate();
    return 0;
}

Tracks mouse movements using a cursor position callback.

Full-screen window

GLFWmonitor* primary = glfwGetPrimaryMonitor();
const GLFWvidmode* mode = glfwGetVideoMode(primary);
GLFWwindow* window = glfwCreateWindow(mode->width, mode->height, "FullScreen", primary, nullptr);

Creates a full-screen window using the primary monitor’s video mode.

V-Sync

glfwSwapInterval(1);

Enables vertical synchronization to limit the frame rate to the display refresh rate, reducing screen tearing.

Handling multiple windows

GLFWwindow* window1 = glfwCreateWindow(400, 300, "Window 1", nullptr, nullptr);
GLFWwindow* window2 = glfwCreateWindow(400, 300, "Window 2", nullptr, window1);

Demonstrates creating multiple windows with shared OpenGL contexts.

Error Handling

GLFW_NOT_INITIALIZED: Ensure `glfwInit()` is called successfully before using other GLFW functions.
Failed to create GLFW window: Verify that the requested video mode and context hints are supported by your system.
OpenGL context not current: Call `glfwMakeContextCurrent(window)` before issuing OpenGL commands.

Best Practices

Always call `glfwTerminate()` before exiting to clean up resources.

Use callbacks for input handling rather than polling for cleaner code.

Check return values of GLFW functions to handle initialization or creation errors.

Use `glfwSwapInterval(1)` for smoother rendering.

Keep rendering and event polling in separate loops for responsive UI.