SDL_GPU minimal, single-header, high-performance 2D graphics painting library
🎨 SDL_gp: A Lightweight, High-Performance 2D Painter for SDL3
SDL_gp is a streamlined, single-header library designed to provide high-performance 2D graphics capabilities specifically for SDL3.
📌 Overview
This project is a dedicated port of the sokol_gp library. While it inherits the philosophy of its predecessor, there is a fundamental architectural shift: . Because the SDL3 GPU API is more low-level, sokol_gp relies on the internal resource management of the sokol frameworkSDL_gp implements its own simplified resource management system to mirror the ease of use found in sokol.
🚀 Quick Start Checklist
- Explore the
samplesdirectory for implementation ideas. - Integrate
SDL_gp.hinto your project. - Initialize the GPU device via SDL3.
- Implement the render loop.
🛠️ Implementation Guide
To get started, refer to the provided samples for primitives, sprites, and blend modes. Below is a concise example demonstrating how to render a red rectangle on a black background.
// 1. Obtain the command buffer for the current frame
SDL_GPUCommandBuffer * cmd_buffer = SDL_AcquireGPUCommandBuffer(device);
// 2. Initialize the GP painter context
SDL_GPBegin(WINDOW_WIDTH, WINDOW_HEIGHT);
{
// Set background to black and clear
SDL_GPSetColor((SDL_Color){0, 0, 0, 255});
SDL_GPClear();
// Define and draw a red filled rectangle
SDL_GPSetColor((SDL_Color){255, 0, 0, 255});
SDL_GPDrawRectFilled((SDL_GPRect){10, 10, 100, 100});
// Handle the swapchain texture for final output
SDL_GPUTexture * swapchain_texture = NULL;
SDL_WaitAndAcquireGPUSwapchainTexture(cmd_buffer, window, &swapchain_texture, NULL, NULL);
// Push recorded commands to the GPU
SDL_GPFlush(cmd_buffer, swapchain_texture);
}
// 3. Finalize the frame
SDL_GPEnd();
SDL_SubmitGPUCommandBuffer(cmd_buffer);
SDL_Delay(DELTA_TIME_MS);
🔄 Rendering Workflow
The following diagram illustrates the lifecycle of a single frame in SDL_gp:
📖 API Reference
⚠️ Error Handling
Note: Always check for errors during resource creation to ensure stability.
| Function | Description |
|---|---|
SDL_GP_Error SDL_GPGetLastError(void) | Retrieves the most recent error code. |
const char * SDL_GPGetErrorMessage(SDL_GP_Error error) | Converts an error code into a human-readable string. |
🖼️ Image Management
The library provides a wrapper around SDL_Surface to handle GPU textures.
SDL_GPImage SDL_GPCreateImage(SDL_Surface * surface): Generates an image. Returns an invalid handle on failure.void SDL_GPDestroyImage(SDL_GPImage image): Frees associated GPU resources.SDL_GPUTexture * SDL_GPGetImageGPUTexture(SDL_GPImage image): Returns the underlying SDL3 GPU texture.int SDL_GPGetImageWidth(SDL_GPImage image): Returns width in pixels.int SDL_GPGetImageHeight(SDL_GPImage image): Returns height in pixels.
⚡ Shaders & Pipelines
The pipeline defines how geometry is processed. The projection can be mathematically represented as a mapping of coordinates:
| Category | Function | Purpose |
|---|---|---|
| Shader | SDL_GPCreateShader | Creates a shader from SDL_GPShaderDesc. |
| Shader | SDL_GPGetGPUShader | Accesses the raw SDL_GPUShader. |
| Shader | SDL_GPDestroyShader | Cleans up shader memory. |
| Pipeline | SDL_GPCreatePipeline | Links shaders, primitive types, and blend modes. |
| Pipeline | SDL_GPDestroyPipeline | Frees the pipeline. |
| Pipeline | SDL_GPGetGPUPipeline | Accesses the raw SDL_GPUGraphicsPipeline. |
🖌️ Painter API
The Painter API manages the state and transformation stack.
-
Lifecycle
bool SDL_GPSetup(SDL_GPDesc * desc): Initializes the context.void SDL_GPShutdown(void): Cleans up the context.bool SDL_GPBegin(int width, int height): Starts recording draw calls.bool SDL_GPFlush(SDL_GPUCommandBuffer * cmd, SDL_GPUTexture * tex): Sends calls to GPU.void SDL_GPEnd(void): Stops recording.
-
Coordinate Space & Transforms
SDL_GPSetProjection(float left, float right, float bottom, float top): Defines the boundaries of the coordinate space.SDL_GPResetProjection(void): Reverts to the default viewport coordinates.SDL_GPPushTransform(void): Pushes the current matrix onto the stack.SDL_GPPopTransform(void): Restores the previous matrix from the stack.SDL_GPResetTransform(void): Sets the matrix to identity.SDL_GPTranslate(float x, float y): Shifts the 2D coordinate space.