邱 璇洛 (ゝ∀・)

邱 璇洛 (ゝ∀・)

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

SDL2 Learning Notes - Rendering Images

Development Environment: MacOS
Reference: Professor 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 methods, but let's start with BMP format rendering.

Configure CMake#

First, configure CMake. As mentioned in the previous article, we can simply copy 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 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 Professor Chen Yun's tutorial.

Cat image link: cat

To render a BMP file, we first need to load the BMP file.

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

Then, we can 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 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
#define FRAMERATE 60

struct SDL_Surface *img;

int x = 0;

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) {
        long 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(
        "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;
    }

    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);

    event_loop(screen, win);

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