=================================
=================================
=================================
기본 헤더
typedef struct tgaTARGAFILEHEADER {
unsigned char imageIDLength; // 식별 필드의 길이 // 0이면 식별 필드가 포함되지 않은 것이다.
unsigned char colorMapType; // 색상 맵의 종류 : 항상 0임
unsigned char imageTypeCode; // 2 이면 압축되지 않은 RGB
// 3 이면 압축되지 않은 그레이 스케일
short int colorMapOrigin; // 색상 맵의 시작 위치( 하위-상위) ; 항상 0임
short int colorMapLength; // 색상 맵의 길이 ( 하위 - 상위) : 항상 0임
unsigned char colorMapEntrySize; // 색상 맵의 항목 크기( 하위 - 상위) : 항상 0임
short int imageXOrigin; // 이미지 우측 하단 x 좌표 (하위 - 상위) : 항상 0임
short int imageYOrigin; // 이미지의 좌측 하단 x좌표 (하위-상위) : 항상 0임
short int imageWidth; // 이미지의 픽셀 단위 너비( 하위 - 상위)
short int imageHeight; // 이미지의 픽셀 단위 높이( 하위 - 상위)
unsigned char bitCount; // 색상 비트 수 : 16, 24, 32
unsigned char imageDescriptor; // 24비트 : 0x00 ; 32비트 : 0x08
}
TARGAFILEHEADER;
=================================
=================================
=================================
기본 구조는 bmp 구조랑 같습니다
-
------------
- 헤더 -
------------
- 이미지 -
- -
------------
읽어 들이기~ 거짐 bmp랑 같습니다 ~
unsigned char ucharBad = 0; // 임시용 unsigned char data 필요없는 정보 넘기기용
short int sintBad = 0; // 임시용 short int data 필요없는 정보 넘기기용
// ucharBad,sintBad 는 저는 불필요해서 뛰어서 넘어 갔습니다. 필요하신분은 읽어서 사용~
TARGAFILEHEADER temp_TgaFileHeader; // 구조체로 저장이 안되어 있기때문에 일일이 읽어야한다(제 생각^^;)
//구조 사이즈로 읽을라 했으나 크기가 않맞아서 이렇게 일일이 로드해야 하더라구요 ~
file.Read( & ucharBad, sizeof(unsigned char));
file.Read( & ucharBad, sizeof(unsigned char));
file.Read( & temp_TgaFileHeader.imageTypeCode, sizeof(unsigned char));
file.Read( & sintBad, sizeof(short int));
file.Read( & sintBad, sizeof(short int));
file.Read( & ucharBad, sizeof(unsigned char));
file.Read( & sintBad, sizeof(short int));
file.Read( & sintBad, sizeof(short int));
file.Read( & temp_TgaFileHeader.imageWidth, sizeof(short int));
file.Read( & temp_TgaFileHeader.imageHeight, sizeof(short int));
file.Read( & temp_TgaFileHeader.bitCount, sizeof(unsigned char));
file.Read( & ucharBad, sizeof(unsigned char));
// colorMode -> 3 = BGR, 4 = BGRA
colorMode = temp_TgaFileHeader.bitCount / 8; //32비트는 4, 24비트는 3이됩니다
//미리 3을 곱하고 4의 배수를 구함으로서 최소의 4의 배수를 구한다. 가로가 657이면 657*3의 4의배수니 1972가 나온다.
tmpWidthBytes = (temp_TgaFileHeader.imageWidth) * colorMode; // 필요한 줄의 바이트 수....
tmpWidthBytes = (tmpWidthBytes + 3) & ~3; // 4의 배수화 시킴.
if (temp_TgaFileHeader.bitCount == 24) {
int imgsize = temp_TgaFileHeader.imageWidth * colorMode;
imgsize = (imgsize + colorMode) & ~colorMode;
imageSize = imgsize * temp_TgaFileHeader.imageHeight;
} else if (temp_TgaFileHeader.bitCount == 32)
imageSize = (temp_TgaFileHeader.imageWidth *
temp_TgaFileHeader.imageHeight * colorMode);
int bitsize = 0;
int nSize = sizeof(BITMAPINFOHEADER) +
(4 * (temp_TgaFileHeader.imageWidth *
temp_TgaFileHeader.imageHeight)) + sizeof(RGBQUAD);
=================================
=================================
=================================
//tga 헤더 내용을 Bmp에 맡게 변경해 줍니다
temp_BmpFileHeader.bfType = 0x4d42;
temp_BmpFileHeader.bfSize = sizeof(BITMAPFILEHEADER)+nSize;
temp_BmpFileHeader.bfReserved1 =0;
temp_BmpFileHeader.bfReserved2 =0;
// -2를 하지 않으면 에러 남 // bfOffBits 를 설정해주어서 얼마만큼이 bitmap인지 알려준다.
temp_BmpFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)+ sizeof(RGBQUAD);
temp_BmpInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
temp_BmpInfoHeader.biWidth = temp_TgaFileHeader.imageWidth;
temp_BmpInfoHeader.biHeight = temp_TgaFileHeader.imageHeight;
temp_BmpInfoHeader.biPlanes = 1;
temp_BmpInfoHeader.biBitCount = temp_TgaFileHeader.bitCount;
temp_BmpInfoHeader.biCompression = 0;
temp_BmpInfoHeader.biSizeImage = temp_TgaFileHeader.imageWidth*temp_TgaFileHeader.imageHeight;
temp_BmpInfoHeader.biXPelsPerMeter = 0;
temp_BmpInfoHeader.biYPelsPerMeter = 0;
temp_BmpInfoHeader.biClrUsed = 0;
temp_BmpInfoHeader.biClrImportant = 0;
temp_RGBQUAD.rgbBlue =0;
temp_RGBQUAD.rgbGreen =0;
temp_RGBQUAD.rgbRed =0;
temp_RGBQUAD.rgbReserved =0;
m_TgaImgSize = imageSize; //타가의 이미지 사이즈를 헤더타가이미지 사이즈에 저장.
m_pImageTga = new BYTE[imageSize];
tmpImg = new BYTE[imageSize];
BYTE* tmpImg2 ;
BYTE* tmpM_pImageTga ; //멤버헤더타가의 임시 포인터
tmpImg2 = tmpImg;
tmpM_pImageTga = m_pImageTga;
int headSize = sizeof(TARGAFILEHEADER);
file.Read(m_pImageTga,imageSize);
int nTargetWidth = (tmpWidthBytes-(temp_BmpInfoHeader.biWidth*colorMode)) ;
//-----------------------------------------------------
//TGA RLE 압축!! tga의 RLE 압축 이미지를 로드 합니다
//압축 포인트
//다른점일때는 0 ~ 127 까지의 숫자를 사용합니다.
//같은점일때에는 128+0 ~ 128+127 의 숫자를 사용합니다.
//width로 하나씩 Height와 비교하면서 그려나가야 한다.
//--------------------------------------------------------
/*
128+0 ~ 128+127 같은 점일때
----------------------
| 점의정보 | 점하나 |
----------------------
0~127 다른 점일때
--------------------------------------
| 점의정보 | 점의 정보갯수만큼 점들 |
--------------------------------------
*/
//예로 들어 설명하겠습니다
//처음 바이트를 읽을때 값이 56 이라면 다른점의 0~127의 안에 들어오니깐
//56개의 다른점을 찍습니다...그리고 다음 점의 정보를 읽습니다
//다음값의 정보가 200이라면 128+0 ~ 128+127 의 범위안에 들어 옵니다
//여기서 200-127의 즉 73개만큼 다른 점을 찍는다고 보시면 됩니다.
//이런방식으로 계속 읽어나가 width와 height를 비교하고 압축을 풀면 됩니다
int pNum;
int imgWidth = 0;
int imgHeight = 0;
if (temp_TgaFileHeader.imageTypeCode == 10) // imageTypeCode 코드가 10이라면 압축된 코드 입니다
while (temp_TgaFileHeader.imageHeight > imgHeight) {
pNum = m_pImageTga[0];
if (pNum > 127) //(128+0 ~ 128+127 ) 범위의 값
for (int i = 0; i < pNum - 127; i++) // 127이 넘으면 같은 점이기에 여기서 127을 빼서 같은 점의 갯수를 구하고 그만큼 루프를 돌립니다.
{
for (int k = 1; k < colorMode + 1; k++) //처음 점의 정보(같은점,다른점)를 넘기기 위해 '1'부터 시작
//여기서는 한점으로 여러번 점의 정보 갯수만큼 채웁니다( 같은 점이기에)
tmpImg[k - 1] = m_pImageTga[k];
}
tmpImg += colorMode;
imgWidth++;
}
m_pImageTga = m_pImageTga + colorMode + 1;
}
//0~127 사이의 범위값 여기서는 점정보 만큼 점의 갯수를 읽고 넘겨줍니다
else {
m_pImageTga++;
for (int i = 0; i <= pNum; i++) { //127까지니깐 i<=pNum크기만큼 끈어주면 된다. 127포함까지
for (int k = 0; k < colorMode; k++) {
tmpImg[k] = m_pImageTga[k]; //점의 정보만큼 넘겨줍니다
}
m_pImageTga += colorMode;
tmpImg += colorMode;
imgWidth++;
}
}
if (imgWidth == temp_TgaFileHeader.imageWidth) {
if (temp_BmpInfoHeader.biBitCount == 24) //24비트일떄만 해준다.
tmpImg = tmpImg + nTargetWidth; //24비트일때는 4자리를 못채우므로 width길이를 맞추어 줍니다
imgWidth = 0;
imgHeight++;
}
}
//------------------------------------------------------------------------------
//TGA 보통 그림 풀기
//그대로 그림의 리소스를 받아 옮겨주기만 하면 됩니다
//
//-------------------------------------------------------------------------------
//psj 고쳐야 할곳
if(temp_TgaFileHeader.imageTypeCode != 10) // 압축이 아닐때
for(int i=0;i<temp_BmpInfoHeader.biHeight;i++)
{
for(int k=0;k<temp_BmpInfoHeader.biWidth;k++)
{
// rgba,argb <=>BGRA
//TGA: 0-blue , 1-green, 2-red , 3-alpha
//BMP: 0-blue , 1-green, 2-red , 3-alpha
if(temp_TgaFileHeader.bitCount==32)
{
tmpImg[0]=m_pImageTga[0]; //a
tmpImg[1]=m_pImageTga[1]; //r
tmpImg[2]=m_pImageTga[2]; //g
tmpImg[3]=m_pImageTga[3]; //b
}
if(temp_TgaFileHeader.bitCount==24)
{
tmpImg[0]=m_pImageTga[0]; //r
tmpImg[1]=m_pImageTga[1]; //a
tmpImg[2]=m_pImageTga[2]; //b
}
tmpImg +=colorMode;
m_pImageTga+=colorMode;
}
if(temp_BmpInfoHeader.biBitCount==24) //24비트일떄만 해준다.
tmpImg=tmpImg+nTargetWidth; //24비트일때는 4자리를 못채우므로 width길이를 맞추어 줍니다
}
tmpImg= tmpImg2;
=================================
=================================
=================================
// 오늘도 오크 코딩~~~~
// 이 tga로딩을 리소스를 빼서 그대로 이용해두 되고 bmp로 로드해서 mfc에 뿌려 주어두 되고 여러가지로 응용~
// 좋은 방법 있으신 분들 언제나 충언 해주세요 +.+ (오크 코딩 이해해 주세요 ㅠㅠ)
=================================
=================================
=================================
'프로그래밍 관련 > 게임프로그래밍' 카테고리의 다른 글
CustomUI IME editbox 멀티라인 텍스트박스~ (DXUT editbox상속) 관련 (0) | 2020.09.16 |
---|---|
게임 GUI 멀티 해상도 팁 (0) | 2020.09.16 |
게임 GUI 구현에 대한 조언 (0) | 2020.09.16 |
네이버 게임게발자 질문/답변 서버 패킷 안보내질때 (0) | 2020.09.13 |
매니지드 언어(Java, C# 등등) 로 MMORPG 만들기 어떤가요? (0) | 2020.09.13 |