第九章:有纹理的球体、圆柱体和锥体_第1页
第九章:有纹理的球体、圆柱体和锥体_第2页
第九章:有纹理的球体、圆柱体和锥体_第3页
第九章:有纹理的球体、圆柱体和锥体_第4页
第九章:有纹理的球体、圆柱体和锥体_第5页
已阅读5页,还剩4页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第九章:有纹理的球体、圆柱体和锥体introduction (序)这一章我们将学习怎样创建有纹理的球体、圆柱体和锥体,我们也会为它们设置法线,这样它们就能产生正确的阴影了。而且,我们将会使所有的类都从一个基类cbase派生,这是一个能以html格式来生成记录文件的和有计算法线向量功能的类。我们这一章的例子将会含有两个圆柱体、两个圆锥体和一个简单的绕太阳旋转的地月模型。how to make a cylinder (怎样生成圆柱体)我们的圆柱体将会含有两个三角扇形,一个做顶,一个做底;它的周身将由一个三角带来完成。下图(9.1)演示了它的构成,顶点和三角形的分布;并且也演示了它的一个段上的几个顶

2、点的法线是什么样子的。这里我们只用顶点缓冲而不用索引缓冲,原因是我们想要它的顶、底与周身相拼接的地方的一些重合顶点拥有不同的法线,如果用索引缓冲就不行了(因为它的实现是把几个重合的顶点看作一个)。fig 9.1要创建一个圆柱体我们需要指定它的分段数,在上面的图示中为8。当然,分段数越多,看起来就会越平滑(越接近圆)。我们还需要指定它的高和半径,这样它的顶点、法线、纹理坐标就都出来了。下面的代码片断能告诉你这一切是怎样完成的。bool ccylinder:updatevertices() cylinder_customvertex* pvertex; word wvertexindex = 0;

3、 int ncurrentsegment; /lock the vertex buffer if(failed(m_pvertexbuffer-lock(0, 0, (byte*)&pvertex, 0) logerror(ccylinder: unable to lock vertex buffer.); return false; float rdeltasegangle = (2.0f * d3dx_pi / m_nsegments); float rsegmentlength = 1.0f / (float)m_nsegments; /create the sides triangle

4、 strip for(ncurrentsegment = 0; ncurrentsegment x = x0; pvertex-y = 0.0f + (m_rheight / 2.0f); pvertex-z = z0; pvertex-nx = x0; pvertex-ny = 0.0f; pvertex-nz = z0; pvertex-tu = 1.0f - (rsegmentlength * (float)ncurrentsegment); pvertex-tv = 0.0f; pvertex+; pvertex-x = x0; pvertex-y = 0.0f - (m_rheigh

5、t / 2.0f); pvertex-z = z0; pvertex-nx = x0; pvertex-ny = 0.0f; pvertex-nz = z0; pvertex-tu = 1.0f - (rsegmentlength * (float)ncurrentsegment); pvertex-tv = 1.0f; pvertex+; /create the top triangle fan: center pvertex-x = 0.0f; pvertex-y = 0.0f + (m_rheight / 2.0f); pvertex-z = 0.0f; pvertex-nx = 0.0

6、f; pvertex-ny = 1.0f; pvertex-nz = 0.0f; pvertex-tu = 0.5f; pvertex-tv = 0.5f; pvertex+; /create the top triangle fan: edges for(ncurrentsegment = 0; ncurrentsegment x = x0; pvertex-y = 0.0f + (m_rheight / 2.0f); pvertex-z = z0; pvertex-nx = 0.0f; pvertex-ny = 1.0f; pvertex-nz = 0.0f; float tu0 = (0

7、.5f * sinf(ncurrentsegment * rdeltasegangle) + 0.5f; float tv0 = (0.5f * cosf(ncurrentsegment * rdeltasegangle) + 0.5f; pvertex-tu = tu0; pvertex-tv = tv0; pvertex+; /create the bottom triangle fan: center pvertex-x = 0.0f; pvertex-y = 0.0f - (m_rheight / 2.0f); pvertex-z = 0.0f; pvertex-nx = 0.0f;

8、pvertex-ny = -1.0f; pvertex-nz = 0.0f; pvertex-tu = 0.5f; pvertex-tv = 0.5f; pvertex+; /create the bottom triangle fan: edges for(ncurrentsegment = m_nsegments; ncurrentsegment = 0; ncurrentsegment-) float x0 = m_rradius * sinf(ncurrentsegment * rdeltasegangle); float z0 = m_rradius * cosf(ncurrents

9、egment * rdeltasegangle); pvertex-x = x0; pvertex-y = 0.0f - (m_rheight / 2.0f); pvertex-z = z0; pvertex-nx = 0.0f; pvertex-ny = -1.0f; pvertex-nz = 0.0f; float tu0 = (0.5f * sinf(ncurrentsegment * rdeltasegangle) + 0.5f; float tv0 = (0.5f * cosf(ncurrentsegment * rdeltasegangle) + 0.5f; pvertex-tu

10、= tu0; pvertex-tv = tv0; pvertex+; if(failed(m_pvertexbuffer-unlock() logerror(ccylinder: unable to unlock vertex buffer.); return false; return true; 那末然后呢?锁定顶点缓冲之后我们需要计算每个段的角度,也就是用分段数来平分2xpi个弧度,它将会被保存在rdeltasegangle中,在以后定义顶点位置时将会被用到。我们为它的周身设置纹理坐标时还得计算每段的长度,也就是用分段数来平分纹理坐标的最大值1.0。然后我们还得定义它的周身。我们有一个循

11、环,它会顺序的处理每一个分段,计算分段的顶和底的顶点的x和z值,它的y值很好计算,正的半个高度和负的半个高度就是了。我们用段的长度来计算当前段的纹理坐标。然后,我们就能定义顶和底的三角扇形了。首先我们定义它们的中心点(圆心),然后用相同的计算方法得出边缘的顶点。完成后,顶点缓冲就应该满了,我们解锁它准备渲染。how to make a cone (怎样生成圆锥体)我们的锥体将由一个三角扇形来构成底,一个三角列来构成周身。像圆柱体一样,我们需要指定它的段数、高和半径。下图(9.2)演示了它的构成方法,图中的锥体为8个段,红线演示了其中一个段的法线。我们将同时使用索引缓冲和顶点缓冲。同时,我们也设

12、置了正确的法线,得到了正确的阴影。fig 9.2我们需要指定锥体的段数,上图中的段数为8,当然,段数越多效果越好。我们还需要指定它的高和半径,这样它的顶点、法线、纹理坐标就都出来了。下面的代码片断能告诉你这一切是怎样完成的。bool ccone:updatevertices() cone_customvertex* pvertex; word* pindices; word wvertexindex = 0; int ncurrentsegment; /lock the vertex buffer if(failed(m_pvertexbuffer-lock(0, 0, (byte*)&pve

13、rtex, 0) logerror(ccone: unable to lock vertex buffer.); return false; /lock the index buffer if(failed(m_pindexbuffer-lock(0, m_dwnumofindices, (byte*)&pindices, 0) logerror(ccone: unable to lock index buffer.); return false; float rdeltasegangle = (2.0f * d3dx_pi / m_nsegments); float rsegmentleng

14、th = 1.0f / (float)m_nsegments; float ny0 = (90.0f - (float)d3dxtodegree(atan(m_rheight / m_rradius) / 90.0f; /for each segment, add a triangle to the sides triangle list for(ncurrentsegment = 0; ncurrentsegment x = 0.0f; pvertex-y = 0.0f + (m_rheight / 2.0f); pvertex-z = 0.0f; pvertex-nx = x0; pver

15、tex-ny = ny0; pvertex-nz = z0; pvertex-tu = 1.0f - (rsegmentlength * (float)ncurrentsegment); pvertex-tv = 0.0f; pvertex+; pvertex-x = x0; pvertex-y = 0.0f - (m_rheight / 2.0f); pvertex-z = z0; pvertex-nx = x0; pvertex-ny = ny0; pvertex-nz = z0; pvertex-tu = 1.0f - (rsegmentlength * (float)ncurrents

16、egment); pvertex-tv = 1.0f; pvertex+; /set three indices (1 triangle) per segment *pindices = wvertexindex; pindices+; wvertexindex+; *pindices = wvertexindex; pindices+; wvertexindex += 2; if(ncurrentsegment = m_nsegments - 1) *pindices = 1; pindices+; wvertexindex-; else *pindices = wvertexindex;

17、pindices+; wvertexindex-; /create the bottom triangle fan: center vertex pvertex-x = 0.0f; pvertex-y = 0.0f - (m_rheight / 2.0f); pvertex-z = 0.0f; pvertex-nx = 0.0f; pvertex-ny = -1.0f; pvertex-nz = 0.0f; pvertex-tu = 0.5f; pvertex-tv = 0.5f; pvertex+; /create the bottom triangle fan: edge vertices

18、 for(ncurrentsegment = m_nsegments; ncurrentsegment = 0; ncurrentsegment-) float x0 = m_rradius * sinf(ncurrentsegment * rdeltasegangle); float z0 = m_rradius * cosf(ncurrentsegment * rdeltasegangle); pvertex-x = x0; pvertex-y = 0.0f - (m_rheight / 2.0f); pvertex-z = z0; pvertex-nx = 0.0f; pvertex-n

19、y = -1.0f; pvertex-nz = 0.0f; float tu0 = (0.5f * sinf(ncurrentsegment * rdeltasegangle) + 0.5f; float tv0 = (0.5f * cosf(ncurrentsegment * rdeltasegangle) + 0.5f; pvertex-tu = tu0; pvertex-tv = tv0; pvertex+; if(failed(m_pvertexbuffer-unlock() logerror(ccone: unable to unlock vertex buffer.); retur

20、n false; if(failed(m_pindexbuffer-unlock() logerror(ccone: unable to unlock index buffer.); return false; return true; 生成圆锥体的方法与生成圆柱体的方法是相似的,具体的细节你可以直接去读源代码,这里就不再罗嗦了。how to make a sphere (怎样生成球体)我们的球体是由一个三角列构成的。我们需要指定它的环数和段数,当然,环数与段数越多,它看起来就越光滑。我们将会使用索引缓冲和顶点缓冲。下图(9.3)演示了它的构成方法。fig 9.3要创建球体我们可以使用下面的代

21、码片断,它出自gamed的dx论坛,是 “laurent” 贴的一个例子的改编。 在此我要感谢他,允许我在本directx 教程中使用他的这段代码。如果你想看那个帖子的全部内容,请到/community/forums/topic.asp?topic_id=85779。bool csphere:updatevertices() /code adapted from a sample by laurent posted on the gamed directx forum //communi

22、ty/forums/topic.asp?topic_id=85779 word* pindices; sphere_customvertex* pvertex; word wvertexindex = 0;. int ncurrentring; int ncurrentsegment; d3dxvector3 vnormal; /lock the vertex buffer if(failed(m_pvertexbuffer-lock(0, 0, (byte*)&pvertex, 0) logerror(csphere: unable to lock vertex buffer.); retu

23、rn false; /lock the index buffer if(failed(m_pindexbuffer-lock(0, m_dwnumofindices, (byte*)&pindices, 0) logerror(csphere: unable to lock index buffer.); return false; /establish constants used in sphere generation float rdeltaringangle = (d3dx_pi / m_nrings); float rdeltasegangle = (2.0f * d3dx_pi

24、/ m_nsegments); /generate the group of rings for the sphere for(ncurrentring = 0; ncurrentring m_nrings + 1; ncurrentring+) float r0 = sinf(ncurrentring * rdeltaringangle); float y0 = cosf(ncurrentring * rdeltaringangle); /generate the group of segments for the current ring for(ncurrentsegment = 0;

25、ncurrentsegment x = x0; pvertex-y = y0; pvertex-z = z0; pvertex-nx = vnormal.x; pvertex-ny = vnormal.y; pvertex-nz = vnormal.z; pvertex-tu = 1.0f - (float)ncurrentsegment / (float)m_nsegments); pvertex-tv = (float)ncurrentring / (float)m_nrings; pvertex+; /add two indices except for the last ring if(ncurrentring != m_nrings) *pindices = wvertexindex; pindices+; *pindices = wvertexindex + (word)(m_nsegments + 1); pindices+; wvertexindex+; if(failed(m_pindexbuffer-unlock() logerror(csphere: unable to unlock index buff

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论