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.
LWXGL can load indexed-color TGA files and 1-bit XBM files and render them into image elements using the same palette-indexed pixel buffer system as the raster drawing API. Images are stored in a named registry — you allocate a TGA once and can draw it into any image element by name. This guide covers loading from disk, loading from memory, XBM support, palette control, transparency, and capturing back-buffer regions.
LWXGL’s TGA loader has strict requirements. Files that do not meet these criteria will be rejected with error code 2.
| Field | Required value |
|---|
| Color map type | 1 (palette present) |
| Image type | 1 (uncompressed indexed) or 9 (RLE indexed) |
| Colormap origin | 0 (both bytes h[3] and h[4] must be 0) |
| Palette entry count | 16 (encoded as h[5]=16, h[6]=0) |
| Palette entry depth | 24-bit RGB (h[7]=24) |
| Image bit depth | 8 bits per pixel (h[16]=8) |
| Origin | Top-left (h[17]=0x20) or bottom-left (h[17]=0x00) |
A 16-entry, 8-bit indexed TGA can be created by most graphics editors (GIMP, Aseprite, etc.) by exporting as “Indexed TGA” with a 16-color palette.
Allocating and Drawing TGA Files
AllocateTGA
int AllocateTGA(const char* name, const char* path,
int change_palette, int transparent);
Loads a TGA file from disk and stores it in the internal registry under name. The name is an arbitrary string key used to reference the image later.
Return values:
0 — success
1 — file not found
2 — invalid TGA format
Parameters:
name — registry key string
path — filesystem path to the .tga file
change_palette — if non-zero, LWXGL replaces its active 16-color palette with the TGA’s own palette each time the image is drawn (see Palette Replacement below)
transparent — palette index to treat as transparent (pixels with this index are skipped during drawing); pass -1 for no transparency
int status = AllocateTGA("player_sprite", "assets/player.tga", 0, -1);
if (status == 1) { /* file not found */ }
if (status == 2) { /* wrong format */ }
DrawIndexedTGA
void DrawIndexedTGA(int id, int x, int y, const char* name);
Draws the named TGA into the image element id at offset (x, y) within the element. Pixels are clipped to the element bounds. If change_palette was set when allocating, the palette is updated before drawing.
// Draw "player_sprite" at offset (0, 0) inside element 5
DrawIndexedTGA(5, 0, 0, "player_sprite");
UpdateImage(5);
CreateTGAImage (convenience)
int CreateTGAImage(int id, int x, int y, const char* path, int change_palette);
A single-call convenience wrapper that:
- Allocates the TGA (if not already loaded) under the internal key
"TGAImage_" + path
- Creates an image element sized to the TGA dimensions
- Draws the TGA at offset
(0, 0)
- Calls
UpdateImage
No transparent parameter — use AllocateTGA + DrawIndexedTGA when you need transparency.
// Load, create element, draw, flush — all in one call
if (CreateTGAImage(10, 50, 50, "assets/logo.tga", 0) != 0) {
// handle error
}
DeleteTGA
void DeleteTGA(const char* name);
Frees the palette and pixel buffers for the named TGA and removes it from the registry. Does nothing if the name is not found.
DeleteTGA("player_sprite");
Palette Replacement
When change_palette is non-zero, DrawIndexedTGA replaces LWXGL’s 16-color palette with the TGA file’s own palette at draw time. This means the TGA is rendered in its original colors rather than the current application palette.
// Draw a TGA in its own colors; all other elements using
// the palette will also reflect the new colors after this call.
AllocateTGA("background", "assets/bg.tga", 1, -1);
DrawIndexedTGA(3, 0, 0, "background");
UpdateImage(3);
Palette replacement is global. After DrawIndexedTGA with change_palette = 1, all other image elements and UI widgets will use the new palette colors until you call PaletteReset(). Plan your draw order accordingly, or load TGAs with change_palette = 0 when you need consistent UI colors.
Palette functions
// Query a palette entry
void PaletteQuery(int idx, unsigned char* r, unsigned char* g, unsigned char* b);
// Modify a palette entry; pass redraw=1 to refresh all image elements
void PaletteModify(int idx, unsigned char r, unsigned char g, unsigned char b, int redraw);
// Reset all 16 palette entries to LWXGL defaults and redraw images
void PaletteReset();
Transparency
The transparent parameter in AllocateTGA specifies a palette index that is treated as transparent — those pixels are skipped during DrawIndexedTGA. Pass -1 to disable transparency.
// Palette index 0 (black) is the transparent color in this sprite
AllocateTGA("icon", "assets/icon.tga", 0, 0);
// Palette index 15 (white) treated as transparent
AllocateTGA("mask", "assets/mask.tga", 0, 15);
Loading TGA from Memory
int AllocateMemoryTGA(const char* name, const char* buffer, int size,
int change_palette, int transparent);
Loads a TGA from an in-memory byte buffer using memfd_create to expose it as a temporary file descriptor, then calls AllocateTGA internally. This is useful for TGA data embedded in your binary (e.g. via xxd -i) or downloaded at runtime.
// Assume tga_data[] and tga_data_len are generated by xxd -i
extern unsigned char tga_data[];
extern unsigned int tga_data_len;
int status = AllocateMemoryTGA("embedded_sprite",
(const char*)tga_data, tga_data_len,
0, -1);
Known parameter-swap bug: inside AllocateMemoryTGA the change_palette and transparent arguments are passed to AllocateTGA in swapped order — transparent is forwarded as change_palette and change_palette is forwarded as transparent. As a workaround, swap your intended values at the call site: pass your desired transparent value as the change_palette argument and vice versa.// Workaround: swap the last two args at the call site
// Desired: change_palette=0, transparent=-1
// Pass: change_palette=-1, transparent=0 (swapped)
AllocateMemoryTGA("sprite", buf, len, -1, 0);
AllocateMemoryTGA uses the Linux-specific memfd_create syscall, so this function is only available on Linux kernel 3.17+.
XBM Support
XBM is a 1-bit bitmap format where each pixel is either 0 or 1. LWXGL maps the two bit values to two palette indices, allowing you to use XBMs as monochrome sprites or icons.
AllocateXBM
int AllocateXBM(const char* name, const char* path, int colors, int transparent);
name — registry key
path — path to the .xbm file
colors — packed palette indices: high nibble = color for bit-1 pixels, low nibble = color for bit-0 pixels
transparent — 1 to make bit-1 pixels transparent, 0 to make bit-0 pixels transparent, or any other value for no transparency
Returns 1 on success, 0 on failure.
// bit-1 → CLR_WHITE (0xF), bit-0 → CLR_BLACK (0x0)
// No transparency
int colors = (CLR_WHITE << 4) | CLR_BLACK; // 0xF0
AllocateXBM("cursor_icon", "assets/cursor.xbm", colors, -1);
DrawIndexedTGA(7, 0, 0, "cursor_icon");
UpdateImage(7);
CreateXBMImage (convenience)
int CreateXBMImage(int id, int x, int y, const char* path, int colors);
Allocates the XBM (if not already loaded) under "XBMImage_" + path, creates a sized image element, draws, and flushes. No transparency parameter.
int colors = (CLR_LGREEN << 4) | CLR_BLACK; // 0xA0
CreateXBMImage(8, 20, 20, "assets/logo.xbm", colors);
Capturing Screen Regions
unsigned char* CaptureRegion(int x, int y, unsigned short w, unsigned short h);
Captures a rectangular region from the current back-buffer and returns it as a heap-allocated in-memory TGA buffer. The buffer is a valid indexed TGA (type 1, 16-entry palette) that reflects the current palette.
- Caller must
free() the returned buffer.
- Buffer size:
66 + w * h bytes (18-byte TGA header + 48-byte palette + w * h pixel data)
// Capture a 200×150 region starting at (50, 30)
unsigned char* screenshot = CaptureRegion(50, 30, 200, 150);
if (screenshot) {
FILE* f = fopen("capture.tga", "wb");
fwrite(screenshot, 1, 66 + 200 * 150, f);
fclose(f);
free(screenshot);
}
CaptureRegion can be used to implement a screenshot button, or to feed back a rendered region into AllocateMemoryTGA for further compositing.
Complete Example: Sprite Sheet with Recoloring
This example loads a TGA sprite with transparency, draws it, then demonstrates palette recoloring to render the same sprite in different team colors.
#include "libLWXGL.h"
#include <stdio.h>
#define CANVAS 1
int main(void) {
CreateWindow(400, 200, "TGA Sprite Demo", CLR_BLACK, FLAG_NONE);
CreateImage(CANVAS, 0, 0, 400, 200);
// Load the sprite: palette index 0 is transparent (background)
int status = AllocateTGA("hero", "assets/hero.tga", 0, 0);
if (status != 0) {
fprintf(stderr, "Failed to load TGA (error %d)\n", status);
TerminateWindow();
return 1;
}
// Draw the sprite at (20, 40) in its default colors
ClearImage(CANVAS, CLR_BLACK);
DrawIndexedTGA(CANVAS, 20, 40, "hero");
// Recolor palette index 4 (red armor) to blue
PaletteModify(4, 30, 80, 220, 0); // r=30 g=80 b=220, no immediate redraw
// Draw a second copy at (200, 40) in the modified palette
DrawIndexedTGA(CANVAS, 200, 40, "hero");
UpdateImage(CANVAS);
// Restore default palette
PaletteReset();
MainWindowLoop(60, NULL);
TerminateWindow();
return 0;
}