Lesson1:
D3D的初始化:
1、获取接口IDirect3D9的指针(用来获取系统物理设备信息和创建接口DirectDevice9)
2、检查设备性能
3、初始化D3DPRESENT_PARAMETERS结构的一个实例
4、利用D3DPRESENT_PARAMETERS结构来创建一个IDirectDevice9对象
关系: IDirect3D9->Init3D填充D3DPRESENT_PARAMETERS结构->IDirectDevice9
Lesson2:
当顶点结构体中有RHW时,就像上面那段英文所述,告知Direct3D使用的顶点已经在屏幕坐标系中了,不再执行视图、投影、世界等变换和光线计算。
默认状态下,D3D认为顶点排列顺序为顺时针。
了解D3D的绘制流水线和坐标系变换。
Ps:(1)不设置观察坐标系,直接投影时,就好像摄像机默认是:
D3DXVECTOR3 position(0.0,0.0f,-0.1f);
D3DXVECTOR3targetPoint(0.0f,0.0f,0.0f);
D3DXVECTOR3worldUp(0.0f,1.0f,0.0f);
(2)之所以用到投影,是将物体从3D变为2D显示,投影有两种:正交和透视投影。
(3)Device->Draw1();
D3DXMatrixTranslation(&World,1.25f,0.0f,0.0f);
g_pDev3D9->SetTransform(D3DTS_WORLD,&World);
Device->Draw2();
显示:两个物体叠在一起(2在1前)。如果在Draw2后再加一个移动变换矩阵,1会在新世界矩阵那里(不明白)。所以,每次绘制物体前,最好之后先设置世界矩阵,多个物体时,世界矩阵要重置。。
Lesson3:
为什么要使用VertexBuffer和IndexBuffer?因为它们可以被放置在显存中。
使用DrawPrimitive或DrawIndexPrimitive绘制顶点缓存或索引缓存。
为了绘制缓存里面的内容,你还要三个步骤:
1、设置数据流 2、设置顶点格式 3、是否设置索引缓存
Ps: 一定要确定程序有没使用深度模板缓存,否则d3dpp.EnableAutoDepthStencil=true时会影响显示效果,例如3D变2D,2D颜色不正常等。
Lesson4: (Material and Light)
使用材质时,Emissive一般设为黑色,不发光,否则会跟方向光源等的颜色叠加。换句话说,没有光源时,材质颜色由Emissive决定(理解Emissive表示内发光)
如果不设置材质而用光照,材质为黑色,因为不知道反射什么颜色,除非用顶点着色。
三维模型顶点法向量的很重要,它直接影响着显示的效果,不设置正确是就像没有光源一样。
注意光照跟光源的区别。光照时本来就有的。光源是可以后来添加上去的。
光照:Device->SetRenderState(D3DRS_LIGHTING,true);没有这句,默认也是开启的。
Lesson5:(Texture)
学会了用纹理坐标(跟OpenGL纹理坐标系不同)贴图,过滤器,和关于mipmap(mipmaps链)的一些知识。
为什么使用纹理时要关闭光照?可以再创建与设置纹理后使用光照,但是会和材质共同影响纹理显示效果。使用纹理时也可以用光照,但是材质设为白色。
寻址模式用于纹理坐标超出范围时(如:0,3)的显示效果。
PS:龙书工程DirextX_T6b 使用灯光时纹理会闪烁。
Lesson6: (Blend)
当你绘制完要融合的几何体后,应该禁止Alpha融合。
Alpha值为0,完全透明,Alpha值为255,完全不透明。
源融合因子和目标融合因子默认值分别为:D3DBLEND_SRCALPHA和D3DBLEND_INVSRCALPHA。
Alpha值默认取自Alpha通道,没有就可以取自顶点的颜色。
PS:绘制图形时,有时要用单位矩阵初始化创建的一个世界矩阵。
用到两个纹理时,一定要在绘制物体前设置纹理。
Lesson7:(模板缓存的应用)
Stencil Buffer相当于后台缓存的过滤网。模板测试,判定是否将某个像素写入后台缓存。
“镜面效果”,步骤:
开启模板缓存并设置绘制状态,这时模板测试总是通过->
绘制反射地方,这时模板测试通过参考值被设为1->
修改模板测试函数,equal1的地方才能通过模板测试,之后设置反射矩阵->
绘制并融合物体
“阴影效果”,(用模版缓存防止二次融合(二次融合的概念看龙书142页)),步骤:
模板缓存清0,并且设置绘制状态(D3DRS_STENCILPASS为D3DSTENCILOP_INCR)
计算阴影矩阵
ALPHA融合
禁用深度缓存并会植物体
PS:(1)两个效果一起用时,官方例子说应该先绘制阴影,因为在镜子效果里我们清除了深度缓存。如果先绘制镜子再绘制阴影的话,阴影会不能被其他物体遮挡。但是我刚才试了一下,阴影还是到墙上的。最好的方法还是重绘一下除了阴影部分的场景或者换成阴影体(Shadow Volume)看看吧-0 -。(2)两个效果一起时,阴影不能到镜子里,这个好解决吧。(3)模板缓存还可以应用于:阴影体,消融和淡入淡出,轮廓图等等......(龙书145页)
Lesson8:(Font)
VC6.0下不能用ID3DXFont绘制字体。D3D中显示中文和自己百度吧。
绘制帧率时,timeGetTime()用到winmm.lib
学会了怎样计算渲染帧率。两种描绘2D文字方法,一种描述3D方法,都不能描述汉字。
Lesson9:(自定义一个网格)
属性缓存,指定每个三角形(面)在哪个子集中。
网格优化:Mesh的顶点和索引能够被重组以便能更"有效"地渲染Mesh。
当一个Mesh使用D3DXMESHOPT_ATTRSORT参数来优化后,Mesh的几何信息将按照属性进行排序,这样各个子集的顶点/索引将组成连续的块,除了进行几何信息的排序外,D3DXMESHOPT_ATTRSORT优化项还将创建一个属性表。(建立了属性表以后,渲染一个子集就很容易了)
对于某些网格运算(如网格优化),有必要了解它的邻接信息。
步骤:
1、 创建一个空mesh。
2、 用一个立方体几何信息来填充mesh。
3、 根据mesh的每个面指定子集。
4、 产生mesh的邻接信息。
5、 优化mesh。
6、 绘制mesh。 //对简单的几何体可以跳过4、5
PS:在Debug里,运行程序时,也必须有资源,否则显示不出来。(今天才知道=- =、)
Lesson10:(自定义一个模型)
直接用ID3DXMesh载入一个.x文件。(163帧)
基于ID3DXMesh使用渐进网格ID3DXPMesh,可以用ECT简化网格。(150帧)
外借体/球常常被用来加速可见性测试,碰撞检测等。
PS:
(1)注意D3DXMATERIAL和D3DMATERIAL9的区别,前者包含了D3DXMATERIAL和纹理名,后者表示才表示是材质。
(2)为什么不使用网格优化,更快地绘制ID3DXMesh呢?可以使用网格优化,只是书本没说。
(3)使用外接体、球时,记得在3DSMAX里把模型置中到原点,否则渲染出来的外接体、球与模型不重合。
(4)最后花了一个下午的时间将载入模型这个过程,弄成了一个类。以后也应该这样,将某些以后可能重复使用的功能弄成了一个类,方便以后调用,也提高面向对象的思想。
Lesson11(Camera):
围绕right向量旋转(pitch倾斜)
围绕up向量旋转(yaw 偏航)
围绕look向量旋转(roll 滚转)
沿着right向量平移(strafe)
沿着up向量飞行(fly)
沿着look向量移动(move)
我们的摄像机支持两种摄像机模式,LANDOBJECT模式和AIRCRAFT模式。
学会了3D数学的某些用法,如:D3DXVec3Dot(&_right,&_pos); //向量点乘
D3DXVec3TransformCoord(&_up, &_up,&T); //用矩阵变换3D向量
ps:知道了如何书写算法,如设计鼠标摄像机时: 1、GetCursorPos(currentPos);2、计算鼠标偏移dx=currentPos- lastPos、dy; 3、绕轴旋转
Lesson12(Terrain):
创建地形的步骤:
1、生成地形的顶点和面片数据
2、对地形进行纹理映射和光照处理
3、安置摄像机的行走
PS:1、这里我们使用高度图(.raw)去描述地形的高度值。2、如何让我们的小蛮也绕着摄像机旋转呢?
Lesson13:(Particle)
1、Direct3D中,我们用点精灵(pointSprite)来显示一个粒子,好处是可以调尺寸、纹理、且只用单点显示
2、设计了一个包含一系列属性和方法的灵活粒子系统基类
3、这里我们用粒子系统模拟了:雪、爆炸和粒子枪,你还可以自己实现火焰、烟雾、雨等等。
PS:
1、这里我明白了地形的大小为640X640,并设置了XYZ坐标显示
2、注意update和render两个方法以便了解粒子系统的实现
3、粒子数目翻倍,帧率也差不多翻倍