Browse Source

Renderer colors now have floating point precision

Sam Lantinga 1 year ago
parent
commit
554f0625d3

+ 2 - 0
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()

+ 31 - 0
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;

+ 149 - 4
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);

+ 6 - 0
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: *;
 };

+ 6 - 0
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

+ 7 - 1
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)

+ 125 - 46
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_RENDER_GEOMETRY
-                SDL_Log("Rect-FILL: RGB %d %d %d - Alpha:%d - texture=%p: dst (%f, %f, %f x %f)", col0_.r, col0_.g, col0_.b, col0_.a,
+                SDL_Log("Rect-FILL: RGB %f %f %f - Alpha:%f - texture=%p: dst (%f, %f, %f x %f)", col0_->r, col0_->g, col0_->b, col0_->a,
                         (void *)texture, d.x, d.y, d.w, d.h);
             } else {
-                SDL_Log("Rect-DISMISS: 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-DISMISS: 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
             }
@@ -3838,7 +3917,7 @@ end:
 int 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)

+ 7 - 7
src/render/SDL_sysrender.h

@@ -69,7 +69,7 @@ struct SDL_Texture
     int h;                      /**< The height of the texture */
     SDL_BlendMode blendMode;    /**< The texture blend mode */
     SDL_ScaleMode scaleMode;    /**< The texture scale mode */
-    SDL_Color color;            /**< Texture modulation values */
+    SDL_FColor color;           /**< Texture modulation values */
     SDL_RenderViewState view;   /**< Target texture view state */
 
     SDL_Renderer *renderer;
@@ -126,14 +126,14 @@ typedef struct SDL_RenderCommand
         {
             size_t first;
             size_t count;
-            Uint8 r, g, b, a;
+            SDL_FColor color;
             SDL_BlendMode blend;
             SDL_Texture *texture;
         } draw;
         struct
         {
             size_t first;
-            Uint8 r, g, b, a;
+            SDL_FColor color;
         } color;
     } data;
     struct SDL_RenderCommand *next;
@@ -142,7 +142,7 @@ typedef struct SDL_RenderCommand
 typedef struct SDL_VertexSolid
 {
     SDL_FPoint position;
-    SDL_Color color;
+    SDL_FColor color;
 } SDL_VertexSolid;
 
 typedef enum
@@ -175,7 +175,7 @@ struct SDL_Renderer
                        const SDL_FRect *srcquad, const SDL_FRect *dstrect,
                        const double angle, const SDL_FPoint *center, const SDL_FlipMode flip, float scale_x, float scale_y);
     int (*QueueGeometry)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture,
-                         const float *xy, int xy_stride, const SDL_Color *color, int color_stride, const float *uv, int uv_stride,
+                         const float *xy, int xy_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,
                          float scale_x, float scale_y);
 
@@ -249,14 +249,14 @@ struct SDL_Renderer
     SDL_Texture *target;
     SDL_Mutex *target_mutex;
 
-    SDL_Color color;         /**< Color for drawing operations values */
+    SDL_FColor color;        /**< Color for drawing operations values */
     SDL_BlendMode blendMode; /**< The drawing blend mode */
 
     SDL_RenderCommand *render_commands;
     SDL_RenderCommand *render_commands_tail;
     SDL_RenderCommand *render_commands_pool;
     Uint32 render_command_generation;
-    Uint32 last_queued_color;
+    SDL_FColor last_queued_color;
     SDL_Rect last_queued_viewport;
     SDL_Rect last_queued_cliprect;
     SDL_bool last_queued_cliprect_enabled;

+ 9 - 6
src/render/direct3d/SDL_render_d3d.c

@@ -804,7 +804,10 @@ static int D3D_QueueSetViewport(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
 
 static int D3D_QueueDrawPoints(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count)
 {
-    const DWORD color = D3DCOLOR_ARGB(cmd->data.draw.a, cmd->data.draw.r, cmd->data.draw.g, cmd->data.draw.b);
+    const DWORD color = D3DCOLOR_COLORVALUE(cmd->data.draw.color.r,
+                                            cmd->data.draw.color.g,
+                                            cmd->data.draw.color.b,
+                                            cmd->data.draw.color.a);
     const size_t vertslen = count * sizeof(Vertex);
     Vertex *verts = (Vertex *)SDL_AllocateRenderVertices(renderer, vertslen, 0, &cmd->data.draw.first);
     int i;
@@ -826,7 +829,7 @@ static int D3D_QueueDrawPoints(SDL_Renderer *renderer, SDL_RenderCommand *cmd, c
 }
 
 static int D3D_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture,
-                             const float *xy, int xy_stride, const SDL_Color *color, int color_stride, const float *uv, int uv_stride,
+                             const float *xy, int xy_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,
                              float scale_x, float scale_y)
 {
@@ -844,7 +847,7 @@ static int D3D_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL
     for (i = 0; i < count; i++) {
         int j;
         float *xy_;
-        SDL_Color col_;
+        SDL_FColor *col_;
         if (size_indices == 4) {
             j = ((const Uint32 *)indices)[i];
         } else if (size_indices == 2) {
@@ -856,12 +859,12 @@ static int D3D_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL
         }
 
         xy_ = (float *)((char *)xy + j * xy_stride);
-        col_ = *(SDL_Color *)((char *)color + j * color_stride);
+        col_ = (SDL_FColor *)((char *)color + j * color_stride);
 
         verts->x = xy_[0] * scale_x - 0.5f;
         verts->y = xy_[1] * scale_y - 0.5f;
         verts->z = 0.0f;
-        verts->color = D3DCOLOR_ARGB(col_.a, col_.r, col_.g, col_.b);
+        verts->color = D3DCOLOR_COLORVALUE(col_->r, col_->g, col_->b, col_->a);
 
         if (texture) {
             float *uv_ = (float *)((char *)uv + j * uv_stride);
@@ -1191,7 +1194,7 @@ static int D3D_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
 
         case SDL_RENDERCMD_CLEAR:
         {
-            const DWORD color = D3DCOLOR_ARGB(cmd->data.color.a, cmd->data.color.r, cmd->data.color.g, cmd->data.color.b);
+            const DWORD color = D3DCOLOR_COLORVALUE(cmd->data.color.color.r, cmd->data.color.color.g, cmd->data.color.color.b, cmd->data.color.color.a);
             const SDL_Rect *viewport = &data->drawstate.viewport;
             const int backw = istarget ? renderer->target->w : data->pparams.BackBufferWidth;
             const int backh = istarget ? renderer->target->h : data->pparams.BackBufferHeight;

+ 5 - 16
src/render/direct3d11/SDL_render_d3d11.c

@@ -77,7 +77,7 @@ typedef struct
 {
     Float2 pos;
     Float2 tex;
-    SDL_Color color;
+    SDL_FColor color;
 } VertexPositionColor;
 
 /* Per-texture data */
@@ -1694,11 +1694,6 @@ static int D3D11_QueueDrawPoints(SDL_Renderer *renderer, SDL_RenderCommand *cmd,
 {
     VertexPositionColor *verts = (VertexPositionColor *)SDL_AllocateRenderVertices(renderer, count * sizeof(VertexPositionColor), 0, &cmd->data.draw.first);
     int i;
-    SDL_Color color;
-    color.r = cmd->data.draw.r;
-    color.g = cmd->data.draw.g;
-    color.b = cmd->data.draw.b;
-    color.a = cmd->data.draw.a;
 
     if (!verts) {
         return -1;
@@ -1711,7 +1706,7 @@ static int D3D11_QueueDrawPoints(SDL_Renderer *renderer, SDL_RenderCommand *cmd,
         verts->pos.y = points[i].y + 0.5f;
         verts->tex.x = 0.0f;
         verts->tex.y = 0.0f;
-        verts->color = color;
+        verts->color = cmd->data.draw.color;
         verts++;
     }
 
@@ -1719,7 +1714,7 @@ static int D3D11_QueueDrawPoints(SDL_Renderer *renderer, SDL_RenderCommand *cmd,
 }
 
 static int D3D11_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture,
-                               const float *xy, int xy_stride, const SDL_Color *color, int color_stride, const float *uv, int uv_stride,
+                               const float *xy, int xy_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,
                                float scale_x, float scale_y)
 {
@@ -1751,7 +1746,7 @@ static int D3D11_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, S
 
         verts->pos.x = xy_[0] * scale_x;
         verts->pos.y = xy_[1] * scale_y;
-        verts->color = *(SDL_Color *)((char *)color + j * color_stride);
+        verts->color = *(SDL_FColor *)((char *)color + j * color_stride);
 
         if (texture) {
             float *uv_ = (float *)((char *)uv + j * uv_stride);
@@ -2195,13 +2190,7 @@ static int D3D11_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd,
 
         case SDL_RENDERCMD_CLEAR:
         {
-            const float colorRGBA[] = {
-                (cmd->data.color.r / 255.0f),
-                (cmd->data.color.g / 255.0f),
-                (cmd->data.color.b / 255.0f),
-                (cmd->data.color.a / 255.0f)
-            };
-            ID3D11DeviceContext_ClearRenderTargetView(rendererData->d3dContext, D3D11_GetCurrentRenderTargetView(renderer), colorRGBA);
+            ID3D11DeviceContext_ClearRenderTargetView(rendererData->d3dContext, D3D11_GetCurrentRenderTargetView(renderer), &cmd->data.color.color.r);
             break;
         }
 

+ 1 - 1
src/render/direct3d11/SDL_shaders_d3d11.c

@@ -1905,7 +1905,7 @@ int D3D11_CreateVertexShader(ID3D11Device1 *d3dDevice, ID3D11VertexShader **vert
     const D3D11_INPUT_ELEMENT_DESC vertexDesc[] = {
         { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
         { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0 },
-        { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 16, D3D11_INPUT_PER_VERTEX_DATA, 0 },
+        { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 16, D3D11_INPUT_PER_VERTEX_DATA, 0 },
     };
     HRESULT result;
 

+ 6 - 18
src/render/direct3d12/SDL_render_d3d12.c

@@ -92,7 +92,7 @@ typedef struct
 {
     Float2 pos;
     Float2 tex;
-    SDL_Color color;
+    SDL_FColor color;
 } VertexPositionColor;
 
 /* Per-texture data */
@@ -598,7 +598,7 @@ static D3D12_PipelineState *D3D12_CreatePipelineState(SDL_Renderer *renderer,
     const D3D12_INPUT_ELEMENT_DESC vertexDesc[] = {
         { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
         { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
-        { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 16, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
+        { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 16, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
     };
     D3D12_RenderData *data = (D3D12_RenderData *)renderer->driverdata;
     D3D12_GRAPHICS_PIPELINE_STATE_DESC pipelineDesc;
@@ -2139,11 +2139,6 @@ static int D3D12_QueueDrawPoints(SDL_Renderer *renderer, SDL_RenderCommand *cmd,
 {
     VertexPositionColor *verts = (VertexPositionColor *)SDL_AllocateRenderVertices(renderer, count * sizeof(VertexPositionColor), 0, &cmd->data.draw.first);
     int i;
-    SDL_Color color;
-    color.r = cmd->data.draw.r;
-    color.g = cmd->data.draw.g;
-    color.b = cmd->data.draw.b;
-    color.a = cmd->data.draw.a;
 
     if (!verts) {
         return -1;
@@ -2156,7 +2151,7 @@ static int D3D12_QueueDrawPoints(SDL_Renderer *renderer, SDL_RenderCommand *cmd,
         verts->pos.y = points[i].y + 0.5f;
         verts->tex.x = 0.0f;
         verts->tex.y = 0.0f;
-        verts->color = color;
+        verts->color = cmd->data.draw.color;
         verts++;
     }
 
@@ -2164,7 +2159,7 @@ static int D3D12_QueueDrawPoints(SDL_Renderer *renderer, SDL_RenderCommand *cmd,
 }
 
 static int D3D12_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture,
-                               const float *xy, int xy_stride, const SDL_Color *color, int color_stride, const float *uv, int uv_stride,
+                               const float *xy, int xy_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,
                                float scale_x, float scale_y)
 {
@@ -2196,7 +2191,7 @@ static int D3D12_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, S
 
         verts->pos.x = xy_[0] * scale_x;
         verts->pos.y = xy_[1] * scale_y;
-        verts->color = *(SDL_Color *)((char *)color + j * color_stride);
+        verts->color = *(SDL_FColor *)((char *)color + j * color_stride);
 
         if (texture) {
             float *uv_ = (float *)((char *)uv + j * uv_stride);
@@ -2659,15 +2654,8 @@ static int D3D12_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd,
 
         case SDL_RENDERCMD_CLEAR:
         {
-            const float colorRGBA[] = {
-                (cmd->data.color.r / 255.0f),
-                (cmd->data.color.g / 255.0f),
-                (cmd->data.color.b / 255.0f),
-                (cmd->data.color.a / 255.0f)
-            };
-
             D3D12_CPU_DESCRIPTOR_HANDLE rtvDescriptor = D3D12_GetCurrentRenderTargetView(renderer);
-            D3D_CALL(rendererData->commandList, ClearRenderTargetView, rtvDescriptor, colorRGBA, 0, NULL);
+            D3D_CALL(rendererData->commandList, ClearRenderTargetView, rtvDescriptor, &cmd->data.color.color.r, 0, NULL);
             break;
         }
 

+ 34 - 45
src/render/metal/SDL_render_metal.m

@@ -274,34 +274,34 @@ static id<MTLRenderPipelineState> MakePipelineState(METAL_RenderData *data, META
 
     switch (cache->vertexFunction) {
     case SDL_METAL_VERTEX_SOLID:
-        /* position (float2), color (uchar4normalized) */
-        vertdesc.layouts[0].stride = sizeof(float) * 2 + sizeof(int);
+        /* position (float2), color (float4) */
+        vertdesc.layouts[0].stride = sizeof(float) * 2 + sizeof(float) * 4;
         vertdesc.layouts[0].stepFunction = MTLVertexStepFunctionPerVertex;
 
         vertdesc.attributes[0].format = MTLVertexFormatFloat2;
         vertdesc.attributes[0].offset = 0;
         vertdesc.attributes[0].bufferIndex = 0;
 
-        vertdesc.attributes[1].format = MTLVertexFormatUChar4Normalized;
+        vertdesc.attributes[1].format = MTLVertexFormatFloat4;
         vertdesc.attributes[1].offset = sizeof(float) * 2;
         vertdesc.attributes[1].bufferIndex = 0;
 
         break;
     case SDL_METAL_VERTEX_COPY:
-        /* position (float2), color (uchar4normalized), texcoord (float2) */
-        vertdesc.layouts[0].stride = sizeof(float) * 2 + sizeof(int) + sizeof(float) * 2;
+        /* position (float2), color (float4), texcoord (float2) */
+        vertdesc.layouts[0].stride = sizeof(float) * 2 + sizeof(float) * 4 + sizeof(float) * 2;
         vertdesc.layouts[0].stepFunction = MTLVertexStepFunctionPerVertex;
 
         vertdesc.attributes[0].format = MTLVertexFormatFloat2;
         vertdesc.attributes[0].offset = 0;
         vertdesc.attributes[0].bufferIndex = 0;
 
-        vertdesc.attributes[1].format = MTLVertexFormatUChar4Normalized;
+        vertdesc.attributes[1].format = MTLVertexFormatFloat4;
         vertdesc.attributes[1].offset = sizeof(float) * 2;
         vertdesc.attributes[1].bufferIndex = 0;
 
         vertdesc.attributes[2].format = MTLVertexFormatFloat2;
-        vertdesc.attributes[2].offset = sizeof(float) * 2 + sizeof(int);
+        vertdesc.attributes[2].offset = sizeof(float) * 2 + sizeof(float) * 4;
         vertdesc.attributes[2].bufferIndex = 0;
         break;
     }
@@ -1042,32 +1042,14 @@ static int METAL_QueueSetViewport(SDL_Renderer *renderer, SDL_RenderCommand *cmd
 
 static int METAL_QueueSetDrawColor(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
 {
-    const size_t vertlen = sizeof(float) * 4;
-    float *verts = (float *)SDL_AllocateRenderVertices(renderer, vertlen, DEVICE_ALIGN(16), &cmd->data.color.first);
-    if (!verts) {
-        return -1;
-    }
-    /*
-     * FIXME: not needed anymore, some cleanup to do
-     *
-     *(verts++) = ((float)cmd->data.color.r) / 255.0f;
-     *(verts++) = ((float)cmd->data.color.g) / 255.0f;
-     *(verts++) = ((float)cmd->data.color.b) / 255.0f;
-     *(verts++) = ((float)cmd->data.color.a) / 255.0f;
-     */
     return 0;
 }
 
 static int METAL_QueueDrawPoints(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count)
 {
-    const SDL_Color color = {
-        cmd->data.draw.r,
-        cmd->data.draw.g,
-        cmd->data.draw.b,
-        cmd->data.draw.a
-    };
-
-    const size_t vertlen = (2 * sizeof(float) + sizeof(SDL_Color)) * count;
+    const SDL_FColor *color = &cmd->data.draw.color;
+
+    const size_t vertlen = (2 * sizeof(float) + 4 * sizeof(float)) * count;
     float *verts = (float *)SDL_AllocateRenderVertices(renderer, vertlen, DEVICE_ALIGN(8), &cmd->data.draw.first);
     if (!verts) {
         return -1;
@@ -1077,25 +1059,23 @@ static int METAL_QueueDrawPoints(SDL_Renderer *renderer, SDL_RenderCommand *cmd,
     for (int i = 0; i < count; i++, points++) {
         *(verts++) = points->x;
         *(verts++) = points->y;
-        *((SDL_Color *)verts++) = color;
+        *(verts++) = color->r;
+        *(verts++) = color->g;
+        *(verts++) = color->b;
+        *(verts++) = color->a;
     }
     return 0;
 }
 
 static int METAL_QueueDrawLines(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count)
 {
-    const SDL_Color color = {
-        cmd->data.draw.r,
-        cmd->data.draw.g,
-        cmd->data.draw.b,
-        cmd->data.draw.a
-    };
+    const SDL_FColor *color = &cmd->data.draw.color;
     size_t vertlen;
     float *verts;
 
     SDL_assert(count >= 2); /* should have been checked at the higher level. */
 
-    vertlen = (2 * sizeof(float) + sizeof(SDL_Color)) * count;
+    vertlen = (2 * sizeof(float) + 4 * sizeof(float)) * count;
     verts = (float *)SDL_AllocateRenderVertices(renderer, vertlen, DEVICE_ALIGN(8), &cmd->data.draw.first);
     if (!verts) {
         return -1;
@@ -1105,7 +1085,10 @@ static int METAL_QueueDrawLines(SDL_Renderer *renderer, SDL_RenderCommand *cmd,
     for (int i = 0; i < count; i++, points++) {
         *(verts++) = points->x;
         *(verts++) = points->y;
-        *((SDL_Color *)verts++) = color;
+        *(verts++) = color->r;
+        *(verts++) = color->g;
+        *(verts++) = color->b;
+        *(verts++) = color->a;
     }
 
     /* If the line segment is completely horizontal or vertical,
@@ -1136,12 +1119,12 @@ static int METAL_QueueDrawLines(SDL_Renderer *renderer, SDL_RenderCommand *cmd,
 }
 
 static int METAL_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture,
-                               const float *xy, int xy_stride, const SDL_Color *color, int color_stride, const float *uv, int uv_stride,
+                               const float *xy, int xy_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,
                                float scale_x, float scale_y)
 {
     int count = indices ? num_indices : num_vertices;
-    const size_t vertlen = (2 * sizeof(float) + sizeof(int) + (texture ? 2 : 0) * sizeof(float)) * count;
+    const size_t vertlen = (2 * sizeof(float) + 4 * sizeof(float) + (texture ? 2 : 0) * sizeof(float)) * count;
     float *verts = (float *)SDL_AllocateRenderVertices(renderer, vertlen, DEVICE_ALIGN(8), &cmd->data.draw.first);
     if (!verts) {
         return -1;
@@ -1153,6 +1136,7 @@ static int METAL_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, S
     for (int i = 0; i < count; i++) {
         int j;
         float *xy_;
+        SDL_FColor *col_;
         if (size_indices == 4) {
             j = ((const Uint32 *)indices)[i];
         } else if (size_indices == 2) {
@@ -1168,7 +1152,12 @@ static int METAL_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, S
         *(verts++) = xy_[0] * scale_x;
         *(verts++) = xy_[1] * scale_y;
 
-        *((SDL_Color *)verts++) = *(SDL_Color *)((char *)color + j * color_stride);
+        col_ = (SDL_FColor *)((char *)color + j * color_stride);
+
+        *(verts++) = col_->r;
+        *(verts++) = col_->g;
+        *(verts++) = col_->b;
+        *(verts++) = col_->a;
 
         if (texture) {
             float *uv_ = (float *)((char *)uv + j * uv_stride);
@@ -1402,11 +1391,11 @@ static int METAL_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd,
                 statecache.viewport_dirty = SDL_TRUE;
 
                 {
-                    const Uint8 r = cmd->data.color.r;
-                    const Uint8 g = cmd->data.color.g;
-                    const Uint8 b = cmd->data.color.b;
-                    const Uint8 a = cmd->data.color.a;
-                    MTLClearColor color = MTLClearColorMake(r / 255.0f, g / 255.0f, b / 255.0f, a / 255.0f);
+                    const float r = cmd->data.color.color.r;
+                    const float g = cmd->data.color.color.g;
+                    const float b = cmd->data.color.color.b;
+                    const float a = cmd->data.color.color.a;
+                    MTLClearColor color = MTLClearColorMake(r, g, b, a);
 
                     // get new command encoder, set up with an initial clear operation.
                     // (this might fail, and future draw operations will notice.)

+ 51 - 42
src/render/opengl/SDL_render_gl.c

@@ -80,9 +80,9 @@ typedef struct
     SDL_bool color_array;
     SDL_bool texture_array;
     SDL_bool color_dirty;
-    Uint32 color;
+    SDL_FColor color;
     SDL_bool clear_color_dirty;
-    Uint32 clear_color;
+    SDL_FColor clear_color;
 } GL_DrawStateCache;
 
 typedef struct
@@ -996,7 +996,7 @@ static int GL_QueueDrawLines(SDL_Renderer *renderer, SDL_RenderCommand *cmd, con
 }
 
 static int GL_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture,
-                            const float *xy, int xy_stride, const SDL_Color *color, int color_stride, const float *uv, int uv_stride,
+                            const float *xy, int xy_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,
                             float scale_x, float scale_y)
 {
@@ -1004,7 +1004,7 @@ static int GL_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_
     int i;
     int count = indices ? num_indices : num_vertices;
     GLfloat *verts;
-    size_t sz = 2 * sizeof(GLfloat) + 4 * sizeof(Uint8) + (texture ? 2 : 0) * sizeof(GLfloat);
+    size_t sz = 2 * sizeof(GLfloat) + 4 * sizeof(GLfloat) + (texture ? 2 : 0) * sizeof(GLfloat);
 
     verts = (GLfloat *)SDL_AllocateRenderVertices(renderer, count * sz, 0, &cmd->data.draw.first);
     if (!verts) {
@@ -1021,6 +1021,7 @@ static int GL_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_
     for (i = 0; i < count; i++) {
         int j;
         float *xy_;
+        SDL_FColor *col_;
         if (size_indices == 4) {
             j = ((const Uint32 *)indices)[i];
         } else if (size_indices == 2) {
@@ -1036,10 +1037,11 @@ static int GL_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_
         *(verts++) = xy_[0] * scale_x;
         *(verts++) = xy_[1] * scale_y;
 
-        /* Not really a float, but it is still 4 bytes and will be cast to the
-           right type in the graphics driver. */
-        SDL_memcpy(verts, ((char *)color + j * color_stride), sizeof(*color));
-        ++verts;
+        col_ = (SDL_FColor *)((char *)color + j * color_stride);
+        *(verts++) = col_->r;
+        *(verts++) = col_->g;
+        *(verts++) = col_->b;
+        *(verts++) = col_->a;
 
         if (texture) {
             float *uv_ = (float *)((char *)uv + j * uv_stride);
@@ -1249,14 +1251,17 @@ static int GL_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, vo
         switch (cmd->command) {
         case SDL_RENDERCMD_SETDRAWCOLOR:
         {
-            const Uint8 r = cmd->data.color.r;
-            const Uint8 g = cmd->data.color.g;
-            const Uint8 b = cmd->data.color.b;
-            const Uint8 a = cmd->data.color.a;
-            const Uint32 color = (((Uint32)a << 24) | (r << 16) | (g << 8) | b);
-            if ((data->drawstate.color_dirty) || (color != data->drawstate.color)) {
-                data->glColor4ub((GLubyte)r, (GLubyte)g, (GLubyte)b, (GLubyte)a);
-                data->drawstate.color = color;
+            const float r = cmd->data.color.color.r;
+            const float g = cmd->data.color.color.g;
+            const float b = cmd->data.color.color.b;
+            const float a = cmd->data.color.color.a;
+            if (data->drawstate.clear_color_dirty ||
+                (r != data->drawstate.color.r) ||
+                (g != data->drawstate.color.g) ||
+                (b != data->drawstate.color.b) ||
+                (a != data->drawstate.color.a)) {
+                data->glColor4f(r, g, b, a);
+                data->drawstate.color = cmd->data.color.color;
                 data->drawstate.color_dirty = SDL_FALSE;
             }
             break;
@@ -1289,18 +1294,17 @@ static int GL_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, vo
 
         case SDL_RENDERCMD_CLEAR:
         {
-            const Uint8 r = cmd->data.color.r;
-            const Uint8 g = cmd->data.color.g;
-            const Uint8 b = cmd->data.color.b;
-            const Uint8 a = cmd->data.color.a;
-            const Uint32 color = (((Uint32)a << 24) | (r << 16) | (g << 8) | b);
-            if ((data->drawstate.clear_color_dirty) || (color != data->drawstate.clear_color)) {
-                const GLfloat fr = ((GLfloat)r) * inv255f;
-                const GLfloat fg = ((GLfloat)g) * inv255f;
-                const GLfloat fb = ((GLfloat)b) * inv255f;
-                const GLfloat fa = ((GLfloat)a) * inv255f;
-                data->glClearColor(fr, fg, fb, fa);
-                data->drawstate.clear_color = color;
+            const float r = cmd->data.color.color.r;
+            const float g = cmd->data.color.color.g;
+            const float b = cmd->data.color.color.b;
+            const float a = cmd->data.color.color.a;
+            if (data->drawstate.clear_color_dirty ||
+                (r != data->drawstate.clear_color.r) ||
+                (g != data->drawstate.clear_color.g) ||
+                (b != data->drawstate.clear_color.b) ||
+                (a != data->drawstate.clear_color.a)) {
+                data->glClearColor(r, g, b, a);
+                data->drawstate.clear_color = cmd->data.color.color;
                 data->drawstate.clear_color_dirty = SDL_FALSE;
             }
 
@@ -1406,12 +1410,12 @@ static int GL_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, vo
                 } else {
                     /* SetDrawState handles glEnableClientState. */
                     if (thistexture) {
-                        data->glVertexPointer(2, GL_FLOAT, sizeof(float) * 5, verts + 0);
-                        data->glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(float) * 5, verts + 2);
-                        data->glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 5, verts + 3);
+                        data->glVertexPointer(2, GL_FLOAT, sizeof(float) * 8, verts + 0);
+                        data->glColorPointer(4, GL_FLOAT, sizeof(float) * 8, verts + 2);
+                        data->glTexCoordPointer(2, GL_FLOAT, sizeof(float) * 8, verts + 6);
                     } else {
-                        data->glVertexPointer(2, GL_FLOAT, sizeof(float) * 3, verts + 0);
-                        data->glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(float) * 3, verts + 2);
+                        data->glVertexPointer(2, GL_FLOAT, sizeof(float) * 6, verts + 0);
+                        data->glColorPointer(4, GL_FLOAT, sizeof(float) * 6, verts + 2);
                     }
                 }
 
@@ -1419,12 +1423,11 @@ static int GL_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, vo
 
                 /* Restore previously set color when we're done. */
                 if (thiscmdtype != SDL_RENDERCMD_DRAW_POINTS) {
-                    Uint32 color = data->drawstate.color;
-                    GLubyte a = (GLubyte)((color >> 24) & 0xFF);
-                    GLubyte r = (GLubyte)((color >> 16) & 0xFF);
-                    GLubyte g = (GLubyte)((color >> 8) & 0xFF);
-                    GLubyte b = (GLubyte)((color >> 0) & 0xFF);
-                    data->glColor4ub(r, g, b, a);
+                    const float r = data->drawstate.color.r;
+                    const float g = data->drawstate.color.g;
+                    const float b = data->drawstate.color.b;
+                    const float a = data->drawstate.color.a;
+                    data->glColor4f(r, g, b, a);
                 }
             }
 
@@ -1906,12 +1909,18 @@ static SDL_Renderer *GL_CreateRenderer(SDL_Window *window, SDL_PropertiesID crea
     data->glDisable(GL_SCISSOR_TEST);
     data->glDisable(data->textype);
     data->glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
-    data->glColor4ub(255, 255, 255, 255);
+    data->glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
     /* This ended up causing video discrepancies between OpenGL and Direct3D */
     /* data->glEnable(GL_LINE_SMOOTH); */
 
-    data->drawstate.color = 0xFFFFFFFF;
-    data->drawstate.clear_color = 0xFFFFFFFF;
+    data->drawstate.color.r = 1.0f;
+    data->drawstate.color.g = 1.0f;
+    data->drawstate.color.b = 1.0f;
+    data->drawstate.color.a = 1.0f;
+    data->drawstate.clear_color.r = 1.0f;
+    data->drawstate.clear_color.g = 1.0f;
+    data->drawstate.clear_color.b = 1.0f;
+    data->drawstate.clear_color.a = 1.0f;
 
     return renderer;
 

+ 27 - 35
src/render/opengles2/SDL_render_gles2.c

@@ -139,7 +139,7 @@ typedef struct
     SDL_Rect cliprect;
     SDL_bool texturing;
     SDL_bool texturing_dirty;
-    Uint32 clear_color;
+    SDL_FColor clear_color;
     SDL_bool clear_color_dirty;
     int drawablew;
     int drawableh;
@@ -178,8 +178,6 @@ typedef struct GLES2_RenderData
 
 #define GLES2_MAX_CACHED_PROGRAMS 8
 
-static const float inv255f = 1.0f / 255.0f;
-
 static const char *GL_TranslateError(GLenum error)
 {
 #define GL_ERROR_TRANSLATE(e) \
@@ -733,18 +731,14 @@ static int GLES2_QueueDrawPoints(SDL_Renderer *renderer, SDL_RenderCommand *cmd,
     const SDL_bool colorswap = (renderer->target && (renderer->target->format == SDL_PIXELFORMAT_BGRA32 || renderer->target->format == SDL_PIXELFORMAT_BGRX32));
     SDL_VertexSolid *verts = (SDL_VertexSolid *)SDL_AllocateRenderVertices(renderer, count * sizeof(*verts), 0, &cmd->data.draw.first);
     int i;
-    SDL_Color color;
-    color.r = cmd->data.draw.r;
-    color.g = cmd->data.draw.g;
-    color.b = cmd->data.draw.b;
-    color.a = cmd->data.draw.a;
+    SDL_FColor color = cmd->data.draw.color;
 
     if (!verts) {
         return -1;
     }
 
     if (colorswap) {
-        Uint8 r = color.r;
+        float r = color.r;
         color.r = color.b;
         color.b = r;
     }
@@ -766,18 +760,14 @@ static int GLES2_QueueDrawLines(SDL_Renderer *renderer, SDL_RenderCommand *cmd,
     int i;
     GLfloat prevx, prevy;
     SDL_VertexSolid *verts = (SDL_VertexSolid *)SDL_AllocateRenderVertices(renderer, count * sizeof(*verts), 0, &cmd->data.draw.first);
-    SDL_Color color;
-    color.r = cmd->data.draw.r;
-    color.g = cmd->data.draw.g;
-    color.b = cmd->data.draw.b;
-    color.a = cmd->data.draw.a;
+    SDL_FColor color = cmd->data.draw.color;
 
     if (!verts) {
         return -1;
     }
 
     if (colorswap) {
-        Uint8 r = color.r;
+        float r = color.r;
         color.r = color.b;
         color.b = r;
     }
@@ -817,7 +807,7 @@ static int GLES2_QueueDrawLines(SDL_Renderer *renderer, SDL_RenderCommand *cmd,
 }
 
 static int GLES2_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture,
-                               const float *xy, int xy_stride, const SDL_Color *color, int color_stride, const float *uv, int uv_stride,
+                               const float *xy, int xy_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,
                                float scale_x, float scale_y)
 {
@@ -837,7 +827,7 @@ static int GLES2_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, S
         for (i = 0; i < count; i++) {
             int j;
             float *xy_;
-            SDL_Color col_;
+            SDL_FColor col_;
             float *uv_;
             if (size_indices == 4) {
                 j = ((const Uint32 *)indices)[i];
@@ -850,14 +840,14 @@ static int GLES2_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, S
             }
 
             xy_ = (float *)((char *)xy + j * xy_stride);
-            col_ = *(SDL_Color *)((char *)color + j * color_stride);
+            col_ = *(SDL_FColor *)((char *)color + j * color_stride);
             uv_ = (float *)((char *)uv + j * uv_stride);
 
             verts->position.x = xy_[0] * scale_x;
             verts->position.y = xy_[1] * scale_y;
 
             if (colorswap) {
-                Uint8 r = col_.r;
+                float r = col_.r;
                 col_.r = col_.b;
                 col_.b = r;
             }
@@ -877,7 +867,7 @@ static int GLES2_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, S
         for (i = 0; i < count; i++) {
             int j;
             float *xy_;
-            SDL_Color col_;
+            SDL_FColor col_;
 
             if (size_indices == 4) {
                 j = ((const Uint32 *)indices)[i];
@@ -890,7 +880,7 @@ static int GLES2_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, S
             }
 
             xy_ = (float *)((char *)xy + j * xy_stride);
-            col_ = *(SDL_Color *)((char *)color + j * color_stride);
+            col_ = *(SDL_FColor *)((char *)color + j * color_stride);
 
             verts->position.x = xy_[0] * scale_x;
             verts->position.y = xy_[1] * scale_y;
@@ -1003,7 +993,7 @@ static int SetDrawState(GLES2_RenderData *data, const SDL_RenderCommand *cmd, co
     {
         SDL_VertexSolid *verts = (SDL_VertexSolid *)(((Uint8 *)vertices) + cmd->data.draw.first);
         data->glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, stride, (const GLvoid *)&verts->position);
-        data->glVertexAttribPointer(GLES2_ATTRIBUTE_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE /* Normalized */, stride, (const GLvoid *)&verts->color);
+        data->glVertexAttribPointer(GLES2_ATTRIBUTE_COLOR, 4, GL_FLOAT, GL_TRUE /* Normalized */, stride, (const GLvoid *)&verts->color);
     }
 
     return 0;
@@ -1244,18 +1234,17 @@ static int GLES2_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd,
 
         case SDL_RENDERCMD_CLEAR:
         {
-            const Uint8 r = colorswap ? cmd->data.color.b : cmd->data.color.r;
-            const Uint8 g = cmd->data.color.g;
-            const Uint8 b = colorswap ? cmd->data.color.r : cmd->data.color.b;
-            const Uint8 a = cmd->data.color.a;
-            const Uint32 color = (((Uint32)a << 24) | (r << 16) | (g << 8) | b);
-            if (data->drawstate.clear_color_dirty || (color != data->drawstate.clear_color)) {
-                const GLfloat fr = ((GLfloat)r) * inv255f;
-                const GLfloat fg = ((GLfloat)g) * inv255f;
-                const GLfloat fb = ((GLfloat)b) * inv255f;
-                const GLfloat fa = ((GLfloat)a) * inv255f;
-                data->glClearColor(fr, fg, fb, fa);
-                data->drawstate.clear_color = color;
+            const float r = colorswap ? cmd->data.color.color.b : cmd->data.color.color.r;
+            const float g = cmd->data.color.color.g;
+            const float b = colorswap ? cmd->data.color.color.r : cmd->data.color.color.b;
+            const float a = cmd->data.color.color.a;
+            if (data->drawstate.clear_color_dirty ||
+                (r != data->drawstate.clear_color.r) ||
+                (g != data->drawstate.clear_color.g) ||
+                (b != data->drawstate.clear_color.b) ||
+                (a != data->drawstate.clear_color.a)) {
+                data->glClearColor(r, g, g, a);
+                data->drawstate.clear_color = cmd->data.color.color;
                 data->drawstate.clear_color_dirty = SDL_FALSE;
             }
 
@@ -2204,7 +2193,10 @@ static SDL_Renderer *GLES2_CreateRenderer(SDL_Window *window, SDL_PropertiesID c
 
     data->glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
 
-    data->drawstate.clear_color = 0xFFFFFFFF;
+    data->drawstate.clear_color.r = 1.0f;
+    data->drawstate.clear_color.g = 1.0f;
+    data->drawstate.clear_color.b = 1.0f;
+    data->drawstate.clear_color.a = 1.0f;
     data->drawstate.projection[3][0] = -1.0f;
     data->drawstate.projection[3][3] = 1.0f;
 

+ 32 - 28
src/render/ps2/SDL_render_ps2.c

@@ -103,6 +103,26 @@ static int PixelFormatToPS2PSM(Uint32 format)
     }
 }
 
+static gs_rgbaq float_color_to_RGBAQ(const SDL_FColor *color)
+{
+    uint8_t colorR = (uint8_t)(color->r * 255.0f);
+    uint8_t colorG = (uint8_t)(color->g * 255.0f);
+    uint8_t colorB = (uint8_t)(color->b * 255.0f);
+    uint8_t colorA = (uint8_t)(color->a * 255.0f);
+
+    return color_to_RGBAQ(colorR, colorG, colorB, colorA, 0x00);
+}
+
+static uint64_t float_GS_SETREG_RGBAQ(const SDL_FColor *color)
+{
+    uint8_t colorR = (uint8_t)(color->r * 255.0f);
+    uint8_t colorG = (uint8_t)(color->g * 255.0f);
+    uint8_t colorB = (uint8_t)(color->b * 255.0f);
+    uint8_t colorA = (uint8_t)(color->a * 255.0f);
+
+    return GS_SETREG_RGBAQ(colorR, colorG, colorB, colorA, 0x00);
+}
+
 static void PS2_WindowEvent(SDL_Renderer *renderer, const SDL_WindowEvent *event)
 {
 }
@@ -217,7 +237,6 @@ static int PS2_QueueDrawPoints(SDL_Renderer *renderer, SDL_RenderCommand *cmd, c
 {
     PS2_RenderData *data = (PS2_RenderData *)renderer->driverdata;
     GSPRIMPOINT *vertices = (GSPRIMPOINT *)SDL_AllocateRenderVertices(renderer, count * sizeof(GSPRIMPOINT), 4, &cmd->data.draw.first);
-    uint8_t colorR, colorG, colorB, colorA;
     gs_rgbaq rgbaq;
     int i;
 
@@ -227,11 +246,7 @@ static int PS2_QueueDrawPoints(SDL_Renderer *renderer, SDL_RenderCommand *cmd, c
 
     cmd->data.draw.count = count;
 
-    colorR = cmd->data.draw.r;
-    colorG = cmd->data.draw.g;
-    colorB = cmd->data.draw.b;
-    colorA = cmd->data.draw.a;
-    rgbaq = color_to_RGBAQ(colorR, colorG, colorB, colorA, 0.0f);
+    rgbaq = float_color_to_RGBAQ(&cmd->data.draw.color);
 
     for (i = 0; i < count; i++, vertices++, points++) {
         vertices->xyz2 = vertex_to_XYZ2(data->gsGlobal, points->x, points->y, 0);
@@ -241,7 +256,7 @@ static int PS2_QueueDrawPoints(SDL_Renderer *renderer, SDL_RenderCommand *cmd, c
 }
 
 static int PS2_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture,
-                             const float *xy, int xy_stride, const SDL_Color *color, int color_stride, const float *uv, int uv_stride,
+                             const float *xy, int xy_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,
                              float scale_x, float scale_y)
 {
@@ -264,7 +279,7 @@ static int PS2_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL
             int j;
             float *xy_;
             float *uv_;
-            SDL_Color col_;
+            SDL_FColor *col_;
             if (size_indices == 4) {
                 j = ((const Uint32 *)indices)[i];
             } else if (size_indices == 2) {
@@ -276,11 +291,11 @@ static int PS2_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL
             }
 
             xy_ = (float *)((char *)xy + j * xy_stride);
-            col_ = *(SDL_Color *)((char *)color + j * color_stride);
+            col_ = (SDL_FColor *)((char *)color + j * color_stride);
             uv_ = (float *)((char *)uv + j * uv_stride);
 
             vertices->xyz2 = vertex_to_XYZ2(data->gsGlobal, xy_[0] * scale_x, xy_[1] * scale_y, 0);
-            vertices->rgbaq = color_to_RGBAQ(col_.r, col_.g, col_.b, col_.a, 0);
+            vertices->rgbaq = float_color_to_RGBAQ(col_);
             vertices->uv = vertex_to_UV(ps2_tex, uv_[0] * ps2_tex->Width, uv_[1] * ps2_tex->Height);
 
             vertices++;
@@ -296,7 +311,7 @@ static int PS2_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL
         for (i = 0; i < count; i++) {
             int j;
             float *xy_;
-            SDL_Color col_;
+            SDL_FColor *col_;
             if (size_indices == 4) {
                 j = ((const Uint32 *)indices)[i];
             } else if (size_indices == 2) {
@@ -308,10 +323,10 @@ static int PS2_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL
             }
 
             xy_ = (float *)((char *)xy + j * xy_stride);
-            col_ = *(SDL_Color *)((char *)color + j * color_stride);
+            col_ = (SDL_FColor *)((char *)color + j * color_stride);
 
             vertices->xyz2 = vertex_to_XYZ2(data->gsGlobal, xy_[0] * scale_x, xy_[1] * scale_y, 0);
-            vertices->rgbaq = color_to_RGBAQ(col_.r, col_.g, col_.b, col_.a, 0.0f);
+            vertices->rgbaq = float_color_to_RGBAQ(col_);
 
             vertices++;
         }
@@ -346,30 +361,19 @@ static int PS2_RenderSetClipRect(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
 
 static int PS2_RenderSetDrawColor(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
 {
-    int colorR, colorG, colorB, colorA;
-
     PS2_RenderData *data = (PS2_RenderData *)renderer->driverdata;
 
-    colorR = (cmd->data.color.r);
-    colorG = (cmd->data.color.g);
-    colorB = (cmd->data.color.b);
-    colorA = (cmd->data.color.a);
-    data->drawColor = GS_SETREG_RGBAQ(colorR, colorG, colorB, colorA, 0x00);
+    data->drawColor = float_GS_SETREG_RGBAQ(&cmd->data.color.color);
     return 0;
 }
 
 static int PS2_RenderClear(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
 {
-    int colorR, colorG, colorB, colorA, offsetX, offsetY;
+    int offsetX, offsetY;
     SDL_Rect *viewport;
 
     PS2_RenderData *data = (PS2_RenderData *)renderer->driverdata;
 
-    colorR = (cmd->data.color.r);
-    colorG = (cmd->data.color.g);
-    colorB = (cmd->data.color.b);
-    colorA = (cmd->data.color.a);
-
     /* Clear the screen, so let's put default viewport */
     gsKit_set_scissor(data->gsGlobal, GS_SCISSOR_RESET);
     /* Put back original offset */
@@ -377,7 +381,7 @@ static int PS2_RenderClear(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
     offsetY = data->gsGlobal->OffsetY;
     data->gsGlobal->OffsetX = (int)(2048.0f * 16.0f);
     data->gsGlobal->OffsetY = (int)(2048.0f * 16.0f);
-    gsKit_clear(data->gsGlobal, GS_SETREG_RGBAQ(colorR, colorG, colorB, colorA, 0x00));
+    gsKit_clear(data->gsGlobal, float_GS_SETREG_RGBAQ(&cmd->data.color.color));
 
     /* Put back original offset */
     data->gsGlobal->OffsetX = offsetX;
@@ -386,7 +390,7 @@ static int PS2_RenderClear(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
     // /* Put back view port */
     viewport = data->viewport;
     gsKit_set_scissor(data->gsGlobal, GS_SETREG_SCISSOR(viewport->x, viewport->x + viewport->w, viewport->y, viewport->y + viewport->h));
-    
+
     return 0;
 }
 

+ 41 - 35
src/render/psp/SDL_render_psp.c

@@ -645,7 +645,7 @@ static int PSP_QueueDrawPoints(SDL_Renderer *renderer, SDL_RenderCommand *cmd, c
 }
 
 static int PSP_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture,
-                             const float *xy, int xy_stride, const SDL_Color *color, int color_stride, const float *uv, int uv_stride,
+                             const float *xy, int xy_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,
                              float scale_x, float scale_y)
 {
@@ -665,7 +665,7 @@ static int PSP_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL
         for (i = 0; i < count; i++) {
             int j;
             float *xy_;
-            SDL_Color col_;
+            SDL_FColor *col_;
             if (size_indices == 4) {
                 j = ((const Uint32 *)indices)[i];
             } else if (size_indices == 2) {
@@ -677,13 +677,16 @@ static int PSP_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL
             }
 
             xy_ = (float *)((char *)xy + j * xy_stride);
-            col_ = *(SDL_Color *)((char *)color + j * color_stride);
+            col_ = (SDL_FColor *)((char *)color + j * color_stride);
 
             verts->x = xy_[0] * scale_x;
             verts->y = xy_[1] * scale_y;
             verts->z = 0;
 
-            verts->col = col_;
+            verts->col.r = (Uint8)(col_->r * 255.0f);
+            verts->col.g = (Uint8)(col_->g * 255.0f);
+            verts->col.b = (Uint8)(col_->b * 255.0f);
+            verts->col.a = (Uint8)(col_->a * 255.0f);
 
             verts++;
         }
@@ -698,7 +701,7 @@ static int PSP_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL
         for (i = 0; i < count; i++) {
             int j;
             float *xy_;
-            SDL_Color col_;
+            SDL_FColor *col_;
             float *uv_;
 
             if (size_indices == 4) {
@@ -712,14 +715,17 @@ static int PSP_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL
             }
 
             xy_ = (float *)((char *)xy + j * xy_stride);
-            col_ = *(SDL_Color *)((char *)color + j * color_stride);
+            col_ = (SDL_FColor *)((char *)color + j * color_stride);
             uv_ = (float *)((char *)uv + j * uv_stride);
 
             verts->x = xy_[0] * scale_x;
             verts->y = xy_[1] * scale_y;
             verts->z = 0;
 
-            verts->col = col_;
+            verts->col.r = (Uint8)(col_->r * 255.0f);
+            verts->col.g = (Uint8)(col_->g * 255.0f);
+            verts->col.b = (Uint8)(col_->b * 255.0f);
+            verts->col.a = (Uint8)(col_->a * 255.0f);
 
             verts->u = uv_[0] * psp_texture->textureWidth;
             verts->v = uv_[1] * psp_texture->textureHeight;
@@ -1074,10 +1080,10 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
 
         case SDL_RENDERCMD_CLEAR:
         {
-            const Uint8 r = cmd->data.color.r;
-            const Uint8 g = cmd->data.color.g;
-            const Uint8 b = cmd->data.color.b;
-            const Uint8 a = cmd->data.color.a;
+            const Uint8 r = (Uint8)(cmd->data.color.color.r * 255.0f);
+            const Uint8 g = (Uint8)(cmd->data.color.color.g * 255.0f);
+            const Uint8 b = (Uint8)(cmd->data.color.color.b * 255.0f);
+            const Uint8 a = (Uint8)(cmd->data.color.color.a * 255.0f);
             sceGuClearColor(GU_RGBA(r, g, b, a));
             sceGuClearStencil(a);
             sceGuClear(GU_COLOR_BUFFER_BIT | GU_STENCIL_BUFFER_BIT);
@@ -1088,10 +1094,10 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
         {
             const size_t count = cmd->data.draw.count;
             const VertV *verts = (VertV *)(gpumem + cmd->data.draw.first);
-            const Uint8 r = cmd->data.draw.r;
-            const Uint8 g = cmd->data.draw.g;
-            const Uint8 b = cmd->data.draw.b;
-            const Uint8 a = cmd->data.draw.a;
+            const Uint8 r = (Uint8)(cmd->data.draw.color.r * 255.0f);
+            const Uint8 g = (Uint8)(cmd->data.draw.color.g * 255.0f);
+            const Uint8 b = (Uint8)(cmd->data.draw.color.b * 255.0f);
+            const Uint8 a = (Uint8)(cmd->data.draw.color.a * 255.0f);
             PSP_BlendState state = {
                 .color = GU_RGBA(r, g, b, a),
                 .texture = NULL,
@@ -1107,10 +1113,10 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
         {
             const size_t count = cmd->data.draw.count;
             const VertV *verts = (VertV *)(gpumem + cmd->data.draw.first);
-            const Uint8 r = cmd->data.draw.r;
-            const Uint8 g = cmd->data.draw.g;
-            const Uint8 b = cmd->data.draw.b;
-            const Uint8 a = cmd->data.draw.a;
+            const Uint8 r = (Uint8)(cmd->data.draw.color.r * 255.0f);
+            const Uint8 g = (Uint8)(cmd->data.draw.color.g * 255.0f);
+            const Uint8 b = (Uint8)(cmd->data.draw.color.b * 255.0f);
+            const Uint8 a = (Uint8)(cmd->data.draw.color.a * 255.0f);
             PSP_BlendState state = {
                 .color = GU_RGBA(r, g, b, a),
                 .texture = NULL,
@@ -1126,10 +1132,10 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
         {
             const size_t count = cmd->data.draw.count;
             const VertV *verts = (VertV *)(gpumem + cmd->data.draw.first);
-            const Uint8 r = cmd->data.draw.r;
-            const Uint8 g = cmd->data.draw.g;
-            const Uint8 b = cmd->data.draw.b;
-            const Uint8 a = cmd->data.draw.a;
+            const Uint8 r = (Uint8)(cmd->data.draw.color.r * 255.0f);
+            const Uint8 g = (Uint8)(cmd->data.draw.color.g * 255.0f);
+            const Uint8 b = (Uint8)(cmd->data.draw.color.b * 255.0f);
+            const Uint8 a = (Uint8)(cmd->data.draw.color.a * 255.0f);
             PSP_BlendState state = {
                 .color = GU_RGBA(r, g, b, a),
                 .texture = NULL,
@@ -1145,10 +1151,10 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
         {
             const size_t count = cmd->data.draw.count;
             const VertTV *verts = (VertTV *)(gpumem + cmd->data.draw.first);
-            const Uint8 a = cmd->data.draw.a;
-            const Uint8 r = cmd->data.draw.r;
-            const Uint8 g = cmd->data.draw.g;
-            const Uint8 b = cmd->data.draw.b;
+            const Uint8 a = (Uint8)(cmd->data.draw.color.a * 255.0f);
+            const Uint8 r = (Uint8)(cmd->data.draw.color.r * 255.0f);
+            const Uint8 g = (Uint8)(cmd->data.draw.color.g * 255.0f);
+            const Uint8 b = (Uint8)(cmd->data.draw.color.b * 255.0f);
             PSP_BlendState state = {
                 .color = GU_RGBA(r, g, b, a),
                 .texture = cmd->data.draw.texture,
@@ -1163,10 +1169,10 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
         case SDL_RENDERCMD_COPY_EX:
         {
             const VertTV *verts = (VertTV *)(gpumem + cmd->data.draw.first);
-            const Uint8 a = cmd->data.draw.a;
-            const Uint8 r = cmd->data.draw.r;
-            const Uint8 g = cmd->data.draw.g;
-            const Uint8 b = cmd->data.draw.b;
+            const Uint8 a = (Uint8)(cmd->data.draw.color.a * 255.0f);
+            const Uint8 r = (Uint8)(cmd->data.draw.color.r * 255.0f);
+            const Uint8 g = (Uint8)(cmd->data.draw.color.g * 255.0f);
+            const Uint8 b = (Uint8)(cmd->data.draw.color.b * 255.0f);
             PSP_BlendState state = {
                 .color = GU_RGBA(r, g, b, a),
                 .texture = cmd->data.draw.texture,
@@ -1189,10 +1195,10 @@ static int PSP_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, v
                 sceGuEnable(GU_TEXTURE_2D);
             } else {
                 const VertTCV *verts = (VertTCV *)(gpumem + cmd->data.draw.first);
-                const Uint8 a = cmd->data.draw.a;
-                const Uint8 r = cmd->data.draw.r;
-                const Uint8 g = cmd->data.draw.g;
-                const Uint8 b = cmd->data.draw.b;
+                const Uint8 a = (Uint8)(cmd->data.draw.color.a * 255.0f);
+                const Uint8 r = (Uint8)(cmd->data.draw.color.r * 255.0f);
+                const Uint8 g = (Uint8)(cmd->data.draw.color.g * 255.0f);
+                const Uint8 b = (Uint8)(cmd->data.draw.color.b * 255.0f);
                 PSP_BlendState state = {
                     .color = GU_RGBA(r, g, b, a),
                     .texture = NULL,

+ 40 - 29
src/render/software/SDL_render_sw.c

@@ -100,13 +100,18 @@ static int SW_GetOutputSize(SDL_Renderer *renderer, int *w, int *h)
 static int SW_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SDL_PropertiesID create_props)
 {
     SDL_Surface *surface = SDL_CreateSurface(texture->w, texture->h, texture->format);
+    Uint8 r, g, b, a;
 
     if (!surface) {
         return SDL_SetError("Cannot create surface");
     }
     texture->driverdata = surface;
-    SDL_SetSurfaceColorMod(texture->driverdata, texture->color.r, texture->color.g, texture->color.b);
-    SDL_SetSurfaceAlphaMod(texture->driverdata, texture->color.a);
+    r = (Uint8)((float)texture->color.r * 255.0f);
+    g = (Uint8)((float)texture->color.g * 255.0f);
+    b = (Uint8)((float)texture->color.b * 255.0f);
+    a = (Uint8)((float)texture->color.a * 255.0f);
+    SDL_SetSurfaceColorMod(texture->driverdata, r, g, b);
+    SDL_SetSurfaceAlphaMod(texture->driverdata, a);
     SDL_SetSurfaceBlendMode(texture->driverdata, texture->blendMode);
 
     /* Only RLE encode textures without an alpha channel since the RLE coder
@@ -531,7 +536,7 @@ typedef struct GeometryCopyData
 } GeometryCopyData;
 
 static int SW_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture,
-                            const float *xy, int xy_stride, const SDL_Color *color, int color_stride, const float *uv, int uv_stride,
+                            const float *xy, int xy_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,
                             float scale_x, float scale_y)
 {
@@ -553,7 +558,7 @@ static int SW_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_
         for (i = 0; i < count; i++) {
             int j;
             float *xy_;
-            SDL_Color col_;
+            SDL_FColor col_;
             float *uv_;
             if (size_indices == 4) {
                 j = ((const Uint32 *)indices)[i];
@@ -566,7 +571,7 @@ static int SW_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_
             }
 
             xy_ = (float *)((char *)xy + j * xy_stride);
-            col_ = *(SDL_Color *)((char *)color + j * color_stride);
+            col_ = *(SDL_FColor *)((char *)color + j * color_stride);
 
             uv_ = (float *)((char *)uv + j * uv_stride);
 
@@ -577,7 +582,10 @@ static int SW_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_
             ptr->dst.y = (int)(xy_[1] * scale_y);
             trianglepoint_2_fixedpoint(&ptr->dst);
 
-            ptr->color = col_;
+            ptr->color.r = (Uint8)((float)col_.r * 255.0f);
+            ptr->color.g = (Uint8)((float)col_.g * 255.0f);
+            ptr->color.b = (Uint8)((float)col_.b * 255.0f);
+            ptr->color.a = (Uint8)((float)col_.a * 255.0f);
 
             ptr++;
         }
@@ -587,7 +595,7 @@ static int SW_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_
         for (i = 0; i < count; i++) {
             int j;
             float *xy_;
-            SDL_Color col_;
+            SDL_FColor col_;
             if (size_indices == 4) {
                 j = ((const Uint32 *)indices)[i];
             } else if (size_indices == 2) {
@@ -599,13 +607,16 @@ static int SW_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_
             }
 
             xy_ = (float *)((char *)xy + j * xy_stride);
-            col_ = *(SDL_Color *)((char *)color + j * color_stride);
+            col_ = *(SDL_FColor *)((char *)color + j * color_stride);
 
             ptr->dst.x = (int)(xy_[0] * scale_x);
             ptr->dst.y = (int)(xy_[1] * scale_y);
             trianglepoint_2_fixedpoint(&ptr->dst);
 
-            ptr->color = col_;
+            ptr->color.r = (Uint8)((float)col_.r * 255.0f);
+            ptr->color.g = (Uint8)((float)col_.g * 255.0f);
+            ptr->color.b = (Uint8)((float)col_.b * 255.0f);
+            ptr->color.a = (Uint8)((float)col_.a * 255.0f);
 
             ptr++;
         }
@@ -615,10 +626,10 @@ static int SW_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_
 
 static void PrepTextureForCopy(const SDL_RenderCommand *cmd)
 {
-    const Uint8 r = cmd->data.draw.r;
-    const Uint8 g = cmd->data.draw.g;
-    const Uint8 b = cmd->data.draw.b;
-    const Uint8 a = cmd->data.draw.a;
+    const Uint8 r = (Uint8)((float)cmd->data.draw.color.r * 255.0f);
+    const Uint8 g = (Uint8)((float)cmd->data.draw.color.g * 255.0f);
+    const Uint8 b = (Uint8)((float)cmd->data.draw.color.b * 255.0f);
+    const Uint8 a = (Uint8)((float)cmd->data.draw.color.a * 255.0f);
     const SDL_BlendMode blend = cmd->data.draw.blend;
     SDL_Texture *texture = cmd->data.draw.texture;
     SDL_Surface *surface = (SDL_Surface *)texture->driverdata;
@@ -700,10 +711,10 @@ static int SW_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, vo
 
         case SDL_RENDERCMD_CLEAR:
         {
-            const Uint8 r = cmd->data.color.r;
-            const Uint8 g = cmd->data.color.g;
-            const Uint8 b = cmd->data.color.b;
-            const Uint8 a = cmd->data.color.a;
+            const Uint8 r = (Uint8)((float)cmd->data.color.color.r * 255.0f);
+            const Uint8 g = (Uint8)((float)cmd->data.color.color.g * 255.0f);
+            const Uint8 b = (Uint8)((float)cmd->data.color.color.b * 255.0f);
+            const Uint8 a = (Uint8)((float)cmd->data.color.color.a * 255.0f);
             /* By definition the clear ignores the clip rect */
             SDL_SetSurfaceClipRect(surface, NULL);
             SDL_FillSurfaceRect(surface, NULL, SDL_MapRGBA(surface->format, r, g, b, a));
@@ -713,10 +724,10 @@ static int SW_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, vo
 
         case SDL_RENDERCMD_DRAW_POINTS:
         {
-            const Uint8 r = cmd->data.draw.r;
-            const Uint8 g = cmd->data.draw.g;
-            const Uint8 b = cmd->data.draw.b;
-            const Uint8 a = cmd->data.draw.a;
+            const Uint8 r = (Uint8)((float)cmd->data.draw.color.r * 255.0f);
+            const Uint8 g = (Uint8)((float)cmd->data.draw.color.g * 255.0f);
+            const Uint8 b = (Uint8)((float)cmd->data.draw.color.b * 255.0f);
+            const Uint8 a = (Uint8)((float)cmd->data.draw.color.a * 255.0f);
             const int count = (int)cmd->data.draw.count;
             SDL_Point *verts = (SDL_Point *)(((Uint8 *)vertices) + cmd->data.draw.first);
             const SDL_BlendMode blend = cmd->data.draw.blend;
@@ -741,10 +752,10 @@ static int SW_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, vo
 
         case SDL_RENDERCMD_DRAW_LINES:
         {
-            const Uint8 r = cmd->data.draw.r;
-            const Uint8 g = cmd->data.draw.g;
-            const Uint8 b = cmd->data.draw.b;
-            const Uint8 a = cmd->data.draw.a;
+            const Uint8 r = (Uint8)((float)cmd->data.draw.color.r * 255.0f);
+            const Uint8 g = (Uint8)((float)cmd->data.draw.color.g * 255.0f);
+            const Uint8 b = (Uint8)((float)cmd->data.draw.color.b * 255.0f);
+            const Uint8 a = (Uint8)((float)cmd->data.draw.color.a * 255.0f);
             const int count = (int)cmd->data.draw.count;
             SDL_Point *verts = (SDL_Point *)(((Uint8 *)vertices) + cmd->data.draw.first);
             const SDL_BlendMode blend = cmd->data.draw.blend;
@@ -769,10 +780,10 @@ static int SW_RunCommandQueue(SDL_Renderer *renderer, SDL_RenderCommand *cmd, vo
 
         case SDL_RENDERCMD_FILL_RECTS:
         {
-            const Uint8 r = cmd->data.draw.r;
-            const Uint8 g = cmd->data.draw.g;
-            const Uint8 b = cmd->data.draw.b;
-            const Uint8 a = cmd->data.draw.a;
+            const Uint8 r = (Uint8)((float)cmd->data.draw.color.r * 255.0f);
+            const Uint8 g = (Uint8)((float)cmd->data.draw.color.g * 255.0f);
+            const Uint8 b = (Uint8)((float)cmd->data.draw.color.b * 255.0f);
+            const Uint8 a = (Uint8)((float)cmd->data.draw.color.a * 255.0f);
             const int count = (int)cmd->data.draw.count;
             SDL_Rect *verts = (SDL_Rect *)(((Uint8 *)vertices) + cmd->data.draw.first);
             const SDL_BlendMode blend = cmd->data.draw.blend;

+ 10 - 19
src/render/vitagxm/SDL_render_vita_gxm.c

@@ -83,7 +83,7 @@ static int VITA_GXM_QueueDrawPoints(SDL_Renderer *renderer, SDL_RenderCommand *c
 static int VITA_GXM_QueueDrawLines(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count);
 
 static int VITA_GXM_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture,
-                                  const float *xy, int xy_stride, const SDL_Color *color, int color_stride, const float *uv, int uv_stride,
+                                  const float *xy, int xy_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,
                                   float scale_x, float scale_y);
 
@@ -659,10 +659,7 @@ static int VITA_GXM_QueueSetDrawColor(SDL_Renderer *renderer, SDL_RenderCommand
 {
     VITA_GXM_RenderData *data = (VITA_GXM_RenderData *)renderer->driverdata;
 
-    data->drawstate.color.r = cmd->data.color.r;
-    data->drawstate.color.g = cmd->data.color.g;
-    data->drawstate.color.b = cmd->data.color.b;
-    data->drawstate.color.a = cmd->data.color.a;
+    data->drawstate.color = cmd->data.color.color;
 
     return 0;
 }
@@ -671,7 +668,7 @@ static int VITA_GXM_QueueDrawPoints(SDL_Renderer *renderer, SDL_RenderCommand *c
 {
     VITA_GXM_RenderData *data = (VITA_GXM_RenderData *)renderer->driverdata;
 
-    SDL_Color color = data->drawstate.color;
+    SDL_FColor color = data->drawstate.color;
 
     color_vertex *vertex = (color_vertex *)pool_malloc(
         data,
@@ -692,7 +689,7 @@ static int VITA_GXM_QueueDrawPoints(SDL_Renderer *renderer, SDL_RenderCommand *c
 static int VITA_GXM_QueueDrawLines(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count)
 {
     VITA_GXM_RenderData *data = (VITA_GXM_RenderData *)renderer->driverdata;
-    SDL_Color color = data->drawstate.color;
+    SDL_FColor color = data->drawstate.color;
 
     color_vertex *vertex = (color_vertex *)pool_malloc(
         data,
@@ -715,7 +712,7 @@ static int VITA_GXM_QueueDrawLines(SDL_Renderer *renderer, SDL_RenderCommand *cm
 }
 
 static int VITA_GXM_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture,
-                                  const float *xy, int xy_stride, const SDL_Color *color, int color_stride, const float *uv, int uv_stride,
+                                  const float *xy, int xy_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,
                                   float scale_x, float scale_y)
 {
@@ -742,7 +739,7 @@ static int VITA_GXM_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd
             int j;
             float *xy_;
             float *uv_;
-            SDL_Color col_;
+            SDL_FColor col_;
             if (size_indices == 4) {
                 j = ((const Uint32 *)indices)[i];
             } else if (size_indices == 2) {
@@ -754,7 +751,7 @@ static int VITA_GXM_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd
             }
 
             xy_ = (float *)((char *)xy + j * xy_stride);
-            col_ = *(SDL_Color *)((char *)color + j * color_stride);
+            col_ = *(SDL_FColor *)((char *)color + j * color_stride);
             uv_ = (float *)((char *)uv + j * uv_stride);
 
             vertices[i].x = xy_[0] * scale_x;
@@ -780,7 +777,7 @@ static int VITA_GXM_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd
         for (i = 0; i < count; i++) {
             int j;
             float *xy_;
-            SDL_Color col_;
+            SDL_FColor col_;
             if (size_indices == 4) {
                 j = ((const Uint32 *)indices)[i];
             } else if (size_indices == 2) {
@@ -792,7 +789,7 @@ static int VITA_GXM_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd
             }
 
             xy_ = (float *)((char *)xy + j * xy_stride);
-            col_ = *(SDL_Color *)((char *)color + j * color_stride);
+            col_ = *(SDL_FColor *)((char *)color + j * color_stride);
 
             vertices[i].x = xy_[0] * scale_x;
             vertices[i].y = xy_[1] * scale_y;
@@ -807,16 +804,10 @@ static int VITA_GXM_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd
 static int VITA_GXM_RenderClear(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
 {
     void *color_buffer;
-    float clear_color[4];
 
     VITA_GXM_RenderData *data = (VITA_GXM_RenderData *)renderer->driverdata;
     unset_clip_rectangle(data);
 
-    clear_color[0] = (cmd->data.color.r) / 255.0f;
-    clear_color[1] = (cmd->data.color.g) / 255.0f;
-    clear_color[2] = (cmd->data.color.b) / 255.0f;
-    clear_color[3] = (cmd->data.color.a) / 255.0f;
-
     // set clear shaders
     data->drawstate.fragment_program = data->clearFragmentProgram;
     data->drawstate.vertex_program = data->clearVertexProgram;
@@ -825,7 +816,7 @@ static int VITA_GXM_RenderClear(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
 
     // set the clear color
     sceGxmReserveFragmentDefaultUniformBuffer(data->gxm_context, &color_buffer);
-    sceGxmSetUniformDataF(color_buffer, data->clearClearColorParam, 0, 4, clear_color);
+    sceGxmSetUniformDataF(color_buffer, data->clearClearColorParam, 0, 4, &cmd->data.color.color.r);
 
     // draw the clear triangle
     sceGxmSetVertexStream(data->gxm_context, 0, data->clearVertices);

+ 3 - 4
src/render/vitagxm/SDL_render_vita_gxm_types.h

@@ -63,7 +63,7 @@ typedef struct color_vertex
 {
     float x;
     float y;
-    SDL_Color color;
+    SDL_FColor color;
 } color_vertex;
 
 typedef struct texture_vertex
@@ -72,7 +72,7 @@ typedef struct texture_vertex
     float y;
     float u;
     float v;
-    SDL_Color color;
+    SDL_FColor color;
 } texture_vertex;
 
 typedef struct gxm_texture
@@ -107,7 +107,7 @@ typedef struct
     SDL_bool viewport_dirty;
     SDL_Texture *texture;
     SDL_Texture *target;
-    SDL_Color color;
+    SDL_FColor color;
     SceGxmFragmentProgram *fragment_program;
     SceGxmVertexProgram *vertex_program;
     int last_command;
@@ -117,7 +117,6 @@ typedef struct
     SDL_bool cliprect_dirty;
     SDL_Rect cliprect;
     SDL_bool texturing;
-    SDL_Color clear_color;
     int drawablew;
     int drawableh;
 } gxm_drawstate_cache;

+ 11 - 11
test/testsprite.c

@@ -141,13 +141,13 @@ static void MoveSprites(SDL_Renderer *renderer, SDL_Texture *sprite)
         SDL_RenderFillRect(renderer, &temp);
     } else {
         /* Draw two triangles, filled, uniform */
-        SDL_Color color;
+        SDL_FColor color;
         SDL_Vertex verts[3];
         SDL_zeroa(verts);
-        color.r = 0xFF;
-        color.g = 0xFF;
-        color.b = 0xFF;
-        color.a = 0xFF;
+        color.r = 1.0f;
+        color.g = 1.0f;
+        color.b = 1.0f;
+        color.a = 1.0f;
 
         verts[0].position.x = temp.x;
         verts[0].position.y = temp.y;
@@ -243,9 +243,9 @@ static void MoveSprites(SDL_Renderer *renderer, SDL_Texture *sprite)
         SDL_Vertex *verts = (SDL_Vertex *)SDL_malloc(num_sprites * sizeof(SDL_Vertex) * 6);
         SDL_Vertex *verts2 = verts;
         if (verts) {
-            SDL_Color color;
-            SDL_GetTextureColorMod(sprite, &color.r, &color.g, &color.b);
-            SDL_GetTextureAlphaMod(sprite, &color.a);
+            SDL_FColor color;
+            SDL_GetTextureColorModFloat(sprite, &color.r, &color.g, &color.b);
+            SDL_GetTextureAlphaModFloat(sprite, &color.a);
             for (i = 0; i < num_sprites; ++i) {
                 position = &positions[i];
                 /* 0 */
@@ -314,9 +314,9 @@ static void MoveSprites(SDL_Renderer *renderer, SDL_Texture *sprite)
         int *indices2 = indices;
         if (verts && indices) {
             int pos = 0;
-            SDL_Color color;
-            SDL_GetTextureColorMod(sprite, &color.r, &color.g, &color.b);
-            SDL_GetTextureAlphaMod(sprite, &color.a);
+            SDL_FColor color;
+            SDL_GetTextureColorModFloat(sprite, &color.r, &color.g, &color.b);
+            SDL_GetTextureAlphaModFloat(sprite, &color.a);
             for (i = 0; i < num_sprites; ++i) {
                 position = &positions[i];
                 /* 0 */