Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/DRessedAlarm184/LWXGL/llms.txt

Use this file to discover all available pages before exploring further.

An image element is a fixed-size pixel canvas backed by an XImage. You write palette-index bytes into the image’s pixel buffer, call GUpdateImage to push changes to the X11 surface, and the canvas is blitted to the window on every GRenderWindow call. Image canvases are ideal for custom rendering, procedural graphics, tilemaps, or any content that doesn’t fit the standard widget model.
All primitive functions (GPrimitiveRect, GPrimitiveCircle, GPrimitiveLine, GPrimitiveSprite) and GDrawString operate in image-local coordinates: (0, 0) is the top-left pixel of the image canvas, not the window. The image element’s (x, y) position only controls where the finished canvas is composited into the window.

Creating and Managing Image Canvases

GCreateImage

void GCreateImage(int id, int x, int y, int w, int h);
Creates an image canvas element of size w × h pixels at window position (x, y). The backing XImage is allocated via XCreateImage at the display’s default visual and depth. Both the user-facing pixel buffer and an internal “previous frame” dirty-tracking buffer are zero-initialised (calloc), so every pixel starts at palette index 0 (black by default).
id
int
required
Element slot to create the image at.
x
int
required
X position of the image’s top-left corner within the window (pixels).
y
int
required
Y position of the image’s top-left corner within the window (pixels).
w
int
required
Width of the image canvas in pixels.
h
int
required
Height of the image canvas in pixels.
Example
/* 320×240 canvas at window position (10, 40) */
GCreateImage(5, 10, 40, 320, 240);

GGetImageData

unsigned char* GGetImageData(int id);
Returns a pointer to the w * h byte pixel buffer for image element id. Each byte holds a palette index in the range 0–15. The buffer is laid out in row-major order: the pixel at column x, row y is at data[y * w + x]. Write palette indices directly into this buffer to paint pixels, then call GUpdateImage to push the changes to the X11 surface.
id
int
required
The image element whose pixel buffer to retrieve.
Return valueunsigned char*: pointer to the writable pixel buffer. Valid until the element is deleted or recreated. Do not free. Example
unsigned char* px = GGetImageData(5);
int w = 320, h = 240;

/* Fill with a horizontal gradient using palette indices 0–7 */
for (int y = 0; y < h; y++)
    for (int x = 0; x < w; x++)
        px[y * w + x] = (x * 8) / w;

GUpdateImage(5);

GUpdateImage

void GUpdateImage(int id);
Compares the current pixel buffer against an internal “previous frame” copy and writes only the changed pixels into the XImage using the display’s put_pixel function. Unchanged pixels are skipped, making incremental updates efficient even for large canvases. You must call GUpdateImage after modifying the pixel buffer before calling GRenderWindow — the renderer always blits whatever pixel data is currently in the XImage; it does not call GUpdateImage automatically.
id
int
required
The image element to synchronise.
Example
/* Animate a single moving pixel */
px[prev_y * w + prev_x] = 0;   /* erase old */
px[new_y  * w + new_x ] = 12;  /* draw new  */
GUpdateImage(5);                /* push changes */

GClearImage

void GClearImage(int id, int c);
Fills the entire pixel buffer with a single palette index c using memset. This is faster than looping over the buffer manually. Call GUpdateImage after clearing if you want the change to appear on screen.
id
int
required
The image element to clear.
c
int
required
Palette index 0–15 to fill every pixel with. Use 0 for black.
Example
GClearImage(5, 0);   /* black out the canvas */
GUpdateImage(5);

GRedrawAllImages

void GRedrawAllImages();
Forces a full re-push of every image element’s pixel data to X11 by invalidating all “previous frame” dirty-tracking buffers (setting them to 255, which never equals a valid 0–15 palette index) and then calling GUpdateImage on each image. This causes every pixel to be rewritten regardless of whether it changed. Call this after GPaletteModify with redraw = 0 to apply colour changes to image canvases, or after restoring a saved pixel buffer from external storage. Example
/* Change palette colour 3 to red, then force image redraw */
GPaletteModify(3, 220, 40, 40, 0);
GRedrawAllImages();

Bitmap Font Rendering

GImageSetFont

void GImageSetFont(int id, unsigned char* font, int h);
Loads a bitmap font into image element id for use with GDrawString. The font is described as a flat byte array of 256 × h bytes: one entry per ASCII code (0–255), each entry h bytes tall. Each byte represents one row of 8 pixels with the MSB mapping to the leftmost pixel. The library copies the font buffer internally, so you can free your source buffer immediately after this call.
id
int
required
The image element that will use this font.
font
unsigned char*
required
Pointer to a 256 * h byte array. Index into it as font[char_code * h + row]. Each byte is an 8-bit bitmask: bit 7 (MSB) = leftmost pixel, bit 0 = rightmost.
h
int
required
Character height in pixels. Also controls the Y advance for \n in GDrawString.
Example
/* Load an 8×8 bitmap font from a file */
unsigned char my_font[256 * 8];
FILE* f = fopen("font8x8.bin", "rb");
fread(my_font, 1, sizeof(my_font), f);
fclose(f);

GImageSetFont(5, my_font, 8);
/* my_font can be freed or go out of scope here */

GDrawString

void GDrawString(int id, int x, int y, const char* txt, int color);
Renders the string txt onto image element id starting at image-local pixel position (x, y) using the bitmap font loaded by GImageSetFont. Each character is 8 pixels wide with a 1-pixel horizontal gap, giving a stride of 9 pixels per character. Pixels with a 0 bit in the font bitmap are not written (transparent background). \n (ASCII 10) resets the X position back to the original x and advances y by h pixels (the font character height).
id
int
required
The image element to draw text onto.
x
int
required
Starting X position in image-local coordinates (pixels from the image’s left edge).
y
int
required
Starting Y position in image-local coordinates (pixels from the image’s top edge).
txt
const char*
required
Null-terminated string to render. Supports \n for line breaks.
color
int
required
Palette index 0–15 for the text foreground color. Background pixels are left unchanged.
Example
GDrawString(5, 4, 4, "Score: 9999\nLevel: 3", 15);
GUpdateImage(5);

Drawing Primitives

All primitives write directly into the pixel buffer of the target image element. Call GUpdateImage after your drawing operations to push the result to the X11 surface.

GPrimitiveRect

void GPrimitiveRect(int id, int x, int y, int w, int h, int fg, int bg);
Draws a rectangle onto image id. The 1-pixel outline uses fg; the interior is filled with bg. Pass -1 for either to skip that part. If fg == -1, the border is treated as bg (the outer edge is drawn with the fill colour instead of being skipped). Pixels outside the image bounds are clipped silently.
id
int
required
Target image element.
x
int
required
Left edge of the rectangle in image-local coordinates.
y
int
required
Top edge of the rectangle in image-local coordinates.
w
int
required
Width in pixels.
h
int
required
Height in pixels.
fg
int
required
Palette index for the 1-pixel border. Pass -1 to skip the border (border falls back to bg).
bg
int
required
Palette index for the fill. Pass -1 to leave the interior unchanged (border only).
Example
/* Outlined box: white border, dark fill */
GPrimitiveRect(5, 10, 10, 80, 50, 15, 1);

/* Filled rectangle, no border */
GPrimitiveRect(5, 100, 10, 40, 40, -1, 4);

GUpdateImage(5);

GPrimitiveCircle

void GPrimitiveCircle(int id, int cx, int cy, int r, int fg, int bg);
Draws a circle centered at (cx, cy) with radius r pixels. Pixels whose squared distance from the center satisfies (r-1)² ≤ dx²+dy² ≤ r² are treated as the border and painted with fg. Pixels strictly inside that ring (dx²+dy² < (r-1)²) are painted with bg. Pass -1 for either to skip that layer. Pixels outside the image bounds are clipped silently.
id
int
required
Target image element.
cx
int
required
X coordinate of the circle center in image-local coordinates.
cy
int
required
Y coordinate of the circle center in image-local coordinates.
r
int
required
Radius in pixels.
fg
int
required
Palette index for the 1-pixel ring border. Pass -1 to draw a solid disc with no distinct border.
bg
int
required
Palette index for the filled interior. Pass -1 for an outline-only circle.
Example
/* Filled green disc with white border, radius 30 */
GPrimitiveCircle(5, 160, 120, 30, 15, 10);

/* White outline circle only */
GPrimitiveCircle(5, 80, 80, 20, 15, -1);

GUpdateImage(5);

GPrimitiveLine

void GPrimitiveLine(int id, int x1, int y1, int x2, int y2, int color);
Draws a straight line from (x1, y1) to (x2, y2) using palette index color. The algorithm computes steps = max(|dx|, |dy|) and advances by fractional increments, rounding to the nearest integer pixel at each step. This produces a connected, single-pixel-wide line regardless of angle. Pixels outside the image bounds are clipped silently.
id
int
required
Target image element.
x1
int
required
X coordinate of the start point (image-local).
y1
int
required
Y coordinate of the start point (image-local).
x2
int
required
X coordinate of the end point (image-local).
y2
int
required
Y coordinate of the end point (image-local).
color
int
required
Palette index 0–15 for the line color.
Example
/* Draw a white diagonal cross */
GPrimitiveLine(5,   0,   0, 319, 239, 15);
GPrimitiveLine(5, 319,   0,   0, 239, 15);
GUpdateImage(5);

GPrimitiveSprite

void GPrimitiveSprite(int id, int sx, int sy, int color,
                      const char* sprite, int scale);
Renders an RLE-encoded sprite onto image id, placing the sprite’s top-left pixel at image-local position (sx, sy). The color parameter sets the foreground palette index used for # pixels. Transparent pixels (.) write palette index 0. The scale parameter multiplies each logical pixel into a scale × scale block.
id
int
required
Target image element.
sx
int
required
X position of the sprite’s top-left corner in image-local coordinates.
sy
int
required
Y position of the sprite’s top-left corner in image-local coordinates.
color
int
required
Palette index 0–15 used to draw # pixels.
sprite
const char*
required
Null-terminated RLE sprite string. See the Sprite Format section below.
scale
int
required
Pixel scale factor. 1 = 1:1 (each logical pixel = 1 screen pixel), 2 = 2×2 block per pixel, etc.
Example
/* 3×3 white cross, 2× scale */
GPrimitiveSprite(5, 10, 10, 15, ".#.$3#.$#.", 2);

/* 5×5 smiley face, 1× scale */
GPrimitiveSprite(5, 50, 20, 11,
    ".3#.$#...#$#.#.#$#...#$.##.", 1);

GUpdateImage(5);

Sprite Format

The RLE sprite string is a compact ASCII encoding for pixel art. The cursor starts at (sx, sy) and advances left-to-right, row by row.
TokenMeaning
#Draw one foreground pixel (color) and advance right by scale px.
.Draw one transparent pixel (palette index 0) and advance right by scale px.
$Move to the start of the next row (x resets to sx, y advances by scale px).
>Skip right by scale px without writing a pixel.
N# / N.Repeat # or . exactly N times (e.g., 3# = three foreground pixels).
N$Advance N rows at once.
N>Skip N pixels right.
N[…]Repeat the group […] exactly N times. Groups can be nested.
Format examples
/* 3×3 cross (+ shape) */
".#.$3#.$#."

Row 0:  .  #  .
Row 1:  #  #  #
Row 2:  .  #  .
/* 5×5 smiley face */
".3#.$#...#$#.#.#$#...#$.##."

Row 0:  .  #  #  #  .
Row 1:  #  .  .  .  #
Row 2:  #  .  #  .  #
Row 3:  #  .  .  .  #
Row 4:  .  #  #  .  .
/* A 4×4 checkerboard tile, repeated 3 times horizontally */
const char* tile = "3[#.$.]";
GPrimitiveSprite(5, 0, 0, 15, tile, 4);

Build docs developers (and LLMs) love