SDL_GPU 最小化、单头文件、高性能的2D图形绘制库
摘要
SDL_gp 是一个为 SDL3 设计的最小化、高性能的2D图形绘制库,从 sokol_gp 移植而来,提供了简单的资源管理系统。
查看缓存全文
缓存时间: 2026/07/30 16:50
n67094/sdl_gp
来源:https://github.com/n67094/sdl_gp
SDL_gp 🏁🏎️
一个基于
SDL3的简约高性能2D(图形)绘制器。
这是 sokol_gp (https://github.com/edubart/sokol_gp) 到 SDL3 的移植,主要区别在于:
sokol_gp 依赖 sokol,其内部管理资源;而 SDL_gpu 是更低层的,不管理资源。因此 SDL_gp 提供了一个非常类似于 sokol 的简单资源管理系统。
示例
基本图形:
基本图形截图
矩形:
矩形截图
精灵:
精灵截图
混合模式:
混合模式截图
快速开始
如果你想直接上手,可以查看 samples 文件夹。
下面是一个绘制红色矩形的简单示例:
// 获取当前帧的命令缓冲区
SDL_GPUCommandBuffer *cmd_buffer = SDL_AcquireGPUCommandBuffer(device);
// 开始新帧
SDL_GPBegin(WINDOW_WIDTH, WINDOW_HEIGHT);
{
// 将屏幕清除为黑色。
SDL_GPSetColor((SDL_Color){ 0, 0, 0, 255 });
SDL_GPClear();
// 绘制一个红色实心矩形。
SDL_GPSetColor((SDL_Color){ 255, 0, 0, 255 });
{
SDL_GPDrawRectFilled((SDL_GPRect){ 10, 10, 100, 100 });
}
// 调用者可以渲染到交换链或纹理。这里我们渲染到交换链。
SDL_GPUTexture *swapchain_texture = NULL;
SDL_WaitAndAcquireGPUSwapchainTexture(
cmd_buffer, window, &swapchain_texture, NULL, NULL);
SDL_GPFlush(cmd_buffer, swapchain_texture);
}
SDL_GPEnd();
SDL_SubmitGPUCommandBuffer(cmd_buffer);
SDL_Delay(DELTA_TIME_MS);
快速参考
错误 API:
// 获取 SDL_gp 中发生的最后一个错误。如果没有发生错误,返回 SDL_GP_ERROR_NONE。
SDL_GP_Error SDL_GPGetLastError(void);
// 获取描述 SDL_GP_Error 值的人类可读字符串。如果错误值无法识别,返回 "Unknown error"。
const char *SDL_GPGetErrorMessage(SDL_GP_Error error);
图像 API:
// 从 SDL_Surface 创建图像。如果创建失败,返回无效图像,使用 SDL_GPGetLastError() 获取更多错误信息。
SDL_GPImage SDL_GPCreateImage(SDL_Surface *surface);
// 销毁图像并释放其资源。
void SDL_GPDestroyImage(SDL_GPImage image);
// 获取与图像关联的 GPU 纹理。如果图像无效,返回 NULL。
SDL_GPUTexture *SDL_GPGetImageGPUTexture(SDL_GPImage image);
// 获取图像的宽度(像素)。如果图像无效,返回 0。
int SDL_GPGetImageWidth(SDL_GPImage image);
// 获取图像的高度(像素)。如果图像无效,返回 0。
int SDL_GPGetImageHeight(SDL_GPImage image);
着色器 API:
// 根据顶点和片段着色器描述创建着色器。如果创建失败,返回无效着色器,使用 SDL_GPGetLastError() 获取更多错误信息。
SDL_GPShader SDL_GPCreateShader(SDL_GPShaderDesc *desc);
// 获取与 SDL_gp 着色器关联的 SDL 着色器。如果着色器无效,返回 NULL。
SDL_GPUShader *SDL_GPGetGPUShader(SDL_GPShader shader);
// 销毁着色器并释放其资源。
void SDL_GPDestroyShader(SDL_GPShader shader);
管线 API:
// 创建图形管线。如果创建失败,返回无效管线,使用 SDL_GPGetLastError() 获取更多错误信息。
SDL_GPPipeline
SDL_GPCreatePipeline(SDL_GPShader shader_vert,
SDL_GPShader shader_frag,
SDL_GPPrimitiveType primitive_type,
SDL_GPBlendMode blend_mode);
// 销毁图形管线并释放其资源。
void SDL_GPDestroyPipeline(SDL_GPPipeline pipeline);
// 获取与 SDL_gp 管线关联的 GPU 图形管线。如果管线无效,返回 NULL。
SDL_GPUGraphicsPipeline *SDL_GPGetGPUPipeline(SDL_GPPipeline pipeline);
绘制器 API:
// 设置 SDL_GP 上下文。如果设置失败返回 false,使用 SDL_GPGetLastError() 获取更多错误信息。
bool SDL_GPSetup(SDL_GPDesc *desc);
// 关闭 SDL_GP 上下文。
void SDL_GPShutdown(void);
// 开始记录当前帧的绘制调用。应在设置 SDL_gp 并获取当前帧的交换链纹理和命令缓冲区后调用。
// 如果返回 false,说明发生错误,应跳过该帧,使用 SDL_GPGetLastError() 获取更多错误信息。
bool SDL_GPBegin(int width, int height);
// 将记录的绘制调用刷新到 GPU。如果发生错误返回 false,使用 SDL_GPGetLastError() 获取更多错误信息。
bool SDL_GPFlush(SDL_GPUCommandBuffer *cmd_buffer, SDL_GPUTexture *texture);
// 结束当前帧的绘制调用记录。
void SDL_GPEnd(void);
// 设置当前视口中坐标空间的边界。
void SDL_GPSetProjection(float left, float right, float bottom, float top);
// 将投影重置为默认坐标空间,即当前视口的坐标。
void SDL_GPResetProjection(void);
// 将当前变换矩阵保存到变换栈中,供稍后使用 SDL_GPPopTransform 弹出。
void SDL_GPPushTransform(void);
// 从变换栈顶部恢复变换矩阵。
void SDL_GPPopTransform(void);
// 将当前变换矩阵设置为单位矩阵(无变换)。
void SDL_GPResetTransform(void);
// 平移二维坐标空间。
void SDL_GPTranslate(float x, float y);
// 绕原点旋转二维坐标空间。
void SDL_GPRotate(float angle);
// 绕某一点旋转二维坐标空间。
void SDL_GPRotateAt(float angle, float ax, float ay);
// 绕原点缩放二维坐标空间。
void SDL_GPScale(float sx, float sy);
// 绕某一点缩放二维坐标空间。
void SDL_GPScaleAt(float sx, float sy, float ax, float ay);
// 设置当前图形管线。
void SDL_GPSetPipeline(SDL_GPPipeline pipeline);
// 将图形管线重置为内置的默认管线。
void SDL_GPResetPipeline(void);
// 为当前管线设置统一数据。
void SDL_GPSetUniform(const void *vs_data, size_t vs_size, const void *fs_data, size_t fs_size);
// 将统一数据重置为默认状态(当前状态颜色)。
void SDL_GPResetUniform(void);
// 设置当前混合模式。
void SDL_GPSetBlendMode(SDL_GPBlendMode blend_mode);
// 将当前混合模式重置为默认混合模式(无混合)。
void SDL_GPResetBlendMode(void);
// 设置当前颜色。
void SDL_GPSetColor(SDL_Color color);
// 获取当前颜色。
SDL_Color SDL_GPGetColor(void);
// 将当前颜色重置为默认颜色(白色)。
void SDL_GPResetColor(void);
// 在纹理通道中设置当前绑定的图像。
void SDL_GPSetImage(int channel, SDL_GPImage image);
// 从纹理通道中移除当前绑定的图像(无纹理)。
void SDL_GPUnsetImage(int channel);
// 将纹理通道中的当前绑定图像重置为默认值(白色纹理)。
void SDL_GPResetImage(int channel);
// 在纹理通道中设置当前绑定的采样器。
void SDL_GPSetSampler(int channel, SDL_GPUSampler *sampler);
// 从纹理通道中移除当前绑定的采样器(无采样器)。
void SDL_GPUnsetSampler(int channel);
// 将纹理通道中的当前绑定采样器重置为默认值(最近邻采样器)。
void SDL_GPResetSampler(int channel);
// 设置要绘制到的屏幕区域。
void SDL_GPViewport(int x, int y, int w, int h);
// 将视口重置为默认值(0, 0, width, height)。
void SDL_GPResetViewport(void);
// 在视口中设置裁剪矩形。
void SDL_GPScissor(int x, int y, int w, int h);
// 将裁剪矩形重置为默认值(视口边界)。
void SDL_GPResetScissor(void);
// 将所有状态重置为默认值。
void SDL_GPResetState(void);
// 用当前颜色清除当前视口。
void SDL_GPClear(void);
// 绘制任意图元。
void SDL_GPDraw(SDL_GPPrimitiveType primitive_type, const SDL_GPVertex *vertices, Uint32 vertices_count);
// 批量绘制点。
void SDL_GPDrawPoints(const SDL_GPPoint *points, Uint32 count);
// 绘制单个点。
void SDL_GPDrawPoint(SDL_GPPoint point);
// 批量绘制线段。
void SDL_GPDrawLines(const SDL_GPLine *lines, Uint32 count);
// 绘制单条线段。
void SDL_GPDrawLine(SDL_GPLine line);
// 绘制线段条带。
void SDL_GPDrawLinesStrip(const SDL_GPVec2 *points, Uint32 count);
// 批量绘制三角形。
void
SDL_GPDrawFilledTriangles(const SDL_GPTriangle *triangles, Uint32 count);
// 绘制单个三角形。
void SDL_GPDrawFilledTriangle(SDL_GPTriangle triangle);
// 绘制三角形条带。
void SDL_GPDrawFilledTrianglesStrip(const SDL_GPVec2 *points, Uint32 count);
// 批量绘制矩形。
void SDL_GPDrawFilledRects(const SDL_GPRect *rects, Uint32 count);
// 绘制单个矩形。
void SDL_GPDrawFilledRect(SDL_GPRect rect);
// 批量绘制带纹理的矩形。
void SDL_GPDrawTexturedRects(int channel, const SDL_GPTexturedRect *rects, Uint32 count);
// 绘制单个带纹理的矩形。
void SDL_GPDrawTexturedRect(int channel, SDL_GPTexturedRect rect);
赞助
大家好,我是 nsix,一名独立游戏开发者和开源贡献者,正在努力通过自己的工作谋生。
如果你喜欢我创作的内容并愿意支持我,可以考虑在 GitHub Sponsors (https://github.com/sponsors/n67094) 上成为赞助者。每一份支持都意义重大,非常感谢!
你也可以访问我的博客 www.nsix.blog (https://www.nsix.blog) 获取更多关于我工作的更新和见解。
致谢
- Edubart (https://github.com/edubart) - 原始
sokol_gp的创建者,他的工作激励我创建了SDL_gp。 - SDL 团队 (https://github.com/libsdl-org) - 开发和维护
SDL3。
许可证
本项目采用 MIT 许可证授权 - 详情请参见 LICENSE 文件。
相似文章
为我的离线渲染器制作一个着色语言
作者详细介绍了为其离线CPU渲染器SORT创建的自定义着色语言库——微型着色语言(TSL),并解释了其动机,包括学习、灵活性、Apple Silicon支持以及相比使用OSL减少依赖等。
降低图形API复杂性:为现代GPU设计的全新方案
塞巴斯蒂安·阿尔托宁批评了现代图形API因遗留硬件抽象而过于复杂的问题,并提出了一种采用64位GPU指针和类CUDA内存管理的全新设计方案。
SDXL 在浏览器中本地运行于 WebGPU,开源
Stable Diffusion XL (SDXL) 现在可以使用 WebGPU 在浏览器中本地运行,通过开源代码直接在设备上生成高质量 AI 图像。
用高斯泼溅作画
作者描述了一个交互式绘画工具的开发过程,该工具利用图像的边缘信息来引导二维高斯泼溅作为笔刷笔触,避免了缓慢的梯度下降方法,并产生类似绘画的效果。
编写一个无绑定GPU抽象层
一位开发者分享了他们实现的无绑定GPU抽象层Loon GPU,它基于Vulkan 1.3和Metal 4,灵感来自Sebastian Aaltonen的《No Graphics API》博客文章。该库使用GPU指针、顶点拉取和无绑定纹理堆来简化现代图形API。