In this section, we will examine the program that changes the texture pixel colors created from an image file with the .png extension with the SDL_SetTextureColorMod() function.
When the program runs, in addition to the basic operations, the following operations occur:
The program runss as follows:
SDL_SetTextureColorMod() function
The SDL_SetTextureColorMod() function sets the color modulation on an SDL_Texture. This process recreates the color channels of an image by multiplying them by a specific color value. This allows you to dynamically change the color tone of the image.
bool SDL_SetTextureColorMod(SDL_Texture *texture, Uint8 r, Uint8 g, Uint8 b);
texture: The SDL_Texture object to set.
r: Red color value (a number in the range of 0-255).
g: Green color value (a number in the range of 0-255).
b: Blue color value (a number in the range of 0-255).
This function multiplies all color channels on the SDL_Texture with the specified color values and recreates them. Color modulation is performed using the following formula:
Color modulation allows us to change the pixel colors of textures. When we perform operations with the texture and RGB parameters that we pass to the SDL_SetTextureColorMod() function, each value that is different from 255 in the SDL_SetTextureColorMod() RGB values changes the corresponding R, G or B value for each pixel in the texture.
The R, G or B value for each pixel in the texture is determined again according to the following formula:
A pixel's new R value = A pixel's old R value * (SDL_SetTextureColorMod() R value / 255)
If we assume that the SDL_SetTextureColorMod() R value is 100 and that the R value of any pixel is 200:
A pixel's new R value = 200 * (100/255) = 78.43
as is calculated.
If 255 is used for any color value in the SDL_SetTextureColorMod() function, there will be no change in that color in any pixel in the texture. In this case, if the R value of SDL_SetTextureColorMod() is 255, the value of the pixel will not change since the neutral value of the multiplication in the parentheses will be 1.
main.c file content will be as follows:
#include <stdio.h>
#include <SDL3/SDL.h>
#include <SDL3_image/SDL_image.h>
// Window width and height
#define WINDOW_WIDTH 640
#define WINDOW_HEIGHT 480
// Global variables
int is_running = false; // Variable that controls the execution of the main loop of the program
SDL_Window *window = NULL; // Main window variable
SDL_Texture *texture = NULL; // Texture variable
SDL_Renderer *renderer = NULL; // Renderer variable
bool r, g, b; // Color variables
int level_rgb; // RGB level variable
// Function prototypes
int init_window(void); // Create window and renderer
void init_vals(void); // Initialize values
void load_img(void); // Load image to texture
void process_event(void); // Process events
void update_screen(); // Update values
void draw_screen(void); // Draw screen
void destroy_window(void); // Destroy window
int main(int argc, char* argv[])
{
// Create window and renderer
is_running = init_window();
// Initialize values
init_vals();
// Load .png file to texture
load_img();
// Main loop
while (is_running) {
process_event(); // Processing SDL events (Here keyboard inputs).
update_screen(); // Updating variables
draw_screen(); // Drawing objects on the window (Rendering)
}
// Destroy renderer and SDL window
destroy_window();
return 0;
}
// Create window and renderer
int init_window(void)
{
// Initialize the SDL library.
if(SDL_Init(SDL_INIT_VIDEO) == false) {
SDL_Log("SDL init error: %s\n", SDL_GetError());
return false;
}
// Create a window and a 2D rendering context for the window.
if(!SDL_CreateWindowAndRenderer("SDL3 window - Color modulation", WINDOW_WIDTH, WINDOW_HEIGHT, 0, &window, &renderer)) {
return false;
}
return true;
}
// Initialization function that runs only once at the beginning of the program
void init_vals(void)
{
r = true;
g = true;
b = true;
level_rgb = 255;
}
// Load image to texture
void load_img(void)
{
// Load image into a GPU texture.
texture = IMG_LoadTexture(renderer, "color_mod.png");
if(texture == NULL) {
SDL_Log("Load texture error: %s\n", SDL_GetError());
}
}
// Function to control SDL events and process keyboard inputs
void process_event(void)
{
SDL_Event event;
// Creating a loop to process user inputs
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_EVENT_QUIT: // Logout action by the user (x button at the top right of the window)
is_running = false; // Terminates the execution of the program main loop.
break;
case SDL_EVENT_KEY_DOWN: // Indicate that a key was pressed.
switch (event.key.key) {
case SDLK_R:
r = !r;
break;
case SDLK_G:
g = !g;
break;
case SDLK_B:
b = !b;
break;
case SDLK_F:
r = true;
g = true;
b = true;
break;
case SDLK_UP:
if(level_rgb<255) level_rgb+=5;
break;
case SDLK_DOWN:
if(level_rgb>0) level_rgb-=5;
break;
case SDLK_ESCAPE:
is_running = false;
break;
}
break;
}
}
}
// Updates objects in the main window
void update_screen(void)
{
int r_color = r ? level_rgb : 255;
int g_color = g ? level_rgb : 255;
int b_color = b ? level_rgb : 255;
char cdizi[100];
sprintf(cdizi, "Color modulation - SDL_SetTextureColorMod(texture, %d, %d, %d) R: %s G: %s B: %s",
r_color, g_color, b_color, r ? "On" : "Off", g ? "On" : "Off", b ? "On" : "Off");
SDL_SetWindowTitle(window, cdizi);
}
// Render function used to draw game objects in the main window
void draw_screen(void)
{
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); // Set the color used for drawing operations.
SDL_RenderClear(renderer); // Clear the current rendering target with the drawing color.
// Recreates an texture by multiplying its color channels by a specific color value.
SDL_SetTextureColorMod(texture, r ? level_rgb : 255, g ? level_rgb : 255, b ? level_rgb : 255);
SDL_RenderTexture(renderer, texture, NULL, NULL);
// Loading all objects drawn one by one to the back buffer to the front buffer at once and loading them onto the screen
// This process prevents each drawn object from being displayed on the screen one by one.
SDL_RenderPresent(renderer); // Update on screen all operations performed since the previous call
}
// Destroy Renderer and SDL window, exit from SDL3
void destroy_window(void)
{
SDL_DestroyTexture(texture);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
}