From 53bcb3e0e987371de153bfdf38879630b6733f9f Mon Sep 17 00:00:00 2001
From: Sylvain <[EMAIL REDACTED]>
Date: Tue, 6 Apr 2021 21:38:24 +0200
Subject: [PATCH] Add an option to 'testsprite2' to render slicing into
triangles. [--use-rendergeometry mode1|mode2] mode1: Draw sprite2 as
triangles that can be recombined as rect by software renderer mode2: Draw
sprite2 as triangles that can *not* be recombined as rect by software
renderer Use an 'indices' array
---
test/testsprite2.c | 219 +++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 211 insertions(+), 8 deletions(-)
diff --git a/test/testsprite2.c b/test/testsprite2.c
index 672ff3f4e1..dc48b1e9e1 100644
--- a/test/testsprite2.c
+++ b/test/testsprite2.c
@@ -39,6 +39,7 @@ static int sprite_w, sprite_h;
static SDL_BlendMode blendMode = SDL_BLENDMODE_BLEND;
static Uint32 next_fps_check, frames;
static const Uint32 fps_check_delay = 5000;
+static int use_rendergeometry = 0;
/* Number of iterations to move sprites - used for visual tests. */
/* -1: infinite random moves (default); >=0: enables N deterministic moves */
@@ -175,7 +176,38 @@ MoveSprites(SDL_Renderer * renderer, SDL_Texture * sprite)
temp.y = 1;
temp.w = sprite_w;
temp.h = sprite_h;
- SDL_RenderFillRect(renderer, &temp);
+ if (use_rendergeometry == 0) {
+ SDL_RenderFillRect(renderer, &temp);
+ } else {
+ /* Draw two triangles, filled, uniform */
+ SDL_Color color;
+ SDL_Vertex verts[3];
+ SDL_zeroa(verts);
+ color.r = 0xFF;
+ color.g = 0xFF;
+ color.b = 0xFF;
+ color.a = 0xFF;
+
+ verts[0].position.x = temp.x;
+ verts[0].position.y = temp.y;
+ verts[0].color = color;
+
+ verts[1].position.x = temp.x + temp.w;
+ verts[1].position.y = temp.y;
+ verts[1].color = color;
+
+ verts[2].position.x = temp.x + temp.w;
+ verts[2].position.y = temp.y + temp.h;
+ verts[2].color = color;
+
+ SDL_RenderGeometry(renderer, NULL, verts, 3, NULL, 0);
+
+ verts[1].position.x = temp.x;
+ verts[1].position.y = temp.y + temp.h;
+ verts[1].color = color;
+
+ SDL_RenderGeometry(renderer, NULL, verts, 3, NULL, 0);
+ }
SDL_RenderCopy(renderer, sprite, NULL, &temp);
temp.x = viewport.w-sprite_w-1;
temp.y = 1;
@@ -220,7 +252,7 @@ MoveSprites(SDL_Renderer * renderer, SDL_Texture * sprite)
}
}
-
+
/* Countdown sprite-move iterations and disable color changes at iteration end - used for visual tests. */
if (iterations > 0) {
iterations--;
@@ -232,11 +264,160 @@ MoveSprites(SDL_Renderer * renderer, SDL_Texture * sprite)
}
/* Draw sprites */
- for (i = 0; i < num_sprites; ++i) {
- position = &positions[i];
+ if (use_rendergeometry == 0) {
+ for (i = 0; i < num_sprites; ++i) {
+ position = &positions[i];
- /* Blit the sprite onto the screen */
- SDL_RenderCopy(renderer, sprite, NULL, position);
+ /* Blit the sprite onto the screen */
+ SDL_RenderCopy(renderer, sprite, NULL, position);
+ }
+ } else if (use_rendergeometry == 1) {
+ /*
+ * 0--1
+ * | /|
+ * |/ |
+ * 3--2
+ *
+ * Draw sprite2 as triangles that can be recombined as rect by software renderer
+ */
+ 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);
+ for (i = 0; i < num_sprites; ++i) {
+ position = &positions[i];
+ /* 0 */
+ verts->position.x = position->x;
+ verts->position.y = position->y;
+ verts->color = color;
+ verts->tex_coord.x = 0.0f;
+ verts->tex_coord.y = 0.0f;
+ verts++;
+ /* 1 */
+ verts->position.x = position->x + position->w;
+ verts->position.y = position->y;
+ verts->color = color;
+ verts->tex_coord.x = 1.0f;
+ verts->tex_coord.y = 0.0f;
+ verts++;
+ /* 2 */
+ verts->position.x = position->x + position->w;
+ verts->position.y = position->y + position->h;
+ verts->color = color;
+ verts->tex_coord.x = 1.0f;
+ verts->tex_coord.y = 1.0f;
+ verts++;
+ /* 0 */
+ verts->position.x = position->x;
+ verts->position.y = position->y;
+ verts->color = color;
+ verts->tex_coord.x = 0.0f;
+ verts->tex_coord.y = 0.0f;
+ verts++;
+ /* 2 */
+ verts->position.x = position->x + position->w;
+ verts->position.y = position->y + position->h;
+ verts->color = color;
+ verts->tex_coord.x = 1.0f;
+ verts->tex_coord.y = 1.0f;
+ verts++;
+ /* 3 */
+ verts->position.x = position->x;
+ verts->position.y = position->y + position->h;
+ verts->color = color;
+ verts->tex_coord.x = 0.0f;
+ verts->tex_coord.y = 1.0f;
+ verts++;
+ }
+
+ /* Blit sprites as triangles onto the screen */
+ SDL_RenderGeometry(renderer, sprite, verts2, num_sprites * 6, NULL, 0);
+ SDL_free(verts2);
+ }
+ } else if (use_rendergeometry == 2) {
+ /* 0-----1
+ * |\ A /|
+ * | \ / |
+ * |D 2 B|
+ * | / \ |
+ * |/ C \|
+ * 3-----4
+ *
+ * Draw sprite2 as triangles that can *not* be recombined as rect by software renderer
+ * Use an 'indices' array
+ */
+ SDL_Vertex *verts = (SDL_Vertex *) SDL_malloc(num_sprites * sizeof (SDL_Vertex) * 5);
+ SDL_Vertex *verts2 = verts;
+ int *indices = (int *) SDL_malloc(num_sprites * sizeof (int) * 4 * 3);
+ 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);
+ for (i = 0; i < num_sprites; ++i) {
+ position = &positions[i];
+ /* 0 */
+ verts->position.x = position->x;
+ verts->position.y = position->y;
+ verts->color = color;
+ verts->tex_coord.x = 0.0f;
+ verts->tex_coord.y = 0.0f;
+ verts++;
+ /* 1 */
+ verts->position.x = position->x + position->w;
+ verts->position.y = position->y;
+ verts->color = color;
+ verts->tex_coord.x = 1.0f;
+ verts->tex_coord.y = 0.0f;
+ verts++;
+ /* 2 */
+ verts->position.x = position->x + position->w / 2.0f;
+ verts->position.y = position->y + position->h / 2.0f;
+ verts->color = color;
+ verts->tex_coord.x = 0.5f;
+ verts->tex_coord.y = 0.5f;
+ verts++;
+ /* 3 */
+ verts->position.x = position->x;
+ verts->position.y = position->y + position->h;
+ verts->color = color;
+ verts->tex_coord.x = 0.0f;
+ verts->tex_coord.y = 1.0f;
+ verts++;
+ /* 4 */
+ verts->position.x = position->x + position->w;
+ verts->position.y = position->y + position->h;
+ verts->color = color;
+ verts->tex_coord.x = 1.0f;
+ verts->tex_coord.y = 1.0f;
+ verts++;
+ /* A */
+ *indices++ = pos + 0;
+ *indices++ = pos + 1;
+ *indices++ = pos + 2;
+ /* B */
+ *indices++ = pos + 1;
+ *indices++ = pos + 2;
+ *indices++ = pos + 4;
+ /* C */
+ *indices++ = pos + 3;
+ *indices++ = pos + 2;
+ *indices++ = pos + 4;
+ /* D */
+ *indices++ = pos + 3;
+ *indices++ = pos + 2;
+ *indices++ = pos + 0;
+ pos += 5;
+ }
+ }
+
+ /* Blit sprites as triangles onto the screen */
+ SDL_RenderGeometry(renderer, sprite, verts2, num_sprites * 5, indices2, num_sprites * 4 * 3);
+ SDL_free(verts2);
+ SDL_free(indices2);
}
/* Update the screen! */
@@ -331,6 +512,20 @@ main(int argc, char *argv[])
} else if (SDL_strcasecmp(argv[i], "--cyclealpha") == 0) {
cycle_alpha = SDL_TRUE;
consumed = 1;
+ } else if (SDL_strcasecmp(argv[i], "--use-rendergeometry") == 0) {
+ if (argv[i + 1]) {
+ if (SDL_strcasecmp(argv[i + 1], "mode1") == 0) {
+ /* Draw sprite2 as triangles that can be recombined as rect by software renderer */
+ use_rendergeometry = 1;
+ } else if (SDL_strcasecmp(argv[i + 1], "mode2") == 0) {
+ /* Draw sprite2 as triangles that can *not* be recombined as rect by software renderer
+ * Use an 'indices' array */
+ use_rendergeometry = 2;
+ } else {
+ return -1;
+ }
+ }
+ consumed = 2;
} else if (SDL_isdigit(*argv[i])) {
num_sprites = SDL_atoi(argv[i]);
consumed = 1;
@@ -340,7 +535,15 @@ main(int argc, char *argv[])
}
}
if (consumed < 0) {
- static const char *options[] = { "[--blend none|blend|add|mod]", "[--cyclecolor]", "[--cyclealpha]", "[--iterations N]", "[num_sprites]", "[icon.bmp]", NULL };
+ static const char *options[] = {
+ "[--blend none|blend|add|mod]",
+ "[--cyclecolor]",
+ "[--cyclealpha]",
+ "[--iterations N]",
+ "[--use-rendergeometry mode1|mode2]",
+ "[num_sprites]",
+ "[icon.bmp]",
+ NULL };
SDLTest_CommonLogUsage(state, argv[0], options);
quit(1);
}
@@ -374,7 +577,7 @@ main(int argc, char *argv[])
quit(2);
}
- /* Position sprites and set their velocities using the fuzzer */
+ /* Position sprites and set their velocities using the fuzzer */
if (iterations >= 0) {
/* Deterministic seed - used for visual tests */
seed = (Uint64)iterations;