版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/DY_1024/article/details/84075503
表面我们可以将其看作是Direct3D主要用于储存2D图像数据的一个像素矩阵。虽然我们将表面看作矩阵,但是其实际的存储是在一个线性数组里面。
表面的宽度(Width)和高度(Height)都是用像素来表示,跨度(Pitch)则用字节来度量,更具体的说:跨度(Pitch)可能比宽度(Width)更宽,这要依赖于底层的硬件实现,所以不能简单的假设pitch = Width×Height。
在代码中我们使用接口:IDirect3DSurface9 来描述表面,该接口提供了几种从表面读取和写入数据的方法,以及一种获取表面相关信息的方法,接口IDirect3DSurface9里面最重要的方法如下:
LockRect:该方法用于获取指向表面储存区的指针,通过指针运算,可以对表面上的每一个像素进行读写操作。
UnlockRect:如果调用了LockRect方法,并且执行完成了访问表面的操作,必须调用该方法对操作的表面储存区进行解除锁定的操作。
GetDesc:该方法可以使用填充结构D3DSURFACE_DESC来获取表面的相关信息。
如果考虑表面跨度,锁定表面储存区然后对每一个像素进行操作,看起来有些复杂,但是这里有一个简单的程序,作用就是锁定表面的储存区以及将每一个像素设为红色,通过这段代码帮助理解:
//假设surface是指向IDirect3DSurface接口的点
//假设每一个像素都采用32位的像素模式
//得到一些表面的描述
D3DSURFACE_DES surfaceDesc;
_surface->GetDesc(&surfaceDesc);
//获取一个指向表面像素的指针
D3DLOCKED_RECT lockedRect;
_surface->LockRect(
&lockRect, //接收锁定数据的指针
0, //锁定整个表面
0 //没有指定锁定标志
);
//迭代表面中的每一个像素,并将其设置为数据
DWORD* inmageData = (DWORD*)lockedRect.pBits;
for (int i = 0;i<surfaceDesc.Height;i++)
{
for (int j = 0;j <surfaceDesc.Width;j++)
{
//我们使用跨度去除以4,因为跨度是以字节为单位,每个DWORD有四个字节
int index = i * lockedRect.Pitch / 4 + j;
inmageData[index] = 0xffff0000; //红色
}
}
_surface->UnlockRect();
结构体D3DLOCKED_RECT定义如下:
typedef struct _D3DLOCKED_RECT{
INT Pitch; //表面的跨度
void* pBits; //指向表面内存开始的指针
}
关于锁定表面的代码有一点说明:32位的像素格式非常重要,因为我们要将位强制转化为32位的DWORD类型。这样我们就可将每个像素数据都用DWORD类型来描述。
关于DWORD的描述:
请参看我的另一篇文章:C++中BYTE、WORD、DWORD的作用以及区别