From c8680c9515de7cb2b89b4d155a28802695a81349 Mon Sep 17 00:00:00 2001 From: Antonio Lattanzio Date: Sun, 1 Mar 2026 21:02:37 +1300 Subject: [PATCH 1/2] render: Add SDL_RenderGeometryRawColor8Bits for 8-bit color vertex input --- include/SDL3/SDL_render.h | 40 ++++++++++++++++++ src/dynapi/SDL_dynapi_overrides.h | 1 + src/dynapi/SDL_dynapi_procs.h | 1 + src/render/SDL_render.c | 68 +++++++++++++++++++++++++++++++ 4 files changed, 110 insertions(+) diff --git a/include/SDL3/SDL_render.h b/include/SDL3/SDL_render.h index 986130ce46b46..abc47758e301a 100644 --- a/include/SDL3/SDL_render.h +++ b/include/SDL3/SDL_render.h @@ -2496,6 +2496,46 @@ extern SDL_DECLSPEC bool SDLCALL SDL_RenderGeometryRaw(SDL_Renderer *renderer, int num_vertices, const void *indices, int num_indices, int size_indices); +/** + * Render a list of triangles, optionally using a texture and indices into the + * vertex arrays Color and alpha modulation is done per vertex + * (SDL_SetTextureColorMod and SDL_SetTextureAlphaMod are ignored). + * + * This variant takes SDL_Color (8-bit per channel) instead of SDL_FColor, + * converting to floating-point internally. + * + * \param renderer the rendering context. + * \param texture (optional) The SDL texture to use. + * \param xy vertex positions. + * \param xy_stride byte size to move from one element to the next element. + * \param color vertex colors (as SDL_Color). + * \param color_stride byte size to move from one element to the next element. + * \param uv vertex normalized texture coordinates. + * \param uv_stride byte size to move from one element to the next element. + * \param num_vertices number of vertices. + * \param indices (optional) An array of indices into the 'vertices' arrays, + * if NULL all vertices will be rendered in sequential order. + * \param num_indices number of indices. + * \param size_indices index size: 1 (byte), 2 (short), 4 (int). + * \returns true on success or false on failure; call SDL_GetError() for more + * information. + * + * \threadsafety This function should only be called on the main thread. + * + * \since This function is available since SDL 3.2.0. + * + * \sa SDL_RenderGeometry + * \sa SDL_RenderGeometryRaw + * \sa SDL_SetRenderTextureAddressMode + */ +extern SDL_DECLSPEC bool SDLCALL SDL_RenderGeometryRawColor8Bits(SDL_Renderer *renderer, + SDL_Texture *texture, + const float *xy, int xy_stride, + const SDL_Color *color, int color_stride, + const float *uv, int uv_stride, + int num_vertices, + const void *indices, int num_indices, int size_indices); + /** * Set the texture addressing mode used in SDL_RenderGeometry(). * diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h index acee86998e2ce..d3f349fa91d9d 100644 --- a/src/dynapi/SDL_dynapi_overrides.h +++ b/src/dynapi/SDL_dynapi_overrides.h @@ -762,6 +762,7 @@ #define SDL_RenderFillRects SDL_RenderFillRects_REAL #define SDL_RenderGeometry SDL_RenderGeometry_REAL #define SDL_RenderGeometryRaw SDL_RenderGeometryRaw_REAL +#define SDL_RenderGeometryRawColor8Bits SDL_RenderGeometryRawColor8Bits_REAL #define SDL_RenderLine SDL_RenderLine_REAL #define SDL_RenderLines SDL_RenderLines_REAL #define SDL_RenderPoint SDL_RenderPoint_REAL diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h index 68dca5a19233b..052540ba4cbca 100644 --- a/src/dynapi/SDL_dynapi_procs.h +++ b/src/dynapi/SDL_dynapi_procs.h @@ -773,6 +773,7 @@ SDL_DYNAPI_PROC(bool,SDL_RenderFillRect,(SDL_Renderer *a, const SDL_FRect *b),(a SDL_DYNAPI_PROC(bool,SDL_RenderFillRects,(SDL_Renderer *a, const SDL_FRect *b, int c),(a,b,c),return) SDL_DYNAPI_PROC(bool,SDL_RenderGeometry,(SDL_Renderer *a, SDL_Texture *b, const SDL_Vertex *c, int d, const int *e, int f),(a,b,c,d,e,f),return) SDL_DYNAPI_PROC(bool,SDL_RenderGeometryRaw,(SDL_Renderer *a, SDL_Texture *b, const float *c, int d, const SDL_FColor *e, int f, const float *g, int h, int i, const void *j, int k, int l),(a,b,c,d,e,f,g,h,i,j,k,l),return) +SDL_DYNAPI_PROC(bool,SDL_RenderGeometryRawColor8Bits,(SDL_Renderer *a, SDL_Texture *b, const float *c, int d, const SDL_Color *e, int f, const float *g, int h, int i, const void *j, int k, int l),(a,b,c,d,e,f,g,h,i,j,k,l),return) SDL_DYNAPI_PROC(bool,SDL_RenderLine,(SDL_Renderer *a, float b, float c, float d, float e),(a,b,c,d,e),return) SDL_DYNAPI_PROC(bool,SDL_RenderLines,(SDL_Renderer *a, const SDL_FPoint *b, int c),(a,b,c),return) SDL_DYNAPI_PROC(bool,SDL_RenderPoint,(SDL_Renderer *a, float b, float c),(a,b,c),return) diff --git a/src/render/SDL_render.c b/src/render/SDL_render.c index 8338255250193..836e299f27207 100644 --- a/src/render/SDL_render.c +++ b/src/render/SDL_render.c @@ -5287,6 +5287,74 @@ static bool SDLCALL SDL_SW_RenderGeometryRaw(SDL_Renderer *renderer, } #endif // SDL_VIDEO_RENDER_SW +bool SDL_RenderGeometryRawColor8Bits(SDL_Renderer *renderer, + SDL_Texture *texture, + const float *xy, int xy_stride, + const SDL_Color *color, int color_stride, + const float *uv, int uv_stride, + int num_vertices, + const void *indices, int num_indices, int size_indices) +{ + CHECK_RENDERER_MAGIC(renderer, false); + + if (texture) { + CHECK_TEXTURE_MAGIC(texture, false); + + CHECK_PARAM(renderer != texture->renderer) { + return SDL_SetError("Texture was not created with this renderer"); + } + } + + CHECK_PARAM(!xy) { + return SDL_InvalidParamError("xy"); + } + + CHECK_PARAM(!color) { + return SDL_InvalidParamError("color"); + } + + CHECK_PARAM(texture && !uv) { + return SDL_InvalidParamError("uv"); + } + + int count = indices ? num_indices : num_vertices; + CHECK_PARAM(count % 3 != 0) { + return SDL_InvalidParamError(indices ? "num_indices" : "num_vertices"); + } + + if (indices) { + CHECK_PARAM(size_indices != 1 && size_indices != 2 && size_indices != 4) { + return SDL_InvalidParamError("size_indices"); + } + } + + SDL_FColor *fcolors = (SDL_FColor *)SDL_stack_alloc(SDL_FColor, num_vertices); + if (!fcolors) { + return SDL_OutOfMemory(); + } + + const float inv255 = 1.0f / 255.0f; + const Uint8 *c = (const Uint8 *)color; + for (int i = 0; i < num_vertices; ++i) { + const SDL_Color *src = (const SDL_Color *)c; + fcolors[i].r = src->r * inv255; + fcolors[i].g = src->g * inv255; + fcolors[i].b = src->b * inv255; + fcolors[i].a = src->a * inv255; + c += color_stride; + } + + bool result = SDL_RenderGeometryRaw(renderer, texture, + xy, xy_stride, + fcolors, sizeof(SDL_FColor), + uv, uv_stride, + num_vertices, + indices, num_indices, size_indices); + + SDL_stack_free(fcolors); + return result; +} + bool SDL_RenderGeometryRaw(SDL_Renderer *renderer, SDL_Texture *texture, const float *xy, int xy_stride, From a4093f5e958f2171d87eb03f1c202e84cee5aabc Mon Sep 17 00:00:00 2001 From: Antonio Lattanzio Date: Sun, 1 Mar 2026 23:43:34 +1300 Subject: [PATCH 2/2] updated PR: removed dynapi changes --- src/dynapi/SDL_dynapi.sym | 1 + src/dynapi/SDL_dynapi_overrides.h | 2 +- src/dynapi/SDL_dynapi_procs.h | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/dynapi/SDL_dynapi.sym b/src/dynapi/SDL_dynapi.sym index 86ff0a684b276..843733658d60d 100644 --- a/src/dynapi/SDL_dynapi.sym +++ b/src/dynapi/SDL_dynapi.sym @@ -1280,6 +1280,7 @@ SDL3_0.0.0 { SDL_OpenXR_UnloadLibrary; SDL_OpenXR_GetXrGetInstanceProcAddr; SDL_CreateTrayWithProperties; + SDL_RenderGeometryRawColor8Bits; # extra symbols go here (don't modify this line) local: *; }; diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h index d3f349fa91d9d..f08ab20601093 100644 --- a/src/dynapi/SDL_dynapi_overrides.h +++ b/src/dynapi/SDL_dynapi_overrides.h @@ -762,7 +762,6 @@ #define SDL_RenderFillRects SDL_RenderFillRects_REAL #define SDL_RenderGeometry SDL_RenderGeometry_REAL #define SDL_RenderGeometryRaw SDL_RenderGeometryRaw_REAL -#define SDL_RenderGeometryRawColor8Bits SDL_RenderGeometryRawColor8Bits_REAL #define SDL_RenderLine SDL_RenderLine_REAL #define SDL_RenderLines SDL_RenderLines_REAL #define SDL_RenderPoint SDL_RenderPoint_REAL @@ -1307,3 +1306,4 @@ #define SDL_OpenXR_UnloadLibrary SDL_OpenXR_UnloadLibrary_REAL #define SDL_OpenXR_GetXrGetInstanceProcAddr SDL_OpenXR_GetXrGetInstanceProcAddr_REAL #define SDL_CreateTrayWithProperties SDL_CreateTrayWithProperties_REAL +#define SDL_RenderGeometryRawColor8Bits SDL_RenderGeometryRawColor8Bits_REAL diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h index 052540ba4cbca..41f26f2723a0f 100644 --- a/src/dynapi/SDL_dynapi_procs.h +++ b/src/dynapi/SDL_dynapi_procs.h @@ -773,7 +773,6 @@ SDL_DYNAPI_PROC(bool,SDL_RenderFillRect,(SDL_Renderer *a, const SDL_FRect *b),(a SDL_DYNAPI_PROC(bool,SDL_RenderFillRects,(SDL_Renderer *a, const SDL_FRect *b, int c),(a,b,c),return) SDL_DYNAPI_PROC(bool,SDL_RenderGeometry,(SDL_Renderer *a, SDL_Texture *b, const SDL_Vertex *c, int d, const int *e, int f),(a,b,c,d,e,f),return) SDL_DYNAPI_PROC(bool,SDL_RenderGeometryRaw,(SDL_Renderer *a, SDL_Texture *b, const float *c, int d, const SDL_FColor *e, int f, const float *g, int h, int i, const void *j, int k, int l),(a,b,c,d,e,f,g,h,i,j,k,l),return) -SDL_DYNAPI_PROC(bool,SDL_RenderGeometryRawColor8Bits,(SDL_Renderer *a, SDL_Texture *b, const float *c, int d, const SDL_Color *e, int f, const float *g, int h, int i, const void *j, int k, int l),(a,b,c,d,e,f,g,h,i,j,k,l),return) SDL_DYNAPI_PROC(bool,SDL_RenderLine,(SDL_Renderer *a, float b, float c, float d, float e),(a,b,c,d,e),return) SDL_DYNAPI_PROC(bool,SDL_RenderLines,(SDL_Renderer *a, const SDL_FPoint *b, int c),(a,b,c),return) SDL_DYNAPI_PROC(bool,SDL_RenderPoint,(SDL_Renderer *a, float b, float c),(a,b,c),return) @@ -1315,3 +1314,4 @@ SDL_DYNAPI_PROC(bool,SDL_OpenXR_LoadLibrary,(void),(),return) SDL_DYNAPI_PROC(void,SDL_OpenXR_UnloadLibrary,(void),(),) SDL_DYNAPI_PROC(PFN_xrGetInstanceProcAddr,SDL_OpenXR_GetXrGetInstanceProcAddr,(void),(),return) SDL_DYNAPI_PROC(SDL_Tray*,SDL_CreateTrayWithProperties,(SDL_PropertiesID a),(a),return) +SDL_DYNAPI_PROC(bool,SDL_RenderGeometryRawColor8Bits,(SDL_Renderer *a,SDL_Texture *b,const float *c,int d,const SDL_Color *e,int f,const float *g,int h,int i,const void *j,int k,int l),(a,b,c,d,e,f,g,h,i,j,k,l),return)