Direct3D基础——预备知识:表面

版权声明:本文为博主原创文章,未经博主允许不得转载。 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的作用以及区别

猜你喜欢

转载自blog.csdn.net/DY_1024/article/details/84075503
今日推荐