본문 바로가기

Study/Engine

[SDL Tutorial] Lesson 5 - Color Keying



 안녕하세요! 오늘은 Color Key에 대해서 강의를 해볼까 합니다. 우리말로 풀어쓰면 색상 키라고 하겠지요. 다른 강의를 보고싶으시면 카테고리에서 Programming/SDL을 방문해주시기 바랍니다.

 그럼 시작하겠습니다.


5 - 1 : Color Key란?

 Color Key는 이미지를 화면에 뿌려줄 때 원하는 색상(배경색이 대부분이지요)을 제거해서 출력시켜주는 것을 말합니다. 예를 들어서,



 위와같은 이미지를 우리가 이제까지 배운 방식대로 출력하면 하얀 배경에서는



 이렇게 보이겠지요. 캐릭터가 둥둥 떠보이는 것 같이 보일겁니다. 하지만 대부분의 프로그래머들이 원하는 것은 이런게 아니라



 이런식으로 배경이 제거되는 것을 원할 것이지요. 이럴 때 쓰는 것입니다. 혹시나 이렇게 반문하실 수도 있습니다. "배경색과 같은 색으로 캐릭터를 표현하면 어떻겠는가?"하고 말이죠. 하지만 배경이 알록달록한 그런거면 어쩔까요?



 이런식으로 말이지요.  오늘 하려는 내용을 대충은 아셨으리라 생각합니다. 그럼 본격적으로 코드를 써볼까요?


5 - 2 : 보노보노와 슬라임(?)이 나오는 프로그램 만들기



 오늘은 이전 강의에 썼던 코드에서 조금의 수정을 할 예정입니다. 이전 강의처럼 전체코드를 포스트엔 쓰지 않을 예정이오니, Lesson 4의 소스 코드가 없으신 분들은,


 에서 미리 받아놓으시기 바랍니다. 물론 포스트를 보면서 따라서 하실 분들의 얘기입니다 ^^;

// Surface
SDL_Surface *image = NULL;
SDL_Surface *slime = NULL;
SDL_Surface *screen = NULL;

먼저 적용하기전에 slime이라는 변수하나를 추가해줍시다.

SDL_Surface *load_image( std::string filename )
{
    // 이미지를 불러올 변수
    SDL_Surface* loadedImage = NULL;

    // 최적화한 이미지를 저장할 변수
    SDL_Surface* optimizedImage = NULL;

    // 이미지를 불러옴
    loadedImage = IMG_Load( filename.c_str() );

    // 만약 이미지를 불러오는데 성공하면,
    if( loadedImage != NULL )
    {
        // 화면의 포멧에 맞게 최적화한다
        optimizedImage = SDL_DisplayFormat( loadedImage );

        // 필요없는 Surface를 해제한다
        SDL_FreeSurface( loadedImage );

 이 부분의 소스부분을 봐주시기 바랍니다. 위의 코드는 Lesson 4에 있는 코드입니다. 이 코드 바로 아래에

        // 만약 최적화가 잘 되었다면,
        if( optimizedImage != NULL )
        {
            // 이미지의 R:0, G:255, B:255 에 해당하는 색상값을 지워라 
            Uint32 colorkey = SDL_MapRGB( optimizedImage->format, 0, 0xFF, 0xFF );

 위와같은 코드를 추가해주시기 바랍니다. 저기에서 SDL_MapRGB는 이미지의 포멧값과 R, G, B값을 받아서 colorkey에 매핑할 색상값을 반환해줍니다.

            // R:0, G:255, B:255 색상의 픽셀을 투명하게 설정 
            SDL_SetColorKey( optimizedImage, SDL_SRCCOLORKEY, colorkey );
        }

 이제 Color Key를 적용하는 코드입니다. 첫번째 인자값은 색상 키를 적용할 이미지를 넣고, 두번째 인자에는 연산방법을 정해주는 플래그를 넣어줍니다. SDL_SRCCOLORKEY는 다른 이미지에 이 이미지가 뿌려질 때 색상 키를 적용하게 해주는 플래그입니다. 세번째 인자값은 사용자가 원하는 색상 키 값을 넣는 곳입니다. 바로 전 코드에서 원하는 색상을 매핑한 것을 집어넣어주면 됩니다.

    // 최적화된 이미지를 반환한다
    return optimizedImage;
}

 이걸로 load_image 함수는 마무리하겠습니다.

bool load_files()
{
    // 이미지 로드
    image = load_image( "bg.png" );

    // 이미지 로드에 실패하면,
    if( image == NULL )
    {
        return false;
    }

    slime = load_image( "slime.png" );

    if(slime == NULL)
    {
     return false;
    }

    // 로드가 끝나면 true를 반환
    return true;
}

 slime에 이미지를 불러와줍시다.

void clean_up()
{
    // 이미지 객체 해제
    SDL_FreeSurface( image );
    SDL_FreeSurface( slime );

    // SDL 종료
    SDL_Quit();
}

 해제시키는 것도 잊으면 안되지요 ^^

        // 화면에 출력
apply_surface( 0, 0, image, screen );
apply_surface(350, 300, slime, screen);

// 화면 갱신
if( SDL_Flip( screen ) == -1 )
{
return 1;
}

 이제 화면에 출력해봅시다! 원하는대로 나왔나요? ^^


5 - 3 : PNG의 투명배경 처리 방법

 아까 5 - 1 에서 설명해드린 것 중에서 다시한번 이렇게 반문할 수 있겠습니다. "SDL은 PNG를 지원하는데, PNG에 투명배경을 쓰면 되지 않느냐?" 저의 답은 "예"입니다. 하지만 이 투명레이어를 SDL에서 사용하기 위해서는 약간의 장치가 필요합니다.

 load_image 함수부분에 있는

        // 화면의 포멧에 맞게 최적화한다
        optimizedImage = SDL_DisplayFormat( loadedImage );

 이 코드를

        // 화면의 포멧에 맞게 최적화한다
        optimizedImage = SDL_DisplayFormatAlpha( loadedImage );

 로 수정하시면 됩니다. 하지만, PNG의 투명레이어와 투명레이어를 적용하지 않은 PNG외의 다른 이미지 포멧에서의 ColorKey의 동시사용을 하면 기능이 적용되지 않습니다. 예를 들어서 JPG의 배경색을 ColorKey로 투명화하려하는데 SDL_DisplayFormatAlpha를 쓰게되면 그 아래에 아무리 ColorKey를 해도 적용이 안된다는 말이지요. 제가 테스트도 해봤답니다 ^^; 그래서 만약 프로그램에서 투명레이어를 적용한 것과 아닌 이미지를 혼용해서 사용해야한다면 load_image 함수에 장치를 걸어두는 것이 좋을 겁니다.

 오늘의 강의는 이것으로 마무리하겠습니다. Color Keying을 배움으로써 여러분께서 게임 개발할 수 있는 폭이 한층 더 넓어졌다고 볼 수 있겠습니다. 게임(특히 2D) 개발시에 빼놓을 수 없는 부분이기도 합니다. 오늘 강의한 코드를 받고 싶으시면 아래에 첨부해두었으니 받아서 써보시기 바랍니다.


 다음 강의는 스프라이트에 대해서 해보겠습니다. 간단히 설명하자면, 서로 관련있는(예를 들어 애니메이션) 이미지를 하나의 이미지에 넣은 것을 프로그램에서 표현하는 방법에 대해서 할까 합니다.


- Lesson 5를 마무리하며...

 이제 본격적으로 재미있는 부분이 시작되려합니다. 저도 힘내서 알기쉬운 강의를 만들도록 노력해야겠네요. 하지만 제가 워낙 가르치는건 잼병이라, 설명하는 걸 잘 하지 못합니다. 그래서 이해를 하지 못하실 수 있습니다 ㅇ<-< 잘 모르시겠으면, 제 프로필에 있는 연락처로 연락해주시기 바랍니다. 하나만 끄적여보자면,

MSN : dack1234@hotmail.com

 제 MSN주소입니다. 등록해주셔서 강의에 대한 평가라던가 거시기한점들을 뽐내주세요(?)