使用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);
(二)D3D9视频显示的流程与初始化相关推荐
- Android 8.0学习(27)--- SystemUI(二)启动流程和初始化
Android 8.0 SystemUI(二):启动流程和初始化 这篇的话,将对SystemUI的启动和大体的初始化作描述.篇幅应该比上篇多了些.哈哈. 老样子,先上目录,简洁明了. 概述 由于需要实 ...
- 【正点原子Linux连载】第三十二章 U-Boot启动流程详解 -摘自【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.0
1)实验平台:正点原子阿尔法Linux开发板 2)平台购买地址:https://item.taobao.com/item.htm?id=603672744434 2)全套实验源码+手册+视频下载地址: ...
- C++二维数组讲解、二维数组的声明和初始化
我们知道,一维空间是一条线,数学中用一条数轴来表达:二维空间是一个平面,数学中用平面坐标系来表达.那么二维数组又是什么样的呢? 线与面 我们用一个下标来描述一维数组中的某个元素,就好像在用数描述一条线 ...
- Windows异常学习笔记(二)—— 内核异常处理流程用户异常的分发
Windows异常学习笔记(二)-- 内核异常处理流程&用户异常分发 用户层与内核层异常 内核异常 分析 KiDispatchException 分析 RtlDispatchException ...
- C#二维数组的定义和初始化
二维数组的定义和初始化: 初始化的值是1-360,用两层for循环,最后用richTextBox显示数据... 结果:
- 分析Spring容器启动流程 Spring初始化
分析Spring容器启动流程 Spring初始化 每当启动Web容器时(例如Tomcat),会读取Web应用中的web.xml文件.以下这段代码就是启动Spring容器的关键代码. ContextLo ...
- spring扩展点之二:spring中关于bean初始化、销毁等使用汇总,ApplicationContextAware将ApplicationContext注入...
<spring扩展点之二:spring中关于bean初始化.销毁等使用汇总,ApplicationContextAware将ApplicationContext注入> <spring ...
- Flowable-UI (二) Flowable 创建报销流程例子
Flowable-UI (二) Flowable 创建报销流程例子 如题,今天楼主为大家介绍下通过界面制作一个最简单的报销流程,步骤如下: 先进入 http://localhost:8080/flow ...
- JPOM - Server启动流程脚本初始化源码解析
文章目录 地址 版本 Server启动流程&脚本初始化流程 地址 Gitee: https://gitee.com/dromara/Jpom 官网: https://jpom.io/ 一款简而 ...
- 分布式系统认证解决方案SpringSecurityOAuth2.0(二)分布式系统认证流程分析与实现
目录 文章 一.简介 1.1 OAuth2.0协议角色 1.2 SpringSecurityOAuth2.0 二.认证流程 三.授权服务器--代码实现 3.1 主要依赖 3.2 Authorizati ...
最新文章
- c++ 优先队列_std::priority_queue(优先队列)
- java 0000 0001 0002 000a 000b_同样的 Java 文件,为什么直接用 Javac 编译和使用 Maven 编译出来所得到的字节码不一样?...
- (52)系统调用阶段测试——基于 SSDT HOOK 的 FindWindowA 监视器
- jQuery、jQury UI、jQuery Mobile----读书笔记
- 计算机网络英文面试题,计算机网络面试题整理
- 从零开始实现ASP.NET Core MVC的插件式开发(一) - 使用ApplicationPart动态加载控制器和视图
- dev.c drv.c bus.c
- Miktex + WinEdit 实现LaTeX写论文
- ASP.NET Core 使用Redis 存储Session 实现共享 Session
- 定制.NET GridView的长文本显示表格
- android 画图 工具下载,画板画图软件下载-画板画图 安卓版v1.1.0-PC6安卓网
- 通过上位机软件测试总线舵机
- 73个GitHub高级搜索技巧
- Linux 进程通信(System V)消息队列
- 深度至尊 GHOST XP SP3 纯净版 V4.0
- 安卓查看内存读写测试软件_办公电脑太慢?试试加条内存就好!内存晒单和内存问题科普...
- Xptah瞄准未来医疗,计划用动捕技术革新老年人康复治疗方式
- BOM和DOM的区别和关联
- aseprite手机版_texture packs泰拉瑞亚
- war3宽屏补丁(已更新)
热门文章
- 微信公众号发送模板通知
- 打开天窗:应用大脑科学提升两性之间的职场关系
- linux自动备份系统快照,我的 Linux 时光机——Snapper系统级自动备份工具
- 【Ubuntu】查询显卡型号
- linux两个邮件服务,Linux系列-Red Hat5平台下的Postfix邮件服务搭建(二)
- 如何用 Ps 制作毛玻璃穿透效果?
- 科普类(二)先有鸡还是先有蛋?看看C语言怎么说......
- 郑州大学计算机翟雨轩,郑州大学文件-20210331220732.doc-原创力文档
- What The F**k Python!!!
- 在线Spirte图定位工具,自动生成CSS