1
| | #include <windows.h>
#include <stdio.h>
#include <math.h>
int m_nWidth, m_nHeight;
typedef struct __TGAHeader
{
unsigned char m_cLength;
unsigned char m_cType;
unsigned char m_cImageType;
unsigned char m_cSize;
unsigned char m_cDepth;
unsigned char m_cDesc;
unsigned short m_wIndex;
unsigned short m_wCnt;
unsigned short m_wHoriz;
unsigned short m_wVert;
unsigned short m_wWidth;
unsigned short m_wHeight;
}TGAHeader;
typedef struct __Pixel { unsigned char m_cR,m_cG,m_cB,m_cA; }Pixel;
void WritePixel(Pixel* Image,Pixel* Pix,int x, int y){ *(Image + m_nWidth * y + x)= *Pix;}
void ReadPixel(Pixel* Image,Pixel* Pix,int x, int y){ *Pix = *(Image + m_nWidth * y + x);}
unsigned char PackFloatInUChar(float in){ return (unsigned char) ((in + 1.0f) / 2.0f * 255.0f);}
#define IFileName "Texture.tga"
#define OFileName "TextureDot3.tga"
void Error(const char* msg,...){
char Buffer[4096];
va_list ap;
va_start(ap,msg);
vsprintf(Buffer,msg,ap);
va_end(ap);
MessageBox(HWND_DESKTOP,Buffer,"TgaToNrm",MB_ICONERROR);
}
int main(){
TGAHeader Header;
FILE* IFile, *OFile;
unsigned long dwBytesRead;
unsigned char* pDescBytes;
Pixel Pix, *SrcImage, *DstImage;
float fNX, fNY, fNZ, fDX, fDY, fLN;
printf("Converts TGA image to normal map\n\n");
IFile = fopen(IFileName,"rb");
OFile = fopen(OFileName,"wb");
if(IFile == NULL){Error("Input file \"%s\" unable to open!",IFileName); return FALSE; }
if(OFile == NULL){Error("Output file \"%s\" unable to open!",OFileName); return FALSE; }
dwBytesRead = (unsigned long)fread(&Header,sizeof(unsigned char),sizeof(Header),IFile);
dwBytesRead = (unsigned long)fwrite(&Header,sizeof(unsigned char),sizeof(Header),OFile);
pDescBytes = (unsigned char*)malloc(sizeof(unsigned char) * Header.m_cLength);
dwBytesRead = (unsigned long)fread(pDescBytes,sizeof(unsigned char),Header.m_cLength,IFile);
dwBytesRead = (unsigned long)fwrite(pDescBytes,sizeof(unsigned char),Header.m_cLength,OFile);
m_nWidth = Header.m_wWidth;
m_nHeight = m_nWidth;
SrcImage = (Pixel*)malloc(sizeof(Pixel) * m_nHeight * m_nWidth);
DstImage = (Pixel*)malloc(sizeof(Pixel) * m_nHeight * m_nWidth);
printf("--- Image loaded: %s(%ix%i)\n",IFileName,m_nWidth,m_nHeight);
for(int y = 0; y < m_nHeight; y ++){
for(int x = 0; x < m_nWidth; x ++){
fread(&Pix.m_cB,sizeof(unsigned char),1,IFile);
fread(&Pix.m_cG,sizeof(unsigned char),1,IFile);
fread(&Pix.m_cR,sizeof(unsigned char),1,IFile);
if(Header.m_cDepth == 32)
fread(&Pix.m_cA,sizeof(unsigned char),1,IFile);
else
Pix.m_cA = 0xCC;
WritePixel(SrcImage,&Pix,x,y);
}
}
for(int y = 0; y < m_nHeight; y ++){
for(int x = 0; x < m_nWidth; x ++){
// Y Sobel
ReadPixel(SrcImage,&Pix,(x - 1 + m_nWidth) % m_nWidth,(y + 1) % m_nHeight);
fDY = ((float)Pix.m_cR) / 255.0f * (-1.0f);
ReadPixel(SrcImage,&Pix,x % m_nWidth,(y + 1) % m_nHeight);
fDY += ((float)Pix.m_cR) / 255.0f * (-2.0f);
ReadPixel(SrcImage,&Pix,(x + 1) % m_nWidth,(y + 1) % m_nHeight);
fDY += ((float)Pix.m_cR) / 255.0f * (-1.0f);
ReadPixel(SrcImage,&Pix,(x - 1 + m_nWidth) % m_nWidth,(y - 1 + m_nHeight) % m_nHeight);
fDY += ((float)Pix.m_cR) / 255.0f * 1.0f;
ReadPixel(SrcImage,&Pix,x % m_nWidth,(y - 1 + m_nHeight) % m_nHeight);
fDY += ((float)Pix.m_cR) / 255.0f * 2.0f;
ReadPixel(SrcImage,&Pix,(x + 1) % m_nWidth,(y - 1 + m_nHeight) % m_nHeight);
fDY += ((float)Pix.m_cR) / 255.0f * 1.0f;
// X Sobel
ReadPixel(SrcImage,&Pix,(x - 1 + m_nWidth) % m_nWidth,(y - 1 + m_nHeight) % m_nHeight);
fDX = ((float)Pix.m_cR) / 255.0f * (-1.0f);
ReadPixel(SrcImage,&Pix,(x - 1 + m_nWidth) % m_nWidth,y % m_nHeight);
fDX += ((float)Pix.m_cR) / 255.0f * (-2.0f);
ReadPixel(SrcImage,&Pix,(x - 1 + m_nWidth) % m_nWidth,(y + 1) % m_nHeight);
fDX += ((float)Pix.m_cR) / 255.0f * (-1.0f);
ReadPixel(SrcImage,&Pix,(x + 1) % m_nWidth,(y - 1 + m_nHeight) % m_nHeight);
fDX += ((float)Pix.m_cR) / 255.0f * 1.0f;
ReadPixel(SrcImage,&Pix,(x + 1) % m_nWidth,y % m_nHeight);
fDX += ((float)Pix.m_cR) / 255.0f * 2.0f;
ReadPixel(SrcImage,&Pix,(x + 1) % m_nWidth,(y + 1) % m_nHeight);
fDX += ((float)Pix.m_cR) / 255.0f * 1.0f;
fNX = -fDX;
fNY = -fDY;
fNZ = 1.0f;
fLN = 1.0f / (sqrtf(fNX * fNX + fNY * fNY + fNZ * fNZ));
fNX *= fLN;
fNY *= fLN;
fNZ *= fLN;
Pix.m_cR = PackFloatInUChar(fNX);
Pix.m_cG = PackFloatInUChar(fNY);
Pix.m_cB = PackFloatInUChar(fNZ);
WritePixel(DstImage,&Pix,x,y);
}
}
for(int y = 0; y < m_nHeight; y ++){
for(int x = 0; x < m_nWidth; x ++){
ReadPixel(DstImage,&Pix,x,y);
fwrite(&Pix.m_cB,sizeof(unsigned char),1,OFile);
fwrite(&Pix.m_cG,sizeof(unsigned char),1,OFile);
fwrite(&Pix.m_cR,sizeof(unsigned char),1,OFile);
if(Header.m_cDepth == 32)
fwrite(&Pix.m_cA,sizeof(unsigned char),1,OFile);
}
}
printf("--- Image saved: %s(%ix%i)\n\n",OFileName,m_nWidth,m_nHeight);
free(SrcImage);
free(DstImage);
free(pDescBytes);
fclose(IFile);
fclose(OFile);
MSG msg;
ZeroMemory(&msg,sizeof(MSG));
while(msg.message != WM_QUIT){
if(PeekMessage(&msg,NULL,0U,0U,PM_NOREMOVE)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return TRUE;
}
|