zoukankan      html  css  js  c++  java
  • 初始化Direct3D(3)

    1.4 初始化Direct3D

    下面几点说明怎样初始化Direct3D。根据下边的步骤你能初始化Direct3D:

    1.获得一个IDirect3D9接口指针。这个接口用于获得物理设备的信息和创建一个IDirect3DDevice9接口,它是一个代表我们显示3D图形的物理设备的C++对象。

    2.检查设备能力(D3DCAPS9),搞清楚主显卡是否支持硬件顶点处理。我们需要知道假如它能支持,我们就能创建IDirect3DDevice9接口。

    3.初始化一个D3DPRESENT_PARAMETERS结构实例,这个结构包含了许多数据成员允许我们指定将要创建的IDirect3DDevice9接口的特性。

    4.创建一个基于已经初始化好的D3DPRESENT_PARAMETERS结构的IDirect3DDevice9对象。它是一个代表我们显示3D图形的物理设备的C++对象。

    请注意,我们使用主显示设备绘制3D图形,如果你的机子只有一块显卡,那它就是主显示设备。如果你有多个显卡,那么你当前使用的显卡将会成为主显示设备(如:用来显示Windows桌面的显卡)。

    1.4.1获得IDirect3D9接口

    Direct3D的初始化是从获得一个IDirect3D9接口指针开始的。使用一个专门的Direct3D函数来完成这个工作是非常容易的,代码如下:

    IDirect3D9* _d3d9;

    _d3d9 = Direct3DCreate9(D3D_SDK_VERSION);

    Direct3DCreate9的唯一一个参数总是D3D_SDK_VERSION,这可以保证应用程序通过正确的头文件被生成。如果函数调用失败,那么它将返回一个空指针。

    IDirect3D9对象通常有两个用途:设备列举和创建IDirect3DDevice9对象。设备列举即为查明系统中显示设备的技术特性,显示模式、格式,以及其它每一种显卡各自支持的特性。创建代表物理设备的IDirect3DDevice9对象,我们需要利用这个物理设备的显示模式结构和格式来创建它。为了找到一个工作配置,我们必须使用IDirect3D9的列举方法。

    然而,设备列举实在太慢了,为了使Direct3D运行得尽可能快,我们通常不使用这个测试,除了下一节所谈到的一项测试。为了安全跳过它,我们可以选择总是被所有显卡都支持的“安全”配置。

    1.4.2 检测硬件顶点处理

    当我们创建一个IDirect3DDevice9对象来表示主显示设备时,必须要设定其顶点处理的类型。如果可以的话,当然要选用硬件顶点处理,但是由于并非所有显卡都支持硬件顶点处理,因此我们必须首先检查显卡是否支持。

    首先我们要根据主显示设备的技术特性来初始化D3DCAPS9实例。可以使用如下方法:

    HRESULT IDirect3D9::GetDeviceCaps(

           UINT Adapter,

           D3DDEVTYPE DeviceType,

           D3DCAPS9 *pCaps

    );

    Adapter——指定要获得哪个显示适配器的特性

    DeviceType——指定设备类型(硬件设备(D3DDEVTYPE_HAL),软件设备(D3DDEVTYPE_REF))

    PCaps——返回一个已初始化的D3DCAPS9结构

    然后,我们就可以象1.3.8部分那样检测显卡的能力了。下面就是代码片段:

    // Fill D3DCAPS9 structure with the capabilities of the primary display adapter.
    D3DCAPS9 caps;
    d3d9->GetDeviceCaps(
          D3DADAPTER_DEFAULT, // Denotes primary display adapter.
          deviceType, // Specifies the device type, usually D3DDEVTYPE HAL.
    &caps);     // Return filled D3DCAPS9 structure that contains
    // the capabilities of the primary display adapter.
    // Can we use hardware vertex processing?
    int vp = 0;
    if( caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT )
    {
    // yes, save in 'vp' the fact that hardware vertex processing is supported.
          vp = D3DCREATE HARDWARE VERTEXPROCESSING;
    }
    else
    {
    // no, save in 'vp' the fact that we must use software vertex processing.
          vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
    }

    观察代码,我们使用变量vp来存储顶点处理类型。这是因为在稍后创建IDirect3DDevice9对象时要求指定其顶点处理的类型。

    注意:标识符D3DCREATE_HARDWARE_VERTEXPROCESSING和D3DCREATE_SOFTWARE_VERTEXPROCESSING是预定义的值,它们分别代表硬件顶点处理和软件顶点处理。

    技巧:若我们开发有一些新的,高级特性的程序,在使用前我们总是先检查硬件是否支持这些特性。

    注意:如果一个应用程序在你的机子上不能运行,说明它用到的一些特性可能你的显卡并不支持,可以试试把设备类型换成REF。

    1.4.3 填充D3DPRESENT_PARAMETERS结构

    初始化过程的下一步是填充一个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;

           UINT FullScreen_RefreshRateInHz;

           UINT PresentationInterval;

    } D3DPRESENT_PARAMETERS;

    下面介绍其比较重要的数据成员,至于更详细的信息,请查阅SDK:

    BackBufferWidth——后备缓冲表面的宽度(以像素为单位)

    BackBufferHeight——后备缓冲表面的高度(以像素为单位)

    BackBufferFormat——后备缓冲表面的像素格式(如:32位像素格式为D3DFMT——A8R8G8B8)

    BackBufferCount——后备缓冲表面的数量,通常设为“1”,即只有一个后备表面

    MultiSampleType——全屏抗锯齿的类型,详情请看SDK

    MultiSampleQuality——全屏抗锯齿的质量等级,详情看SDK

    SwapEffect——指定表面在交换链中是如何被交换的,取D3DSWAPEFFECT枚举类型中的一个成员。其中D3DSWAPEFFECT_DISCARD是最有效的

    hDeviceWindow——与设备相关的窗口句柄,你想在哪个窗口绘制就写那个窗口的句柄

    Windowed——BOOL型,设为true则为窗口模式,false则为全屏模式

    EnableAutoDepthStencil——设为true,D3D将自动创建深度/模版缓冲

    AutoDepthStencilFormat——深度/模版缓冲的格式

    Flags——一些附加特性,设为0或D3DPRESENTFLAG类型的一个成员。下列两个最常用的标志

    全部的标志请查阅SDK:

    D3DPRESENTFLAG_LOCKABLE_BACKBUFFER——设定后备表面能够被锁定,这会降低应用程序的性能

    D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL——深度/模版缓冲在调用IDirect3DDevice9::present方法后将被删除,这有利于提升程序性能

    FullScreen_RefreshRateInHz——刷新率,设定D3DPRESENT_RATE_DEFAULT使用默认刷新率

    PresentationInterval——属于D3DPRESENT成员,又有两个常用标志,其余请查SDK:

             D3DPRESENT_INTERVAL_IMMEDIATE——立即交换

             D3DPRESENT_INTERVAL_DEFAULT——D3D选择交换速度,通常等于刷新率

    填充示例如下:

    D3DPRESENT_PARAMETERS d3dpp;

    d3dpp.BackBufferWidth = 800;

    d3dpp.BackBufferHeight = 600;

    d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8; //像素格式

    d3dpp.BackBufferCount = 1;

    d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;

    d3dpp.MultiSampleQuality = 0;

    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;

    d3dpp.hDeviceWindow = hwnd;

    d3dpp.Windowed = false; // fullscreen

    d3dpp.EnableAutoDepthStencil = true;

    d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8; // depth format

    d3dpp.Flags = 0;

    d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;

    d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;

    1.4.4 创建IDirect3DDevice9对象

    在填充完了D3DPRESENT_PARAMETERS结构后,我们就可以用下面的方法创建一个IDirect3DDevice9对象了:

    HRESULT IDirect3D9::CreateDevice(

           UINT Adapter,

           D3DDEVTYPE DeviceType,

           HWND hFocusWindow,

           DWORD BehaviorFlags,

           D3DPRESENT_PARAMETERS *pPresentationParameters,

           IDirect3DDevice9** ppReturnedDeviceInterface

    );

    Adapter——指定对象要表示的物理显示设备

    DeviceType——设备类型,前面说过

    hFocusWindow——同我们在前面d3dpp.hDeviceWindow的相同

    BehaviorFlags——设定为D3DCREATE_SOFTWARE_VERTEXPROCESSING或者D3DCREATE_HARDWARE_VERTEXPROCESSING

    pPresentationParameters——指定一个已经初始化好的D3DPRESENT_PARAMETERS实例

    ppReturnedDeviceInterface——返回创建的设备

    例子:

    IDirect3DDevice9* device = 0;
    hr = d3d9->CreateDevice(
           D3DADAPTER_DEFAULT, // primary adapter
           D3DDEVTYPE_HAL, // device type
           hwnd, // window associated with device
           D3DCREATE_HARDWARE_VERTEXPROCESSING, // vertex processing type
    &d3dpp, // present parameters
    &device); // returned created device
    if( FAILED(hr) )
    {
           ::MessageBox(0, "CreateDevice() - FAILED", 0, 0);
    return 0;
    }

  • 相关阅读:
    一些误解和错误的看法
    负载均衡了解
    《网络编程》守护进程
    Cocos2d-x 3.2编译Android程序错误的解决方案
    ArcMap合并之路 -- 该段路合并成一个完整的路
    让你提前知道软件开发(24):C语言和主要特征的历史
    Java中的TCP/UDP网络通信编程
    Android中Socket大文件断点上传
    android 自定义progressDialog实现
    开发Mhealth(即:Mobile Health 移动医疗)应用必知的10个掘金点
  • 原文地址:https://www.cnblogs.com/flying_bat/p/1108362.html
Copyright © 2011-2022 走看看