From 554f0625d349c106f2633f6db039e332c4c18cec Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Mon, 29 Jan 2024 13:28:33 -0800
Subject: [PATCH] Renderer colors now have floating point precision
---
docs/README-migration.md | 2 +
include/SDL3/SDL_pixels.h | 31 ++++
include/SDL3/SDL_render.h | 153 +++++++++++++++-
src/dynapi/SDL_dynapi.sym | 6 +
src/dynapi/SDL_dynapi_overrides.h | 6 +
src/dynapi/SDL_dynapi_procs.h | 8 +-
src/render/SDL_render.c | 171 +++++++++++++-----
src/render/SDL_sysrender.h | 14 +-
src/render/direct3d/SDL_render_d3d.c | 15 +-
src/render/direct3d11/SDL_render_d3d11.c | 21 +--
src/render/direct3d11/SDL_shaders_d3d11.c | 2 +-
src/render/direct3d12/SDL_render_d3d12.c | 24 +--
src/render/metal/SDL_render_metal.m | 79 ++++----
src/render/opengl/SDL_render_gl.c | 93 +++++-----
src/render/opengles2/SDL_render_gles2.c | 62 +++----
src/render/ps2/SDL_render_ps2.c | 60 +++---
src/render/psp/SDL_render_psp.c | 76 ++++----
src/render/software/SDL_render_sw.c | 69 ++++---
src/render/vitagxm/SDL_render_vita_gxm.c | 29 +--
.../vitagxm/SDL_render_vita_gxm_types.h | 7 +-
test/testsprite.c | 22 +--
21 files changed, 603 insertions(+), 347 deletions(-)
diff --git a/docs/README-migration.md b/docs/README-migration.md
index 1bb0c4ba57f1..5f135c38d2d0 100644
--- a/docs/README-migration.md
+++ b/docs/README-migration.md
@@ -1051,6 +1051,8 @@ SDL_RenderWindowToLogical() and SDL_RenderLogicalToWindow() have been renamed SD
The viewport, clipping state, and scale for render targets are now persistent and will remain set whenever they are active.
+SDL_RenderGeometryRaw() and SDL_Vertex have been changed to use floating point colors, in the range of [0..1] for SDR content.
+
The following functions have been renamed:
* SDL_GetRendererOutputSize() => SDL_GetCurrentRenderOutputSize()
* SDL_RenderCopy() => SDL_RenderTexture()
diff --git a/include/SDL3/SDL_pixels.h b/include/SDL3/SDL_pixels.h
index 30cb413387da..57e640fff2c3 100644
--- a/include/SDL3/SDL_pixels.h
+++ b/include/SDL3/SDL_pixels.h
@@ -354,6 +354,24 @@ typedef enum
SDL_PIXELFORMAT_ABGR64_FLOAT =
SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_ARRAYF16, SDL_ARRAYORDER_ABGR, 0,
64, 4),
+ SDL_PIXELFORMAT_RGB96_FLOAT =
+ SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_ARRAYF32, SDL_ARRAYORDER_RGB, 0,
+ 96, 3),
+ SDL_PIXELFORMAT_BGR96_FLOAT =
+ SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_ARRAYF32, SDL_ARRAYORDER_BGR, 0,
+ 96, 3),
+ SDL_PIXELFORMAT_RGBA128_FLOAT =
+ SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_ARRAYF32, SDL_ARRAYORDER_RGBA, 0,
+ 128, 4),
+ SDL_PIXELFORMAT_ARGB128_FLOAT =
+ SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_ARRAYF32, SDL_ARRAYORDER_ARGB, 0,
+ 128, 4),
+ SDL_PIXELFORMAT_BGRA128_FLOAT =
+ SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_ARRAYF32, SDL_ARRAYORDER_BGRA, 0,
+ 128, 4),
+ SDL_PIXELFORMAT_ABGR128_FLOAT =
+ SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_ARRAYF32, SDL_ARRAYORDER_ABGR, 0,
+ 128, 4),
/* Aliases for RGBA byte arrays of color data, for the current platform */
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
@@ -602,6 +620,19 @@ typedef struct SDL_Color
} SDL_Color;
#define SDL_Colour SDL_Color
+/**
+ * The bits of this structure can be directly reinterpreted as a float-packed
+ * color which uses the SDL_PIXELFORMAT_RGBA128_FLOAT format
+ */
+typedef struct SDL_FColor
+{
+ float r;
+ float g;
+ float b;
+ float a;
+} SDL_FColor;
+#define SDL_FColour SDL_FColor
+
typedef struct SDL_Palette
{
int ncolors;
diff --git a/include/SDL3/SDL_render.h b/include/SDL3/SDL_render.h
index 878f7a7cf0df..41b87b44107f 100644
--- a/include/SDL3/SDL_render.h
+++ b/include/SDL3/SDL_render.h
@@ -91,7 +91,7 @@ typedef struct SDL_RendererInfo
typedef struct SDL_Vertex
{
SDL_FPoint position; /**< Vertex position, in SDL_Renderer coordinates */
- SDL_Color color; /**< Vertex color */
+ SDL_FColor color; /**< Vertex color */
SDL_FPoint tex_coord; /**< Normalized texture coordinates, if needed */
} SDL_Vertex;
@@ -692,10 +692,39 @@ extern DECLSPEC int SDLCALL SDL_QueryTexture(SDL_Texture *texture, Uint32 *forma
*
* \sa SDL_GetTextureColorMod
* \sa SDL_SetTextureAlphaMod
+ * \sa SDL_SetTextureColorModFloat
*/
extern DECLSPEC int SDLCALL SDL_SetTextureColorMod(SDL_Texture *texture, Uint8 r, Uint8 g, Uint8 b);
+/**
+ * Set an additional color value multiplied into render copy operations.
+ *
+ * When this texture is rendered, during the copy operation each source color
+ * channel is modulated by the appropriate color value according to the
+ * following formula:
+ *
+ * `srcC = srcC * color`
+ *
+ * Color modulation is not always supported by the renderer; it will return -1
+ * if color modulation is not supported.
+ *
+ * \param texture the texture to update
+ * \param r the red color value multiplied into copy operations
+ * \param g the green color value multiplied into copy operations
+ * \param b the blue color value multiplied into copy operations
+ * \returns 0 on success or a negative error code on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.0.0.
+ *
+ * \sa SDL_GetTextureColorModFloat
+ * \sa SDL_SetTextureAlphaModFloat
+ * \sa SDL_SetTextureColorMod
+ */
+extern DECLSPEC int SDLCALL SDL_SetTextureColorModFloat(SDL_Texture *texture, float r, float g, float b);
+
+
/**
* Get the additional color value multiplied into render copy operations.
*
@@ -709,10 +738,29 @@ extern DECLSPEC int SDLCALL SDL_SetTextureColorMod(SDL_Texture *texture, Uint8 r
* \since This function is available since SDL 3.0.0.
*
* \sa SDL_GetTextureAlphaMod
+ * \sa SDL_GetTextureColorModFloat
* \sa SDL_SetTextureColorMod
*/
extern DECLSPEC int SDLCALL SDL_GetTextureColorMod(SDL_Texture *texture, Uint8 *r, Uint8 *g, Uint8 *b);
+/**
+ * Get the additional color value multiplied into render copy operations.
+ *
+ * \param texture the texture to query
+ * \param r a pointer filled in with the current red color value
+ * \param g a pointer filled in with the current green color value
+ * \param b a pointer filled in with the current blue color value
+ * \returns 0 on success or a negative error code on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.0.0.
+ *
+ * \sa SDL_GetTextureAlphaModFloat
+ * \sa SDL_GetTextureColorMod
+ * \sa SDL_SetTextureColorModFloat
+ */
+extern DECLSPEC int SDLCALL SDL_GetTextureColorModFloat(SDL_Texture *texture, float *r, float *g, float *b);
+
/**
* Set an additional alpha value multiplied into render copy operations.
*
@@ -732,10 +780,35 @@ extern DECLSPEC int SDLCALL SDL_GetTextureColorMod(SDL_Texture *texture, Uint8 *
* \since This function is available since SDL 3.0.0.
*
* \sa SDL_GetTextureAlphaMod
+ * \sa SDL_SetTextureAlphaModFloat
* \sa SDL_SetTextureColorMod
*/
extern DECLSPEC int SDLCALL SDL_SetTextureAlphaMod(SDL_Texture *texture, Uint8 alpha);
+/**
+ * Set an additional alpha value multiplied into render copy operations.
+ *
+ * When this texture is rendered, during the copy operation the source alpha
+ * value is modulated by this alpha value according to the following formula:
+ *
+ * `srcA = srcA * alpha`
+ *
+ * Alpha modulation is not always supported by the renderer; it will return -1
+ * if alpha modulation is not supported.
+ *
+ * \param texture the texture to update
+ * \param alpha the source alpha value multiplied into copy operations
+ * \returns 0 on success or a negative error code on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.0.0.
+ *
+ * \sa SDL_GetTextureAlphaModFloat
+ * \sa SDL_SetTextureAlphaMod
+ * \sa SDL_SetTextureColorModFloat
+ */
+extern DECLSPEC int SDLCALL SDL_SetTextureAlphaModFloat(SDL_Texture *texture, float alpha);
+
/**
* Get the additional alpha value multiplied into render copy operations.
*
@@ -746,11 +819,28 @@ extern DECLSPEC int SDLCALL SDL_SetTextureAlphaMod(SDL_Texture *texture, Uint8 a
*
* \since This function is available since SDL 3.0.0.
*
+ * \sa SDL_GetTextureAlphaModFloat
* \sa SDL_GetTextureColorMod
* \sa SDL_SetTextureAlphaMod
*/
extern DECLSPEC int SDLCALL SDL_GetTextureAlphaMod(SDL_Texture *texture, Uint8 *alpha);
+/**
+ * Get the additional alpha value multiplied into render copy operations.
+ *
+ * \param texture the texture to query
+ * \param alpha a pointer filled in with the current alpha value
+ * \returns 0 on success or a negative error code on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.0.0.
+ *
+ * \sa SDL_GetTextureAlphaMod
+ * \sa SDL_GetTextureColorModFloat
+ * \sa SDL_SetTextureAlphaModFloat
+ */
+extern DECLSPEC int SDLCALL SDL_GetTextureAlphaModFloat(SDL_Texture *texture, float *alpha);
+
/**
* Set the blend mode for a texture, used by SDL_RenderTexture().
*
@@ -1263,16 +1353,48 @@ extern DECLSPEC int SDLCALL SDL_GetRenderScale(SDL_Renderer *renderer, float *sc
*
* \sa SDL_GetRenderDrawColor
* \sa SDL_RenderClear
+ * \sa SDL_RenderFillRect
+ * \sa SDL_RenderFillRects
* \sa SDL_RenderLine
* \sa SDL_RenderLines
* \sa SDL_RenderPoint
* \sa SDL_RenderPoints
* \sa SDL_RenderRect
* \sa SDL_RenderRects
+ * \sa SDL_SetRenderDrawColorFloat
+ */
+extern DECLSPEC int SDLCALL SDL_SetRenderDrawColor(SDL_Renderer *renderer, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
+
+/**
+ * Set the color used for drawing operations (Rect, Line and Clear).
+ *
+ * Set the color for drawing or filling rectangles, lines, and points, and for
+ * SDL_RenderClear().
+ *
+ * \param renderer the rendering context
+ * \param r the red value used to draw on the rendering target
+ * \param g the green value used to draw on the rendering target
+ * \param b the blue value used to draw on the rendering target
+ * \param a the alpha value used to draw on the rendering target. Use SDL_SetRenderDrawBlendMode to
+ * specify how the alpha channel is used
+ * \returns 0 on success or a negative error code on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.0.0.
+ *
+ * \sa SDL_GetRenderDrawColorFloat
+ * \sa SDL_RenderClear
* \sa SDL_RenderFillRect
* \sa SDL_RenderFillRects
+ * \sa SDL_RenderLine
+ * \sa SDL_RenderLines
+ * \sa SDL_RenderPoint
+ * \sa SDL_RenderPoints
+ * \sa SDL_RenderRect
+ * \sa SDL_RenderRects
+ * \sa SDL_SetRenderDrawColor
*/
-extern DECLSPEC int SDLCALL SDL_SetRenderDrawColor(SDL_Renderer *renderer, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
+extern DECLSPEC int SDLCALL SDL_SetRenderDrawColorFloat(SDL_Renderer *renderer, float r, float g, float b, float a);
/**
* Get the color used for drawing operations (Rect, Line and Clear).
@@ -1291,10 +1413,33 @@ extern DECLSPEC int SDLCALL SDL_SetRenderDrawColor(SDL_Renderer *renderer, Uint8
*
* \since This function is available since SDL 3.0.0.
*
+ * \sa SDL_GetRenderDrawColorFloat
* \sa SDL_SetRenderDrawColor
*/
extern DECLSPEC int SDLCALL SDL_GetRenderDrawColor(SDL_Renderer *renderer, Uint8 *r, Uint8 *g, Uint8 *b, Uint8 *a);
+/**
+ * Get the color used for drawing operations (Rect, Line and Clear).
+ *
+ * \param renderer the rendering context
+ * \param r a pointer filled in with the red value used to draw on the
+ * rendering target
+ * \param g a pointer filled in with the green value used to draw on the
+ * rendering target
+ * \param b a pointer filled in with the blue value used to draw on the
+ * rendering target
+ * \param a a pointer filled in with the alpha value used to draw on the
+ * rendering target
+ * \returns 0 on success or a negative error code on failure; call
+ * SDL_GetError() for more information.
+ *
+ * \since This function is available since SDL 3.0.0.
+ *
+ * \sa SDL_SetRenderDrawColorFloat
+ * \sa SDL_GetRenderDrawColor
+ */
+extern DECLSPEC int SDLCALL SDL_GetRenderDrawColorFloat(SDL_Renderer *renderer, float *r, float *g, float *b, float *a);
+
/**
* Set the blend mode used for drawing operations (Fill and Line).
*
@@ -1532,7 +1677,7 @@ extern DECLSPEC int SDLCALL SDL_RenderGeometry(SDL_Renderer *renderer,
* \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 Vertex colors (as SDL_FColor)
* \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
@@ -1552,7 +1697,7 @@ extern DECLSPEC int SDLCALL SDL_RenderGeometry(SDL_Renderer *renderer,
extern DECLSPEC int SDLCALL SDL_RenderGeometryRaw(SDL_Renderer *renderer,
SDL_Texture *texture,
const float *xy, int xy_stride,
- const SDL_Color *color, int color_stride,
+ const SDL_FColor *color, int color_stride,
const float *uv, int uv_stride,
int num_vertices,
const void *indices, int num_indices, int size_indices);
diff --git a/src/dynapi/SDL_dynapi.sym b/src/dynapi/SDL_dynapi.sym
index edeca4f1bb69..6e7fa2ee3e03 100644
--- a/src/dynapi/SDL_dynapi.sym
+++ b/src/dynapi/SDL_dynapi.sym
@@ -959,6 +959,12 @@ SDL3_0.0.0 {
SDL_GetHapticName;
SDL_ReadSurfacePixel;
SDL_FlipSurface;
+ SDL_SetTextureColorModFloat;
+ SDL_GetTextureColorModFloat;
+ SDL_SetTextureAlphaModFloat;
+ SDL_GetTextureAlphaModFloat;
+ SDL_SetRenderDrawColorFloat;
+ SDL_GetRenderDrawColorFloat;
# 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 eefa79983461..cae15b798054 100644
--- a/src/dynapi/SDL_dynapi_overrides.h
+++ b/src/dynapi/SDL_dynapi_overrides.h
@@ -984,3 +984,9 @@
#define SDL_GetHapticName SDL_GetHapticName_REAL
#define SDL_ReadSurfacePixel SDL_ReadSurfacePixel_REAL
#define SDL_FlipSurface SDL_FlipSurface_REAL
+#define SDL_SetTextureColorModFloat SDL_SetTextureColorModFloat_REAL
+#define SDL_GetTextureColorModFloat SDL_GetTextureColorModFloat_REAL
+#define SDL_SetTextureAlphaModFloat SDL_SetTextureAlphaModFloat_REAL
+#define SDL_GetTextureAlphaModFloat SDL_GetTextureAlphaModFloat_REAL
+#define SDL_SetRenderDrawColorFloat SDL_SetRenderDrawColorFloat_REAL
+#define SDL_GetRenderDrawColorFloat SDL_GetRenderDrawColorFloat_REAL
diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h
index 41b05c74b5dc..05561268a112 100644
--- a/src/dynapi/SDL_dynapi_procs.h
+++ b/src/dynapi/SDL_dynapi_procs.h
@@ -564,7 +564,7 @@ SDL_DYNAPI_PROC(int,SDL_RenderCoordinatesToWindow,(SDL_Renderer *a, float b, flo
SDL_DYNAPI_PROC(int,SDL_RenderFillRect,(SDL_Renderer *a, const SDL_FRect *b),(a,b),return)
SDL_DYNAPI_PROC(int,SDL_RenderFillRects,(SDL_Renderer *a, const SDL_FRect *b, int c),(a,b,c),return)
SDL_DYNAPI_PROC(int,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(int,SDL_RenderGeometryRaw,(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(int,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(int,SDL_RenderLine,(SDL_Renderer *a, float b, float c, float d, float e),(a,b,c,d,e),return)
SDL_DYNAPI_PROC(int,SDL_RenderLines,(SDL_Renderer *a, const SDL_FPoint *b, int c),(a,b,c),return)
SDL_DYNAPI_PROC(int,SDL_RenderPoint,(SDL_Renderer *a, float b, float c),(a,b,c),return)
@@ -1009,3 +1009,9 @@ SDL_DYNAPI_PROC(SDL_HapticID,SDL_GetHapticInstanceID,(SDL_Haptic *a),(a),return)
SDL_DYNAPI_PROC(const char*,SDL_GetHapticName,(SDL_Haptic *a),(a),return)
SDL_DYNAPI_PROC(int,SDL_ReadSurfacePixel,(SDL_Surface *a, int b, int c, Uint8 *d, Uint8 *e, Uint8 *f, Uint8 *g),(a,b,c,d,e,f,g),return)
SDL_DYNAPI_PROC(int,SDL_FlipSurface,(SDL_Surface *a, SDL_FlipMode b),(a,b),return)
+SDL_DYNAPI_PROC(int,SDL_SetTextureColorModFloat,(SDL_Texture *a, float b, float c, float d),(a,b,c,d),return)
+SDL_DYNAPI_PROC(int,SDL_GetTextureColorModFloat,(SDL_Texture *a, float *b, float *c, float *d),(a,b,c,d),return)
+SDL_DYNAPI_PROC(int,SDL_SetTextureAlphaModFloat,(SDL_Texture *a, float b),(a,b),return)
+SDL_DYNAPI_PROC(int,SDL_GetTextureAlphaModFloat,(SDL_Texture *a, float *b),(a,b),return)
+SDL_DYNAPI_PROC(int,SDL_SetRenderDrawColorFloat,(SDL_Renderer *a, float b, float c, float d, float e),(a,b,c,d,e),return)
+SDL_DYNAPI_PROC(int,SDL_GetRenderDrawColorFloat,(SDL_Renderer *a, float *b, float *c, float *d, float *e),(a,b,c,d,e),return)
diff --git a/src/render/SDL_render.c b/src/render/SDL_render.c
index 37745bd97d32..9bb163f52b0b 100644
--- a/src/render/SDL_render.c
+++ b/src/render/SDL_render.c
@@ -407,27 +407,27 @@ static int QueueCmdSetClipRect(SDL_Renderer *renderer)
return retval;
}
-static int QueueCmdSetDrawColor(SDL_Renderer *renderer, SDL_Color *col)
+static int QueueCmdSetDrawColor(SDL_Renderer *renderer, SDL_FColor *color)
{
- const Uint32 color = (((Uint32)col->a << 24) | (col->r << 16) | (col->g << 8) | col->b);
int retval = 0;
- if (!renderer->color_queued || (color != renderer->last_queued_color)) {
+ if (!renderer->color_queued ||
+ color->r != renderer->last_queued_color.r ||
+ color->g != renderer->last_queued_color.g ||
+ color->b != renderer->last_queued_color.b ||
+ color->a != renderer->last_queued_color.a) {
SDL_RenderCommand *cmd = AllocateRenderCommand(renderer);
retval = -1;
if (cmd) {
cmd->command = SDL_RENDERCMD_SETDRAWCOLOR;
cmd->data.color.first = 0; /* render backend will fill this in. */
- cmd->data.color.r = col->r;
- cmd->data.color.g = col->g;
- cmd->data.color.b = col->b;
- cmd->data.color.a = col->a;
+ cmd->data.color.color = *color;
retval = renderer->QueueSetDrawColor(renderer, cmd);
if (retval < 0) {
cmd->command = SDL_RENDERCMD_NO_OP;
} else {
- renderer->last_queued_color = color;
+ renderer->last_queued_color = *color;
renderer->color_queued = SDL_TRUE;
}
}
@@ -444,10 +444,7 @@ static int QueueCmdClear(SDL_Renderer *renderer)
cmd->command = SDL_RENDERCMD_CLEAR;
cmd->data.color.first = 0;
- cmd->data.color.r = renderer->color.r;
- cmd->data.color.g = renderer->color.g;
- cmd->data.color.b = renderer->color.b;
- cmd->data.color.a = renderer->color.a;
+ cmd->data.color.color = renderer->color;
return 0;
}
@@ -455,7 +452,7 @@ static SDL_RenderCommand *PrepQueueCmdDraw(SDL_Renderer *renderer, const SDL_Ren
{
SDL_RenderCommand *cmd = NULL;
int retval = 0;
- SDL_Color *color;
+ SDL_FColor *color;
SDL_BlendMode blendMode;
if (texture) {
@@ -485,10 +482,7 @@ static SDL_RenderCommand *PrepQueueCmdDraw(SDL_Renderer *renderer, const SDL_Ren
cmd->command = cmdtype;
cmd->data.draw.first = 0; /* render backend will fill this in. */
cmd->data.draw.count = 0; /* render backend will fill this in. */
- cmd->data.draw.r = color->r;
- cmd->data.draw.g = color->g;
- cmd->data.draw.b = color->b;
- cmd->data.draw.a = color->a;
+ cmd->data.draw.color = *color;
cmd->data.draw.blend = blendMode;
cmd->data.draw.texture = texture;
}
@@ -626,7 +620,7 @@ static int QueueCmdCopyEx(SDL_Renderer *renderer, SDL_Texture *texture,
static int QueueCmdGeometry(SDL_Renderer *renderer, SDL_Texture *texture,
const float *xy, int xy_stride,
- const SDL_Color *color, int color_stride,
+ const SDL_FColor *color, int color_stride,
const float *uv, int uv_stride,
int num_vertices,
const void *indices, int num_indices, int size_indices,
@@ -1163,10 +1157,10 @@ SDL_Texture *SDL_CreateTextureWithProperties(SDL_Renderer *renderer, SDL_Propert
texture->access = access;
texture->w = w;
texture->h = h;
- texture->color.r = 255;
- texture->color.g = 255;
- texture->color.b = 255;
- texture->color.a = 255;
+ texture->color.r = 1.0f;
+ texture->color.g = 1.0f;
+ texture->color.b = 1.0f;
+ texture->color.a = 1.0f;
texture->scaleMode = SDL_GetScaleMode();
texture->view.pixel_w = w;
texture->view.pixel_h = h;
@@ -1432,6 +1426,15 @@ int SDL_QueryTexture(SDL_Texture *texture, Uint32 *format, int *access, int *w,
}
int SDL_SetTextureColorMod(SDL_Texture *texture, Uint8 r, Uint8 g, Uint8 b)
+{
+ const float fR = (float)r / 255.0f;
+ const float fG = (float)g / 255.0f;
+ const float fB = (float)b / 255.0f;
+
+ return SDL_SetTextureColorModFloat(texture, fR, fG, fB);
+}
+
+int SDL_SetTextureColorModFloat(SDL_Texture *texture, float r, float g, float b)
{
CHECK_TEXTURE_MAGIC(texture, -1);
@@ -1439,12 +1442,32 @@ int SDL_SetTextureColorMod(SDL_Texture *texture, Uint8 r, Uint8 g, Uint8 b)
texture->color.g = g;
texture->color.b = b;
if (texture->native) {
- return SDL_SetTextureColorMod(texture->native, r, g, b);
+ return SDL_SetTextureColorModFloat(texture->native, r, g, b);
}
return 0;
}
int SDL_GetTextureColorMod(SDL_Texture *texture, Uint8 *r, Uint8 *g, Uint8 *b)
+{
+ float fR, fG, fB;
+
+ if (SDL_GetTextureColorModFloat(texture, &fR, &fG, &fB) < 0) {
+ return -1;
+ }
+
+ if (r) {
+ *r = (Uint8)(fR * 255.0f);
+ }
+ if (g) {
+ *g = (Uint8)(fG * 255.0f);
+ }
+ if (b) {
+ *b = (Uint8)(fB * 255.0f);
+ }
+ return 0;
+}
+
+int SDL_GetTextureColorModFloat(SDL_Texture *texture, float *r, float *g, float *b)
{
CHECK_TEXTURE_MAGIC(texture, -1);
@@ -1461,17 +1484,38 @@ int SDL_GetTextureColorMod(SDL_Texture *texture, Uint8 *r, Uint8 *g, Uint8 *b)
}
int SDL_SetTextureAlphaMod(SDL_Texture *texture, Uint8 alpha)
+{
+ const float fA = (float)alpha / 255.0f;
+
+ return SDL_SetTextureAlphaModFloat(texture, fA);
+}
+
+int SDL_SetTextureAlphaModFloat(SDL_Texture *texture, float alpha)
{
CHECK_TEXTURE_MAGIC(texture, -1);
texture->color.a = alpha;
if (texture->native) {
- return SDL_SetTextureAlphaMod(texture->native, alpha);
+ return SDL_SetTextureAlphaModFloat(texture->native, alpha);
}
return 0;
}
int SDL_GetTextureAlphaMod(SDL_Texture *texture, Uint8 *alpha)
+{
+ float fA;
+
+ if (SDL_GetTextureAlphaModFloat(texture, &fA) < 0) {
+ return -1;
+ }
+
+ if (alpha) {
+ *alpha = (Uint8)(fA * 255.0f);
+ }
+ return 0;
+}
+
+int SDL_GetTextureAlphaModFloat(SDL_Texture *texture, float *alpha)
{
CHECK_TEXTURE_MAGIC(texture, -1);
@@ -2291,7 +2335,7 @@ static void SDL_RenderLogicalBorders(SDL_Renderer *renderer)
if (dst->x > 0.0f || dst->y > 0.0f) {
SDL_BlendMode saved_blend_mode = renderer->blendMode;
- SDL_Color saved_color = renderer->color;
+ SDL_FColor saved_color = renderer->color;
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE);
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
@@ -2628,6 +2672,16 @@ int SDL_GetRenderScale(SDL_Renderer *renderer, float *scaleX, float *scaleY)
}
int SDL_SetRenderDrawColor(SDL_Renderer *renderer, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
+{
+ const float fR = (float)r / 255.0f;
+ const float fG = (float)g / 255.0f;
+ const float fB = (float)b / 255.0f;
+ const float fA = (float)a / 255.0f;
+
+ return SDL_SetRenderDrawColorFloat(renderer, fR, fG, fB, fA);
+}
+
+int SDL_SetRenderDrawColorFloat(SDL_Renderer *renderer, float r, float g, float b, float a)
{
CHECK_RENDERER_MAGIC(renderer, -1);
@@ -2639,6 +2693,29 @@ int SDL_SetRenderDrawColor(SDL_Renderer *renderer, Uint8 r, Uint8 g, Uint8 b, Ui
}
int SDL_GetRenderDrawColor(SDL_Renderer *renderer, Uint8 *r, Uint8 *g, Uint8 *b, Uint8 *a)
+{
+ float fR, fG, fB, fA;
+
+ if (SDL_GetRenderDrawColorFloat(renderer, &fR, &fG, &fB, &fA) < 0) {
+ return -1;
+ }
+
+ if (r) {
+ *r = (Uint8)(fR * 255.0f);
+ }
+ if (g) {
+ *g = (Uint8)(fG * 255.0f);
+ }
+ if (b) {
+ *b = (Uint8)(fB * 255.0f);
+ }
+ if (a) {
+ *a = (Uint8)(fA * 255.0f);
+ }
+ return 0;
+}
+
+int SDL_GetRenderDrawColorFloat(SDL_Renderer *renderer, float *r, float *g, float *b, float *a)
{
CHECK_RENDERER_MAGIC(renderer, -1);
@@ -3457,7 +3534,7 @@ int SDL_RenderGeometry(SDL_Renderer *renderer,
if (vertices) {
const float *xy = &vertices->position.x;
int xy_stride = sizeof(SDL_Vertex);
- const SDL_Color *color = &vertices->color;
+ const SDL_FColor *color = &vertices->color;
int color_stride = sizeof(SDL_Vertex);
const float *uv = &vertices->tex_coord.x;
int uv_stride = sizeof(SDL_Vertex);
@@ -3473,11 +3550,11 @@ static int remap_one_indice(
int k,
SDL_Texture *texture,
const float *xy, int xy_stride,
- const SDL_Color *color, int color_stride,
+ const SDL_FColor *color, int color_stride,
const float *uv, int uv_stride)
{
const float *xy0_, *xy1_, *uv0_, *uv1_;
- int col0_, col1_;
+ const SDL_FColor *col0_, *col1_;
xy0_ = (const float *)((const char *)xy + prev * xy_stride);
xy1_ = (const float *)((const char *)xy + k * xy_stride);
if (xy0_[0] != xy1_[0]) {
@@ -3496,10 +3573,10 @@ static int remap_one_indice(
return k;
}
}
- col0_ = *(const int *)((const char *)color + prev * color_stride);
- col1_ = *(const int *)((const char *)color + k * color_stride);
+ col0_ = (const SDL_FColor *)((const char *)color + prev * color_stride);
+ col1_ = (const SDL_FColor *)((const char *)color + k * color_stride);
- if (col0_ != col1_) {
+ if (SDL_memcmp(col0_, col1_, sizeof(*col0_)) != 0) {
return k;
}
@@ -3511,7 +3588,7 @@ static int remap_indices(
int k,
SDL_Texture *texture,
const float *xy, int xy_stride,
- const SDL_Color *color, int color_stride,
+ const SDL_FColor *color, int color_stride,
const float *uv, int uv_stride)
{
int i;
@@ -3533,7 +3610,7 @@ static int remap_indices(
static int SDLCALL SDL_SW_RenderGeometryRaw(SDL_Renderer *renderer,
SDL_Texture *texture,
const float *xy, int xy_stride,
- const SDL_Color *color, int color_stride,
+ const SDL_FColor *color, int color_stride,
const float *uv, int uv_stride,
int num_vertices,
const void *indices, int num_indices, int size_indices)
@@ -3711,11 +3788,13 @@ static int SDLCALL SDL_SW_RenderGeometryRaw(SDL_Renderer *renderer,
/* Check if uniformly colored */
if (is_quad) {
- const int col0_ = *(const int *)((const char *)color + A * color_stride);
- const int col1_ = *(const int *)((const char *)color + B * color_stride);
- const int col2_ = *(const int *)((const char *)color + C * color_stride);
- const int col3_ = *(const int *)((const char *)color + C2 * color_stride);
- if (col0_ == col1_ && col0_ == col2_ && col0_ == col3_) {
+ const SDL_FColor *col0_ = (const SDL_FColor *)((const char *)color + A * color_stride);
+ const SDL_FColor *col1_ = (const SDL_FColor *)((const char *)color + B * color_stride);
+ const SDL_FColor *col2_ = (const SDL_FColor *)((const char *)color + C * color_stride);
+ const SDL_FColor *col3_ = (const SDL_FColor *)((const char *)color + C2 * color_stride);
+ if (SDL_memcmp(col0_, col1_, sizeof(*col0_)) == 0 &&
+ SDL_memcmp(col0_, col2_, sizeof(*col0_)) == 0 &&
+ SDL_memcmp(col0_, col3_, sizeof(*col0_)) == 0) {
/* ok */
} else {
is_quad = 0;
@@ -3730,7 +3809,7 @@ static int SDLCALL SDL_SW_RenderGeometryRaw(SDL_Renderer *renderer,
SDL_FRect s;
SDL_FRect d;
const float *xy0_, *xy1_, *uv0_, *uv1_;
- SDL_Color col0_ = *(const SDL_Color *)((const char *)color + k0 * color_stride);
+ const SDL_FColor *col0_ = (const SDL_FColor *)((const char *)color + k0 * color_stride);
xy0_ = (const float *)((const char *)xy + A * xy_stride);
xy1_ = (const float *)((const char *)xy + B * xy_stride);
@@ -3753,8 +3832,8 @@ static int SDLCALL SDL_SW_RenderGeometryRaw(SDL_Renderer *renderer,
/* Rect + texture */
if (texture && s.w != 0 && s.h != 0) {
- SDL_SetTextureAlphaMod(texture, col0_.a);
- SDL_SetTextureColorMod(texture, col0_.r, col0_.g, col0_.b);
+ SDL_SetTextureAlphaModFloat(texture, col0_->a);
+ SDL_SetTextureColorModFloat(texture, col0_->r, col0_->g, col0_->b);
if (s.w > 0 && s.h > 0) {
SDL_RenderTexture(renderer, texture, &s, &d);
} else {
@@ -3773,18 +3852,18 @@ static int SDLCALL SDL_SW_RenderGeometryRaw(SDL_Renderer *renderer,
}
#if DEBUG_SW_RENDER_GEOMETRY
- SDL_Log("Rect-COPY: RGB %d %d %d - Alpha:%d - texture=%p: src=(%d,%d, %d x %d) dst (%f, %f, %f x %f)", col0_.r, col0_.g, col0_.b, col0_.a,
+ SDL_Log("Rect-COPY: RGB %f %f %f - Alpha:%f - texture=%p: src=(%d,%d, %d x %d) dst (%f, %f, %f x %f)", col0_->r, col0_->g, col0_->b, col0_->a,
(void *)texture, s.x, s.y, s.w, s.h, d.x, d.y, d.w, d.h);
#endif
} else if (d.w != 0.0f && d.h != 0.0f) { /* Rect, no texture */
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
- SDL_SetRenderDrawColor(renderer, col0_.r, col0_.g, col0_.b, col0_.a);
+ SDL_SetRenderDrawColorFloat(renderer, col0_->r, col0_->g, col0_->b, col0_->a);
SDL_RenderFillRect(renderer, &d);
#if DEBUG_SW_RE
(Patch may be truncated, please check the link at the top of this post.)