2014년 7월 1일 화요일

[일기] SDL 초기 TUTORIAL 연습 2

이번 찾아본 강의의 목적은 SDL을 이용하여 화면에 이미지를 출력하는 내용이다.

 1. 화면에 나타낼 윈도우의 크기를 미리 상수로 잡아놓는다.


[그림 1]

 2. 이후 에러 출력을 담당할 함수를 만들었다.



[그림 2] [그림 3]

 3. 그리고 텍스처를 불러오는 함수를 만드는데...

======================================================================
SDL에서 윈도우를 그리기 위해서는 SDL_CreateWindow 를 호출하면 된다. 인자는 6개로,

 타이틀명
 좌상단 좌표 x
 좌상단 좌표 y
 폭
 높이
 깃발(flag)

이다.

 여기서 6번째 인자로 SDL_WINDOW_SHOWN 을 이용하면 화면에 나타난다. null을 리턴할 경우, 에러가 발생한 것으로 간주할 수 있다.

 SDL_Window *win = SDL_CreateWindow("Title", 0, 0, 300, 500, SDL_WINDOW_SHOWN);

 화면에 무엇을 그리기 위해 SDL에서는 Renderer가 필요하다. 이는 SDL_CreateRenderer 를 이용하면 된다. 인자는 3개로

 윈도우 포인터
 렌더링 드라이버 인덱스
 렌더링 정렬(?) 플래그

이다.

 SDL_Renderer *ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);

 여기서 플래그는 모르고 넘어갔다. 문제 발생시 nullptr를 리턴한다.

비트맵을 로딩해야 한다. 이는 SDL_LoadBMP를 통해서 하며, 인자는 1개로 파일 경로 문자열이다. SDL_Surface*를 리턴한다.

 SDL_Surface *bmp = SDL_LoadBMP("my.bmp");

문제가 있는 경우 nullptr이 리턴된다.

 문제는 우리가 필요한 것은 텍스처라는 놈이다라는 것이다.  이는 SDL_CreateTextureFromSurface를 통해 해결한다. 인자는 2개로 렌더러와 이미지 표면(surface)이다.

SDL_Texture* tex = SDL_CreateTextureFromSurface(ren, bmp);

역시 문제가 발생하면 nullptr이 리턴된다.

위 모든 경우에 있어 문제의 원인의 상세는 SDL_GetError()를 통해 얻을 수 있다.

SDL_FreeSurface를 통해 더 이상 사용않는 표면의 메모리를 해제할 수 있다.

 SDL_FreeSurface(bmp);

SDL_DestroyRenderer를 통해 더 이상 사용않는 렌더러를 소멸시킬 수 있다.

 SDL_DestroyRenderer(ren);

SDL_DestroyWindow를 통해 더 이상 사용않는 윈도우를 소멸시킬 수 있다.

 SDL_DestroyWindow(win);

 그림을 화면에 뿌리기 위해서 다음 순서의 작업이 추천된다.

 1. 렌더러를 깨끗하게 만든다.

  SDL_RenderClear(ren);

 2. 렌더러에 이미지를 복사한다.

 SDL_RenderCopy(ren, tex, NULL, NULL); //함수 상세는 이후에...

 3. 화면에 고속복사한다.

 SDL_RenderPresent(ren);

 * SDL_Delay를 이용하면 ms 단위의 프로그램 정지(Sleep)가 가능하다.

 SDL_Delay(2000); //2초 기다린다.

========================================================================

*반드시 모든 일을 끝내고 나서는 할당한 메모리를 해제한다.

SDL_DestroyTexture(tex)
SDL_DestroyRenderer(ren)
SDL_DestroyWindow(win)
SDL_Quit()

....가 기본 내용인데.. 이를 심화해서 나갔다.

반복적인 작업이므로 한꺼번에 하도록 함수로 만들었다.


[그림 4]

4. 그림을 출력하기 위한 함수를 만드는데....

  렌더러에 이미지를 복사할때, 복사 영역을 설정할 수 있다. 이때 SDL_Rect 를 이용하게 된다.

 SDL_Rect는 단순히 x, y, w, h 즉, 좌상단 x좌표, 좌상단 y좌표, 폭, 높이를 갖는다.

 * SDL_QueryTexture를 이용하면 우리가 불러온 텍스처의 폭과 높이를 알 수 있다.

 SDL_Rect dst;
 ...
 SDL_QueryTexture(tex, NULL, NULL, &dst.w, &dst.h);

이를 이용하여 복사 영역을 알아낸 후, 렌더러에 이미지를 복사한다.

 SDL_RenderCopy(ren, tex, NULL, &dst);

 만일 4번째 인자에 nullptr가 들어가면 자동으로 텍스처의 폭과 높이를 맞추어준다. 그리고
출력 좌상단 좌표는 0, 0이 된다.

...가 기본 내용이므로 이를 묶어버렸다.


[그림 5]


5. 윈도우, 렌더러 만들었다.


[그림 6]

6. 지금까지 가져온 것들을 기반으로 이미지를 가져와 화면에 출력한다.

 이미지를 2개 가져오는데 하나는 배경으로, 나머지 하나는 전경으로 사용한다.




[그림 7] [그림 8] [그림 9] [그림 10]

이미지 출처 : http://www.livescience.com/34143-blue-moon-phrase.html
http://www.twitterevolutions.com/tree-and-a-moonlight-twitter-background/

결과]


[그림 11]


댓글 없음:

댓글 쓰기