Warning: Undefined array key "HTTP_ACCEPT_LANGUAGE" in /var/www/vhosts/bilgigunlugum.net/httpdocs/index.php on line 43
SDL Game Programming

SDL3 Oyun Programlama sayfalarımız yayında...

Ana sayfa > Oyun programlama > SDL3 programming > Changing pixel color

Changing pixel color

In this section, we will examine a program that makes the background color of an image transparent using the pixel method and loads it into the main window.

When the program runs, in addition to the basic operations, the following operations occur:

  1. At the beginning of the program, the following global variables are defined:
    • SDL_Texture *texture_img: Texture variable
    • int image_width: Image width
    • int image_height: Image height
  2. In the init_vars() function, initial values ​​are assigned to global variables.
  3. In the load_img() function,
    • An image file is loaded with the IMG_Load() function and transferred to the surface_img surface variable.
    • The surface width and height are transferred to the image_width and image_height variables.
    • surface_img->pixels values ​​are assigned to the pixels pointer.
    • The SDL_MapSurfaceRGBA() function, which maps an RGBA quad to the pixel value of a surface, loads the background color of the image loaded into the surface_img surface variable to the colorKey variable and the black color to the transparent variable.
    • The transparent variable value is assigned to pixel values ​​with the colorKey color using the indexing method with the pixels pointer.
    • A texture is created from the surface with the SDL_CreateTextureFromSurface() function and assigned to the texture_img variable.
    • The surface_img surface variable is destroyed with the SDL_DestroySurface() function.
  4. Within the draw_screen() function, the texture is transferred to the main window with the SDL_RenderTexture() function.

main.c file content will be as follows:


#include <stdio.h>
#include <stdlib.h>
#include <SDL3/SDL.h>
#include <SDL3_image/SDL_image.h>

#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_img = NULL;  // Texture variable
SDL_Renderer *renderer = NULL;    // Renderer variable

int image_width;                  // Image width
int image_height;                 // Image height

// Function prototypes
int init_window(void);     // Create window and renderer
void init_vars(void);      // Initialize variables
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 variables
    init_vars();

    // 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", WINDOW_WIDTH, WINDOW_HEIGHT, 0, &window, &renderer)) {
       return false;
    }

    return true;
}

// Load image to texture
void load_img(void)
{
	// Load image
	SDL_Surface *surface_img = IMG_Load("front.png");
	if(surface_img == NULL){
	   SDL_Log("Unable to load image! SDL_image Error: %s\n", SDL_GetError());
	   SDL_Log("Unable to load texture!\n");
	}
	else {
	   // Get image dimensions
	   image_width = surface_img->w;
       image_height = surface_img->h;

	   // Get pixel data
	   Uint32* pixels = surface_img->pixels;
	   int pixelCount = (surface_img->pitch / 4) * image_height;

       // Map colors
       Uint32 colorKey = SDL_MapSurfaceRGBA(surface_img, 255, 240, 70, 255);
       Uint32 transparent = SDL_MapSurfaceRGBA(surface_img, 0, 0, 0, 0);

       // Color key pixels
       for(int i=0; i<pixelCount; i++) {
		   if(pixels[i] == colorKey) {
			  pixels[i] = transparent;
		   }
	   }

       // Create texture from surface pixels
       texture_img = SDL_CreateTextureFromSurface(renderer, surface_img);

       if(texture_img == NULL) {
		  SDL_Log("Unable to create texture from loaded pixels! SDL Error: %s\n", SDL_GetError());
		  SDL_Log("Unable to load texture from surface!\n");
	   }
       else	{
		  // Get image dimensions
	      image_width = surface_img->w;
          image_height = surface_img->h;
	   }

       SDL_DestroySurface(surface_img);
       surface_img = NULL;
	}
}

// Initialization function that runs only once at the beginning of the program
void init_vars(void)
{
    image_width=0;
    image_height=0;
}

// 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;
                break;

           case SDL_EVENT_KEY_DOWN: // Key pressed
                if(event.key.key==SDLK_ESCAPE) {
                   is_running = false; break;
                }
                break;
        }
    }
}

// Updates objects in the main window
void update_screen(void)
{

}

// 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.

    SDL_FRect frect_dst = { (WINDOW_WIDTH - image_width) / 2, ( WINDOW_HEIGHT - image_height ) / 2, image_width, image_height };
	SDL_RenderTexture(renderer, texture_img, NULL, &frect_dst);

    // 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_img);
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    SDL_Quit();
}