1.Direct3D概述

Direct3D的工作框架图如下图所示。

应用程序通过调用Direct3D的API来绘图,Direct3D不直接作用于图形设备,而是通过硬件抽象层(HAL,Hardware Abstraction Layer)操作图形设备。这样的好处是:Direct3D不需要了解图形设备的细节,只要图形设备支持HAL,Direct3D就可以操作该 图形设备。

bool supportsHardwareVertexProcessing;
// 如果为真,意味着硬件设备支持它
if ( caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT ){// 支持supportsHardwareVertexProcessing = true;}
else
{
// 不支持hardwareSupportsVertexProcessing = false ;
}

HAL设备的定义

在代码中,HAL设备用D3DDEVTYPE_HAL来定义。

设备能力

Direct3D支持的每一项特性都对应于D3DCAPS9结构的一个数据成员。我们能够通过监测D3DCAPS9结构中相对应的某一成员来监测设备是否支持这一特性。下面将举例说明,假设我们想要检测显卡是否支持硬件顶点处理(换句话说,就是显卡是否支持硬件几何转换和光源计算)。通过查阅SDK中的D3DCAPS9结构,可以得知数据成员D3DCAPS9::DevCaps中的D3DDEVCAPS _HWTRANSFORMANDLIGHT 位表示硬件是否支持硬件顶点处理即硬件几何变换和光源计算。

// 填充主显示设备的能力(D3DCAPS9结构)
D3DCAPS9 caps;
d3d9->GetDeviceCaps(
D3DADAPTER_DEFAULT, // 主显示设备
deviceType, // 设备类型,一般是D3DDEVTYPE_HAL.
&caps); // 返回填充后的D3DCAPS9 结构,包含主显示设备的能力// 是否可以使用硬件顶点处理?
int vp = 0;
if ( caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT )
{// 是,支持硬件顶点处理vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;
}
else
{// 不,只能用软件顶点处理vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
}

2.初始化Direct3D(重点!)

步骤:

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

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

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

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

具体说明如下:(重点!)

1.获得IDirect3D9接口

IDirect3D9* _d3d9;_d3d9 = Direct3DCreate9(D3D_SDK_VERSION);

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

2.监测硬件顶点处理能力

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

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

HRESULT IDirect3D9::GetDeviceCaps(UINT Adapter,D3DDEVTYPE DeviceType,D3DCAPS9 *pCaps);

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

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

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

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

// 填充主显示设备的能力(D3DCAPS9结构)
D3DCAPS9 caps;d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, // 主显示设备deviceType, // 设备类型,一般是D3DDEVTYPE_HAL.&caps); // 返回填充后的D3DCAPS9 结构,包含主显示设备的能力// 是否可以使用硬件顶点处理?
int vp = 0;if ( caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT ){// 是,支持硬件顶点处理vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;}else{// 不,只能用软件顶点处理vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;}

注意:我们将顶点运算类型用变量vp保存供以后使用。这是因为在创建IDrect3DDevice类型的对象时,必须指定以后所要使用的顶点运算类型。

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_Ref reshRateInHz;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            = width; //width=800d3dpp.BackBufferHeight           = height;  //height=600d3dpp.BackBufferFormat           = D3DFMT_A8R8G8B8;d3dpp.BackBufferCount            = 1;d3dpp.MultiSampleType            = D3DMULTISAMPLE_NONE;d3dpp.MultiSampleQuality         = 0;d3dpp.SwapEffect                 = D3DSWAPEFFECT_DISCARD; d3dpp.hDeviceWindow              = hwnd;d3dpp.Windowed                   = windowed;   //windowed=trued3dpp.EnableAutoDepthStencil     = true; d3dpp.AutoDepthStencilFormat     = D3DFMT_D24S8;d3dpp.Flags                      = 0;d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;d3dpp.PresentationInterval       = D3DPRESENT_INTERVAL_IMMEDIATE;

4.创建IDirect3DDevice9对象

createDevice结构源码:

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* d3d9= 0;  //承接上面的获取接口IDirect3D9指针hr = d3d9->CreateDevice(D3DADAPTER_DEFAULT, // primary adapterD3DDEVTYPE_HAL, // device typehwnd, // window associated with deviceD3DCREATE_HARDWARE_VERTEXPROCESSING, // vertex processing type&d3dpp, // present parameters&device); // returned created deviceif ( FAILED(hr) ){::MessageBox(0, "CreateDevice() - FAILED", 0, 0);return 0;}

至此,初始化结束。以下附上完整代码:

d3dUtility.h

//
//
// File: d3dUtility.h
//
// Author: Frank Luna (C) All Rights Reserved
//
// System: AMD Athlon 1800+ XP, 512 DDR, Geforce 3, Windows XP, MSVC++ 7.0
//
// Desc: Provides utility functions for simplifying common tasks.
//
//#ifndef __d3dUtilityH__
#define __d3dUtilityH__#include <d3dx9.h>
#include <string>namespace d3d
{bool InitD3D(HINSTANCE hInstance,       // [in] Application instance.int width, int height,     // [in] Backbuffer dimensions.bool windowed,             // [in] Windowed (true)or full screen (false).D3DDEVTYPE deviceType,     // [in] HAL or REFIDirect3DDevice9** device);// [out]The created device.int EnterMsgLoop( bool (*ptr_display)(float timeDelta));LRESULT CALLBACK WndProc(HWND hwnd,UINT msg, WPARAM wParam,LPARAM lParam);template<class T> void Release(T t){if( t ){t->Release();t = 0;}}template<class T> void Delete(T t){if( t ){delete t;t = 0;}}
}#endif // __d3dUtilityH__

d3dinit.cpp

//
//
// File: d3dinit.cpp
//
// Author: Frank Luna (C) All Rights Reserved
//
// System: AMD Athlon 1800+ XP, 512 DDR, Geforce 3, Windows XP, MSVC++ 7.0
//
// Desc: Demonstrates how to initialize Direct3D, how to use the book's framework
//       functions, and how to clear the screen to black.  Note that the Direct3D
//       initialization code is in the d3dUtility.h/.cpp files.
//
//#include "d3dUtility.h"//
// Globals
//IDirect3DDevice9* Device = 0; //
// Framework Functions
//bool Setup()
{// Nothing to setup in this sample.return true;
}void Cleanup()
{// Nothing to cleanup in this sample.
}bool Display(float timeDelta)
{if( Device ) // Only use Device methods if we have a valid device.{// Instruct the device to set each pixel on the back buffer black -// D3DCLEAR_TARGET: 0x00000000 (black) - and to set each pixel on// the depth buffer to a value of 1.0 - D3DCLEAR_ZBUFFER: 1.0f.Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);// Swap the back and front buffers.Device->Present(0, 0, 0, 0);}return true;
}//
// WndProc
//
LRESULT CALLBACK d3d::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{switch( msg ){case WM_DESTROY:::PostQuitMessage(0);break;case WM_KEYDOWN:if( wParam == VK_ESCAPE )::DestroyWindow(hwnd);break;}return ::DefWindowProc(hwnd, msg, wParam, lParam);
}//
// WinMain
//
int WINAPI WinMain(HINSTANCE hinstance,HINSTANCE prevInstance, PSTR cmdLine,int showCmd)
{if(!d3d::InitD3D(hinstance,640, 480, true, D3DDEVTYPE_HAL, &Device)){::MessageBox(0, "InitD3D() - FAILED", 0, 0);return 0;}if(!Setup()){::MessageBox(0, "Setup() - FAILED", 0, 0);return 0;}d3d::EnterMsgLoop( Display );Cleanup();Device->Release();return 0;
}

d3dUtility.cpp

//
//
// File: d3dUtility.cpp
//
// Author: Frank Luna (C) All Rights Reserved
//
// System: AMD Athlon 1800+ XP, 512 DDR, Geforce 3, Windows XP, MSVC++ 7.0
//
// Desc: Provides utility functions for simplifying common tasks.
//
//#include "d3dUtility.h"bool d3d::InitD3D(HINSTANCE hInstance,int width, int height,bool windowed,D3DDEVTYPE deviceType,IDirect3DDevice9** device)
{//// Create the main application window.//WNDCLASS wc;wc.style         = CS_HREDRAW | CS_VREDRAW;wc.lpfnWndProc   = (WNDPROC)d3d::WndProc; wc.cbClsExtra    = 0;wc.cbWndExtra    = 0;wc.hInstance     = hInstance;wc.hIcon         = LoadIcon(0, IDI_APPLICATION);wc.hCursor       = LoadCursor(0, IDC_ARROW);wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);wc.lpszMenuName  = 0;wc.lpszClassName = "Direct3D9App";if( !RegisterClass(&wc) ) {::MessageBox(0, "RegisterClass() - FAILED", 0, 0);return false;}HWND hwnd = 0;hwnd = ::CreateWindow("Direct3D9App", "Direct3D9App", WS_EX_TOPMOST,0, 0, width, height,0 /*parent hwnd*/, 0 /* menu */, hInstance, 0 /*extra*/); if( !hwnd ){::MessageBox(0, "CreateWindow() - FAILED", 0, 0);return false;}::ShowWindow(hwnd, SW_SHOW);::UpdateWindow(hwnd);//// Init D3D: //HRESULT hr = 0;// Step 1: Create the IDirect3D9 object.IDirect3D9* d3d9 = 0;d3d9 = Direct3DCreate9(D3D_SDK_VERSION);if( !d3d9 ){::MessageBox(0, "Direct3DCreate9() - FAILED", 0, 0);return false;}// Step 2: Check for hardware vp.D3DCAPS9 caps;d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, deviceType, &caps);int vp = 0;if( caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT )vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;elsevp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;// Step 3: Fill out the D3DPRESENT_PARAMETERS structure.D3DPRESENT_PARAMETERS d3dpp;d3dpp.BackBufferWidth            = width;d3dpp.BackBufferHeight           = height;d3dpp.BackBufferFormat           = D3DFMT_A8R8G8B8;d3dpp.BackBufferCount            = 1;d3dpp.MultiSampleType            = D3DMULTISAMPLE_NONE;d3dpp.MultiSampleQuality         = 0;d3dpp.SwapEffect                 = D3DSWAPEFFECT_DISCARD; d3dpp.hDeviceWindow              = hwnd;d3dpp.Windowed                   = windowed;d3dpp.EnableAutoDepthStencil     = true; d3dpp.AutoDepthStencilFormat     = D3DFMT_D24S8;d3dpp.Flags                      = 0;d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;d3dpp.PresentationInterval       = D3DPRESENT_INTERVAL_IMMEDIATE;// Step 4: Create the device.hr = d3d9->CreateDevice(D3DADAPTER_DEFAULT, // primary adapterdeviceType,         // device typehwnd,               // window associated with devicevp,                 // vertex processing&d3dpp,             // present parametersdevice);            // return created deviceif( FAILED(hr) ){// try again using a 16-bit depth bufferd3dpp.AutoDepthStencilFormat = D3DFMT_D16;hr = d3d9->CreateDevice(D3DADAPTER_DEFAULT,deviceType,hwnd,vp,&d3dpp,device);if( FAILED(hr) ){d3d9->Release(); // done with d3d9 object::MessageBox(0, "CreateDevice() - FAILED", 0, 0);return false;}}d3d9->Release(); // done with d3d9 objectreturn true;
}int d3d::EnterMsgLoop( bool (*ptr_display)(float timeDelta) )
{MSG msg;::ZeroMemory(&msg, sizeof(MSG));static float lastTime = (float)timeGetTime(); while(msg.message != WM_QUIT){if(::PeekMessage(&msg, 0, 0, 0, PM_REMOVE)){::TranslateMessage(&msg);::DispatchMessage(&msg);}else{  float currTime  = (float)timeGetTime();float timeDelta = (currTime - lastTime)*0.001f;ptr_display(timeDelta);lastTime = currTime;}}return msg.wParam;
}

csdn上的代码,写的非常好,因为之前没做过window编程,这里有些弱,还得多看!

本文很多参考:https://www.cnblogs.com/wangke1020/p/3623145.html

DirectX 9.0笔记]第一章 初始化 Direct3D相关推荐

  1. 《DirectX 9.0 3D游戏开发编程基础》 第一章 初始化Direct3D 读书笔记

    REF设备 参考光栅设备,他能以软件计算方式完全支持Direct3D Api.借助Ref设备,可以在代码中使用那些不为当前硬件所支持的特性,并对这此特性进行测试. D3DDEVTYPE 在程序代码中, ...

  2. [DirectX 9.0笔记]第二章 渲染管线

    本章的主题是渲染管线.渲染管线是什么意思呢?我去查了一下,百度百科里说, 渲染管线也称为渲染流水线或像素流水线或像素管线,是显示芯片内部处理图形信号相互独立的的并行处理单元.在某种程度上可以把渲染管线 ...

  3. 《Go语言圣经》学习笔记 第一章 Go语言入门

    Go语言圣经学习笔记 第一章 Go语言入门 目录 Hello, World 命令行参数 查找重复的行 GIF动画 获取URL 并发获取多个URL Web服务 本章要点 注:学习<Go语言圣经&g ...

  4. 微服务笔记:第一章_微服务简介|Eureka注册中心|Nacos注册中心|Nacos配置管理|Feign|Gateway服务网关

    微服务笔记:第一章_微服务简介|Eureka注册中心|Nacos注册中心|Nacos配置管理|Feign|Gateway服务网关 1. 微服务简介 1.1 服务架构演变 1.2 SpringCloud ...

  5. NHibernate.3.0.Cookbook第一章第六节Handling versioning and concurrency的翻译

    NHibernate.3.0.Cookbook第一章第六节Handling versioning and concurrency的翻译 第一章第二节Mapping a class with XML第一 ...

  6. 【王道考研】操作系统 笔记 第一章

    特此鸣谢王道考研 本文参考王道考研的相关课程 若有侵权请联系,立删 其余笔记链接: [王道考研]操作系统笔记 第一章_才疏学浅743的博客-CSDN博客 [王道考研]操作系统 笔记 第二章上 进程调度 ...

  7. 《MAC OS X 技术内幕》读书笔记第一章:MAC OS X的起源

    <MAC OS X 技术内幕>读书笔记第一章:MAC OS X的起源 前言 1 System x.x系列 1.1System 1.0(1984年1月24日) 1.2System 2.x(1 ...

  8. Unity 游戏黑暗之光笔记第一章 完善场景

    Unity 游戏黑暗之光笔记 第一章 完善场景 1. 导入资地形.地貌资源,新建场景,导入地形.地貌prefab 2. 设置相机与视野匹配 选中主摄像机,点选菜单栏中GameObject > A ...

  9. 小吴的《机器学习 周志华》学习笔记 第一章 绪论

    小吴的<机器学习 周志华>学习笔记 第一章 绪论 近一年时间接触到不少机器学习的知识,虽然断断续续学了一些,总感觉还没有入门(只学会了疯狂调包).因此,最近开始系统学习Machine Le ...

最新文章

  1. php pdo mysql存储过程_MySQL从PHP PDO中的存储过程检索变量
  2. JavaScript实现longestCommonSubsequence最长公共子序列算法(附完整源码)
  3. html盒子阴影只设置左右,只在容器一边或两边显示盒子阴影
  4. PAT-乙级-1009. *说反话 (20)
  5. Bsdiff:Bsd断电差分升级
  6. [HNOI2019]JOJO(KMP自动机+主席树)
  7. 风控体系建设、数字化转型、金融科技应用前,您是如何看待数据问题的?
  8. guass法matlab
  9. c语言如何画函数图形,c语言绘制函数曲线
  10. uni-app自定义搜索框-自定义按钮及搜索图标
  11. 如何用ping 命令简单测试网速
  12. win7电脑蓝屏没有修复计算机,Win7旗舰版系统电脑老是出现蓝屏的修复教程
  13. Ubuntu16.04 安装 indicator-sysmonitor
  14. DB2日期函数DATE函数
  15. 7-6 计算存款利息
  16. (附源码)Python云顶之弈数据分析系统 毕业设计451545
  17. RTX腾讯通字体全变成横着的了
  18. 如何选择微信小程序开发框架?2018年更新
  19. 非苹果机安装 Mac OS X 全教程~~~~转
  20. js 获取下周一的具体年月日格式为(YYYY-MM-DD)

热门文章

  1. 云应用设计模式(三)
  2. 4.3 协方差及相关系数、矩
  3. 服务器(2080Ti)配置pytorch,distiller开发环境踩坑记录
  4. 禁止用户从网页上下载图片
  5. 数据结构 c语言(严蔚敏) 总结 + 代码
  6. shell du命令
  7. js数组遍历所有元素方法 总结
  8. 解读正则化 LASSO回归 岭回归
  9. 单片机工程师面试题小计
  10. 《数据时代 2025》报告-2017年版