初始化Direct3D
(在这个过程中仍需要程序员熟知图形学的基础知识和D3D的基本类型)
Direct3D:是一种低层图形API,它能让我们利用3D硬件加速来渲染3D世界。我们可以把Direct3D看作是应用程序和图形设备之间的中介。
HAL: Direct3D不能直接作用于图形设备,因为现在市面上的显卡种类实在是太多了并且每种显卡都有不同的性能和处理事件的方式。例如,两种不同的显卡实现清屏的方式也可能是不同的。因此,Direct3D要求设备制造商实现HAL。HAL是一组指示设备执行某种操作的特殊设备代码的集合。用这种方法,Direct3D避免了必须去了解某个设备的特殊细节,使它能够独立于硬件设备。
表面:表面是一个像素点阵,在Direct3D中主要用来存储2D图形数据。
表面的Width和Height是按像素计算的。Pitch以字节为单位。而且Pitch有可能比Width大且依赖于低层硬件,所以不能单纯的认为Pitch = Width * sizeof (pixelFormat)。
先来看看SDK上定义的D3DSURFACE_DESC结构
D3DSURFACE_DESC Structure
Describes a surface.
Syntax
typedef struct _D3DSURFACE_DESC {
D3DFORMAT Format;
D3DRESOURCETYPE Type;
DWORD Usage;
D3DPOOL Pool;
D3DMULTISAMPLE_TYPE MultiSampleType;
DWORD MultiSampleQuality;
UINT Width;
UINT Height;
} D3DSURFACE_DESC;
Members
Format
Member of the D3DFORMAT enumerated type, describing the surface format.
Type
Member of the D3DRESOURCETYPE enumerated type, identifying this resource as a surface.
Usage
Either the D3DUSAGE_DEPTHSTENCIL or D3DUSAGE_RENDERTARGET values. For more information, see D3DUSAGE.
Pool
Member of the D3DPOOL enumerated type, specifying the class of memory allocated for this surface.
MultiSampleType
Member of the D3DMULTISAMPLE_TYPE enumerated type, specifying the levels of full-scene multisampling supported by the surface.
MultiSampleQuality
Quality level. The valid range is between zero and one less than the level returned by pQualityLevels used by IDirect3D9::CheckDeviceMultiSampleType. Passing a larger value returns the error, D3DERR_INVALIDCALL. The MultisampleQuality values of paired render targets, depth stencil surfaces and the MultiSample type must all match.
Width
Width of the surface, in pixels.
Height
Height of the surface, in pixels.
SDK中对 LockRect的说明
----------------------------------------------------------------------------------------------------------------------
IDirect3DSurface9::LockRect Method
Locks a rectangle on a surface.
Syntax
HRESULT LockRect(
D3DLOCKED_RECT *pLockedRect,
const RECT *pRect,
DWORD Flags
);
Parameters
pLockedRect
[out] Pointer to a D3DLOCKED_RECT structure that describes the locked region.
pRect
[in] Pointer to a rectangle to lock. Specified by a pointer to a RECT
structure. Specifying NULL for this parameter expands the dirty region to cover the entire surface.
Flags
[in] Combination of zero or more locking flags that describe the type of lock to perform. For this method, the valid flags are:
D3DLOCK_DISCARD
D3DLOCK_DONOTWAIT
D3DLOCK_NO_DIRTY_UPDATE
D3DLOCK_NOSYSLOCK
D3DLOCK_READONLY
You may not specify a subrect when using D3DLOCK_DISCARD. For a description of the flags, see D3DLOCK.
Return Value
If the method succeeds, the return value is D3D_OK.
If the method fails, the return value can be D3DERR_INVALIDCALL or D3DERR_WASSTILLDRAWING.
Remarks
If the D3DLOCK_DONOTWAIT flag is specified and the driver cannot lock the surface immediately, IDirect3DSurface9::LockRect will return D3DERR_WASSTILLDRAWING so that an application can use the CPU cycles while waiting for the driver to lock the surface.
The only lockable format for a depth-stencil surface is D3DFMT_D16_LOCKABLE. See D3DFORMAT.
For performance reasons, dirty regions are recorded only for level zero of a texture. Dirty regions are automatically recorded when IDirect3DSurface9::LockRect is called without D3DLOCK_NO_DIRTY_UPDATE or D3DLOCK_READONLY. See IDirect3DDevice9::UpdateTexture for more information.
A multisample back buffer cannot be locked.
This method cannot retrieve data from a surface that is is contained by a texture resource created with D3DUSAGE_RENDERTARGET because such a texture must be assigned to D3DPOOL_DEFAULT memory and is therefore not lockable. In this case, use instead IDirect3DDevice9::GetRenderTargetData to copy texture data from device memory to system memory.
----------------------------------------------------------------------------------------------------------------------------------------
在代码中,我们可以使用IDirect3DSurface9接口来描述表面。这个接口提供若干方法来直接读写表面数据并且还有一个方法用来返回表面信息。IDirect3DSurface9中最重要的方法是:
LockRect——使用这个方法,我们将获得一个指向表面内存的指针,然后,通过一系列指针运算,我们可以对表面上任一个像素点进行读、写操作。
UnlockRect——当你调用了LockRect和完成了对表面内存的访问后,你必须调用这个方法给表面解锁。
GetDesc——这个方法将通过填充D3DSURFACE_DESC结构来返回表面的描述信息。
最初锁定表面和改写每一像素看来稍微有点迷茫。下面的代码表示锁定表面并将每一像素染成红色:
// Assume _surface is a pointer to an IDirect3DSurface9 interface.
// Assumes a 32-bit pixel format for each pixel.
// Get the surface description.描述表面
D3DSURFACE_DESC surfaceDesc;
_surface->GetDesc(&surfaceDesc);//注意已经假定了_surface是指向IDirect3DSurface9借//口的指针
// Get a pointer to the surface pixel data.取得指向该内存区的指针
D3DLOCKED_RECT lockedRect;
_surface->LockRect(
&lockedRect,// pointer to receive locked data指向申请到的内存区域
0, // lock entire surface
0); // no lock flags specified
// Iterate through each pixel in the surface and set it to red.设置指定的表面为红色
DWORD* imageData = (DWORD*)lockedRect.pBits;
for(int i = 0; i < surfaceDesc.Height; i++)
{
for(int j = 0; j < surfaceDesc.Width; j++)
{
// index into texture, note we use the pitch and divide by
// four since the pitch is given in bytes and there are
// 4 bytes per DWORD.
int index = i * lockedRect.Pitch / 4 + j;
imageData[index] = 0xffff0000; // red
}
}
_surface->UnlockRect();
程序中D3DLOCKED_RECT结构的定义如下:
typedef struct _D3DLOCKED_RECT {
INT Pitch; // the surface pitch
void *pBits; // pointer to the start of the surface memory
} D3DLOCKED_RECT;
在这里有一些关于表面锁定代码的一些说明。32-bit像素格式设定这是很重要的,我们把bits转换成DWORDs。