한국어
오픈소스포럼
 이곳은 다양한 오픈소스 프로젝트를 소개하고 리뷰, 활용 방법을 공유합니다.

[SDL2 와 OpenGL]윈도우 생성과 2D그래픽

makersweb 2020.04.11 18:00 조회 수 : 3869

SDL2의 간단한 소개와 개념에 대해서는 이전에 다른 글을 통해 다룬적이 있었다.

 
이글에서는 SDL2를 이용하여 2D그래픽스 및 OpenGL 프로그래밍을 위해 필요한 준비과정과 이전 글에 대한 조금 더 구체적인 내용을 다룬다. (SDL2 위키문서 참조)
 
개발 환경: 윈도우10, QtCreator, MinGW32 64비트
 
헤더파일
SDL2 기본 기능을 사용하기위해는 다음의 헤더를 포함해야 한다.
#include <SDL2/SDL.h>
 
main함수
SDL응용프로그램을 작성하기위해 main함수는 다음과 같이 선언한다.
int main(int argc, char *argv[])
 
다음과 같은 에러를 출력한다면 main함수를 올바르게 선언하였는지 확인해야 한다.
"Undefined reference to 'SDL_main'"
 
초기화
SDL의 기능을 사용하기위해 라이브러리 초기화를 수행한다. 다른 SDL 기능을 사용하기 전에 호출해야한다. 성공하면 0을, 실패하면 음수 오류 코드를 반환한다.
int SDL_Init(Uint32 flags)
 
다음의 플래그의 조합으로 특정 서브시스템을 초기화할 수 있다.

SDL_INIT_TIMER

타이머 서브시스템

SDL_INIT_AUDIO

오디오 서브시스템

SDL_INIT_VIDEO

비디오 서브시스템

SDL_INIT_JOYSTICK

조이스틱 서브시스템

SDL_INIT_HAPTIC

햅틱 (force feedback) 서브시스템

SDL_INIT_GAMECONTROLLER

게임 컨트롤러 서브시스템

SDL_INIT_EVENTS

이벤트 서브시스템

SDL_INIT_EVERYTHING

위의 모든 서브시스템

SDL_INIT_NOPARACHUTE

치명적인 신호를 무시

 
예제
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO);
 
 
윈도우 생성
지정된 위치, 치수 및 플래그로 창을 만든다.
SDL_Window* SDL_CreateWindow(const char* title,
                             int         x,
                             int         y,
                             int         w,
                             int         h,
                             Uint32      flags)
 
title
UTF-8 인코딩으로 된 창의 제목
 
x
윈도우의 x위치, SDL_WINDOWPOS_CENTERED, or SDL_WINDOWPOS_UNDEFINED 플래그 사용가능.
 
y
윈도우의 y위치, SDL_WINDOWPOS_CENTERED, or SDL_WINDOWPOS_UNDEFINED
 
w
윈도우의 넓이
 
h
윈도우의 높이
 
flags
0 또는 하나 이상의 SDL_WindowFlags
 
flags는 다음과 같다.

SDL_WINDOW_FULLSCREEN

전체화면 창

SDL_WINDOW_FULLSCREEN_DESKTOP

데스크탑 해상도의 전체 화면 창

SDL_WINDOW_OPENGL

OpenGL 컨텍스트로 사용가능한 창

SDL_WINDOW_VULKAN

Vulkan 과 함께 사용 가능한 창

SDL_WINDOW_HIDDEN

보이지 않는 창

SDL_WINDOW_BORDERLESS

데코레이션이 없는 창

SDL_WINDOW_RESIZABLE

크기를 조정 가능

SDL_WINDOW_MINIMIZED

최소화 창

SDL_WINDOW_MAXIMIZED

최대화 창

SDL_WINDOW_INPUT_GRABBED

입력 포커스를 얻음

SDL_WINDOW_ALLOW_HIGHDPI

지원되는 경우 높은 DPI 모드에서 창 (>= SDL 2.0.1)

 
작성된 창을 리턴하거나 실패시 NULL을 리턴한다. 
 
예제
SDL_Window *window = NULL;
 
window = SDL_CreateWindow(
    "An SDL2 window",
    SDL_WINDOWPOS_UNDEFINED,
    SDL_WINDOWPOS_UNDEFINED,
    640,
    480,
    SDL_WINDOW_OPENGL
);
 
 
렌더러생성
창에 대한 2D 렌더링 컨텍스트를 만든다.
SDL_Renderer* SDL_CreateRenderer(SDL_Window* window,
                                 int         index,
                                 Uint32      flags)
 
window
렌더링 시 표시되는 창
 
index
초기화 할 렌더링 드라이버의 인덱스 또는 지원하는 첫 번째 드라이버를 초기화하려면 -1
 
flags
0 또는 하나 이상의 SDL_RendererFlags
 
플래그는 다음과 같다.

SDL_RENDERER_SOFTWARE

소프트웨어 대체

SDL_RENDERER_ACCELERATED

하드웨어 가속을 사용

SDL_RENDERER_PRESENTVSYNC

새로고침 수직동기화

SDL_RENDERER_TARGETTEXTURE

텍스처 렌더링을 지원

 

플래그를 제공하지 않으면 사용 가능한 SDL_RENDERER_ACCELERATED 플래그가 렌더러에 우선순위로 부여된다.
 
예제:
SDL_Renderer *renderer = NULL;
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
 
 
그리기 컬러 설정
2D 그리기 작업에 사용되는 색상을 설정
int SDL_SetRenderDrawColor(SDL_Renderer* renderer,
                           Uint8         r,
                           Uint8         g,
                           Uint8         b,
                           Uint8         a)
 
renderer
렌더링 컨텍스트
 
r
렌더링 대상에 그리는 데 사용되는 빨간색 값(0 ~ 255)
 
g
렌더링 대상에 그리는 데 사용되는 녹색 값(0 ~ 255)
 
b
렌더링 대상에 그리는 데 사용되는 파란색 값(0 ~ 255)
 
a
렌더링 대상에 그리는 데 사용되는 알파 값(0 ~ 255)
 
성공하면 0을, 실패하면 음수 오류 코드를 반환한다.
 
예제:
SDL_SetRenderDrawColor(renderer, 0, 0, 255, 255);
 
 
지우기
현재 렌더링 대상을 설정된 색상으로 지운다.
int SDL_RenderClear(SDL_Renderer* renderer)
 
화면업데이트
그리기가 수행 된 렌더링으로 화면을 업데이트(프론트 버퍼와 백버퍼 교환)
void SDL_RenderPresent(SDL_Renderer* renderer)
 
정리하기
윈도우의 렌더링 컨텍스트를 해제하고 관련 텍스처를 해제
void SDL_DestroyRenderer(SDL_Renderer* renderer)
 
생성된 윈도우를 파괴한다.
void SDL_DestroyWindow(SDL_Window* window)
 
 
종료
초기화 된 모든 서브 시스템을 정리한다.
void SDL_Quit(void)
 
전체 예제
main.cpp
#include <iostream>
#include <SDL2/SDL.h>

using namespace std;

#define UNUSED(x) (void)(x)

int sdl_window_example()
{
    SDL_Window *window;                    // Declare a pointer

    SDL_Init(SDL_INIT_VIDEO);              // Initialize SDL2

    // Create an application window with the following settings:
    window = SDL_CreateWindow(
        "An SDL2 window",                  // window title
        SDL_WINDOWPOS_UNDEFINED,           // initial x position
        SDL_WINDOWPOS_UNDEFINED,           // initial y position
        640,                               // width, in pixels
        480,                               // height, in pixels
        SDL_WINDOW_OPENGL                  // flags - see below
    );

    // Check that the window was successfully created
    if (window == nullptr) {
        // In the case that the window could not be made...
        printf("Could not create window: %s\n", SDL_GetError());
        return 1;
    }

    auto renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);

    if(renderer == nullptr)
        goto destroy_window;

    SDL_SetRenderDrawColor(renderer, 0, 255, 0, 255);
    SDL_RenderClear(renderer);
    SDL_RenderPresent(renderer);

    // The window is open: could enter program loop here (see SDL_PollEvent())

    SDL_Delay(3000);  // Pause execution for 3000 milliseconds, for example

    // Close and destroy the renderer
    SDL_DestroyRenderer(renderer);

destroy_window:
    // Close and destroy the window
    SDL_DestroyWindow(window);

    // Clean up
    SDL_Quit();

    return 0;
}

int main(int argc, char *argv[])
{
    UNUSED(argc);
    UNUSED(argv);

    cout << "Hello World!" << endl;

    return sdl_window_example();
}

결과: 윈도우를 녹색으로 칠한 모습
SDL2GreenWindow.png