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 surfaceformat.
Type
Member of the D3DRESOURCETYPE enumerated type, identifying thisresource 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 ofmemory allocated for this surface.
MultiSampleType
Member of the D3DMULTISAMPLE_TYPE enumerated type, specifying thelevels of full-scene multisampling supported by the surface.
MultiSampleQuality
Quality level. The valid range is between zero and one less thanthe level returned by pQualityLevels used byIDirect3D9::CheckDeviceMultiSampleType. Passing a larger valuereturns the error, D3DERR_INVALIDCALL. The MultisampleQualityvalues of paired render targets, depth stencil surfaces and theMultiSample 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 thelocked region.
pRect
[in] Pointer to a rectangle to lock. Specified by a pointer to aRECT structure. Specifying NULL for this parameter expands thedirty region to cover the entire surface.
Flags
[in] Combination of zero or more locking flags that describe thetype of lock to perform. For this method, the valid flagsare:
D3DLOCK_DISCARD
D3DLOCK_DONOTWAIT
D3DLOCK_NO_DIRTY_UPDATE
D3DLOCK_NOSYSLOCK
D3DLOCK_READONLY
You may not specify a subrect when using D3DLOCK_DISCARD. For adescription 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 orD3DERR_WASSTILLDRAWING.
Remarks
If the D3DLOCK_DONOTWAIT flag is specified and the driver cannotlock the surface immediately, IDirect3DSurface9::LockRect willreturn D3DERR_WASSTILLDRAWING so that an application can use theCPU cycles while waiting for the driver to lock the surface.
The only lockable format for a depth-stencil surface isD3DFMT_D16_LOCKABLE. See D3DFORMAT.
For performance reasons, dirty regions are recorded only for levelzero of a texture. Dirty regions are automatically recorded whenIDirect3DSurface9::LockRect is called withoutD3DLOCK_NO_DIRTY_UPDATE or D3DLOCK_READONLY. SeeIDirect3DDevice9::UpdateTexture for more information.
A multisample back buffer cannot be locked.
This method cannot retrieve data from a surface that is iscontained by a texture resource created with D3DUSAGE_RENDERTARGETbecause such a texture must be assigned to D3DPOOL_DEFAULT memoryand is therefore not lockable. In this case, use insteadIDirect3DDevice9::GetRenderTargetData to copy texture data fromdevice memory to system memory.
----------------------------------------------------------------------------------------------------------------------------------------
在代码中,我们可以使用IDirect3DSurface9接口来描述表面。这个接口提供若干方法来直接读写表面数据并且还有一个方法用来返回表面信息。IDirect3DSurface9中最重要的方法是:
LockRect——使用这个方法,我们将获得一个指向表面内存的指针,然后,通过一系列指针运算,我们可以对表面上任一个像素点进行读、写操作。
UnlockRect——当你调用了LockRect和完成了对表面内存的访问后,你必须调用这个方法给表面解锁。
GetDesc——这个方法将通过填充D3DSURFACE_DESC结构来返回表面的描述信息。
最初锁定表面和改写每一像素看来稍微有点迷茫。下面的代码表示锁定表面并将每一像素染成红色:
// Assume _surface is a pointer to an IDirect3DSurface9interface.
// 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 lockeddata指向申请到的内存区域
0, // lock entire surface
0); // no lock flags specified
// Iterate through each pixel in the surface and set it tored.设置指定的表面为红色
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。
本文来自CSDN博客,转载请标明出处:file:///E:/工作心得文件夹/LPDIRECT3DSURFACE9 -uzzgroup的专栏 - CSDN博客.htm
i 用法介绍
1、Surfaces是什么:
通俗的讲surfaces就是一个二维的矩形平面。在DX9中,与其对应的com接口为IDirect3DSurface9,LPDIRECT3DSURFACE9。
2、Surfaces的作用:
作为一个矩形平面,surfaces用来在屏幕上显示平面图象,即从文件中读取图象数据呈现给用户。
3、IDirect3DSurface9的使用一般过程:
声明: LPDIRECT3DSURFACE9
创建: CreateOffscreenPlainSurface(…)
获取图象信息: D3DXGetImageInfoFromFile(…)
装载到surfaces中: D3DXLoadSurfaceFromFile(…)
获取back buffer地址: GetBackBuffer(…)
显示: UpdateSurface(…)
释放内存 Release()
代码段如下:
//初始化
LPDIRECT3DSURFACE9 g_Surface =NULL;
D3DXIMAGE_INFO Info;
D3DXGetImageInfoFromFile("image.jpg", &Info);
g_pd3dDevice->CreateOffscreenPlainSurface(Info.Width,Info.Height, Info.Format,D3DPOOL_SYSTEMMEM,&g_Surface, NULL);
D3DXLoadSurfaceFromFile(g_Surface, NULL, NULL, "image.jpg", NULL,D3DX_FILTER_NONE, 0xFF000000, NULL);
//渲染
//--------------------------------------------------------------------------------------------------
LPDIRECT3DSURFACE9 BackBuffer = NULL;
g_pd3dDevice->GetBackBuffer(0,0,D3DBACKBUFFER_TYPE_MONO,&BackBuffer);
g_pd3dDevice->UpdateSurface(g_Surface, NULL,BackBuffer, NULL);
if(BackBuffer != NULL)
BackBuffer->Release();
//释放
//---------------------------------------------------------------------------------------------------
if(g_Surface!= NULL)
g_Surface ->Release();
ii 封装源码
1.CXSurface的定义
class CXSurface
{
protected:
LPDIRECT3DSURFACE9 m_pSurface;
LPDIRECT3DSURFACE9 m_pBackBuffer; //Back buffer
LPDIRECT3DDEVICE9 m_pDevice; //Direct3D的设备指针
public:
CXSurface(LPDIRECT3DDEVICE9 pDevice);
~CXSurface();
LPDIRECT3DSURFACE9 GetSurface() const {return m_pSurface;}
void SetSurface(LPDIRECT3DSURFACE9 pSurface){m_pSurface=pSurface;}
LPDIRECT3DDEVICE9 GetDevice() const {return m_pDevice;}
void SetDevice(LPDIRECT3DDEVICE9 pDevice){m_pDevice=pDevice;}
LPDIRECT3DSURFACE9 GetBuffer() const { return m_pBackBuffer;}
void SetBuffer(LPDIRECT3DSURFACE9 pBuffer) {m_pBackBuffer=pBuffer;}
HRESULT CreateSurface(UINT Width,UINT Height,D3DFORMATFormat,D3DPOOL Pool);//创建
HRESULT MakeBuffer(void);//获取缓存区
HRESULT LoadFromFile(LPCWSTR Path);//加载文件
void Render(void);
};
2.CXSurface的实现
CXSurface(LPDIRECT3DDEVICE9 pDevice) //构造函数的实现
{
this->SetDevice(pDevice);
this->SetSurface(NULL);
this->SetBuffer(NULL):
}
CXSurface::~CXSurface() //析构函数的实现
{
if (m_pSurface!=NULL)
{
m_pSurface->Release();
}
if (m_pBuffer!=NULL)
{
m_pBuffer->Release();
}
}
HRESULT CreateSurface(UINT Width,UINT Height,D3DFORMATFormat,D3DPOOL Pool) //创建的实现
HRESULT CXSurface::CreateSurface(UINT Width,UINT Height,D3DFORMATFormat,D3DPOOL Pool)
{
returnm_pDevice->CreateOffscreenPlainSurface(Width,Height,Format,Pool,&m_pSurface,NULL);
}
HRESULT MakeBuffer(void) //获取缓存区的实现
{
if (m_pDevice)
{
m_pBackBuffer->Release();
returnm_pDevice->GetBackBuffer(0,0,D3DBACKBUFFER_TYPE_MONO,&m_pBackBuffer);
}
else
return E_FAIL;
}
HRESULT LoadFromFile(LPCWSTR Path) //加载文件的实现
{
HRESULT Result=E_FAIL;
D3DXIMAGE_INFO Info;
ZeroMemory(&Info,sizeof(D3DXIMAGE_INFO));
if(SUCCEEDED(D3DXGetImageInfoFromFile(Path,&Info)))
{
Result=CreateSurface(800,600,Info.Format,D3DPOOL_SYSTEMMEM);
}
if (Result==S_OK)
{
Result=D3DXLoadSurfaceFromFile(this->m_pSurface,NULL,NULL,Path,NULL,D3DX_DEFAULT,0,&Info);
}
else
Result=E_FAIL;
return Result;
}
void Render(void) //渲染的实现
{
HRESULT hr=this->MakeBuffer();
if(!hr)
{
MessageBox(NULL,L"获取缓存区失败",L"失败",MB_OK);
return ;
POINT point ;
point.x=0;
point.y=0;
m_pDevice->UpdateSurface(this->m_pSurface,NULL,this->m_pBackBuffer,&point);
if(m_pbackbuffer!=NULL)
backbuffer->Release();
}