读书人

请教一上DX9关于surface的有关问题

发布时间: 2013-01-04 10:04:12 作者: rapoo

请问一下DX9关于surface的问题
1.如何显示一块surface
2.如何对surface像素进行操作
[解决办法]
我给你一个完整的例子(除了加载和渲染IDirect3DSurface9外,没有其他多余代码),另外有一个读取tga问的函数,这函数是为了演示如何手动加载像素到IDirect3DSurface9的,另外D3D的相关定义未给出,这个也就没必要写了:


// 保存对齐状态
#pragma pack(push)
#pragma pack(1)

// TGA 文件头
struct TGA_FILE_HEADER
{
// TGA像素数据的排列顺序:B G R A

BYTEIdLength;// 图像信息字段(默认:0)
BYTEColorMapType;// 颜色标的类型(默认0)
BYTEImageType;// 图像类型码(支持2或10)
WORDColorMapFirstIndex;// 颜色表的索引(默认:0)
WORDColorMapLength;// 颜色表的长度(默认:0)
BYTEColorMapEntrySize;// 颜色表表项的为数(默认:0,支持16/24/32)
WORDXOrigin;// 图像X坐标的起始位置(默认:0)
WORDYOrigin;// 图像Y坐标的起始位置(默认:0)
WORDImageWidth;// 图像的宽度
WORDImageHeight;// 图像的高度
BYTEPixelDepth;// 图像每像素存储占用位数
BYTEImageDescruptor;// 图像描述字符字节(默认: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);

//...
}



另外,本代码已经经过编译,运行无误。

读书人网 >网络游戏

热点推荐