SDL: examples: Add blending example (#15657)

From c9e2e732b674679f4bc5caa0e36c192411cb6fc8 Mon Sep 17 00:00:00 2001
From: Ahmed Lyas <[EMAIL REDACTED]>
Date: Wed, 20 May 2026 04:05:23 +0000
Subject: [PATCH] examples: Add blending example (#15657)

---
 .../renderer/20-blending/20-blending.vcxproj  |  12 +
 examples/CMakeLists.txt                       |   1 +
 examples/renderer/20-blending/README.txt      |   5 +
 examples/renderer/20-blending/blending.c      | 234 ++++++++++++++++++
 .../renderer/20-blending/onmouseover.webp     | Bin 0 -> 150910 bytes
 examples/renderer/20-blending/thumbnail.png   | Bin 0 -> 11663 bytes
 6 files changed, 252 insertions(+)
 create mode 100644 VisualC/examples/renderer/20-blending/20-blending.vcxproj
 create mode 100644 examples/renderer/20-blending/README.txt
 create mode 100644 examples/renderer/20-blending/blending.c
 create mode 100644 examples/renderer/20-blending/onmouseover.webp
 create mode 100644 examples/renderer/20-blending/thumbnail.png

diff --git a/VisualC/examples/renderer/20-blending/20-blending.vcxproj b/VisualC/examples/renderer/20-blending/20-blending.vcxproj
new file mode 100644
index 0000000000000..ff89bd3e0d133
--- /dev/null
+++ b/VisualC/examples/renderer/20-blending/20-blending.vcxproj
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{B938A3C0-6C64-4734-B705-ED3642C01B47}</ProjectGuid>
+  </PropertyGroup>
+  <Import Project="$(SolutionDir)\examples\Examples.props" />
+  <ItemGroup>
+    <None Include="$(SolutionDir)\..\examples\renderer\20-blending\README.txt" />
+    <ClCompile Include="$(SolutionDir)\..\examples\renderer\20-blending\blending.c" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project>
\ No newline at end of file
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index ca88933009019..752eb640e3de1 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -142,6 +142,7 @@ add_sdl_example_executable(renderer-cliprect SOURCES renderer/15-cliprect/clipre
 add_sdl_example_executable(renderer-read-pixels SOURCES renderer/17-read-pixels/read-pixels.c DATAFILES ${CMAKE_CURRENT_SOURCE_DIR}/../test/sample.png)
 add_sdl_example_executable(renderer-debug-text SOURCES renderer/18-debug-text/debug-text.c)
 add_sdl_example_executable(renderer-affine-textures SOURCES renderer/19-affine-textures/affine-textures.c DATAFILES ${CMAKE_CURRENT_SOURCE_DIR}/../test/sample.png)
+add_sdl_example_executable(renderer-blending SOURCES renderer/20-blending/blending.c)
 add_sdl_example_executable(audio-simple-playback SOURCES audio/01-simple-playback/simple-playback.c)
 add_sdl_example_executable(audio-simple-playback-callback SOURCES audio/02-simple-playback-callback/simple-playback-callback.c)
 add_sdl_example_executable(audio-load-wav SOURCES audio/03-load-wav/load-wav.c DATAFILES ${CMAKE_CURRENT_SOURCE_DIR}/../test/sample.wav)
diff --git a/examples/renderer/20-blending/README.txt b/examples/renderer/20-blending/README.txt
new file mode 100644
index 0000000000000..fb7ae5333bee7
--- /dev/null
+++ b/examples/renderer/20-blending/README.txt
@@ -0,0 +1,5 @@
+This example uses SDL_SetTextureBlendMode() to apply blending to textures,
+and SDL_ComposeCustomBlendMode() to create a custom blend mode.
+
+You can also use SDL_SetRenderDrawBlendMode() to apply blending to the
+entire renderer, but it only affects filled rects and lines, not texture
diff --git a/examples/renderer/20-blending/blending.c b/examples/renderer/20-blending/blending.c
new file mode 100644
index 0000000000000..53701fb9698c4
--- /dev/null
+++ b/examples/renderer/20-blending/blending.c
@@ -0,0 +1,234 @@
+/*
+ * Blending combines a source color 'src',
+ * with the pixels already on the screen 'dst',
+ * to produce transparency and other visual effects.
+ *
+ * formula: dst := (a * dst) op (b * src)
+ *
+ * where:
+ *     dst: existed pixel on the screen.
+ *     src: new pixel.
+ *     a:   dst factor.
+ *     b:   src factor.
+ *     op:  blend operation (usually addition).
+ *
+ * In graphics programming, color and alpha are usually blended separately:
+ *     dstRGB := (a * srcRGB) op (b * dstRGB)
+ *     dstA   := (c * srcA)   op (d * dstA)
+ *
+ * This example uses SDL_SetTextureBlendMode() to apply blending to textures,
+ * and uses SDL_ComposeCustomBlendMode() to create a custom blend mode.
+ *
+ * You can also use SDL_SetRenderDrawBlendMode() to apply blending to the
+ * entire renderer, but it only affects filled rects and lines, not textures.
+ *
+ * This code is public domain. Feel free to use it for any purpose!
+ */
+
+
+#define SDL_MAIN_USE_CALLBACKS 1
+#include <SDL3/SDL.h>
+#include <SDL3/SDL_main.h>
+
+#define WINDOW_WIDTH  640
+#define WINDOW_HEIGHT 480
+
+/* UI Constants */
+#define ROWS 2
+#define COLS 3
+#define GRID_SIZE    ((WINDOW_WIDTH - 1) / 18.0f)
+#define PANEL_SIZE   (GRID_SIZE * 4)
+#define ROW_OFFSET   ((WINDOW_HEIGHT - ROWS * PANEL_SIZE) / 4)
+#define COL_OFFSET   (GRID_SIZE * COLS)
+#define RECT_SIZE     50.0f
+#define RED_OFFSET   (GRID_SIZE)
+#define GREEN_OFFSET (RECT_SIZE / 3 + GRID_SIZE)
+#define BLUE_OFFSET  (RECT_SIZE * 2 / 3 + GRID_SIZE)
+
+static SDL_FRect     panels[ROWS*COLS];
+static SDL_Window    *window             = NULL;
+static SDL_Renderer  *renderer           = NULL;
+static SDL_Texture   *red_rect_texture   = NULL;
+static SDL_Texture   *green_rect_texture = NULL;
+static SDL_Texture   *blue_rect_texture  = NULL;
+static Uint8         alpha               = 255;
+static SDL_BlendMode blend_modes[]       = {
+    /*The default no blending: dstRGB := srcRGB
+                                dstA  := srcA   */
+    SDL_BLENDMODE_NONE,
+
+    /* Alpha blending: dstRGB := srcA * srcRGB + (1 - srcA) * dstRGB
+                       dstA   := srcA          + (1 - srcA) * dstA   */
+    SDL_BLENDMODE_BLEND,
+
+    /* Additive blending: dstRGB := srcRGB + dstRGB
+                          dstA   := srcA   + dstA   */
+    SDL_BLENDMODE_ADD,
+
+    /* Modulate blending: dstRGB := srcRGB * dstRGB
+                          dstA   := dstA            */
+    SDL_BLENDMODE_MOD,
+
+    /* Multiply blending: dstRGB := srcRGB * dstRGB + (1 - srcA) * dstRGB
+                          dstA   := dstA                                  */
+    SDL_BLENDMODE_MUL,
+
+    /* Our custom blending 'Screen Blending': dstRGB := 1 - (1 - dstRGB) * (1 - srcRGB)
+                                              dstA   := dstA                            */
+    0
+};
+static const char *blend_mode_names[] = { "NONE", "BLEND", "ADD", "MOD", "MUL", "SCREEN \"CUSTOM\"" };
+
+SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
+{
+    SDL_Surface *surface  = NULL;
+
+    SDL_SetAppMetadata("Example Blending", "1.0", "com.example.blending");
+    if (!SDL_Init(SDL_INIT_VIDEO)) {
+        SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
+        return SDL_APP_FAILURE;
+    }
+    if (!SDL_CreateWindowAndRenderer("examples/renderer/blending", WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_RESIZABLE, &window, &renderer)) {
+        SDL_Log("Couldn't create window/renderer: %s", SDL_GetError());
+        return SDL_APP_FAILURE;
+    }
+    SDL_SetRenderLogicalPresentation(renderer, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_LOGICAL_PRESENTATION_LETTERBOX);
+
+    int row = 0;
+    int col = 0;
+    for (row = 0; row < ROWS; row++)
+    {
+        for (col = 0; col < COLS; col++)
+        {
+            panels[col + row*COLS] = (SDL_FRect){ col*PANEL_SIZE + col*COL_OFFSET, row*PANEL_SIZE + (row+1)*ROW_OFFSET, PANEL_SIZE, PANEL_SIZE };
+        }
+    }
+
+    /* Create 'screen blend' mode */
+    blend_modes[ROWS*COLS - 1] = SDL_ComposeCustomBlendMode(
+        SDL_BLENDFACTOR_ONE_MINUS_DST_COLOR, /* srcRGB factor    := (1 - dstRGB) */
+        SDL_BLENDFACTOR_ONE,                 /* dstRGB factor    := 1            */
+        SDL_BLENDOPERATION_ADD,              /* RGB    operation := +            */
+        SDL_BLENDFACTOR_ZERO,                /* srcA   factor    := 0            */
+        SDL_BLENDFACTOR_ONE,                 /* dstA   factor    := dstA         */
+        SDL_BLENDOPERATION_ADD               /* A      operation := +            */
+    );
+
+    surface = SDL_CreateSurface((int)RECT_SIZE, (int)RECT_SIZE, SDL_PIXELFORMAT_RGBA8888);
+    if (!surface) {
+        SDL_Log("Couldn't create surface: %s", SDL_GetError());
+        return SDL_APP_FAILURE;
+    }
+
+    SDL_FillSurfaceRect(surface, NULL, 0xFF0000FF); /* Red */
+    red_rect_texture = SDL_CreateTextureFromSurface(renderer, surface);
+    if (!red_rect_texture) {
+        SDL_Log("Couldn't create texture: %s", SDL_GetError());
+        return SDL_APP_FAILURE;
+    }
+
+    SDL_FillSurfaceRect(surface, NULL, 0x00FF00FF); /* Green */
+    green_rect_texture = SDL_CreateTextureFromSurface(renderer, surface);
+    if (!green_rect_texture) {
+        SDL_Log("Couldn't create texture: %s", SDL_GetError());
+        return SDL_APP_FAILURE;
+    }
+
+    SDL_FillSurfaceRect(surface, NULL, 0x0000FFFF); /* Blue */
+    blue_rect_texture = SDL_CreateTextureFromSurface(renderer, surface);
+    if (!blue_rect_texture) {
+        SDL_Log("Couldn't create texture: %s", SDL_GetError());
+        return SDL_APP_FAILURE;
+    }
+
+    SDL_DestroySurface(surface);
+
+    return SDL_APP_CONTINUE;
+}
+
+SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event)
+{
+    if (event->type == SDL_EVENT_QUIT) {
+        return SDL_APP_SUCCESS;
+    }
+    if (event->type == SDL_EVENT_KEY_DOWN) {
+        /* UP arrow increase alpha */
+        if (event->key.key == SDLK_UP && alpha <= 255-8) alpha += 8;
+        /* DOWN arrow decrease alpha */
+        if (event->key.key == SDLK_DOWN && alpha >= 8)   alpha -= 8;
+    }
+    return SDL_APP_CONTINUE;
+}
+
+SDL_AppResult SDL_AppIterate(void *appstate)
+{
+    SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE);
+    SDL_RenderClear(renderer);
+
+    int i = 0;
+    float x;
+    float y;
+    /* Render checkerboard panels */
+    for (i = 0; i < ROWS*COLS; i++)
+    {
+        /* Loop through the panel pixels */
+        for (y = panels[i].y; y < PANEL_SIZE + panels[i].y; y += GRID_SIZE)
+        {
+            for (x = panels[i].x; x < PANEL_SIZE + panels[i].x; x += GRID_SIZE)
+            {
+                SDL_FRect grid = { x, y, GRID_SIZE, GRID_SIZE };
+                bool dark      = (int)(x/GRID_SIZE + y/GRID_SIZE) % 2;
+
+                if (dark) SDL_SetRenderDrawColor(renderer, 70, 70, 70, 255);    /* Darker color  */
+                else      SDL_SetRenderDrawColor(renderer, 110, 110, 110, 255); /* Lighter color */
+
+                SDL_RenderFillRect(renderer, &grid);
+            }
+        }
+
+        /* Label the blend mode */
+        SDL_SetRenderDrawColor(renderer, 255, 255, 255, SDL_ALPHA_OPAQUE);
+        SDL_RenderDebugText(renderer, panels[i].x, panels[i].y - 15, blend_mode_names[i]);
+    }
+
+    /* Render panels */
+    SDL_RenderRects(renderer, panels, ROWS*COLS);
+
+    /* Render UI text */
+    SDL_RenderDebugText(renderer, WINDOW_WIDTH - 176, WINDOW_HEIGHT - 20, "UP/DOWN: CHANGE ALPHA");
+    SDL_RenderDebugTextFormat(renderer, 0, WINDOW_HEIGHT - 20, "ALPHA: %d", alpha);
+
+    /* Update textures alpha mod */
+    SDL_SetTextureAlphaMod(red_rect_texture,   alpha);
+    SDL_SetTextureAlphaMod(green_rect_texture, alpha);
+    SDL_SetTextureAlphaMod(blue_rect_texture,  alpha);
+
+    /* Render panels */
+    for (i = 0; i < ROWS*COLS; i++) {
+        /* Update rects destination */
+        SDL_FRect red_dst   = { panels[i].x + RED_OFFSET,   panels[i].y + RED_OFFSET,   RECT_SIZE, RECT_SIZE };
+        SDL_FRect green_dst = { panels[i].x + GREEN_OFFSET, panels[i].y + GREEN_OFFSET, RECT_SIZE, RECT_SIZE };
+        SDL_FRect blue_dst  = { panels[i].x + BLUE_OFFSET,  panels[i].y + BLUE_OFFSET,  RECT_SIZE, RECT_SIZE };
+
+        /* Apply the current blend mode */
+        SDL_SetTextureBlendMode(red_rect_texture,   blend_modes[i]);
+        SDL_SetTextureBlendMode(green_rect_texture, blend_modes[i]);
+        SDL_SetTextureBlendMode(blue_rect_texture,  blend_modes[i]);
+
+        /* Render textures */
+        SDL_RenderTexture(renderer, red_rect_texture,   NULL, &red_dst);
+        SDL_RenderTexture(renderer, green_rect_texture, NULL, &green_dst);
+        SDL_RenderTexture(renderer, blue_rect_texture,  NULL, &blue_dst);
+    }
+
+    SDL_RenderPresent(renderer);
+
+    return SDL_APP_CONTINUE;
+}
+
+void SDL_AppQuit(void *appstate, SDL_AppResult result)
+{
+    SDL_DestroyTexture(red_rect_texture);
+    SDL_DestroyTexture(green_rect_texture);
+    SDL_DestroyTexture(blue_rect_texture);
+}
diff --git a/examples/renderer/20-blending/onmouseover.webp b/examples/renderer/20-blending/onmouseover.webp
new file mode 100644
index 0000000000000000000000000000000000000000..dc1e2d94df3d9cbc86d10cac92202a2352af462d
GIT binary patch
literal 150910
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

(Patch may be truncated, please check the link at the top of this post.)