Atlas - testrendertarget.c
Home / ext / SDL / test Lines: 1 | Size: 8362 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)][FILE BEGIN]1/* 2 Copyright (C) 1997-2025 Sam Lantinga <[email protected]> 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 drawstate->sprite = LoadTexture(drawstate->renderer, "icon.png", true); 256 drawstate->background = LoadTexture(drawstate->renderer, "sample.png", false); 257 if (!drawstate->sprite || !drawstate->background) { 258 quit(2); 259 } 260 SDL_GetTextureSize(drawstate->sprite, &drawstate->sprite_rect.w, &drawstate->sprite_rect.h); 261 drawstate->scale_direction = 1; 262 263 if (test_composite) { 264 SDL_SetTextureAlphaMod(drawstate->sprite, 0x80); 265 } 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} 294[FILE END](C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.