summaryrefslogtreecommitdiff
path: root/src/contrib/SDL-3.2.20/test/testrendertarget.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/contrib/SDL-3.2.20/test/testrendertarget.c')
-rw-r--r--src/contrib/SDL-3.2.20/test/testrendertarget.c293
1 files changed, 293 insertions, 0 deletions
diff --git a/src/contrib/SDL-3.2.20/test/testrendertarget.c b/src/contrib/SDL-3.2.20/test/testrendertarget.c
new file mode 100644
index 0000000..bad57fd
--- /dev/null
+++ b/src/contrib/SDL-3.2.20/test/testrendertarget.c
@@ -0,0 +1,293 @@
1/*
2 Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
3
4 This software is provided 'as-is', without any express or implied
5 warranty. In no event will the authors be held liable for any damages
6 arising from the use of this software.
7
8 Permission is granted to anyone to use this software for any purpose,
9 including commercial applications, and to alter it and redistribute it
10 freely.
11*/
12/* Simple program: Move N sprites around on the screen as fast as possible */
13
14#include <SDL3/SDL_test_common.h>
15#include <SDL3/SDL_main.h>
16#include "testutils.h"
17
18#ifdef SDL_PLATFORM_EMSCRIPTEN
19#include <emscripten/emscripten.h>
20#endif
21
22#include <stdlib.h>
23
24static SDLTest_CommonState *state;
25
26typedef struct
27{
28 SDL_Window *window;
29 SDL_Renderer *renderer;
30 SDL_Texture *background;
31 SDL_Texture *sprite;
32 SDL_FRect sprite_rect;
33 int scale_direction;
34} DrawState;
35
36static DrawState *drawstates;
37static int done;
38static bool test_composite = false;
39
40/* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
41static void
42quit(int rc)
43{
44 SDLTest_CommonQuit(state);
45 /* Let 'main()' return normally */
46 if (rc != 0) {
47 exit(rc);
48 }
49}
50
51static bool
52DrawComposite(DrawState *s)
53{
54 SDL_Rect viewport;
55 SDL_FRect R;
56 SDL_Texture *target;
57 SDL_Surface *surface;
58
59 static bool blend_tested = false;
60 if (!blend_tested) {
61 SDL_Texture *A, *B;
62
63 A = SDL_CreateTexture(s->renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, 1, 1);
64 SDL_SetTextureBlendMode(A, SDL_BLENDMODE_BLEND);
65
66 B = SDL_CreateTexture(s->renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, 1, 1);
67 SDL_SetTextureBlendMode(B, SDL_BLENDMODE_BLEND);
68
69 SDL_SetRenderTarget(s->renderer, A);
70 SDL_SetRenderDrawColor(s->renderer, 0x00, 0x00, 0x00, 0x80);
71 SDL_RenderFillRect(s->renderer, NULL);
72
73 SDL_SetRenderTarget(s->renderer, B);
74 SDL_SetRenderDrawColor(s->renderer, 0x00, 0x00, 0x00, 0x00);
75 SDL_RenderFillRect(s->renderer, NULL);
76 SDL_RenderTexture(s->renderer, A, NULL, NULL);
77
78 surface = SDL_RenderReadPixels(s->renderer, NULL);
79 if (surface) {
80 Uint8 r, g, b, a;
81 if (SDL_ReadSurfacePixel(surface, 0, 0, &r, &g, &b, &a)) {
82 SDL_Log("Blended pixel: 0x%.2x%.2x%.2x%.2x", r, g, b, a);
83 }
84 SDL_DestroySurface(surface);
85 }
86
87 SDL_DestroyTexture(A);
88 SDL_DestroyTexture(B);
89 blend_tested = true;
90 }
91
92 SDL_GetRenderViewport(s->renderer, &viewport);
93
94 target = SDL_CreateTexture(s->renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, viewport.w, viewport.h);
95 SDL_SetTextureBlendMode(target, SDL_BLENDMODE_BLEND);
96 SDL_SetRenderTarget(s->renderer, target);
97
98 /* Draw the background.
99 This is solid black so when the sprite is copied to it, any per-pixel alpha will be blended through.
100 */
101 SDL_SetRenderDrawColor(s->renderer, 0x00, 0x00, 0x00, 0x00);
102 SDL_RenderFillRect(s->renderer, NULL);
103
104 /* Scale and draw the sprite */
105 s->sprite_rect.w += s->scale_direction;
106 s->sprite_rect.h += s->scale_direction;
107 if (s->scale_direction > 0) {
108 if (s->sprite_rect.w >= viewport.w || s->sprite_rect.h >= viewport.h) {
109 s->scale_direction = -1;
110 }
111 } else {
112 if (s->sprite_rect.w <= 1 || s->sprite_rect.h <= 1) {
113 s->scale_direction = 1;
114 }
115 }
116 s->sprite_rect.x = (viewport.w - s->sprite_rect.w) / 2;
117 s->sprite_rect.y = (viewport.h - s->sprite_rect.h) / 2;
118
119 SDL_RenderTexture(s->renderer, s->sprite, NULL, &s->sprite_rect);
120
121 SDL_SetRenderTarget(s->renderer, NULL);
122 SDL_RenderTexture(s->renderer, s->background, NULL, NULL);
123
124 SDL_SetRenderDrawBlendMode(s->renderer, SDL_BLENDMODE_BLEND);
125 SDL_SetRenderDrawColor(s->renderer, 0xff, 0x00, 0x00, 0x80);
126 R.x = 0.0f;
127 R.y = 0.0f;
128 R.w = 100.0f;
129 R.h = 100.0f;
130 SDL_RenderFillRect(s->renderer, &R);
131 SDL_SetRenderDrawBlendMode(s->renderer, SDL_BLENDMODE_NONE);
132
133 SDL_RenderTexture(s->renderer, target, NULL, NULL);
134 SDL_DestroyTexture(target);
135
136 /* Update the screen! */
137 SDL_RenderPresent(s->renderer);
138 return true;
139}
140
141static bool
142Draw(DrawState *s)
143{
144 SDL_Rect viewport;
145 SDL_Texture *target;
146
147 SDL_GetRenderViewport(s->renderer, &viewport);
148
149 target = SDL_CreateTexture(s->renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, viewport.w, viewport.h);
150 if (!target) {
151 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create render target texture: %s", SDL_GetError());
152 return false;
153 }
154 SDL_SetRenderTarget(s->renderer, target);
155
156 /* Draw the background */
157 SDL_RenderTexture(s->renderer, s->background, NULL, NULL);
158
159 /* Scale and draw the sprite */
160 s->sprite_rect.w += s->scale_direction;
161 s->sprite_rect.h += s->scale_direction;
162 if (s->scale_direction > 0) {
163 if (s->sprite_rect.w >= viewport.w || s->sprite_rect.h >= viewport.h) {
164 s->scale_direction = -1;
165 }
166 } else {
167 if (s->sprite_rect.w <= 1 || s->sprite_rect.h <= 1) {
168 s->scale_direction = 1;
169 }
170 }
171 s->sprite_rect.x = (viewport.w - s->sprite_rect.w) / 2;
172 s->sprite_rect.y = (viewport.h - s->sprite_rect.h) / 2;
173
174 SDL_RenderTexture(s->renderer, s->sprite, NULL, &s->sprite_rect);
175
176 SDL_SetRenderTarget(s->renderer, NULL);
177 SDL_RenderTexture(s->renderer, target, NULL, NULL);
178 SDL_DestroyTexture(target);
179
180 /* Update the screen! */
181 SDL_RenderPresent(s->renderer);
182 return true;
183}
184
185static void loop(void)
186{
187 int i;
188 SDL_Event event;
189
190 /* Check for events */
191 while (SDL_PollEvent(&event)) {
192 SDLTest_CommonEvent(state, &event, &done);
193 }
194 for (i = 0; i < state->num_windows; ++i) {
195 if (state->windows[i] == NULL) {
196 continue;
197 }
198 if (test_composite) {
199 if (!DrawComposite(&drawstates[i])) {
200 done = 1;
201 }
202 } else {
203 if (!Draw(&drawstates[i])) {
204 done = 1;
205 }
206 }
207 }
208#ifdef SDL_PLATFORM_EMSCRIPTEN
209 if (done) {
210 emscripten_cancel_main_loop();
211 }
212#endif
213}
214
215int main(int argc, char *argv[])
216{
217 int i;
218 int frames;
219 Uint64 then, now;
220
221 /* Initialize test framework */
222 state = SDLTest_CommonCreateState(argv, SDL_INIT_VIDEO);
223 if (!state) {
224 return 1;
225 }
226
227 for (i = 1; i < argc;) {
228 int consumed;
229
230 consumed = SDLTest_CommonArg(state, i);
231 if (consumed == 0) {
232 consumed = -1;
233 if (SDL_strcasecmp(argv[i], "--composite") == 0) {
234 test_composite = true;
235 consumed = 1;
236 }
237 }
238 if (consumed < 0) {
239 static const char *options[] = { "[--composite]", NULL };
240 SDLTest_CommonLogUsage(state, argv[0], options);
241 quit(1);
242 }
243 i += consumed;
244 }
245 if (!SDLTest_CommonInit(state)) {
246 quit(2);
247 }
248
249 drawstates = SDL_stack_alloc(DrawState, state->num_windows);
250 for (i = 0; i < state->num_windows; ++i) {
251 DrawState *drawstate = &drawstates[i];
252
253 drawstate->window = state->windows[i];
254 drawstate->renderer = state->renderers[i];
255 if (test_composite) {
256 drawstate->sprite = LoadTexture(drawstate->renderer, "icon-alpha.bmp", true, NULL, NULL);
257 } else {
258 drawstate->sprite = LoadTexture(drawstate->renderer, "icon.bmp", true, NULL, NULL);
259 }
260 drawstate->background = LoadTexture(drawstate->renderer, "sample.bmp", false, NULL, NULL);
261 if (!drawstate->sprite || !drawstate->background) {
262 quit(2);
263 }
264 SDL_GetTextureSize(drawstate->sprite, &drawstate->sprite_rect.w, &drawstate->sprite_rect.h);
265 drawstate->scale_direction = 1;
266 }
267
268 /* Main render loop */
269 frames = 0;
270 then = SDL_GetTicks();
271 done = 0;
272
273#ifdef SDL_PLATFORM_EMSCRIPTEN
274 emscripten_set_main_loop(loop, 0, 1);
275#else
276 while (!done) {
277 ++frames;
278 loop();
279 }
280#endif
281
282 /* Print out some timing information */
283 now = SDL_GetTicks();
284 if (now > then) {
285 double fps = ((double)frames * 1000) / (now - then);
286 SDL_Log("%2.2f frames per second", fps);
287 }
288
289 SDL_stack_free(drawstates);
290
291 quit(0);
292 return 0;
293}