第三章 Direct3D中的绘制
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
为了创建一个自定义的顶ห้องสมุดไป่ตู้结构,我们首先 要创建一个包含能存放我们所使用的顶点数 据的结构 例如,下面我们定放了两种顶点数据结构:
第一种包含了位置,颜色信息 第一种包含了位置 颜色信息 struct ColorVertex { float x, y, , z; //坐标 DWORD color //颜色值 }; 第二种包含了位置,法向量 纹理坐标信息 第二种包含了位置 法向量,纹理坐标信息 法向量 struct NormalTexVertex { float x, y, z; //坐标 float nx, ny, nz; //法向量 float u, v; //纹理坐标 };
17
D3D顶点格式 顶点格式
然后把FVF加到自定义顶点数据结构中去
第一种包含了位置,颜色信息 第一种包含了位置 颜色信息 const ColorVertex::FVF = FVF_COLOR; 第二种包含了位置,法向量 纹理坐标信息 第二种包含了位置 法向量,纹理坐标信息 法向量 const NormalTexVertex ::FVF = FVF_NORMAL_TEX ;
19
顶点缓存
为了描述下面这个三角形,我们会定义如下3 个顶点: Vertex* vertices; //Vertex是自定义顶点格式
y
vertices[0] = Vertex( 3.0f, 1.0f, 0.0f); vertices[1] = Vertex(11.0f, 1.0f, 0.0f); vertices[2] = Vertex( 7.0f, 6.0f, 0.0f);
12
D3D顶点格式 顶点格式
我们以前定义的点在数学上来说是正确的 但是当我们在Direct3D环境中使用它的时候 就会觉得很不完善,这是因为在Direct3D中 的顶点包含了许多附加的属性,而不再单纯 的只有空间位置 Direct3D允许我们灵活地构造自己的顶点格 式
13
D3D顶点格式 顶点格式
同时,也要在D3D中定义:
第一种: 第一种: Device->SetFVF(VColorVertex::FVF); 第二种: 第二种: Device->SetFVF(NormalTexVertex::FVF);
18
顶点缓存
三角形是构建3D物体的基本图形
第一步,我们需要记录每一个顶点的信息 顶点缓存的作用就是保存每个顶点的信息
16
D3D顶点格式 顶点格式
我们定义好顶点数据结构后,需要告知D3D, 让它应用到3D场景绘制中 通过定义一个宏命令(#define),设置FVF(灵 活顶点格式)
第一种包含了位置,颜色信息 第一种包含了位置 颜色信息 #define FVF_COLOR (D3DFVF_XYZ | D3DFVF_DIFFUSE) 第二种包含了位置,法向量 纹理坐标信息 第二种包含了位置 法向量,纹理坐标信息 法向量 #define FVF_NORMAL_TEX (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1)
Direct3D中的绘制 中的绘制
1
D3DX几何体 几何体
2
Direct3D几何体 几何体(ID3DXMesh) 几何体
D3DXCreateBox D3DXCreateSphere D3DXCreateCylinder D3DXCreateTeapot D3DXCreatePolygon D3DXCreateTorus
V1 V4 WORD indexList[6] = { V1, V2, V4, //第一个三角形 第一个三角形 V2, V4, V3 //第二个三角形 第二个三角形 }; V2 V3
25
索引缓存
与顶点缓存类似,D3D提供索引缓存的管理 一个索引缓存是通过IDirect3DIndexBuffer9 接口来定义 针对上面的四边形例子, 针对上面的四边形例子,我们看是如何调用 索引缓存的: 索引缓存的:
3
D3DXCreateBox
//用此函数产生一个 长方体 用此函数产生一 用此函数产生 ID3DXMesh* meshBox; D3DXCreateBox( Device, //D3D绘制对象 绘制对象 2.0f, //宽度 //宽度 2.0f, //高度 高度 2.0f, //深度 深度 &meshBox, 0 //指向ID3DXBuffer,存放相邻平 相邻平 指 ,存放相邻 //面的信息,通常设置成 或NULL) 面的信息 面的信息,通常设置成0(或 ); Device->BeginScene(); meshBox->DrawSubset(0);
5
D3DXCreateCylinder
//用此函数产生一个圆柱体 用此函数产生一个圆柱体 用此 ID3DXMesh* meshCylinder; D3DXCreateCylinder( Device, //D3D绘制对象 绘制对象 1.0f, //半径 朝 -Z 轴方向 半径(朝 方向) 半径 1.0f, //半径 朝 +Z轴方向 半径(朝 轴方向) 半径 3.0f, //圆柱长 (沿着+Z轴方向 轴方向) 圆 沿 轴方向 10, //圆柱体的外围有几个面 圆柱体的外围有几个面 //(例:如果设为 就成为四角柱 设为4就成 例 如果设为 就成为四角柱) 10, //圆柱体的两端间共有几段 圆柱体的两端间共有几段 圆柱体的两端间共有 //(灯光效果需要要用到) 灯光效果需要要用 灯光效果需要要用到 &meshCylinder, 0 //通常设置成 或NULL) 通常设置成0(或 通常设置成 ); Device->BeginScene(); meshCylinder->DrawSubset(0);
9
D3D物体的绘制 物体的绘制
10
模型表示
场景是物体或者模型的集合 我们编写DX程序,首先在虚拟世界搭建场景 任何物体都可以用三角形网格来逼近表示:
11
三角形的描述
为了描述一个三角形,我们通常确定三个顶 点的位置 这样我们就能够很明确的表示出这个三角形
y (7, 6)
(3, 1) 0
(11, 1) x
Triangle->Unlock();
23
索引缓存
现在我们已经得到一个物体所有顶点的信息 接下来的问题是如何用这些顶点构建成一个 个的三角形
V1 V4
右图是一个四边形
现在已经定义了4个顶点的信息 现在已经定义了 个顶点的信息 V1, V2, V3, V4 , , , V2 V3
24
索引缓存
我们可以把这个图形分割为两个三角形: {V1, V2, V4} 和 {V2, V4,V3} 绘制完这两个三角形 == 绘制完一个四边形
4
D3DXCreateSphere
//用此函数产生一个球面体 用此函数产生一 球面体 用此函数产生 ID3DXMesh* meshSphere; D3DXCreateSphere( Device, //D3D绘制对象 绘制对象 1.0f, //球面体半径 球面体半径 球面 10, //用几条经线绘制 用几条经线绘制 10, //用几条维线绘制 用几条维线绘制 &meshSphere, 0 //通常设置成 或NULL) 通常设置成0(或 通常设置成 ); Device->BeginScene(); meshSphere->DrawSubset(0);
14
1.什么是纹理坐标呢? 一般的纹理都是一个二维的图片,比如一幅画,纹 理坐标就是指画中每一个像素的坐标。当然还有其 他格式的坐标,比如三维坐标---立体纹理坐标;一 维坐标等等。
15
2.纹理坐标有啥用呢? 当画一个primitive的时候,需要给这个primitive填充颜色,当 然不是简简单单的刷上一个颜色,要的是更复杂的结果。这个 时候就需要给这个primitive指定一个纹理,制定完成后就等着 画图了。画图的时候,DirectX 根据指定的primitive中的坐标-----0.0到1.0,从纹理中去取,比如把一个纹理的对应坐标值赋 值给一个primitive,然后(0.5, 0.7)这个点的颜色就是 (0.5*texture_width, 0.5*texture_height)的颜色值,如果取出来 的坐标不是一个整数,那么就最近取一个点的色值了。通过这 种方法达到给primitive中的每个点赋值来达到显示效果。
7
D3DXCreatePolygon
//用此函数产生一个2D 多边体 用此函数产生一个 用此函数产生一个 ID3DXMesh* meshPolygon; D3DXCreatePolygon( Device, //D3D绘制对象 绘制对象 2.0f, //每条边的长度 每 6, //包含几个三角形 包含几个三角形 &meshPolygon, 0 //通常设置成 或NULL) 通常设置成0(或 通常设置成 ); Device->BeginScene(); meshPolygon->DrawSubset(0);
(7, 6)
(3, 1) 0
(11, 1) x
20
顶点缓存
?
顶点的信息是被放在显存中,怎样 才能在D3D中实现? D3D为我们提供了 IDirect3DVertexBuffer9 接口来管理顶点信息,使之可以存储在显存 中。
我们来看具体是怎么应用的: 我们来看具体是怎么应用的:
21
顶点缓存
/*以前面的三角形为例*/ //第一步:创建顶点缓存 IDirect3DVertexBuffer9* Triangle = 0; // //第二步:为顶点缓存分配显存地址空间 Device->CreateVertexBuffer( 3 * sizeof(Vertex), //分配的顶点缓存空间大小 D3DUSAGE_WRITEONLY, //一些附加属性 Vertex::FVF, //自定义的顶点格式 D3DPOOL_MANAGED, //容纳缓存的内存池 &Triangle, //待返回的顶点缓存指针 0);
8
D3DXCreateTorus
//用此函数产生一个甜甜圈 用此函数产生一个甜甜圈 用此函数产生一个 ID3DXMesh* meshTours; D3DXCreateTorus( Device, //D3D绘制对象 绘制对象 1.0f, //甜甜圈的內圈半径 甜甜圈的 甜甜圈 內圈半径 3.0f, //甜甜圈的外圈半径 甜甜圈的 甜甜圈 外圈半径 10, //外圈有几个面 外圈有 外圈 几个面 10, //內圈和外圈间有 內圈和外圈间 內圈和外圈间有 //几个面(同心圆) 几个面 同心圆 几个 同心 &meshTours, 0 //通常设置成 或NULL) 通常设置成0(或 通常设置成 ); Device->BeginScene(); meshTours->DrawSubset(0);
22
顶点缓存
//第三步:创建顶点信息数组 Vertex* vertices; //第四步:锁定该内存(此时禁止其他进程修改该显存区域)
Triangle->Lock(0, 0, (void**)&vertices, 0);
//第五步:填充顶点信息 vertices[0] = Vertex( 3.0f, 1.0f, 0.0f); vertices[1] = Vertex(11.0f, 1.0f, 0.0f); vertices[2] = Vertex( 7.0f, 6.0f, 0.0f); //第六步:解除锁定
26
索引缓存
/*以上面的四边形为例*/ //第一步:创建索引缓存 IDirect3DIndexBuffer9* IB = 0; //Index Buffer // //第二步:为索引缓存分配显存地址空间 Device->CreateIndexBuffer( 6 * sizeof(WORD), //分配的索引缓存空间大小 D3DUSAGE_WRITEONLY, //一些附加属性 D3DFMT_INDEX16, D3DPOOL_MANAGED, //容纳缓存的内存池 &IB, //待返回的索引缓存指针 0);
6
D3DXCreateTeapot
//用此函数产生一个茶壶 用此函数产生一个茶壶 用此 ID3DXMesh* meshTeapot; D3DXCreateTeapot( Device, //D3D绘制对象 绘制对象 &meshTeapot, 0 //通常设置成 或NULL) 通常设置成0(或 通常设置成 ); Device->BeginScene(); meshTeapot->DrawSubset(0);
第一种包含了位置,颜色信息 第一种包含了位置 颜色信息 struct ColorVertex { float x, y, , z; //坐标 DWORD color //颜色值 }; 第二种包含了位置,法向量 纹理坐标信息 第二种包含了位置 法向量,纹理坐标信息 法向量 struct NormalTexVertex { float x, y, z; //坐标 float nx, ny, nz; //法向量 float u, v; //纹理坐标 };
17
D3D顶点格式 顶点格式
然后把FVF加到自定义顶点数据结构中去
第一种包含了位置,颜色信息 第一种包含了位置 颜色信息 const ColorVertex::FVF = FVF_COLOR; 第二种包含了位置,法向量 纹理坐标信息 第二种包含了位置 法向量,纹理坐标信息 法向量 const NormalTexVertex ::FVF = FVF_NORMAL_TEX ;
19
顶点缓存
为了描述下面这个三角形,我们会定义如下3 个顶点: Vertex* vertices; //Vertex是自定义顶点格式
y
vertices[0] = Vertex( 3.0f, 1.0f, 0.0f); vertices[1] = Vertex(11.0f, 1.0f, 0.0f); vertices[2] = Vertex( 7.0f, 6.0f, 0.0f);
12
D3D顶点格式 顶点格式
我们以前定义的点在数学上来说是正确的 但是当我们在Direct3D环境中使用它的时候 就会觉得很不完善,这是因为在Direct3D中 的顶点包含了许多附加的属性,而不再单纯 的只有空间位置 Direct3D允许我们灵活地构造自己的顶点格 式
13
D3D顶点格式 顶点格式
同时,也要在D3D中定义:
第一种: 第一种: Device->SetFVF(VColorVertex::FVF); 第二种: 第二种: Device->SetFVF(NormalTexVertex::FVF);
18
顶点缓存
三角形是构建3D物体的基本图形
第一步,我们需要记录每一个顶点的信息 顶点缓存的作用就是保存每个顶点的信息
16
D3D顶点格式 顶点格式
我们定义好顶点数据结构后,需要告知D3D, 让它应用到3D场景绘制中 通过定义一个宏命令(#define),设置FVF(灵 活顶点格式)
第一种包含了位置,颜色信息 第一种包含了位置 颜色信息 #define FVF_COLOR (D3DFVF_XYZ | D3DFVF_DIFFUSE) 第二种包含了位置,法向量 纹理坐标信息 第二种包含了位置 法向量,纹理坐标信息 法向量 #define FVF_NORMAL_TEX (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1)
Direct3D中的绘制 中的绘制
1
D3DX几何体 几何体
2
Direct3D几何体 几何体(ID3DXMesh) 几何体
D3DXCreateBox D3DXCreateSphere D3DXCreateCylinder D3DXCreateTeapot D3DXCreatePolygon D3DXCreateTorus
V1 V4 WORD indexList[6] = { V1, V2, V4, //第一个三角形 第一个三角形 V2, V4, V3 //第二个三角形 第二个三角形 }; V2 V3
25
索引缓存
与顶点缓存类似,D3D提供索引缓存的管理 一个索引缓存是通过IDirect3DIndexBuffer9 接口来定义 针对上面的四边形例子, 针对上面的四边形例子,我们看是如何调用 索引缓存的: 索引缓存的:
3
D3DXCreateBox
//用此函数产生一个 长方体 用此函数产生一 用此函数产生 ID3DXMesh* meshBox; D3DXCreateBox( Device, //D3D绘制对象 绘制对象 2.0f, //宽度 //宽度 2.0f, //高度 高度 2.0f, //深度 深度 &meshBox, 0 //指向ID3DXBuffer,存放相邻平 相邻平 指 ,存放相邻 //面的信息,通常设置成 或NULL) 面的信息 面的信息,通常设置成0(或 ); Device->BeginScene(); meshBox->DrawSubset(0);
5
D3DXCreateCylinder
//用此函数产生一个圆柱体 用此函数产生一个圆柱体 用此 ID3DXMesh* meshCylinder; D3DXCreateCylinder( Device, //D3D绘制对象 绘制对象 1.0f, //半径 朝 -Z 轴方向 半径(朝 方向) 半径 1.0f, //半径 朝 +Z轴方向 半径(朝 轴方向) 半径 3.0f, //圆柱长 (沿着+Z轴方向 轴方向) 圆 沿 轴方向 10, //圆柱体的外围有几个面 圆柱体的外围有几个面 //(例:如果设为 就成为四角柱 设为4就成 例 如果设为 就成为四角柱) 10, //圆柱体的两端间共有几段 圆柱体的两端间共有几段 圆柱体的两端间共有 //(灯光效果需要要用到) 灯光效果需要要用 灯光效果需要要用到 &meshCylinder, 0 //通常设置成 或NULL) 通常设置成0(或 通常设置成 ); Device->BeginScene(); meshCylinder->DrawSubset(0);
9
D3D物体的绘制 物体的绘制
10
模型表示
场景是物体或者模型的集合 我们编写DX程序,首先在虚拟世界搭建场景 任何物体都可以用三角形网格来逼近表示:
11
三角形的描述
为了描述一个三角形,我们通常确定三个顶 点的位置 这样我们就能够很明确的表示出这个三角形
y (7, 6)
(3, 1) 0
(11, 1) x
Triangle->Unlock();
23
索引缓存
现在我们已经得到一个物体所有顶点的信息 接下来的问题是如何用这些顶点构建成一个 个的三角形
V1 V4
右图是一个四边形
现在已经定义了4个顶点的信息 现在已经定义了 个顶点的信息 V1, V2, V3, V4 , , , V2 V3
24
索引缓存
我们可以把这个图形分割为两个三角形: {V1, V2, V4} 和 {V2, V4,V3} 绘制完这两个三角形 == 绘制完一个四边形
4
D3DXCreateSphere
//用此函数产生一个球面体 用此函数产生一 球面体 用此函数产生 ID3DXMesh* meshSphere; D3DXCreateSphere( Device, //D3D绘制对象 绘制对象 1.0f, //球面体半径 球面体半径 球面 10, //用几条经线绘制 用几条经线绘制 10, //用几条维线绘制 用几条维线绘制 &meshSphere, 0 //通常设置成 或NULL) 通常设置成0(或 通常设置成 ); Device->BeginScene(); meshSphere->DrawSubset(0);
14
1.什么是纹理坐标呢? 一般的纹理都是一个二维的图片,比如一幅画,纹 理坐标就是指画中每一个像素的坐标。当然还有其 他格式的坐标,比如三维坐标---立体纹理坐标;一 维坐标等等。
15
2.纹理坐标有啥用呢? 当画一个primitive的时候,需要给这个primitive填充颜色,当 然不是简简单单的刷上一个颜色,要的是更复杂的结果。这个 时候就需要给这个primitive指定一个纹理,制定完成后就等着 画图了。画图的时候,DirectX 根据指定的primitive中的坐标-----0.0到1.0,从纹理中去取,比如把一个纹理的对应坐标值赋 值给一个primitive,然后(0.5, 0.7)这个点的颜色就是 (0.5*texture_width, 0.5*texture_height)的颜色值,如果取出来 的坐标不是一个整数,那么就最近取一个点的色值了。通过这 种方法达到给primitive中的每个点赋值来达到显示效果。
7
D3DXCreatePolygon
//用此函数产生一个2D 多边体 用此函数产生一个 用此函数产生一个 ID3DXMesh* meshPolygon; D3DXCreatePolygon( Device, //D3D绘制对象 绘制对象 2.0f, //每条边的长度 每 6, //包含几个三角形 包含几个三角形 &meshPolygon, 0 //通常设置成 或NULL) 通常设置成0(或 通常设置成 ); Device->BeginScene(); meshPolygon->DrawSubset(0);
(7, 6)
(3, 1) 0
(11, 1) x
20
顶点缓存
?
顶点的信息是被放在显存中,怎样 才能在D3D中实现? D3D为我们提供了 IDirect3DVertexBuffer9 接口来管理顶点信息,使之可以存储在显存 中。
我们来看具体是怎么应用的: 我们来看具体是怎么应用的:
21
顶点缓存
/*以前面的三角形为例*/ //第一步:创建顶点缓存 IDirect3DVertexBuffer9* Triangle = 0; // //第二步:为顶点缓存分配显存地址空间 Device->CreateVertexBuffer( 3 * sizeof(Vertex), //分配的顶点缓存空间大小 D3DUSAGE_WRITEONLY, //一些附加属性 Vertex::FVF, //自定义的顶点格式 D3DPOOL_MANAGED, //容纳缓存的内存池 &Triangle, //待返回的顶点缓存指针 0);
8
D3DXCreateTorus
//用此函数产生一个甜甜圈 用此函数产生一个甜甜圈 用此函数产生一个 ID3DXMesh* meshTours; D3DXCreateTorus( Device, //D3D绘制对象 绘制对象 1.0f, //甜甜圈的內圈半径 甜甜圈的 甜甜圈 內圈半径 3.0f, //甜甜圈的外圈半径 甜甜圈的 甜甜圈 外圈半径 10, //外圈有几个面 外圈有 外圈 几个面 10, //內圈和外圈间有 內圈和外圈间 內圈和外圈间有 //几个面(同心圆) 几个面 同心圆 几个 同心 &meshTours, 0 //通常设置成 或NULL) 通常设置成0(或 通常设置成 ); Device->BeginScene(); meshTours->DrawSubset(0);
22
顶点缓存
//第三步:创建顶点信息数组 Vertex* vertices; //第四步:锁定该内存(此时禁止其他进程修改该显存区域)
Triangle->Lock(0, 0, (void**)&vertices, 0);
//第五步:填充顶点信息 vertices[0] = Vertex( 3.0f, 1.0f, 0.0f); vertices[1] = Vertex(11.0f, 1.0f, 0.0f); vertices[2] = Vertex( 7.0f, 6.0f, 0.0f); //第六步:解除锁定
26
索引缓存
/*以上面的四边形为例*/ //第一步:创建索引缓存 IDirect3DIndexBuffer9* IB = 0; //Index Buffer // //第二步:为索引缓存分配显存地址空间 Device->CreateIndexBuffer( 6 * sizeof(WORD), //分配的索引缓存空间大小 D3DUSAGE_WRITEONLY, //一些附加属性 D3DFMT_INDEX16, D3DPOOL_MANAGED, //容纳缓存的内存池 &IB, //待返回的索引缓存指针 0);
6
D3DXCreateTeapot
//用此函数产生一个茶壶 用此函数产生一个茶壶 用此 ID3DXMesh* meshTeapot; D3DXCreateTeapot( Device, //D3D绘制对象 绘制对象 &meshTeapot, 0 //通常设置成 或NULL) 通常设置成0(或 通常设置成 ); Device->BeginScene(); meshTeapot->DrawSubset(0);