邱 璇洛 (ゝ∀・)

邱 璇洛 (ゝ∀・)

你好哇(*゚∀゚*)~这里是邱璇洛的博客,常常用来记录一些技术文章和小日常~(σ゚∀゚)σ
twitter
tg_channel

SDL2 Learning Notes - Rendering Images

Development Environment: MacOS
Reference Material: Teacher Chen Yun's SDL2 Tutorial
Note: This is a note
EP-2

Environment Configuration#

In SDL2, we have two methods for rendering images.

  1. One is to use BMP format images, which have the advantage of lossless images and can be directly rendered using the SDL2 library.
  2. The other is to use the SDL2_image library to render common formats such as PNG and JPG.

We will discuss both of these methods, starting with BMP format rendering.

Configure CMake#

First, configure CMake. As mentioned in the previous article, we can simply copy and paste the configuration for SDL_image.
It is worth noting that when using the CMakeTools extension in VScode on MacOS, starting directly may fail due to the executable file not being able to find the image. Therefore, we need to add a line of code to move the executable file to the working directory.

cmake_minimum_required(VERSION 3.23.2)
project(SimpleAnimation C)

set(CMAKE_C_STANDARD 11)

set(SDL_DIR /usr/local/Cellar/sdl2/2.26.0)
include_directories(${SDL_DIR}/include/SDL2)
link_directories(${SDL_DIR}/lib/)

set(SDL2_image /usr/local/Cellar/sdl2_image/2.6.2)
include_directories(${SDL2_image}/include/)
link_directories(${SDL2_image}/lib/)

link_libraries(SDL2)
link_libraries(SDL2_image)

# Move the executable file
set(EXECUTABLE_OUTPUT_PATH ../)
add_executable(SimpleAnimation main.c)

Now, we can start the actual process.

Render BMP Format Images#

The BMP file used in this article is from Teacher Chen Yun's tutorial, with permission to use.
Cat image link: cat
To render a BMP file, we first load the BMP file.

img = SDL_LoadBMP("cat.bmp");
struct SDL_Surface *screen = SDL_GetWindowSurface(win);

Then, we write a drawing function.

void draw(SDL_Surface *screen, SDL_Window *win) {
    SDL_Rect src = {0, 0, img->w, img->h};
    SDL_BlitSurface(img, &src, screen, &src);
    // Apply the changes
    SDL_UpdateWindowSurface(win);
}

Complete code:

#include <stdio.h>
#include <SDL2/SDL.h>

#define WIDTH 600
#define HEIGHT 500
#define FRAMERATE 60


struct SDL_Surface *img;

void draw(SDL_Surface *screen, SDL_Window *win) {

    SDL_Rect src = {0, 0, img->w, img->h};
    SDL_BlitSurface(img, &src, screen, &src);

    SDL_UpdateWindowSurface(win);
}

void event_loop(SDL_Surface *screen, SDL_Window *win) {
    while (1) {
        uint32_t begin = SDL_GetTicks();
        draw(screen, win);

        SDL_Event event;
        while (SDL_PollEvent(&event)) {
            if (event.type == SDL_QUIT) {
                return;
            }
        }
        long current = SDL_GetTicks();
        long cost = current - begin;
        long frame = 1000 / FRAMERATE;
        long delay = frame - cost;

        if (delay > 0) {
            SDL_Delay(delay);
        }
    }
}

int main() {
    if (SDL_Init(SDL_INIT_VIDEO)) {
        SDL_Log("Can not init video, %s", SDL_GetError());
        return 1;
    }

    SDL_Window *win = SDL_CreateWindow(
            "Hello World",

            SDL_WINDOWPOS_CENTERED,
            SDL_WINDOWPOS_CENTERED,
            WIDTH, HEIGHT,

            SDL_WINDOW_SHOWN
    );
    if (win == NULL) {
        SDL_Log("Can not create window, %s", SDL_GetError());
        return 1;
    }

    img = SDL_LoadBMP("cat.bmp");
    struct SDL_Surface *screen = SDL_GetWindowSurface(win);

    event_loop(screen, win);
    SDL_FreeSurface(img);
    SDL_DestroyWindow(win);
    return 0;
}

Render Images in Other Formats#

We need to include the SDL_image library, which can be downloaded just like SDL.

#include <SDL.h>
#include <SDL2/SDL_image.h>

#define WIDTH 1280
#define HEIGHT 783
/* Set the frame rate */
#define FRAMERATE 60

/* Declare the image */
struct SDL_Surface *img;

int x = 0;

void draw(SDL_Surface *screen, SDL_Window *win) {
    /* Set the img rectangle */
    SDL_Rect src = {0, 0, img->w, img->h};//x, y, w, h
    /* Copy the img to the screen (display) */
    SDL_BlitSurface(img, &src, screen, &src);

    SDL_UpdateWindowSurface(win);
}

/* Event loop */
void event_loop(SDL_Surface *screen, SDL_Window *win) {
    while (1) {
        /* Frame rate: get the millisecond value */
        long begin = SDL_GetTicks();

        /* Render */
        draw(screen, win);

        SDL_Event event;
        /* Using a loop to read events is faster than using if, as we don't have to wait */
        while (SDL_PollEvent(&event)) {
            if(event.type == SDL_QUIT) {
                return;
            }
        }

        /* Frame rate: current value */
        long current = SDL_GetTicks();
        /* Time spent on the current frame */
        long cost = current - begin;
        /* Time for each frame */
        long frame = 1000/FRAMERATE;
        /* Calculate the delay time to maintain the frame rate */
        long delay = frame - cost;
        /* If the delay is negative, do not sleep to maintain the frame rate */
        if (delay > 0) {
            SDL_Delay(delay);
        }
        /* In the case of sufficient system resources, it can maintain a sufficient frame rate, but if not, there is nothing we can do */
    }
}

int main() {
    if (SDL_Init(SDL_INIT_VIDEO)) {
        SDL_Log("Can not init video, %s", SDL_GetError());
        return 1;
    }

    SDL_Window *win = SDL_CreateWindow(
        "img",
        SDL_WINDOWPOS_CENTERED,
        SDL_WINDOWPOS_CENTERED,
        WIDTH,HEIGHT,
        SDL_WINDOW_SHOWN
    );

    if (win==NULL) {
        SDL_Log("Can not create window, %s", SDL_GetError());
        return 1;
    }

    /* Load the image */
    img = IMG_Load("img_1.png");
    if (img==NULL) {
        SDL_Log("Can not load image, %s", SDL_GetError());
        return 1;
    }

    SDL_Surface *screen = SDL_GetWindowSurface(win); // Find the window

    event_loop(screen, win);

    /* Free the image */
    SDL_FreeSurface(img);
    /* Destroy the window */
    SDL_DestroyWindow(win);
    return 0;
}
Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.