学生时期,虽然自己并非是计算机专业的,但是自己对写程序还是挺感兴趣的。我也是刚毕业,由于并不是学习的计算机,并没有从事有关电脑方面的工作。我最初学习DirectX大约是在大学二年级的时候(2008年)。那个时候刚拥有个人电脑不久,可以说是真正开始自我学习编程的时候。虽然初中时接触过一点,但当时毕竟没有电脑,不能实践使得自己好像什么也学不懂,再加上高中时期的忙碌学习,更是难有进步。到大学时,空余时间比较多,再加上大一下学期有了自己的电脑,才稍微觉得自己有点摸到门框了。DirectX确实相当的庞大,再加上帮助文档都是英文,更是难以学习。不过了解了其中一个分支,整个的体系就有了大致的了解。

在我看来,DirectX就好比是一个能干的下属,那些繁琐、难以理解的东西,他全部包了,而你只需要做一些高层次的规划就行。也是由于兴趣所致,想着自己能够写出一个3D游戏,就算是3D的小游戏那有多高兴,于是就找到这个能干的下属,开始学习如何命令他,就好像学习开车一样。

Direct3D并不那么好操作,其中有很多东西都难以理解,为什么难以理解呢?我想主要就是以前从来没有见过。我们对没有见过的东西确实是难以理解。所有,我将我的一些理解写了下来。

由于大多数游戏都用的是DirectX9,所以我也用9.0的版本。

如果将电脑里的硬件比喻成一个机器人,那么DirectX就好比是一个很大很复杂的操控室,通过操控室可以操控机器人干这干那。如果将电脑的显卡(或是显示设备)比喻成机器人的头部,那么Direct3D就是操控机器人头部的操作区域。头部是关键,那么这样的操控区域一定不简单。

什么是Direct3D的初始化呢?可以说就是获得操控室那块区域的操作权。获得操作权的方法很简单,就是告诉DirectX你要操控Direct3D。在Direct3D的语言里,把获得操控权的步骤叫做创建设备,由于主要是显卡设备,所以也可以叫创建视频设备。主要的函数如下:

 

HRESULT IDirect3D9(1)::CreateDevice(2)(

UINT Adapter,(3)

D3DDEVTYPE DeviceType,(4)

HWND hFocusWindow,(5)

DWORD BehaviorFlags,(6)

D3DPRESENT_PARAMETERS *pPresentationParameters,(7)

IDirect3DDevice9** ppReturnedDeviceInterface(8)

);

 

还有一个IDirect3D9Ex::CreateDeviceEx(…);的函数,该函数主要为了更加适应(兼容)vista或win7(基本设备实现兼容),不用影响也不是很大。

如果你从来就没有接触过DirectX,或许会有些迷茫,但其实这并不是很复杂。我对上述函数的理解其实也不是很好,不过既然已经献丑了,就继续一个个说我的理解吧。

(1)CreateDevice函数前面有域操作符(::),就说明不能直接用该函数。其实IDirect3D9是Direct3D的主指针,可以说是整个Direct3D的钥匙,申请(获取)该主指针就一步:

 

IDirect3D9* d3d9 = 0;

d3d9 = Direct3DCreate9(D3D_SDK_VERSION);

 

这一步很好理解,我们那能干的下属通过一个简单的函数就让我们获得了Direct3D的主指针。

(2)既然我们已经有了主指针d3d9,那么调用该函数就行了。

 

d3d9->CreateDevice(…);

 

(3)函数的第一个参数字面意思就是显卡,而一般的电脑就一个显卡,所有填上D3DADAPTER_DEFAULT让函数默认选择主要的显卡就行了。

(4)第二个参数是设备类型。Direct3D只提供了HAL和REF两个类型。绝大多数情况下都用HAL,这代表我的电脑有显卡,而不只是一个显示元件,这样在运行视频程序的时候,可以用到硬件加速。REF是不用硬件,而用软件(算法)去模拟硬件的效果,这就好比一辆汽车没有引擎而靠一个人推着走一样,REF只是在测试视频程序的时候才用到。所有填上D3DDEVTYPE_HAL就好。

(5)一般的游戏程序在构建窗口框架的时候是越简单越好,而大部分只有一个窗口,所以对于游戏程序,将唯一的游戏窗口句柄传递给它就行了,比如hwnd。而对于有很多窗口的其他视频程序,就要看你想要在那个窗口中显示东西了。

(6)3D中的几何物体是很复杂的,物体的顶点很重要,显卡中是否有处理顶点的能力也很重要。虽然该参数有很多其他的选项,但是Direct3D的特性是你必须指定你的程序是依靠显卡处理顶点还是依靠软件(算法)处理顶点,异或是两者皆可。这三个选项(D3DCREATE_HARDWARE_VERTEXPROCESSING,    D3DCREATE_MIXED_VERTEXPROCESSING, D3DCREATE_SOFTWARE_VERTEXPROCESSING)必选其一。道理可想而知,用软件模拟功能就好比大家都坐电梯上100层,而你非要走上去,除非是没有电梯,那只有走上去了。所以要先检查显卡是否具有处理顶点的能力。一般做法是获取整个显卡属性,然后查看就知道了。

 

D3DCAPS9 caps;

    d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT,//选择默认主显卡

 D3DDEVTYPE_HAL,

 &caps);//该结构保存显卡属性

 

    bool bf = false;

    if( caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT )//查看顶点处理能力

           bf = true;

    else

           bf = true;

 

(7)这个参数的表面意思是显示中的细节,它主要是通过传递一个D3DPRESENT_PARAMETERS结构而实现的。

 

typedef struct _D3DPRESENT_PARAMETERS_ {
    UINT BackBufferWidth, BackBufferHeight;
    D3DFORMAT BackBufferFormat;
    UINT BackBufferCount;
    D3DMULTISAMPLE_TYPE MultiSampleType;
    DWORD MultiSampleQuality;
    D3DSWAPEFFECT SwapEffect;
    HWND hDeviceWindow;
    BOOL Windowed;
    BOOL EnableAutoDepthStencil;
    D3DFORMAT AutoDepthStencilFormat;
    DWORD Flags;
    UINT FullScreen_RefreshRateInHz;
    UINT PresentationInterval;
} D3DPRESENT_PARAMETERS;

 

BackBufferWidth, BackBufferHeight

DirectX显示和绘制二维或三维的物体时,并不是直接在屏幕上操作的,那样的话屏幕就会闪,感觉很不好。一般把主屏幕(DirectX中叫主表面)复制一个或多个复制品(叫后备缓存),然后在复制品上面绘制几何模型,显示的时候把主缓存与后备缓存交换就实现显示了。这两个数据成员则分别表示了后备缓存的宽度与高度。

BackBufferFormat

表示单个像素的格式,一般使用A8R8G8B8(32位颜色,前8位表示Alpha通道,依次为红、绿、蓝)就可以了。

BackBufferCount

一般后备缓存一个就可以了,一般为1。

MultiSampleType,MultiSampleQuality

字面意思是多重采样。几何模型显示的时候,一条直线很多情况下会显示成锯齿状,而它主要的功能是将锯齿消除,让一条直线更加平滑。这里主要是Direct3D的初始化,设置如此高级的东西还看不出效果,设置成D3DMULTISAMPLE_NONE就行。

SwapEffect

主缓存和后备缓存的交换有多种选项。像我这种个人,并不会写太大的东西,东西写出了运行良好就行,而像多缓存的技术我是一直没有用过。就一个后备缓存的情况下,使用D3DSWAPEFFECT_DISCARD就可以了,而不需要使用D3DSWAPEFFECT_FLIP和D3DSWAPEFFECT_COPY,使用前者的话DirectX会自动选择最好的方式交换主/后缓存,而后者使用需要非常小心,不然很容易出现内存泄露或溢出等问题。

hDeviceWindow,Windowed

显卡使用的窗口和程序是否需要窗口化。

EnableAutoDepthStencil

物体在三维空间显示的时候,总会有一个物体挡住另一个物体的情况,设置为true就可以让DirectX自动帮你完成物体遮挡的问题。

AutoDepthStencilFormat

一般设置32位(一般24位用于Depth,8位用于Stencil)格式,如果显卡不行(现在应该很难找到那样的显卡)才用16位的。

Flags

这个在非常多的情况下是不用的,设置成0就可以了。

FullScreen_RefreshRateInHz

程序全屏时的刷新率。

PresentationInterval

一般设置D3DPRESENT_INTERVAL_IMMEDIATE让主/后缓存立即交换即可,设置其他值的情况比较少。

(8)这个就是我们需要的操控区域的操控权,我们叫它设备,通过它,我们就几乎可以操作整个机器人的头部即显卡。因为指针的操控性能比较好,所有我们得到的是一个指针。而正是由于我们需要的是一个指针,我们必须把我们需要的东西的指针传递进去后,返回出来的才能得到我们需要的东西,所以传递的是指针的指针。

 

到此,整个Direct3D的初始化过程就算完毕了。总结的说,Direct3D的初始化过程就是创建视频设备的过程。

posted on 2012-11-07 19:18  漫长的等待  阅读(520)  评论(0)    收藏  举报