龙书笔记(2)

1.  D3DDEVTYPE_HAL: HAL设备

   D3DDEVTYPE_REF: REF设备

HAL需要的是硬件支持,速度快; 而REF是软件支持的,所以什么硬件都能用,但是速度慢。


2. COM(组件对象模型),不可使用new关键字去创建COM接口, 调用完毕后使用 Release 方法释放

注意:COM接口都有一个前缀 ! 比如,表示表面的COM接口为 IDirect3DSurface9, 这是一些其它接口:IDirect3DDevice9 IDirect3D9...


3. 表面: Direct3D主要用于 存储2D图像数据 的一个 像素矩阵

一般用接口 IDirect3DSurface9 来描述表面, 他最重要的方法有:
1.LockRect: 获取指向表面存储区的指针, 通过指针的运算, 可以对表面中的每一个像素进行读写操作。
2.UnlockRect: 若执行访问表面存储区的操作完毕,则必须调用这个方法来解除锁定。
3.GetDesc: 通过填充结构 D3DSURFACE_DESC 来获取该表面 的描述信息。
注:后面对自己创建的空纹理 也是使用 LockRect来管理具体内容


4. 多重采样:平滑块状图像

D3DMULTISAMPLE_NONE:禁用多重采样

D3DMULTISAMPLE_1_SAMPLE...D3DMULTISAMPLE_16_SAMPLE:指定了 1 ~ 16 级的多重采样

注:采样,简单的理解就是不让绘制的图像出现锯齿状的边缘


5. 像素格式: 创建 表面或纹理 时,常须指出这些Direct3D资源的像素格式。

D3DFMT_R8G8B8, D3DFMT_X8R8G8B8, D3DFMT_A8R8G8B8....


6. 内存池: 表面 和其他的 Direct3D资源 可以放入许多类型的 内存池 中。

D3DPOOL_DEFUALT, D3DPOOL_MANAGED...

7. 交换链和页面置换:主要用于生成更加平滑的动画。

可以想象一下周星驰演的《武状元苏乞儿》,他最后看到降龙第18掌的时候,风吹动地上的书页,从前往后翻,形成了动画,这就是第18 掌。

同理,交换链也是不断在两个或者多个面之间转换,当达到一定速度的时候就是动画的效果了


8. 深度缓存:判定某一物体的哪些像素位于另一个物体之前,称为深度缓存或者z缓存

一般用24位深度缓存就可以满足需求了: D3DFMT_D24S8

"D24S8"说明有8位的 stencil 缓存,还有24位的depth缓存, 这个后面会说到。




我的第一个程序终于历经千辛万苦弄出来了:
1.创建的是win32项目,而不是控制台的程序。
2.头文件导入的是 d3dUtility.h, 源文件是 d3dUtility.cpp 和 d3dInit.cpp
3.运行,出错...
4. 项目 -> 属性 -> 连接器 -> 输入-> 写入需要的3个库(d3d9.lib d3dx9.lib winmm.lib)
5.再运行,再出错...
6. 项目 -> 属性 -> 常规 -> 字符集 -> 使用多字节字符集
7.运行,终于出来一个 黑的界面(成功)。
   
接下来是对这几个文件的探究:

初始化(Init)的步骤:

			HRESULT hr = 0;		//主要用于判断创建的对象是否成功



1.创建 IDirect3D9 对象,用到的函数是 Direct3DCreate9(D3D_SDK_VERSION);

			//这一步是为了得到d3d9			
			IDirect3D9* d3d9 = 0;
			d3d9 = Direct3DCreate9(D3D_SDK_VERSION);

			if( !d3d9 )
			{
				::MessageBox(0, "Direct3DCreate9() - FAILED", 0, 0);
				return false;
			}


2.检测 硬件顶点运算, 创建一个D3DCAPS9的对象,用刚才创建好的 IDirect3D9 对象的GetDeviceCaps()方法 返回已初始化设备性能的结构实例,

通过这个实例选择是 支持硬件顶点运算 还是 软件顶点的运算。(这一步主要是因为在 创建IDirect3DDevice 时,需要指明顶点运算的类型)

		//这一步是为了得到vp
		D3DCAPS9 caps;
		d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, deviceType, &caps);

		int vp = 0;
		if( caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT )
			vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;
		else
			vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;


3.填充 D3DPRESENT_PARAMETERS 的具体值(首先要创建一个 D3DPRESENT_PARAMETERS 对象)

		//这一步是为了得到d3dpp。注意在赋予BackBufferFormat值得时候,我看到一些其他的书上用了D3DDISPLAYMODE的Format属性,都差不多
		D3DPRESENT_PARAMETERS d3dpp;
		d3dpp.BackBufferWidth            = width;					//后台缓存中表面的宽度
		d3dpp.BackBufferHeight           = height;					//后台缓存中表面的高度
		d3dpp.BackBufferFormat           = D3DFMT_A8R8G8B8;				//后台缓存的像素格式
		d3dpp.BackBufferCount            = 1;						//后台缓存的数量,通常是1
		d3dpp.MultiSampleType            = D3DMULTISAMPLE_NONE;				//多重采样的类型,这里用的是 禁用多重采样
		d3dpp.MultiSampleQuality         = 0;						//多重采样的质量水平
		d3dpp.SwapEffect                 = D3DSWAPEFFECT_DISCARD; 			//指定交换链中缓存页面的方式,D3DSWAPEFFECT_DISCARD的效率最高
		d3dpp.hDeviceWindow              = hwnd;					//指定所需要进行绘制的应用程序窗口
		d3dpp.Windowed                   = windowed;					//窗口的模式,true表示的是窗口模式, false表示的是全屏模式
		d3dpp.EnableAutoDepthStencil     = true; 					//设置为true时,Direct3D自动创建并维护深度缓存
		d3dpp.AutoDepthStencilFormat     = D3DFMT_D24S8;				//深度缓存的像素格式
		d3dpp.Flags                      = 0;						//一些附加的特性
		d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;			//这里使用了默认的刷新频率
		d3dpp.PresentationInterval       = D3DPRESENT_INTERVAL_IMMEDIATE;		//这里使用的是 立即提交 



4.创建 IDirect3DDevice9 接口
		//device创建完毕
		hr = d3d9->CreateDevice(
			D3DADAPTER_DEFAULT,						
			deviceType,        					//设备的类型,D3DDEVTYPE_HAL或者D3DDEVTYPE_REF
			hwnd,              					//与设备相关的窗口
			vp,                 					//在第三步中设置好的顶点运算类型
			&d3dpp,            					//已被填充好的D3DPRESENT_PARAMETER 对象
			device);            					//取的最终的结果



5.Display函数
		bool Display(float timeDelta)
		{
			if(Device)
			{
				Device->Clear(0,0,D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);		//后台缓存设为黑色 深度缓存设为1.0f
				Device->Present(0,0,0,0);								//清除操作执行完毕之后还要 提交后台缓存
			}
			return true;
		}



你可能感兴趣的:(龙书笔记(2))