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

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

Ana sayfa > Oyun programlama > SDL3 programming > Loading bmp images with surface

Loading bmp images with surface

In this section, we will examine a program that loads an image file with the extension .bmp into the main window via surfaces.

When the program runs,

  1. In addition to the basic operations, the following operations occur:
  2. At the beginning of the program, the following global variables are defined:
    • SDL_Surface *surface_scr: Surface variable for the main window
    • SDL_Surface *surface_img: Surface variable for the image file to be loaded
  3. The main window surface is retrieved with the SDL_GetWindowSurface() function and assigned to the surface_scr variable.
  4. When the load_img() function runs,
    • A surface is created by loading the image file named sample.bmp with the SDL_LoadBMP() function and the created surface is assigned to the surface_img variable. draw_img() function is called.
    • Inside the draw_img() function,
      • The image surface is copied to the main window surface with the SDL_BlitSurface() function.
      • The window surface is updated with the SDL_UpdateWindowSurface() function.

Used surface functions

  • SDL_GetWindowSurface() function gets the SDL surface associated with the window. This surface will be freed when the window is destroyed. Do not free this surface. This surface will be invalidated if the window is resized. After resizing a window this function must be called again to return a valid surface.
  • SDL_LoadBMP() function loads a BMP image from a file and creates a new surface. The new surface should be freed with SDL_DestroySurface().
  • SDL_BlitSurface() function performs a fast blit from the source surface to the destination surface.
  • SDL_UpdateWindowSurface() function copy the window surface to the screen.

The data for the SDL_Surface structure used by the surface functions are as follows:/p>

struct SDL_Surface
{
    SDL_SurfaceFlags flags; /* The flags of the surface, read-only */
    SDL_PixelFormat format; /* The format of the surface, read-only */
    int w;                  /* The width of the surface, read-only. */
    int h;                  /* The height of the surface, read-only. */
    int pitch;              /* The distance in bytes between rows of pixels, read-only */
    void *pixels;           /* A pointer to the pixels of the surface, the pixels are writeable if non-NULL */
    int refcount;           /* Application reference count, used when freeing surface */
    void *reserved;         /* Reserved for internal use */
};

SDL_Surface is a buffer of pixels in memory accessible by the CPU.

SDL_Surface is a tool for CPU side blit rendering, where as SDL_Renderer takes advantage of hardware acceleration, and performs the rendering on the Graphics Processing Unit (GPU).

In this program, the image is drawn only at the beginning of the program and only once. If you disable the draw_img() function in the load_img() function and enable it in the while loop in the main() function, the image will be drawn again each time the program loop iterates.

The main.c file content will be as follows:


#include <SDL3/SDL.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_Renderer *renderer = NULL;    // Renderer variable
SDL_Surface *surface_scr = NULL;  // Surface variable for main window
SDL_Surface *surface_img = NULL;  // Surface variable for image

// Function prototypes
int init_window(void);            // Create window and renderer
void init_vals(void);             // Initialize values
void load_img(void);              // Load image to surface
void draw_img(void);              // Copy image surface to window surface
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 .bmp file to image surface
    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 - Load bmp image with surface", WINDOW_WIDTH, WINDOW_HEIGHT, 0, &window, &renderer)) {
       return false;
    }

    // Get window surface
    surface_scr = SDL_GetWindowSurface(window);

    if(surface_scr == NULL) {
       SDL_Log("Get window surface error: %s\n", SDL_GetError());
       return false;
    }

    return true;
}

// Initialization function that runs only once at the beginning of the program
void init_vals(void)
{

}

// Load image to surface
void load_img(void)
{
	 // Load image to surface
	 surface_img = SDL_LoadBMP("sample.bmp");

	 if(surface_img == NULL)	{
	    SDL_Log("Load image error: %s\n", SDL_GetError());
	 }

     draw_img(); // Copy image surface to window surface
}

// Copy image surface to window surface
void draw_img(void)
{
     // Pencerede resmin koordinatlarını belirleme
     SDL_Rect dstrect = { (WINDOW_WIDTH-200)/2, (WINDOW_HEIGHT-150)/2, 200, 150 };

     // Resim yüzeyini pencere yüzeyine yapıştırma
     SDL_BlitSurface(surface_img, NULL, surface_scr, &dstrect);

     // Pencere yüzeyini güncelleştirme
     SDL_UpdateWindowSurface(window);
}

// 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.
                 if(event.key.key == SDLK_ESCAPE) { // Esc key pressed
                    is_running = false; // Terminates the execution of the program main loop.
                 }
                 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)
{

}

// Destroy Renderer and SDL window, exit from SDL3
void destroy_window(void)
{
     SDL_DestroySurface(surface_img);
     SDL_DestroyRenderer(renderer);
     SDL_DestroyWindow(window);
     SDL_Quit();
}