user@saiboot:~/portfolio/projects/ngui/readme.md
README.MD FORMAT / MARKDOWN

NGUI

A lightweight immediate-mode GUI framework written in C, with a focus on performance, control and cross-platform rendering.

The project started when it occurred to me that I wanted to write native GUI applications without relying on a large framework. I wanted full control over the system, from the rendering layer to the application interface. This naturally led me onto the path of creating my own GUI library which eventually evolved into a framework.

Design Goals

NGUI is built around a few core principles:

Feather LIGHTWEIGHT Minimal dependencies and overhead
Tuning CONTROL Explicit control over rendering and resources
Speed PERFORMANCE Batching, caching, and predictable frame work
Plug PORTABILITY Platform-specific functionality isolated at the boundary

Architecture

Layers:

Dashboard UI Hierarchy · Components · Events
GPU RENDERING Batching · Clipping · Text · GPU synchronization
Cog CORE Application · Window · Input · Containers
World PLATFORM Operating System · Operations

Each layer builds on the layer below it, forming a dependency chain from platform-specific operations to the user interface.

UI

The top layer that brings all functionality together into an interactive user interface.

Hierarchy

UI elements form a hierarchical tree in which parent elements control the layout and clipping context of their children. Elements maintain their own bounds and can be assembled and dissassembled dynamically as the interface changes.

Components

Components provide higher-level controls built on top of the core UI primitives. The building blocks of which the user interact with the application.

Events

Interactive ui elements receive input through a centralized event system. Events cover pointer interaction, keyboard and text -input, and focus state changes.

Rendering

At the beginning of each frame, a pre-allocated chunk of memory is reset and used as a scratch arena for frame data. UI Elements are processed and submitted to the renderer during each frame, making the renderer architecture immediate-mode. Rendering data is generated as the UI hierarchy is processed rather than maintained as a persistent set of render objects.

Each batch within a frame is defined by its primitive type, clipping region, and texture slots. Elements can only be batched together when their rendering requirements are compatible. This allows the renderer to minimize the number of draw calls issued to the GPU while retaining explicit control over how UI geometry is rendered.

Clipping

Clipping is enabled throughout the renderer's lifecycle rather than being toggled independently for each batch. The default clipping region covers the entire application window, while elements may explicitly defeine their own clipping region.

A clipping region establishes a boundary for its descendants. Children must therefore render within the clipping region inherited from their parent, or within a more restrictive region of their own.

Textures

Regular textures are loaded using the stb_image header library made by Sean Barret. The data loaded from the texture defines the texture format, width, height, and pixels. A new OpenGL texture object resource is then created based on loaded texture data. And returned is a resource handle to the newly created texture object. Each handle is stored in a texture slot array within a frame batch. As of writing, texture loading is yet to support mipmaps.

Text

Text rendering is built around FeeType, HarfBuzz, and ICU. Freetype handles glyph rasterization, Harfbuzz performs text shaping, and ICU provides Unicode and script handling.

Rasterized glyphs are cached in texture atlases to avoid repeatedly generating the same glyphs. NGUI maintains separate monochrome and color atlases, allowing it to support both conventional fonts and color fonts such as emoji.

GPU Synchronization

Frame resources are synchronized with GPU execution using OpenGL fences. This prevents CPU-side frame data from being altered while the GPU is actively consuming it.

Core

The core layer provides functionality shared throughout the framework, including common data types, containers, logging, application state, window management, input handling, and memory management.

Application

Provides the main application lifecycle and coordinates the initialization, update, and shutdown of NGUI. It serves as the entry point through which the framework is initialized and the application loop is controlled.

Window

Provides the platform-independent interface for creating and managing the application window. It handles window state, dimensions, and the connection between the operating system and the rendering context.

Internal debugging

NGUI tracks metadata associated with heap and virtual memory allocations throughout the lifetime of the program. In debug builds, this provides extensive visibility into allocation counts, memory usage, leaks, and allocation lifetime.

Allocations are marked with magic values representing their current state. A distinct value is written when memory is allocated and another when it is freed, allowing the allocator to detect invalid allocation states and help indentifying memory lifetime errors during debugging.

Platform

The platform layer isolates operating-system functionality from the rest of the framework. It currently provides memory management, file I/O, debugger output, timing, and other platform-specific operations.

Development

NGUI is actively evolving. It has progressively expanded from basic OpenGL rendering into a light framework, aiming to cover the main necessities of desktop application development.