8,304
社区成员
发帖
与我相关
我的任务
分享
// 保存对齐状态
#pragma pack(push)
#pragma pack(1)
// TGA 文件头
struct TGA_FILE_HEADER
{
// TGA像素数据的排列顺序:B G R A
BYTE IdLength; // 图像信息字段(默认:0)
BYTE ColorMapType; // 颜色标的类型(默认0)
BYTE ImageType; // 图像类型码(支持2或10)
WORD ColorMapFirstIndex; // 颜色表的索引(默认:0)
WORD ColorMapLength; // 颜色表的长度(默认:0)
BYTE ColorMapEntrySize; // 颜色表表项的为数(默认:0,支持16/24/32)
WORD XOrigin; // 图像X坐标的起始位置(默认:0)
WORD YOrigin; // 图像Y坐标的起始位置(默认:0)
WORD ImageWidth; // 图像的宽度
WORD ImageHeight; // 图像的高度
BYTE PixelDepth; // 图像每像素存储占用位数
BYTE ImageDescruptor; // 图像描述字符字节(默认:0,不支持16bit 565格式)
};
// 像素
struct PIXEL32
{
BYTE B; // 蓝色
BYTE G; // 绿色
BYTE R; // 红色
BYTE A; // 通道
};
#pragma pack(pop)//恢复对齐状态
// 获取tga文件的bmp数据(无压缩的tga文件)
void GetBmpFromTga(const char* srcFile, UINT** ppDstBmpBuffer, int* pOutWidth, int* pOutHeight, int* pOutSize)
{
TGA_FILE_HEADER TgaHeader;
memset(&TgaHeader, 0, sizeof(TGA_FILE_HEADER));
FILE* pFile = fopen(srcFile, "rb");
if (pFile == NULL)
{
char strErrorInfo[256];
sprintf(strErrorInfo, "%s打开失败!", srcFile);
MessageBox(0, strErrorInfo, 0, MB_OK);
return;
}
UINT* pBmpData = NULL;
int pixelCount = 0;
// 读TGA图像文件头
fread((char*)(&TgaHeader), sizeof(TGA_FILE_HEADER), 1, pFile);
pixelCount = TgaHeader.ImageWidth * TgaHeader.ImageHeight;
pBmpData = new UINT[pixelCount];
// 读图像数据
fread(pBmpData, sizeof(PIXEL32)*pixelCount, 1, pFile);
fclose(pFile);
if (ppDstBmpBuffer != NULL) *ppDstBmpBuffer = pBmpData;
if (pOutWidth != NULL) *pOutWidth = TgaHeader.ImageWidth;
if (pOutHeight != NULL) *pOutHeight = TgaHeader.ImageHeight;
if (pOutSize != NULL) *pOutSize = sizeof(PIXEL32) * pixelCount;
}
// 初始化
void CRender::InitData()
{
m_pSurface = NULL;
D3DXIMAGE_INFO imageInfo;
D3DXGetImageInfoFromFile("test.tga", &imageInfo);
HRESULT hr;
hr = m_pD3DDevice->CreateOffscreenPlainSurface(imageInfo.Width, imageInfo.Height, imageInfo.Format, D3DPOOL_DEFAULT, &m_pSurface, NULL);
if (FAILED(hr))
{
MessageBox(0, "CreateOffscreenPlainSurface()创建失败!", 0, MB_OK);
}
m_Width = imageInfo.Width;
m_Height = imageInfo.Height;
// 用D3DXLoadSurfaceFromFile()加载像素
if (true)
{
D3DXLoadSurfaceFromFile(m_pSurface, NULL, NULL, "test.tga", NULL, D3DX_FILTER_NONE, 0, &imageInfo);
}
// 手动加载像素
if (false)
{
UINT* pBmp32 = NULL;
// 加载tga文件
{
GetBmpFromTga("test.tga", &pBmp32, &m_Width, &m_Height, NULL);
}
D3DLOCKED_RECT lrect;
hr = m_pSurface->LockRect(&lrect, NULL, 0);
if (FAILED(hr))
{
delete pBmp32;
pBmp32 = NULL;
m_pSurface->UnlockRect();
return;
}
UINT* pSrc = (UINT*)pBmp32;
UINT* pDst = static_cast<UINT*>(lrect.pBits);
int pitch = lrect.Pitch/sizeof(UINT);
pSrc += (m_Height-1)*m_Width;
for (int h=0, w=0, index=0; h<m_Height; h++)
{
memcpy(pDst, pSrc, sizeof(UINT)*m_Width);
pSrc-=m_Width, pDst+=pitch;
}
m_pSurface->UnlockRect();
delete pBmp32;
pBmp32 = NULL;
}
}
// 加载表面数据
void CRender::InitData()
{
m_pSurface = NULL;
D3DXIMAGE_INFO imageInfo;
D3DXGetImageInfoFromFile("test.tga", &imageInfo);
HRESULT hr;
hr = m_pD3DDevice->CreateOffscreenPlainSurface(imageInfo.Width, imageInfo.Height, imageInfo.Format, D3DPOOL_DEFAULT, &m_pSurface, NULL);
if (FAILED(hr))
{
MessageBox(0, "CreateOffscreenPlainSurface()创建失败!", 0, MB_OK);
}
m_Width = imageInfo.Width;
m_Height = imageInfo.Height;
// 用D3DXLoadSurfaceFromFile()加载像素
if (true)
{
D3DXLoadSurfaceFromFile(m_pSurface, NULL, NULL, "test.tga", NULL, D3DX_FILTER_NONE, 0, &imageInfo);
}
// 手动加载像素
if (false)
{
UINT* pBmp32 = NULL;
// 加载tga文件
{
GetBmpFromTga("test.tga", &pBmp32, &m_Width, &m_Height, NULL);
}
D3DLOCKED_RECT lrect;
hr = m_pSurface->LockRect(&lrect, NULL, 0);
if (FAILED(hr))
{
delete pBmp32;
pBmp32 = NULL;
m_pSurface->UnlockRect();
return;
}
UINT* pSrc = (UINT*)pBmp32;
UINT* pDst = static_cast<UINT*>(lrect.pBits);
int pitch = lrect.Pitch/sizeof(UINT);
pSrc += (m_Height-1)*m_Width;
for (int h=0, w=0, index=0; h<m_Height; h++)
{
memcpy(pDst, pSrc, sizeof(UINT)*m_Width);
pSrc-=m_Width, pDst+=pitch;
}
m_pSurface->UnlockRect();
delete pBmp32;
pBmp32 = NULL;
}
}
// 渲染表面数据
void CRender::RenderExample()
{
// ...
IDirect3DSurface9* backbuffer = NULL;
RECT rcSrc = { 0, 0, m_Width, m_Height }; // 纹理坐标
RECT rcDst = { 200, 200, 0, 0 }; // 目标矩形区域
rcDst.right = rcDst.left + (rcSrc.right-rcSrc.left);
rcDst.bottom = rcDst.top + (rcSrc.bottom-rcSrc.top);
m_pD3DDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
m_pD3DDevice->StretchRect(m_pSurface, &rcSrc, backbuffer, &rcDst, D3DTEXF_NONE);
m_pD3DDevice->UpdateSurface(m_pSurface, NULL, backbuffer, NULL);
//...
}