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.
- One is to use BMP format images, which have the advantage of lossless images and can be directly rendered using the SDL2 library.
- 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;
}