1. SDL2 확인 코드 분석하기
이제 기본적인 SDL2 확인 코드를 분석하며 SDL2의 기본적인 생명주기를 이해해본다.
SDL2가 C로 작성되어 절차 지향적인 구조를 가지고 있기 때문에
순서에 따라 코드를 하나씩 추가해가며 프로그램 흐름을 이해해보자.
필요한 헤더 파일 포함하기
▼ 코드
// SDL2와 표준입출력 헤더 포함
#include <SDL2.h>
#include <cstdio>
SDL2 헤더 파일은 아주 직관적이다.
기본 기능외의 추가적인 기능을 사용하려면 몇 가지 헤더 파일을 더해줘야 하지만 지금은 필요 없다.
화면 크기 전역 변수 선언하기
▼ 코드
// SDL2와 표준입출력 헤더 포함
#include <SDL2.h>
#include <cstdio>
// 화면 해상도 전역 상수 설정
const static int SCREEN_WIDTH = 640;
const static int SCREEN_HEIGHT = 480;
화면의 해상도(Dimension)를 설정한다.
지금은 따로 해상도를 변경하지 않는 고정 해상도로 창을 만들기 때문에 const로 전역 상수로 선언했다.
SDL2 Main 함수
▼ 코드
// SDL2와 표준입출력 헤더 포함
#include <SDL2.h>
#include <cstdio>
// 화면 해상도 전역 변수 설정
const static int SCREEN_WIDTH = 640;
const static int SCREEN_HEIGHT = 480;
int main(int argc, char *argv[])
{
return (0);
}
Main 함수의 인자 중 인자 값 문자열은 char **argv와 char *argv []의 두 가지 방법을 사용한다.
둘 다 SDL2의 작동에는 차이가 없지만 SDL2 라이브러리의 코딩 룰은 char *argv []로 정해져 있다.
SDL2 창(Window)과 표면(Surface) 선언 및 초기화
▼ 코드
// SDL2와 표준입출력 헤더 포함
#include <SDL2.h>
#include <cstdio>
// 화면 해상도 전역 변수 설정
const static int SCREEN_WIDTH = 640;
const static int SCREEN_HEIGHT = 480;
int main(int argc, char* args[])
{
// SDL 창 선언 및 초기화
SDL_Window* window = NULL;
// SDL창이 포함할 표면 선언 및 초기화
SDL_Surface* screenSurface = NULL;
return (0);
}
SDL 창(Window)은 우리가 흔히 사용하는 윈도 운영체제(Windows)의 바로 그 창을 의미한다.
애초에 윈도우 운영체제가 이 창을 여러 개 띄워서 사용할 수 있는 특징 때문에
윈도(Windows) 운영체제라고 부르는 것이다.
SDL2 창(WIndow) 초기화
▼ 코드
// SDL2와 표준입출력 헤더 포함
#include <SDL2.h>
#include <cstdio>
// 화면 해상도 전역 변수 설정
const static int SCREEN_WIDTH = 640;
const static int SCREEN_HEIGHT = 480;
int main(int argc, char* args[])
{
// SDL 창 선언 및 초기화
SDL_Window* window = NULL;
// SDL창이 포함할 표면 선언 및 초기화
SDL_Surface* screenSurface = NULL;
// SDL2 초기화 실패시 음수 반환
if (SDL_Init(SDL_INIT_VIDEO) < 0)
{
printf("SDL could not initialize! SDL_Error: %s\n", SDL_GetError());
}
else
{
}
return (0);
}
이제 SDL2를 SDL_Init() 함수로 초기화한다.
SDL_Init() 함수 인자로 들어가는 SDL_INIT_VIDEO는 비디오 시스템을 뜻한다.
우리가 흔히 비디오 게임이라고 부르는 것처럼 비디오는 화면을 송출하는 그 자체를 의미한다.
결국 SDL_Init(SDL_INIT_VIDEO)는 비디오 시스템을 초기화하는데
이 초기화가 실패하면 음수 값을 반환한다.
표면 생성하고 하얀 배경 칠하기
▼ 코드
// SDL2와 표준입출력 헤더 포함
#include <SDL.h>
#include <cstdio>
// 화면 해상도 전역 상수 설정
const static int SCREEN_WIDTH = 640;
const static int SCREEN_HEIGHT = 480;
int main(int argc, char* args[])
{
// SDL 창 선언 및 초기화
SDL_Window* window = NULL;
// 창이 포함할 표면 선언 및 초기화
SDL_Surface* screenSurface = NULL;
// SDL2 초기화 실패시 음수 반환
if (SDL_Init(SDL_INIT_VIDEO) < 0)
{
printf("SDL could not initialize! SDL_Error: %s\n", SDL_GetError());
}
else
{
// 윈도우 생성
window = SDL_CreateWindow("SDL INIT", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
if (window == NULL)
{
printf("Window could not be created! SDL_Error: %s\n", SDL_GetError());
}
else
{
// 화면 표면 받아넣기
screenSurface = SDL_GetWindowSurface(window);
// 표면을 (R(1), G(1), B(1))로 채우기
SDL_FillRect(screenSurface, NULL, SDL_MapRGB(screenSurface->format, 0xFF, 0xFF, 0xFF));
// 표면 업데이트
SDL_UpdateWindowSurface(window);
// 2초 딜레이
SDL_Delay(2000);
}
}
return 0;
}
SDL_GetWindowSurface()를 사용해서 우리가 만든 창의 표면을 받아서 screenSurface에 받아 넣는다.
SDL_FillRect는 말 그대로 채워진(Fill) 사각형(Rect)을 그리는 함수다.
원래라면 크기를 정해준 만큼 사각형을 그려주지만 이 코드에서는 화면 전체에 그리기 위해서
NULL이 넣어져 있다.
색상을 넣는 부분을 보면 SDL_MapRGB()로 RGB 컬러 값을 변환해서 넣어주고 있다.
원래라면 SDL_FillRect()는 uint32인 8바이트 크기의 정수 값을 입력받는다.
하지만 매번 프로그래머가 색을 바꿀 때마다 변환하는 건 귀찮기 때문에
프로그래머가 좀 더 직관적이고 수정이 편한 RGB 컬러 값으로 작성할 수 있도록 SDL_MapRGB()를 제공한다.
SDL_UpdateWindowSurface는 말 그대로 우리가 작성한 창을 업데이트한다.
SDL_Delay는 밀리초 단위로 지연시간을 입력할 수 있다.
이 코드는 창을 만들고 자동으로 종료가 정상적인지 확인하는 코드인데
컴퓨터의 연산능력이 너무나 빠르기 때문에 프로그래머가 창 뜨는 것을 보지도 못한 채 종료되어 버린다.
그래서 2000 밀리초 즉, 2초의 지연시간을 설정해서 2초 뒤에 창이 종료되도록 한다.
SDL 화면 제거 및 종료
▼ 코드
// SDL2와 표준입출력 헤더 포함
#include <SDL.h>
#include <cstdio>
// 화면 해상도 전역 상수 설정
const static int SCREEN_WIDTH = 640;
const static int SCREEN_HEIGHT = 480;
int main(int argc, char* args[])
{
// SDL 창 선언 및 초기화
SDL_Window* window = NULL;
// 창이 포함할 표면 선언 및 초기화
SDL_Surface* screenSurface = NULL;
// SDL2 초기화 실패시 음수 반환
if (SDL_Init(SDL_INIT_VIDEO) < 0)
{
printf("SDL could not initialize! SDL_Error: %s\n", SDL_GetError());
}
else
{
// 윈도우 생성
window = SDL_CreateWindow("SDL INIT", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
if (window == NULL)
{
printf("Window could not be created! SDL_Error: %s\n", SDL_GetError());
}
else
{
// 화면 표면 받아넣기
screenSurface = SDL_GetWindowSurface(window);
// 표면을 (R(1), G(1), B(1))로 채우기
SDL_FillRect(screenSurface, NULL, SDL_MapRGB(screenSurface->format, 0xFF, 0xFF, 0xFF));
// 표면 업데이트
SDL_UpdateWindowSurface(window);
// 2초 딜레이
SDL_Delay(2000);
}
}
// 화면 제거
SDL_DestroyWindow(window);
// SDL 종료
SDL_Quit();
return 0;
}
비록 화면을 흰색으로 채우는 것뿐이었지만 화면을 그리는 과정이 모두 완료되었다.
우리가 생성한 창을 없애기 위해서 SDL_DestroyWindow()로 창을 꼭 제거한다.
우리가 메모리를 할당하면 해제는 언제나 세트처럼 같이 따라와야 한다.
마찬가지로 SDL_Init()으로 생성한 SDL을 종료하기 위해서는 SDL_Quit()를 호출해야 한다.
이것으로 가장 기본적인 SDL2 확인 코드를 분석을 마무리한다.
SDL2는 오랜 시간 동안 사용되어 온 만큼 양질의 자료들이 많다.
아래 링크의 lazyfoo의 강좌가 특히 좋다.