摘要:从本篇起,我将进入DirectX图形和游戏的世界。更多Managed DirectX的信息,可以参考IceShark的Blog文章,我这里简单提一下我的感受。Managed DirectX是对DirectX大部分功能的托管封装,可以用任何支持.NET的语言开发。MDX只对DirectX做了非常低层次的封装,因此保持了用COM接口DirectX开发时的大部分原貌。MDX的性能是不用担心的,因为它还是象COM DirectX一样提供对硬件层次的访问,大部分功能都是在你的显卡/网卡/声卡上起作用的,托管部分只是它的接口。事实证明MDX在DirectX Graphics中的性能与COM接口的DirectX不相上下。既然MDX的开发方式、API和性能都与COM接口的DirectX差不多,那为什么要用MDX呢?我自己对这个问题的回答是:
1、托管代码的对象模型更好。MDX基于类库的组织结构,比用COM接口的处理方式更方便。2、用MDX,一般不用操心资源释放的问题。很大一部分资源释放的操作,都被封装好了。3、与更多现代技术结合得更好。我们可以让DirectX程序使用XML、WebService和智能客户端等技术。
Direct3D程序最基本的流程是:创建Windows窗口、创建设备、处理消息循环、物体图形显示、退出和清理。在MDX的世界里,窗口创建和处理消息循环我们交给Windows Forms模型来做,剩下最主要的任务就是创建设备和物体图形显示。Direct3D设备是Direct3D开发最基本的入口,它定义了Direct3D所有的绘图组件,大部分的操作都需要从Direct3D设备开始。创建设备需要设定几个参数,包括显卡序号、设备类型、所属窗口、3D运算方式等。除了这些信息外,还需要一个PresentParameters类型的参数,其中定义了Direct3D设备所需的相关信息。下面代码中的InitializeDirect3D函数完整的演示了创建设备的步骤
设备类型:Direct3D支持3种设备,其中HAL和REF最为重要。HAL通过硬件进行光栅化、坐标变换和光照处理等,速度最快。REF则是用软件实现相关的操作,仅用于硬件不支持某种操作的情况。DeviceType枚举定义了设备类型可能的选项。
3D运算方式包括一些选项,如HardwareVertexProcessing,PureHardwareVertexProcessing等,用于指定顶点运算由硬件执行还是软件执行等。
PresentParameters还包括一些设置,如后台缓冲区的高度、宽度和像素格式,以及从后台缓冲区复制到前台缓存屏幕显示的方式等等。如果Direct3D采用窗口方式运行,像素格式必须查询当前的显示模式获得。
Direct3D设备创建成功以后,就可以进入图形显示阶段。在下面的代码中以Render()函数的形式出现。在绘制图形前,需要调用Device::Clear()函数重制ViewPort的颜色缓冲区。ViewPort就是3D形状投射到平面显示器上供我们看到的那个区域。Clear函数的Flag参数指定了对颜色缓冲区、深度缓冲区还是模板缓冲区进行初始化。因为我用ATI显卡,所以我选择了将颜色缓冲区初始化为红色:)。接下来是调用BeginScene()函数和EndScene()函数。实际的绘图中,所有渲染的代码都必须放在BeginScene函数和EndScene函数之间,否则就会出错。最后调用Present()函数,将后台缓冲区中的数据复制到前台缓冲区,我们就能看见图形了。
下面就是完成这个步骤所需的类。我将其定义为sealed,并将构造函数私有。这样做是为了让这个类仅仅成为我所用静态函数的容器。(在C#中,可以用静态类;在VB中,可以用模块)。
public ref class DirectXProgram sealed{private: DirectXProgram(void) { }public: //Direct3D 设备全局对象 static Device^ d3dDevice; static Boolean InitializeDirect3D(Form^ window) { //获取显示适配器信息,以便查询显示模式信息 AdapterListCollection^ adapters = Manager::Adapters; DisplayMode d3ddm = adapters->Default->CurrentDisplayMode; //创建设备所需的参数 PresentParameters^ params = gcnew PresentParameters(); params->Windowed = true; params->SwapEffect = SwapEffect::Discard; params->BackBufferFormat = d3ddm.Format; try { d3dDevice = gcnew Device(0, DeviceType::Hardware, window, CreateFlags::HardwareVertexProcessing, params); return true; } catch(DirectXException^) { return false; } } static void Render() { if(!d3dDevice) { return; } //后台缓冲区设置为红色 d3dDevice->Clear(ClearFlags::Target, Color::Red, 1.0f, 0); d3dDevice->BeginScene(); //在这里加入图形绘制程序 d3dDevice->EndScene(); d3dDevice->Present(); } static void CleanUp() { if(d3dDevice) { d3dDevice->Dispose(); } }};
这是DirectXProgram.h的完整代码
#pragma once
namespace......[
阅读全文]