블로그는 나의 힘!
[ Programing ]/OpenGL2010. 3. 16. 08:59

#include <stdio.h>
#include <memory.h>
#include <SDL.h>       // SDL
#include <GLut.h>      // OpenGL Util

// bmp 파일로 해당 위치에 저장한다.
bool SetSaveFile( char* Position )
{
    sprintf( FileName, "%s/SceenShot_%d.bmp", Position, Sequence++ );

    SDL_Surface* SDL_Image = NULL;
    long long int ReadDataMax = 0;

    // SDL_Surface 의 map, format의 정보 속성 설정을 몰라 일단 백지 샘플 비트맵 로드.
    // 이후 거기에 들어 있는 값 중에 픽셀과 해상도 크기를 교체 하는 식으로 대처 저장.

    SDL_Image = SDL_LoadBMP( "./resource/sample.bmp" ); 

    // 픽셀 교체로 이미지 변경
    // 크기 변경으로 이미지 변경 ( 참고 : 지금 게임 상태의 0 좌표는 좌측 하단 )

    SDL_Image->pixels = ( void* )DataBuffer;
    SDL_Image->clip_rect.x = 0;
    SDL_Image->clip_rect.y = 0;
    SDL_Image->clip_rect.w = WindowWidth;
    SDL_Image->clip_rect.h = WindowHeight;


    // 비트맵 저장
    SDL_SaveBMP( SDL_Image, FileName );

    return true;
}

// 화면을 스캔 한다.
bool SetSceenShot()

    // 전체 화면의 픽셀을 읽어 온다. ( DX9 : D3DXSaveSurfaceToFile() )
    switch ( WindowRGB )
    {
    case 3:  // RGB
       // 앞에 4개는 윈도우 좌표계에서 읽어 들일 범위, 픽셀포맷, 데이터 포맷, 저장될 대상
       glReadPixels( 0, 0, WindowWidth, WindowHeight, GL_RGB, GL_UNSIGNED_BYTE, ReadData );
       break;
    case 4:  // RGBA
        // 앞에 4개는 윈도우 좌표계에서 읽어 들일 범위, 픽셀포맷, 데이터 포맷, 저장될 대상
       glReadPixels( 0, 0, WindowWidth, WindowHeight, GL_RGBA, GL_UNSIGNED_BYTE, ReadData );
       break;
    default:

       break;
    }

    return true;
}

// 픽셀을 읽어 온다.
bool SetReadPixel( bool Turn )

    if( Turn )    // 비트맵이 상하 반전 되었다면 되돌려 주고, ReadData -> DataBuffer 로 저장.
    {    
        long int Index   = WindowWidth * WindowRGB;     // 가로 길이
        long int Count   = 0;          // 현재 세로 위치 ( Height )
        long int Line   = WindowWidth * WindowRGB * ( Count++ );    // 가로 다음줄 인덱스 계산 위해

        for( long int i = ReadPixelMax; i > 0; i-- )
        {
            DataBuffer[Index--] = ReadData[i];
            if( Line == Index )
            {
                Line = WindowWidth * WindowRGB * ( Count++ );
                Index = WindowWidth * WindowRGB * Count;    
            }  // >>> END if
        } // >>> END for

    } // >>> END if
    else    // ReadData -> DataBuffer 로 저장.
    {
        memcpy( DataBuffer, ReadData, sizeof( ReadData ) );
    } // >>> END else

    return true;
}

// 색 반전 변경.
bool SetChangeRGB()
{
    // BGR -> RGB 반전 변경 처리. RGB의 RB 값이 바뀌어 있어 임의 변경.
    for( long int i = 0; i < ReadPixelMax; i+= WindowRGB )
    {
        char *ReadRGB = (char *)&ReadData[i];
        char TempRGB = *( ReadRGB +0 );

        *( ReadRGB +0 ) = *( ReadRGB +2 );
        *( ReadRGB +2 ) = TempRGB;
    } // >>> END for 

    return true;
}

bool SceenShot::Initialize()

    // BMP 가로 * 세로 * 현재 컬러 ( 24비트 ) 
    // RGBA : 32 비트, RGB : 24 비트

    // 전체 화면 픽셀 담기 위한 변수.   GLbyte == signed char
    if( !ReadData )  ReadData = new GLbyte[WindowWidth * WindowHeight * WindowRGB];   
    // 비트맵 저장하기 위한 변수.   GLbyte == signed char
    if( !DataBuffer ) DataBuffer = new GLbyte[WindowWidth * WindowHeight * WindowRGB];

    return true;
}

bool Release()
{
    if( ReadData )
    {
        delete[] ReadData;
        ReadData = NULL;
    } // >>> END if

    if( DataBuffer )
    {
        delete[] DataBuffer;
        DataBuffer = NULL;
    } // >>> END if

    return true;
}

bool Clear()
{
    WindowWidth   = 800;    // long int
    WindowHeight  = 600;    // long int
    WindowRGB    =    3;    // long int RGB 이면 *3, RGBA 이면 *4

    Sequence       =    0;    // long int
    ReadPixelMax = WindowWidth * WindowHeight * WindowRGB;   // 전체 이미지 크기.   long int
    memset( FileName, 0, sizeof( FileName ) );

    return true;
}

// 게임 화면을 스캔한다.  ( Manager )
// Position : 저장할 위치, Turn : 상하 반전, RGBChange : BGR -> RGB 값 변경

bool SetPrint( char* Position, bool Turn, bool RGBChange )
{
    SetSceenShot(); 

    if( RGBChange ) SetChangeRGB();
 
    SetReadPixel( Turn );   
    SetSaveFile( Position );

    return true;
}



To be contiunued... [Private]

'[ Programing ] > OpenGL' 카테고리의 다른 글

전체 화면 설정 및 기타 설정  (0) 2010.04.19
[OpenGL Move]  (0) 2009.12.23
Posted by Mister_Q