Using SDL: 비디오

[이전] 목차 [다음] # Simple DirectMedia Layer API 사용하기 ## 비디오(Video)
비디오 모드의 선택과 설정 (쉬운방법) 여러분의 맘에 드는 bit-depth 와 해상도를 선택하여 설정한다! | 팁 #1: SDL_GetVideoInfo() 함수를 사용해서 하드웨어에 의해 지원되는 가장 빠른 비디오 depth 를 얻을 수 있다. 팁 #2: SDL_ListModes() 함수를 사용해서 특정 bit-depth 하에 지원되는 비디오 해상도의 목록을 얻을 수 있다.
예제:
    { SDL_Surface *screen;

        screen = SDL_SetVideoMode(640, 480, 16, SDL_SWSURFACE);
        if ( screen == NULL ) {
            fprintf(stderr, "Unable to set 640x480 video: %s\n", SDL_GetError());
            exit(1);
        }
    }
화면에 점찍기 화면에 그리는 작업은 그래픽 프레임버퍼에 직접 쓴뒤 화면 갱신 함수를 호출함으로써 수행된다. | 팁: 만약 화면에 그릴 것이 많다면, 그리기 전에 (필요하다면) 화면을 한번 잠그고 갱신될 영역의 목록을 유지하다가 디스플레이를 갱신하기 전에 다시 화면을 푸는 것이 가장 좋은 방법이다.
예제: 무작위 포맷의 화면에 점찍기
    #include <SDL_endian.h>	/* 엔디안-종속적인 24 bpp 모드를 위해 사용 */

    void DrawPixel(SDL_Surface *screen, int x, int y, Uint8 R, Uint8 G, Uint8 B)
    {
        Uint32 color = SDL_MapRGB(screen->format, R, G, B);

        if ( SDL_MUSTLOCK(screen) ) {
            if ( SDL_LockSurface(screen) < 0 ) {
                return;
            }
        }
        switch (screen->format->BytesPerPixel) {
            case 1: { /* 8-bpp 라고 가정 */
                Uint8 *bufp;

                bufp = (Uint8 *)screen->pixels + y*screen->pitch + x;
                *bufp = color;
            }
            break;

            case 2: { /* 아마 15-bpp 아니면 16-bpp */
                Uint16 *bufp;

                bufp = (Uint16 *)screen->pixels + y*screen->pitch/2 + x;
                *bufp = color;
            }
            break;

            case 3: { /* 느린 24-bpp mode, 보통 사용되지 않는다 */
                Uint8 *bufp;

                bufp = (Uint8 *)screen->pixels + y*screen->pitch + x * 3;
                if(SDL_BYTEORDER == SDL_LIL_ENDIAN) {
                    bufp[0] = color;
                    bufp[1] = color >> 8;
                    bufp[2] = color >> 16;
                } else {
                    bufp[2] = color;
                    bufp[1] = color >> 8;
                    bufp[0] = color >> 16;
                }
            }
            break;

            case 4: { /* 아마 32-bpp */
                Uint32 *bufp;

                bufp = (Uint32 *)screen->pixels + y*screen->pitch/4 + x;
                *bufp = color;
            }
            break;
        }
        if ( SDL_MUSTLOCK(screen) ) {
            SDL_UnlockSurface(screen);
        }
        SDL_UpdateRect(screen, x, y, 1, 1);
    }
이미지의 로딩과 디스플레이 SDL은 사용자 편의를 위한 SDL_LoadBMP() 이라는 하나의 이미지 로딩 루틴을 제공한다. 이미지 로딩을 위한 라이브러리는 SDL 데모 모음에서 발견할 수 있다. SDL_BlitSurface() 를 사용해서 그래픽 프레임버퍼로 이미지를 blit 하면 화면에 디스플레이할 수 있다. SDL_BlitSurface() 는 자동적으로 blit 사각형을 클립(clip)하는데, 이 blit 사각형은 SDL_BlitSurface()에 넘겨져 바뀐 화면의 영역이 갱신되도록 한다. | 팁 #1: 만약 여러번 그려질 이미지를 로딩하려면, 이미지를 스크린의 포맷으로 변환하여 blit 속도를 향상시킬 수 있다. SDL_DisplayFormat() 함수가 이러한 변환을 해 준다. 팁 #2: 많은 스프라이트 이미지들은 투명한 배경을 가진다. SDL_SetColorKey() 함수를 사용해서 투명한 blit(컬러키 blit)을 할 수 있다.
예제:
    void ShowBMP(char *file, SDL_Surface *screen, int x, int y)
    {
        SDL_Surface *image;
        SDL_Rect dest;

        /* BMP 파일을 서페이스로 읽어들임 */
        image = SDL_LoadBMP(file);
        if ( image == NULL ) {
            fprintf(stderr, "Couldn't load %s: %s\n", file, SDL_GetError());
            return;
        }

        /* 화면 서페이스에 Blit.
           서페이스는 이 시점에서 잠궈져있지 않아야 한다. */
        dest.x = x;
        dest.y = y;
        dest.w = image->w;
        dest.h = image->h;
        SDL_BlitSurface(image, NULL, screen, &dest);

        /* 화면의 변화된 부분을 갱신 */
        SDL_UpdateRects(screen, 1, &dest);

        SDL_FreeSurface(image);
    }
[이전] 목차 [다음]