Disclosure: This draft was generated with AI and checked against the cited primary sources, with a separate AI editorial review. It was prepared for the FrameSprite team, which has a commercial interest in FrameSprite. Proposed examples are not executed tests unless explicitly identified as recorded fixture results.
SDL_RenderGeometry applies color and alpha modulation per vertex and ignores SDL_SetTextureColorMod and SDL_SetTextureAlphaMod for that draw. If a sprite mesh stays white or opaque after changing texture modulation, inspect its vertex colors. This behavior is explicit in the geometry reference.
Key Takeaways
- Textured-copy state and triangle-vertex state are different tint paths.
- Initialize every vertex color, including alpha.
- Keep normalized UV coordinates separate from pixel-space frame rectangles.
Compare the two draw paths
Draw the same source through an ordinary texture copy and through your geometry path. Keep the destination and texture the same. If only the geometry path ignores a tint, do not rewrite the source PNG to compensate.
The texture-color modulation reference describes its copy-operation behavior. A value applied to the texture is not a universal material setting for every rendering operation.
This is different from a shared-texture tint leaking into other enemies, covered by the SDL3 shared-modulation guide. In this case the geometry draw uses a different source for modulation.
Initialize the vertex data
SDL_Vertex contains a position, color and texture coordinate, as defined in the vertex reference. Use a neutral white color with full alpha when you want the original texture colors unchanged. Apply the intended tint to those vertex values when a mesh should change appearance.
A data fragment illustrates neutral modulation:
/* SDL 3.2+ fragment; not compiled or executed here. */
for (int i = 0; i < vertex_count; ++i) {
vertices[i].color.r = 1.0f;
vertices[i].color.g = 1.0f;
vertices[i].color.b = 1.0f;
vertices[i].color.a = 1.0f;
}
The fragment assumes a valid initialized vertex array and a checked count. It does not construct the mesh or establish correct triangle indices. Do not leave color fields uninitialized just because the positions and UVs are already assigned.
Check all vertices of the intended region
A tint applied to only one corner can produce a gradient across a triangle. That can be useful for a deliberate effect, but it is not a uniform character hit flash. Inspect every vertex of the mesh, including duplicated vertices used along seams.
Texture UVs use their own normalized domain. Convert atlas pixel rectangles using the full texture dimensions, and keep that conversion separate from screen positions. A tint problem should not be fixed by changing UVs.
| Visual result | Inspect |
|---|---|
| Texture-mod call has no effect | Per-vertex modulation path |
| Unexpected gradient | Inconsistent corner colors |
| Entire mesh invisible | Vertex alpha and texture alpha |
| Wrong neighboring frame | UV rectangle and atlas dimensions |
The hit-flash design guide helps choose the visual effect. A multiplicative tint cannot express every bright replacement-style flash.
Acceptance with two adjacent triangles
Use a simple quad divided into two triangles, with an asymmetric diagnostic texture. Apply neutral white, one uniform tint and one intentional gradient. Confirm there is no unexpected seam at the diagonal.
Then animate an atlas region without changing vertex color and verify frame selection independently. Record vertex modulation, UV generation and index validation in the handoff checklist.
No geometry draw or backend comparison was executed for this article. It targets SDL 3.2+ and the documented distinction between geometry vertex colors and texture-copy modulation.
Keep shared texture effects independent
Per-vertex modulation can be useful when several meshes share a texture but need different colors. Store each mesh's intended color in its own draw data instead of mutating the shared texture between geometry submissions and expecting those mutations to apply. If a renderer wrapper supports both copy and geometry paths, expose their color ownership clearly. A common draw interface can still exist, but its implementation must translate the requested appearance into the correct state for each path. Test that translation with two differently tinted instances in one frame.
Sources and editorial ownership
Primary references checked on October 20, 2026:
Editorial owner: FrameSprite Workflow Team. Editorial and verification policy. Report a documentation correction.
Top comments (0)