(二)D3D9视频显示的流程与初始化

使用Direct3D的简单的多设备交换步骤如下:
1、创建一个窗口(Windows窗口)
2、初始化
1)创建Device
2)基于Device创建Surface(离屏表面)
3)创建Texture(纹理)
4) 获取指定层的纹理表面
3、画面渲染与保存
1)保存当前表面
2 ) 开始渲染
3 ) 为设备设置一个新的颜色缓冲区
4)为纹理填充颜色Clear
5)将画面从纹理转移到表面
6) 从设备的交换链中检索一个备份缓冲区
7)进行屏幕显示
8)保存渲染内存的数据
4、第三设备数据交换和保存

1.创建一个窗口(不属于D3D的API)
建立一个Win32的窗口程序,就可以用于Direct3D的显示。程序的入口函数是WinMain(),调用CreateWindow()即可创建一个窗口。这一步是必须的,不然Direct3D绘制的内容就没有地方显示了。
2.初始化
1) 创建Device
这一步完成的时候,可以得到一个IDirect3DDevice9接口的指针。创建一个Device又可以分成以下几个详细的步骤:
(a) 通过 Direct3DCreate9()或者Direct3DCreate9Ex()创建一个IDirect3D9或者LPDIRECT3D9EX接口。
获取IDirect3D9接口的关键实现代码:
IDirect3D9 *m_pDirect3D9 = Direct3DCreate9( D3D_SDK_VERSION );
获取LPDIRECT3D9EX接口的关键代码:
LPDIRECT3D9EX d3dex = NULL;
Direct3DCreate9Ex(D3D_SDK_VERSION, &d3dex);

IDirect3D9接口是一个代表我们显示3D图形的物理设备的C++对象。它可以用于获得物理设备的信息和创建一个IDirect3DDevice9接口。例如,可以通过它的GetAdapterDisplayMode()函数获取当前主显卡输出的分辨率,刷新频率等参数,实现代码如下。
D3DDISPLAYMODE d3dDisplayMode;  
lRet = m_pDirect3D9->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3dDisplayMode ); 
由代码可以看出,获取的信息存储在D3DDISPLAYMODE结构体中。D3DDISPLAYMODE结构体中包含了主显卡的分辨率等信息:
/* Display Modes */   
typedef   struct  _D3DDISPLAYMODE  
{  
     UINT             Width;  
     UINT             Height;  
     UINT             RefreshRate;  
    D3DFORMAT       Format;  
} D3DDISPLAYMODE;  

也可以用它的GetDeviceCaps()函数搞清楚主显卡是否支持硬件顶点处理,实现的代码如下。
D3DCAPS9 d3dcaps;  
lRet=m_pDirect3D9->GetDeviceCaps(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,&d3dcaps);  
int  hal_vp = 0;  
if ( d3dcaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT ){  
     // yes, save in ‘vp’ the fact that hardware vertex   
     // processing is supported.   
    hal_vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;  
}  
由代码可以看出,获取的设备信息存储在D3DCAPS9结构体中。D3DCAPS9定义比较长包含了各种各样的信息,不再列出来。从该结构体的DevCaps字段可以判断得出该设备是否支持硬件顶点处理。

(b) 设置D3DPRESENT_PARAMETERS结构体,为创建Device做准备。
接下来填充一个D3DPRESENT_PARAMETERS结构的实例。这个结构用于设定我们将要创建的IDirect3DDevice9对象的一些特性,它的定义如下。

typedef   struct  _D3DPRESENT_PARAMETERS_  
{  
     UINT                 BackBufferWidth;  
     UINT                 BackBufferHeight;  
    D3DFORMAT           BackBufferFormat;  
     UINT                 BackBufferCount;  
  
  
    D3DMULTISAMPLE_TYPE MultiSampleType;  
     DWORD                MultiSampleQuality;  
  
  
    D3DSWAPEFFECT       SwapEffect;  
     HWND                 hDeviceWindow;  
     BOOL                 Windowed;  
     BOOL                 EnableAutoDepthStencil;  
    D3DFORMAT           AutoDepthStencilFormat;  
     DWORD                Flags;  
  
  
     /* FullScreen_RefreshRateInHz must be zero for Windowed mode */   
     UINT                 FullScreen_RefreshRateInHz;  
     UINT                 PresentationInterval;  
} D3DPRESENT_PARAMETERS;

D3DPRESENT_PARAMETERS这个结构体比较重要。详细列一下它每个参数的含义:
BackBufferWidth:后台缓冲表面的宽度(以像素为单位)。
BackBufferHeight:后台缓冲表面的高度(以像素为单位)。
BackBufferFormat:后台缓冲表面的像素格式(例如:32位像素格式为D3DFMT:A8R8G8B8)。
BackBufferCount:后台缓冲表面的数量,通常设为“1”,即只有一个后备表面。
MultiSampleType:全屏抗锯齿的类型,显示视频没用到,不详细分析。
MultiSampleQuality:全屏抗锯齿的质量等级,显示视频没用到,不详细分析。
SwapEffect:指定表面在交换链中是如何被交换的。支持以下取值:
*D3DSWAPEFFECT_DISCARD:后台缓冲表面区的东西被复制到屏幕上后,后台缓冲表面区的东西就没有什么用了,可以丢弃了。
*D3DSWAPEFFECT_FLIP:后台缓冲表面拷贝到前台表面,保持后台缓冲表面内容不变。当后台缓冲表面大于1个时使用。
*D3DSWAPEFFECT_COPY:同上。当后台缓冲表面等于1个时使用。
一般使用D3DSWAPEFFECT_DISCARD。
hDeviceWindow:与设备相关的窗口句柄,你想在哪个窗口绘制就写那个窗口的句柄
Windowed:BOOL型,设为true则为窗口模式,false则为全屏模式
EnableAutoDepthStencil:设为true,D3D将自动创建深度/模版缓冲。
AutoDepthStencilFormat:深度/模版缓冲的格式
Flags:一些附加特性
FullScreen_RefreshRateInHz:刷新率,设定D3DPRESENT_RATE_DEFAULT使用默认刷新率
PresentationInterval:设置刷新的间隔,可以用以下方式:
*D3DPRENSENT_INTERVAL_DEFAULT,则说明在显示一个渲染画面的时候必要等候显示器刷新完一次屏幕。例如显示器刷新率设为80Hz的话,则一秒最多可以显示80个渲染画面。
*D3DPRENSENT_INTERVAL_IMMEDIATE:表示可以以实时的方式来显示渲染画面。

下面列出使用Direct3D的时候D3DPRESENT_PARAMETERS的一个最简单的设置。
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.Windowed = true;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
d3dpp.BackBufferCount = 1;
d3dpp.BackBufferWidth = SCREENW;
d3dpp.BackBufferHeight = SCREENH;
d3dpp.hDeviceWindow = window;  

(c) 通过IDirect3D9的CreateDevice ()创建一个Device。
最后就可以调用IDirect3D9的CreateDevice()方法创建Device了。
CreateDevice()的函数原型如下:
HRESULT  CreateDevice(  
UINT  Adapter,  
D3DDEVTYPE DeviceType,  
HWND  hFocusWindow,  
DWORD  BehaviorFlags,  
D3DPRESENT_PARAMETERS *pPresentationParameters,  
IDirect3DDevice9** ppReturnedDeviceInterface  
); 

其中每个参数的含义如下所列:
Adapter:指定对象要表示的物理显示设备。D3DADAPTER_DEFAULT始终是主要的显示器适配器。
DeviceType:设备类型,包括D3DDEVTYPE_HAL(Hardware Accelerator,硬件加速)、D3DDEVTYPE_SW(SoftWare,软件)。
hFocusWindow:同我们在前面d3dpp.hDeviceWindow的相同
BehaviorFlags:设定为D3DCREATE_SOFTWARE_VERTEXPROCESSING(软件顶点处理)或者D3DCREATE_HARDWARE_VERTEXPROCESSING(硬件顶点处理),使用前应该用D3DCAPS9来检测用户计算机是否支持硬件顶点处理功能。
pPresentationParameters:指定一个已经初始化好的D3DPRESENT_PARAMETERS实例
ppReturnedDeviceInterface:返回创建的Device

下面列出使用Direct3D的时候CreateDevice()的一个典型的代码。

LPDIRECT3D9EX d3dex = NULL;
D3DPRESENT_PARAMETERS d3dpp;
...
d3dex->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev);

2) 基于Device创建一个Surface
通过IDirect3DDevice9接口的CreateOffscreenPlainSurface ()方法即可创建一个Surface(离屏表面。所谓的“离屏”指的是永远不在屏幕上显示)。CreateOffscreenPlainSurface ()的函数原型如下所示:
HRESULT  CreateOffscreenPlainSurface( UINT  width,  
  UINT  height,  
 D3DFORMAT format,  
 D3DPOOL pool,  
 IDirect3DSurface9 ** result,  
  HANDLE  * unused  
 );  
其中每个参数的含义如下所列:
Width:离屏表面的宽。
Height:离屏表面的高。
Format:离屏表面的像素格式(例如:32位像素格式为D3DFMT_A8R8G8B8)
Pool:D3DPOOL定义了资源对应的内存类型,例如如下几种类型。
D3D3POOL_DEFAULT: 默认值,表示存在于显卡的显存中。
D3D3POOL_MANAGED:由Direct3D自由调度内存的位置(显存或者缓存中)。
D3DPOOL_SYSTEMMEM: 表示位于内存中。
Result:返回创建的Surface。
Unused:还未研究。

下面给出一个使用Direct3D的时候CreateTexture()的典型代码。
LPDIRECT3DDEVICE9 d3ddev;
LPDIRECT3DSURFACE9 surface;
...
d3ddev->CreateOffscreenPlainSurface(100, 100, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &surface, NULL);
if (!SUCCEEDED(result)) return false;

3)创建Texture(纹理)
通过IDirect3DDevice9接口的CreateTexture()方法即可创建一个Texture(纹理)。CreateTexture()的函数原型如下所示:
HRESULT CreateTexture( [in]          UINT              Width, [in]          UINT              Height, [in]          UINT              Levels, [in]          DWORD             Usage, [in]          D3DFORMAT         Format, [in]          D3DPOOL           Pool, [out, retval] IDirect3DTexture9 **ppTexture, [in]          HANDLE            *pSharedHandle);

其中每个参数的含义如下所列:
Width:纹理的宽度,以像素为单位。。
Height:纹理的高度,以像素为单位。
Levels:纹理的数量。
Usage:使用可以是0,这表示没有使用价值。但是,如果需要使用的话,可以使用一个或多个D3DUSAGE常量的组合。一般与IDirect3D9::CreateDevice的行为标志相匹配。
Format: D3DFORMAT枚举类型的成员,描述纹理的格式。
Pool:D3DPOOL枚举类型的成员,描述了应该放置纹理的类型。
**ppTexture:指向IDirect3DTexture9接口的指针,表示所创建的纹理资源。
*pSharedHandle:用作不同d3d设备资源交换。一般将该参数设置为NULL。该参数可用于Windows Vista的Direct3D 9,以共享资源。

下面给出一个使用D3D的时候CreateTexture()的典型代码。
LPDIRECT3DTEXTURE9 pTexture = NULL;
d3ddev->CreateTexture(100, 100, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pTexture, NULL);

下当不同的D3D设备进行资源交换时。
HANDLE SharedHandle = NULL;
LPDIRECT3DTEXTURE9 pTexture = NULL;
d3ddev->CreateTexture(100, 100, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pTexture, &SharedHandle);

4)获取指定层的纹理表面
HRESULT GetSurfaceLevel( [in]          UINT              Level, [out, retval] IDirect3DSurface9 **ppSurfaceLevel);

level : 识别纹理资源的层次。这个方法返回一个表面,以达到这个参数指定的级别。顶层的表面用0表示。
ppSurfaceLevel : 一个指向IDirect3DSurface9接口的指针的地址,表示返回的表面。

注意: 调用此方法将增加IDirect3DSurface9接口的内部引用计数。如果没有在结束时调用Release 释放资源在结束时将发生内存泄漏。

一般用法(获取顶层表面):
LPDIRECT3DSURFACE9 pSurface = NULL;
LPDIRECT3DTEXTURE9 pTexture = NULL;
pTexture->GetSurfaceLevel(0, &pSurface);

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值