Atlas - testcolorspace.c
Home / ext / SDL / test Lines: 1 | Size: 21898 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 13#include <SDL3/SDL.h> 14#include <SDL3/SDL_test.h> 15#include <SDL3/SDL_main.h> 16 17#ifdef SDL_PLATFORM_EMSCRIPTEN 18#include <emscripten/emscripten.h> 19#endif 20 21#define WINDOW_WIDTH 640 22#define WINDOW_HEIGHT 480 23 24#define TEXT_START_X 6.0f 25#define TEXT_START_Y 6.0f 26#define TEXT_LINE_ADVANCE FONT_CHARACTER_SIZE * 2 27 28static SDL_Window *window; 29static SDL_Renderer *renderer; 30static const char *renderer_name; 31static SDL_Colorspace colorspace = SDL_COLORSPACE_SRGB; 32static const char *colorspace_name = "sRGB"; 33static int renderer_count = 0; 34static int renderer_index = 0; 35static int stage_index = 0; 36static int done; 37static float HDR_headroom = 1.0f; 38 39enum 40{ 41 StageClearBackground, 42 StageDrawBackground, 43 StageTextureBackground, 44 StageTargetBackground, 45 StageBlendDrawing, 46 StageBlendTexture, 47 StageGradientDrawing, 48 StageGradientTexture, 49 StageCount 50}; 51 52static void FreeRenderer(void) 53{ 54 SDLTest_CleanupTextDrawing(); 55 SDL_DestroyRenderer(renderer); 56 renderer = NULL; 57} 58 59static void UpdateHDRState(void) 60{ 61 SDL_PropertiesID props; 62 bool HDR_enabled; 63 64 props = SDL_GetWindowProperties(window); 65 HDR_enabled = SDL_GetBooleanProperty(props, SDL_PROP_WINDOW_HDR_ENABLED_BOOLEAN, false); 66 67 SDL_Log("HDR %s", HDR_enabled ? "enabled" : "disabled"); 68 69 if (HDR_enabled) { 70 props = SDL_GetRendererProperties(renderer); 71 if (SDL_GetNumberProperty(props, SDL_PROP_RENDERER_OUTPUT_COLORSPACE_NUMBER, SDL_COLORSPACE_SRGB) != SDL_COLORSPACE_SRGB_LINEAR) { 72 SDL_Log("Run with --colorspace linear to display HDR colors"); 73 } 74 HDR_headroom = SDL_GetFloatProperty(props, SDL_PROP_RENDERER_HDR_HEADROOM_FLOAT, 1.0f); 75 } 76} 77 78static void CreateRenderer(void) 79{ 80 SDL_PropertiesID props; 81 82 props = SDL_CreateProperties(); 83 SDL_SetPointerProperty(props, SDL_PROP_RENDERER_CREATE_WINDOW_POINTER, window); 84 SDL_SetStringProperty(props, SDL_PROP_RENDERER_CREATE_NAME_STRING, SDL_GetRenderDriver(renderer_index)); 85 SDL_SetNumberProperty(props, SDL_PROP_RENDERER_CREATE_OUTPUT_COLORSPACE_NUMBER, colorspace); 86 renderer = SDL_CreateRendererWithProperties(props); 87 SDL_DestroyProperties(props); 88 if (!renderer) { 89 SDL_Log("Couldn't create renderer: %s", SDL_GetError()); 90 return; 91 } 92 93 renderer_name = SDL_GetRendererName(renderer); 94 SDL_Log("Created renderer %s", renderer_name); 95 96 UpdateHDRState(); 97} 98 99static void NextRenderer( void ) 100{ 101 if (renderer_count <= 0) { 102 return; 103 } 104 105 ++renderer_index; 106 if (renderer_index == renderer_count) { 107 renderer_index = 0; 108 } 109 FreeRenderer(); 110 CreateRenderer(); 111} 112 113static void PrevRenderer(void) 114{ 115 if (renderer_count <= 0) { 116 return; 117 } 118 119 --renderer_index; 120 if (renderer_index == -1) { 121 renderer_index += renderer_count; 122 } 123 FreeRenderer(); 124 CreateRenderer(); 125} 126 127static void NextStage(void) 128{ 129 ++stage_index; 130 if (stage_index == StageCount) { 131 stage_index = 0; 132 } 133} 134 135static void PrevStage(void) 136{ 137 --stage_index; 138 if (stage_index == -1) { 139 stage_index += StageCount; 140 } 141} 142 143static bool ReadPixel(int x, int y, SDL_Color *c) 144{ 145 SDL_Surface *surface; 146 SDL_Rect r; 147 bool result = false; 148 149 r.x = x; 150 r.y = y; 151 r.w = 1; 152 r.h = 1; 153 154 surface = SDL_RenderReadPixels(renderer, &r); 155 if (surface) { 156 /* Don't tonemap back to SDR, our source content was SDR */ 157 SDL_SetStringProperty(SDL_GetSurfaceProperties(surface), SDL_PROP_SURFACE_TONEMAP_OPERATOR_STRING, "*=1"); 158 159 if (SDL_ReadSurfacePixel(surface, 0, 0, &c->r, &c->g, &c->b, &c->a)) { 160 result = true; 161 } else { 162 SDL_Log("Couldn't read pixel: %s", SDL_GetError()); 163 } 164 SDL_DestroySurface(surface); 165 } else { 166 SDL_Log("Couldn't read back pixels: %s", SDL_GetError()); 167 } 168 return result; 169} 170 171static void DrawText(float x, float y, const char *fmt, ...) 172{ 173 char *text; 174 175 va_list ap; 176 va_start(ap, fmt); 177 SDL_vasprintf(&text, fmt, ap); 178 va_end(ap); 179 180 SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); 181 SDLTest_DrawString(renderer, x + 1.0f, y + 1.0f, text); 182 SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); 183 SDLTest_DrawString(renderer, x, y, text); 184 SDL_free(text); 185} 186 187static void RenderClearBackground(void) 188{ 189 /* Draw a 50% gray background. 190 * This will be darker when using sRGB colors and lighter using linear colors 191 */ 192 SDL_SetRenderDrawColor(renderer, 128, 128, 128, 255); 193 SDL_RenderClear(renderer); 194 195 /* Check the renderered pixels */ 196 SDL_Color c; 197 if (!ReadPixel(0, 0, &c)) { 198 return; 199 } 200 201 float x = TEXT_START_X; 202 float y = TEXT_START_Y; 203 DrawText(x, y, "%s %s", renderer_name, colorspace_name); 204 y += TEXT_LINE_ADVANCE; 205 DrawText(x, y, "Test: Clear 50%% Gray Background"); 206 y += TEXT_LINE_ADVANCE; 207 DrawText(x, y, "Background color written: 0x808080, read: 0x%.2x%.2x%.2x", c.r, c.g, c.b); 208 y += TEXT_LINE_ADVANCE; 209 if (c.r != 128) { 210 DrawText(x, y, "Incorrect background color, unknown reason"); 211 y += TEXT_LINE_ADVANCE; 212 } 213} 214 215static void RenderDrawBackground(void) 216{ 217 /* Draw a 50% gray background. 218 * This will be darker when using sRGB colors and lighter using linear colors 219 */ 220 SDL_SetRenderDrawColor(renderer, 128, 128, 128, 255); 221 SDL_RenderFillRect(renderer, NULL); 222 223 /* Check the renderered pixels */ 224 SDL_Color c; 225 if (!ReadPixel(0, 0, &c)) { 226 return; 227 } 228 229 float x = TEXT_START_X; 230 float y = TEXT_START_Y; 231 DrawText(x, y, "%s %s", renderer_name, colorspace_name); 232 y += TEXT_LINE_ADVANCE; 233 DrawText(x, y, "Test: Draw 50%% Gray Background"); 234 y += TEXT_LINE_ADVANCE; 235 DrawText(x, y, "Background color written: 0x808080, read: 0x%.2x%.2x%.2x", c.r, c.g, c.b); 236 y += TEXT_LINE_ADVANCE; 237 if (c.r != 128) { 238 DrawText(x, y, "Incorrect background color, unknown reason"); 239 y += TEXT_LINE_ADVANCE; 240 } 241} 242 243static SDL_Texture *CreateGrayTexture(void) 244{ 245 SDL_Texture *texture; 246 Uint8 pixels[4]; 247 248 /* Floating point textures are in the linear colorspace by default */ 249 texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_STATIC, 1, 1); 250 if (!texture) { 251 return NULL; 252 } 253 254 pixels[0] = 128; 255 pixels[1] = 128; 256 pixels[2] = 128; 257 pixels[3] = 255; 258 SDL_UpdateTexture(texture, NULL, pixels, sizeof(pixels)); 259 260 return texture; 261} 262 263static void RenderTextureBackground(void) 264{ 265 /* Fill the background with a 50% gray texture. 266 * This will be darker when using sRGB colors and lighter using linear colors 267 */ 268 SDL_Texture *texture = CreateGrayTexture(); 269 SDL_RenderTexture(renderer, texture, NULL, NULL); 270 SDL_DestroyTexture(texture); 271 272 /* Check the renderered pixels */ 273 SDL_Color c; 274 if (!ReadPixel(0, 0, &c)) { 275 return; 276 } 277 278 float x = TEXT_START_X; 279 float y = TEXT_START_Y; 280 DrawText(x, y, "%s %s", renderer_name, colorspace_name); 281 y += TEXT_LINE_ADVANCE; 282 DrawText(x, y, "Test: Fill 50%% Gray Texture"); 283 y += TEXT_LINE_ADVANCE; 284 DrawText(x, y, "Background color written: 0x808080, read: 0x%.2x%.2x%.2x", c.r, c.g, c.b); 285 y += TEXT_LINE_ADVANCE; 286 if (c.r != 128) { 287 DrawText(x, y, "Incorrect background color, unknown reason"); 288 y += TEXT_LINE_ADVANCE; 289 } 290} 291 292static void RenderTargetBackground(void) 293{ 294 /* Fill the background with a 50% gray texture. 295 * This will be darker when using sRGB colors and lighter using linear colors 296 */ 297 SDL_Texture *target = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_TARGET, 1, 1); 298 SDL_Texture *texture = CreateGrayTexture(); 299 300 /* Fill the render target with the gray texture */ 301 SDL_SetRenderTarget(renderer, target); 302 SDL_RenderTexture(renderer, texture, NULL, NULL); 303 SDL_DestroyTexture(texture); 304 305 /* Fill the output with the render target */ 306 SDL_SetRenderTarget(renderer, NULL); 307 SDL_RenderTexture(renderer, target, NULL, NULL); 308 SDL_DestroyTexture(target); 309 310 /* Check the renderered pixels */ 311 SDL_Color c; 312 if (!ReadPixel(0, 0, &c)) { 313 return; 314 } 315 316 float x = TEXT_START_X; 317 float y = TEXT_START_Y; 318 DrawText(x, y, "%s %s", renderer_name, colorspace_name); 319 y += TEXT_LINE_ADVANCE; 320 DrawText(x, y, "Test: Fill 50%% Gray Render Target"); 321 y += TEXT_LINE_ADVANCE; 322 DrawText(x, y, "Background color written: 0x808080, read: 0x%.2x%.2x%.2x", c.r, c.g, c.b); 323 y += TEXT_LINE_ADVANCE; 324 if (c.r != 128) { 325 DrawText(x, y, "Incorrect background color, unknown reason"); 326 y += TEXT_LINE_ADVANCE; 327 } 328} 329 330static void RenderBlendDrawing(void) 331{ 332 SDL_Color a = { 238, 70, 166, 255 }; /* red square */ 333 SDL_Color b = { 147, 255, 0, 255 }; /* green square */ 334 SDL_FRect rect; 335 336 /* Draw a green square blended over a red square 337 * This will have different effects based on whether sRGB colorspaces and sRGB vs linear blending is used. 338 */ 339 SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); 340 SDL_RenderClear(renderer); 341 rect.x = WINDOW_WIDTH / 3; 342 rect.y = 0; 343 rect.w = WINDOW_WIDTH / 3; 344 rect.h = WINDOW_HEIGHT; 345 SDL_SetRenderDrawColor(renderer, a.r, a.g, a.b, a.a); 346 SDL_RenderFillRect(renderer, &rect); 347 348 rect.x = 0; 349 rect.y = WINDOW_HEIGHT / 3; 350 rect.w = WINDOW_WIDTH; 351 rect.h = WINDOW_HEIGHT / 6; 352 SDL_SetRenderDrawColor(renderer, b.r, b.g, b.b, b.a); 353 SDL_RenderFillRect(renderer, &rect); 354 SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND); 355 SDL_SetRenderDrawColor(renderer, b.r, b.g, b.b, 128); 356 rect.y += WINDOW_HEIGHT / 6; 357 SDL_RenderFillRect(renderer, &rect); 358 359 SDL_Color ar, br, cr; 360 if (!ReadPixel(WINDOW_WIDTH / 2, 0, &ar) || 361 !ReadPixel(WINDOW_WIDTH / 2, WINDOW_HEIGHT / 3, &br) || 362 !ReadPixel(WINDOW_WIDTH / 2, WINDOW_HEIGHT / 2, &cr)) { 363 return; 364 } 365 366 float x = TEXT_START_X; 367 float y = TEXT_START_Y; 368 DrawText(x, y, "%s %s", renderer_name, colorspace_name); 369 y += TEXT_LINE_ADVANCE; 370 DrawText(x, y, "Test: Draw Blending"); 371 y += TEXT_LINE_ADVANCE; 372 if (cr.r == 199 && cr.g == 193 && cr.b == 121) { 373 DrawText(x, y, "Correct blend color, blending in linear space"); 374 } else if ((cr.r == 192 && cr.g == 163 && cr.b == 83) || 375 (cr.r == 191 && cr.g == 162 && cr.b == 82)) { 376 DrawText(x, y, "Correct blend color, blending in sRGB space"); 377 } else if (cr.r == 214 && cr.g == 156 && cr.b == 113) { 378 DrawText(x, y, "Incorrect blend color, blending in PQ space"); 379 } else { 380 DrawText(x, y, "Incorrect blend color, unknown reason"); 381 } 382 y += TEXT_LINE_ADVANCE; 383} 384 385static void RenderBlendTexture(void) 386{ 387 SDL_Color color_a = { 238, 70, 166, 255 }; /* red square */ 388 SDL_Color color_b = { 147, 255, 0, 255 }; /* green square */ 389 SDL_Texture *a; 390 SDL_Texture *b; 391 SDL_FRect rect; 392 393 /* Draw a green square blended over a red square 394 * This will have different effects based on whether sRGB colorspaces and sRGB vs linear blending is used. 395 */ 396 a = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_STATIC, 1, 1); 397 SDL_UpdateTexture(a, NULL, &color_a, sizeof(color_a)); 398 b = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_STATIC, 1, 1); 399 SDL_UpdateTexture(b, NULL, &color_b, sizeof(color_b)); 400 401 SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); 402 SDL_RenderClear(renderer); 403 rect.x = WINDOW_WIDTH / 3; 404 rect.y = 0; 405 rect.w = WINDOW_WIDTH / 3; 406 rect.h = WINDOW_HEIGHT; 407 SDL_RenderTexture(renderer, a, NULL, &rect); 408 409 rect.x = 0; 410 rect.y = WINDOW_HEIGHT / 3; 411 rect.w = WINDOW_WIDTH; 412 rect.h = WINDOW_HEIGHT / 6; 413 SDL_RenderTexture(renderer, b, NULL, &rect); 414 rect.y += WINDOW_HEIGHT / 6; 415 SDL_SetTextureBlendMode(b, SDL_BLENDMODE_BLEND); 416 SDL_SetTextureAlphaModFloat(b, 128 / 255.0f); 417 SDL_RenderTexture(renderer, b, NULL, &rect); 418 419 SDL_Color ar, br, cr; 420 if (!ReadPixel(WINDOW_WIDTH / 2, 0, &ar) || 421 !ReadPixel(WINDOW_WIDTH / 2, WINDOW_HEIGHT / 3, &br) || 422 !ReadPixel(WINDOW_WIDTH / 2, WINDOW_HEIGHT / 2, &cr)) { 423 return; 424 } 425 426 float x = TEXT_START_X; 427 float y = TEXT_START_Y; 428 DrawText(x, y, "%s %s", renderer_name, colorspace_name); 429 y += TEXT_LINE_ADVANCE; 430 DrawText(x, y, "Test: Texture Blending"); 431 y += TEXT_LINE_ADVANCE; 432 if (cr.r == 199 && cr.g == 193 && cr.b == 121) { 433 DrawText(x, y, "Correct blend color, blending in linear space"); 434 } else if ((cr.r == 192 && cr.g == 163 && cr.b == 83) || 435 (cr.r == 191 && cr.g == 162 && cr.b == 82)) { 436 DrawText(x, y, "Correct blend color, blending in sRGB space"); 437 } else { 438 DrawText(x, y, "Incorrect blend color, unknown reason"); 439 } 440 y += TEXT_LINE_ADVANCE; 441 442 SDL_DestroyTexture(a); 443 SDL_DestroyTexture(b); 444} 445 446static void DrawGradient(float x, float y, float width, float height, float start, float end) 447{ 448 float xy[8]; 449 const int xy_stride = 2 * sizeof(float); 450 SDL_FColor color[4]; 451 const int color_stride = sizeof(SDL_FColor); 452 const int num_vertices = 4; 453 const int indices[6] = { 0, 1, 2, 0, 2, 3 }; 454 const int num_indices = 6; 455 const int size_indices = 4; 456 float minx, miny, maxx, maxy; 457 SDL_FColor min_color = { start, start, start, 1.0f }; 458 SDL_FColor max_color = { end, end, end, 1.0f }; 459 460 minx = x; 461 miny = y; 462 maxx = minx + width; 463 maxy = miny + height; 464 465 xy[0] = minx; 466 xy[1] = miny; 467 xy[2] = maxx; 468 xy[3] = miny; 469 xy[4] = maxx; 470 xy[5] = maxy; 471 xy[6] = minx; 472 xy[7] = maxy; 473 474 color[0] = min_color; 475 color[1] = max_color; 476 color[2] = max_color; 477 color[3] = min_color; 478 479 SDL_RenderGeometryRaw(renderer, NULL, xy, xy_stride, color, color_stride, NULL, 0, num_vertices, indices, num_indices, size_indices); 480} 481 482static void RenderGradientDrawing(void) 483{ 484 SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); 485 SDL_RenderClear(renderer); 486 487 float x = TEXT_START_X; 488 float y = TEXT_START_Y; 489 DrawText(x, y, "%s %s", renderer_name, colorspace_name); 490 y += TEXT_LINE_ADVANCE; 491 DrawText(x, y, "Test: Draw SDR and HDR gradients"); 492 y += TEXT_LINE_ADVANCE; 493 494 y += TEXT_LINE_ADVANCE; 495 496 DrawText(x, y, "SDR gradient"); 497 y += TEXT_LINE_ADVANCE; 498 DrawGradient(x, y, WINDOW_WIDTH - 2 * x, 64.0f, 0.0f, 1.0f); 499 y += 64.0f; 500 501 y += TEXT_LINE_ADVANCE; 502 y += TEXT_LINE_ADVANCE; 503 504 if (HDR_headroom > 1.0f) { 505 DrawText(x, y, "HDR gradient"); 506 } else { 507 DrawText(x, y, "No HDR headroom, HDR and SDR gradient are the same"); 508 } 509 y += TEXT_LINE_ADVANCE; 510 /* Drawing is in the sRGB colorspace, so we need to use the color scale, which is applied in linear space, to get into high dynamic range */ 511 SDL_SetRenderColorScale(renderer, HDR_headroom); 512 DrawGradient(x, y, WINDOW_WIDTH - 2 * x, 64.0f, 0.0f, 1.0f); 513 SDL_SetRenderColorScale(renderer, 1.0f); 514 y += 64.0f; 515} 516 517static SDL_Texture *CreateGradientTexture(int width, float start, float end) 518{ 519 SDL_Texture *texture; 520 float *pixels; 521 522 /* Floating point textures are in the linear colorspace by default */ 523 texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA128_FLOAT, SDL_TEXTUREACCESS_STATIC, width, 1); 524 if (!texture) { 525 return NULL; 526 } 527 528 pixels = (float *)SDL_malloc(width * sizeof(float) * 4); 529 if (pixels) { 530 int i; 531 float length = (end - start); 532 533 for (i = 0; i < width; ++i) { 534 float v = (start + (length * i) / width); 535 pixels[i * 4 + 0] = v; 536 pixels[i * 4 + 1] = v; 537 pixels[i * 4 + 2] = v; 538 pixels[i * 4 + 3] = 1.0f; 539 } 540 SDL_UpdateTexture(texture, NULL, pixels, width * sizeof(float) * 4); 541 SDL_free(pixels); 542 } 543 return texture; 544} 545 546static void DrawGradientTexture(float x, float y, float width, float height, float start, float end) 547{ 548 SDL_FRect rect = { x, y, width, height }; 549 SDL_Texture *texture = CreateGradientTexture((int)width, start, end); 550 SDL_RenderTexture(renderer, texture, NULL, &rect); 551 SDL_DestroyTexture(texture); 552} 553 554static void RenderGradientTexture(void) 555{ 556 SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); 557 SDL_RenderClear(renderer); 558 559 float x = TEXT_START_X; 560 float y = TEXT_START_Y; 561 DrawText(x, y, "%s %s", renderer_name, colorspace_name); 562 y += TEXT_LINE_ADVANCE; 563 DrawText(x, y, "Test: Texture SDR and HDR gradients"); 564 y += TEXT_LINE_ADVANCE; 565 566 y += TEXT_LINE_ADVANCE; 567 568 DrawText(x, y, "SDR gradient"); 569 y += TEXT_LINE_ADVANCE; 570 DrawGradientTexture(x, y, WINDOW_WIDTH - 2 * x, 64.0f, 0.0f, 1.0f); 571 y += 64.0f; 572 573 y += TEXT_LINE_ADVANCE; 574 y += TEXT_LINE_ADVANCE; 575 576 if (HDR_headroom > 1.0f) { 577 DrawText(x, y, "HDR gradient"); 578 } else { 579 DrawText(x, y, "No HDR headroom, HDR and SDR gradient are the same"); 580 } 581 y += TEXT_LINE_ADVANCE; 582 /* The gradient texture is in the linear colorspace, so we can use the HDR_headroom value directly */ 583 DrawGradientTexture(x, y, WINDOW_WIDTH - 2 * x, 64.0f, 0.0f, HDR_headroom); 584 y += 64.0f; 585} 586 587static void loop(void) 588{ 589 SDL_Event event; 590 591 /* Check for events */ 592 while (SDL_PollEvent(&event)) { 593 if (event.type == SDL_EVENT_KEY_DOWN) { 594 switch (event.key.key) { 595 case SDLK_ESCAPE: 596 done = 1; 597 break; 598 case SDLK_SPACE: 599 case SDLK_RIGHT: 600 NextStage(); 601 break; 602 case SDLK_LEFT: 603 PrevStage(); 604 break; 605 case SDLK_DOWN: 606 NextRenderer(); 607 break; 608 case SDLK_UP: 609 PrevRenderer(); 610 break; 611 default: 612 break; 613 } 614 } else if (event.type == SDL_EVENT_WINDOW_HDR_STATE_CHANGED) { 615 UpdateHDRState(); 616 } else if (event.type == SDL_EVENT_QUIT) { 617 done = 1; 618 } 619 } 620 621 if (renderer) { 622 SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); 623 SDL_RenderClear(renderer); 624 625 switch (stage_index) { 626 case StageClearBackground: 627 RenderClearBackground(); 628 break; 629 case StageDrawBackground: 630 RenderDrawBackground(); 631 break; 632 case StageTextureBackground: 633 RenderTextureBackground(); 634 break; 635 case StageTargetBackground: 636 RenderTargetBackground(); 637 break; 638 case StageBlendDrawing: 639 RenderBlendDrawing(); 640 break; 641 case StageBlendTexture: 642 RenderBlendTexture(); 643 break; 644 case StageGradientDrawing: 645 RenderGradientDrawing(); 646 break; 647 case StageGradientTexture: 648 RenderGradientTexture(); 649 break; 650 } 651 652 SDL_RenderPresent(renderer); 653 } 654 SDL_Delay(100); 655 656#ifdef SDL_PLATFORM_EMSCRIPTEN 657 if (done) { 658 emscripten_cancel_main_loop(); 659 } 660#endif 661} 662 663static void LogUsage(const char *argv0) 664{ 665 SDL_Log("Usage: %s [--renderer renderer] [--colorspace colorspace]", argv0); 666} 667 668int main(int argc, char *argv[]) 669{ 670 int return_code = 1; 671 int i; 672 673 for (i = 1; i < argc; ++i) { 674 if (SDL_strcmp(argv[i], "--renderer") == 0) { 675 if (argv[i + 1]) { 676 renderer_name = argv[i + 1]; 677 ++i; 678 } else { 679 LogUsage(argv[0]); 680 goto quit; 681 } 682 } else if (SDL_strcmp(argv[i], "--colorspace") == 0) { 683 if (argv[i + 1]) { 684 colorspace_name = argv[i + 1]; 685 if (SDL_strcasecmp(colorspace_name, "sRGB") == 0) { 686 colorspace = SDL_COLORSPACE_SRGB; 687 } else if (SDL_strcasecmp(colorspace_name, "linear") == 0) { 688 colorspace = SDL_COLORSPACE_SRGB_LINEAR; 689/* Not currently supported 690 } else if (SDL_strcasecmp(colorspace_name, "HDR10") == 0) { 691 colorspace = SDL_COLORSPACE_HDR10; 692*/ 693 } else { 694 SDL_Log("Unknown colorspace %s", argv[i + 1]); 695 goto quit; 696 } 697 ++i; 698 } else { 699 LogUsage(argv[0]); 700 goto quit; 701 } 702 } else { 703 LogUsage(argv[0]); 704 goto quit; 705 } 706 } 707 708 window = SDL_CreateWindow("SDL colorspace test", WINDOW_WIDTH, WINDOW_HEIGHT, 0); 709 if (!window) { 710 SDL_Log("Couldn't create window: %s", SDL_GetError()); 711 return_code = 2; 712 goto quit; 713 } 714 715 renderer_count = SDL_GetNumRenderDrivers(); 716 SDL_Log("There are %d render drivers:", renderer_count); 717 for (i = 0; i < renderer_count; ++i) { 718 const char *name = SDL_GetRenderDriver(i); 719 720 if (renderer_name && SDL_strcasecmp(renderer_name, name) == 0) { 721 renderer_index = i; 722 } 723 SDL_Log(" %s", name); 724 } 725 CreateRenderer(); 726 727 /* Main render loop */ 728 done = 0; 729 730#ifdef SDL_PLATFORM_EMSCRIPTEN 731 emscripten_set_main_loop(loop, 0, 1); 732#else 733 while (!done) { 734 loop(); 735 } 736#endif 737 return_code = 0; 738quit: 739 SDL_DestroyRenderer(renderer); 740 SDL_DestroyWindow(window); 741 SDL_Quit(); 742 return return_code; 743} 744[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.