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,
Used surface functions
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();
}