이제 기본적인 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의 강좌가 특히 좋다.
'<LIBRARY> > SDL2' 카테고리의 다른 글
0. SDL2 개발 환경 설정하기 (1) | 2021.01.17 |
---|
댓글