




已阅读5页,还剩36页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
6. 绘制 3D基本形状现在您已学到了如何以Microsoft Direct3D立即模式来建立3D环境,整个迷宫只剩下最后一个关键片段:建立一个3D对象并绘制出来。在第五章中,您看到了Direct3D中的所有可用顶点。您也看到了如何自行为顶点配置内存或自行使用顶点缓冲区去管理内存。在本章中,您可以用这些顶点来建立3D基本形状(3D primitive)。所谓3D基本形状是指由一群顶点组成的对象。您所能建立的最基本形状是一个点串行(point list),它只是一些单一像素点的集合。您也可以建立并绘制一个线串行(line list),这是一个单像素宽线条的集合。然而您所建立的通常是三角形。Direct3D使用三角形(而非其它种多边形)来描述3D对象的各个面,因为三角形是共平面且是凸面形状(意谓他们比较容易快速绘制)。Direct3D让您可以结合三角形来建立更复杂的多边形和网格。如果运用大量的三角形时,您还可以达到逼近弧面(如球体)的效果。BeginScene和EndScene方法在进入绘制基本形状的细节之前,您应该要了解BeginScene和EndScene。在Direct3D中,您可以用IDirect3DDevice7:BeginScene方法来表示要开始绘制某个场景。这个方法会告诉DirectX检查绘制数据和确定成像绘图页已经设定好了。一旦使用该方法后,您可以开始用Direct3D方法来绘制场景中的对象所需的基本形状。如果您在呼叫BeginScene前呼叫这些方法,Direct3D会传回D3DERR_SCENE_NOT_IN_SCENE。一旦您的绘制工作告一段落。您必须去呼叫IDirect3DDevice7:EndScene来清除内部旗标(表示场景绘制进行中),更新快取数据,确定成像绘图页已完成。您必须以BeginScene/EndScene组合把所有的对绘制方法的呼叫包起来。如果BeginScene失败了,场景就不会开始,而且呼叫Endscene也会失败(因为一开始就没有启动场景)。如果在呼叫BeginScene前某个绘图页没有回复,则它会传回DDERR_SURFACELOST。如果绘图页在绘制过程中不见了, EndScene也会传回此错误值,而在呼叫绘制方法时也回传回错误。注意一旦BeginScene成功之后,如果在场景绘制过程中传回了错误,您必须去呼叫EndScene来完成您的绘制过程。记住一件重要的事,您必须先结束一个场景的绘制作业,才能再开始另外一个。如果您试着要使用巢状BeginScene/EndScene组合,就会传回D3DERR_SCENE_IN_SCENE错误。如果您呼叫了EndScene但没有呼叫BeginScene,也会有这种错误。索引和非索引的基本形状立即模式提供了二种将基本形状顶点分类的方式:使用非索引基本形状和使用索引基本形状。要建立一个非索引基本形状,您可以用有顺序的顶点序列填入数组中。这里的顺序是指由数组中顶点顺序指示如何产生三角形。第一个三角形是由数组中的前三个顶点所组成,第二个三角形是由接下来三个点所组成,依此类推。这意谓着多个三角形不能共享顶点。如果您有二个相连的三角形,您必须要定义同一个顶点很多次。要建立一个索引基本形状,你可以用没有顺序的顶点序列填入数组中。并且建立第二个数组,并且用一个有顺序的索引序列指向这个无顺序的数组中。对索引基本形状而言,数组中的顶点顺序并不重要。而是由索引数组中的索引顺序指示如何造出三角形。第一个三角形是由索引数组中的前三个索引所参照的顶点所组成,第二个三角形是由接下来三个索引所参照的顶点所组成,依此类推。这意谓着多个三角形可以共享顶点,只要让索引数组中的多个项目参照到同一个顶点即可。本章稍后会谈到的三角条(strip)和扇,也是可以共享顶点,所以您应该依据3D对象的结构来选择使用索引或非索引基本形状。大部分的3D模型分享多个顶点。因此,您可以让多个三角形间(或线条)分享这些顶点来节省内存、频宽以及CPU时间。当3D模型分享顶点时,索引顶点是很有用的。然而要小心某些看起来可以共享,事实却不然的顶点。立方体就是个典型的例子。让构成立方体的12个三角形只须共享8个顶点,看起来很诱人。但是如果您这样做,就会在这些点的法向量出问题。每个三角形的面都有一个向量,称为表面法向量(face normal),和平面垂直。这个表面法向量指向远离三角形面的前方边缘,在Direct3D中这是唯一可见边。因为法向量是依顶点而非面来定义,二个不同法向量的三角形就不能共享顶点。即使他们可以,但是被共享的顶点只能有一个法向量,所以就无法产生您想得到的打光效果。在立方体的情况中,事实上使用24个顶点会比较好,甚至比12个三角形所必须的36个顶点(不用索引时)还要好。图6-1说明了这些法向量的组成。图6-1一个立方体表面的顶点法向量DrawPrimitive方法您可能开始觉得在绘制基本形状时有许多不同的情况要考虑。您已经学到顶点有三种储存方式:使用者数组、间插顶点和顶点缓冲区。而且您已学到Direct3D可以绘制三种基本形状:点、线和三角形。线可以分成二种:线串行(line list)和线条块。三角形可以区分成三种:串行、条块和扇。最后,基本形状可以是索引或非索引的。如此一来,又增加了绘制基本形状时的许多不同方式!IDirect3DDevice7接口的6种DrawPrimitive方法可以处理所有的情况。表6-1说明了针对各种顶点型态和索引型态组合所适用的不同方法。表6-1绘制基本形状的方法基本形状的型态 一般的使用者顶点 间插的使用者顶点 顶点缓冲区非索引DrawPrimitiveDrawPrimitiveStridedDrawPrimitiveVB索引DrawIndexedPrimitiveDrawIndexedPrimitiveStridedDrawIndexedPrimitiveVB让我们再详细看看这些方法DrawPrimitiveIDirect3DDevice7:DrawPrimitive方法会依您所提供作为任意几何基本形状类型的顶点数组来绘制。以下是本方法的函式宣告:HRESULT IDirect3DDevice7:DrawPrimitive(D3DPRIMITIVETYPE dptPrimitiveType,DWORD dwVertexTypeDesc,LPVOID lpvVertices,DWORD dwVertexCount,DWORD dwFlags);参数 说明dptPrimitiveType这个指令所要绘制的基本形状型态。这个基本形状型态必须是 D3DPRIMITIVE列举型态的成员之一。dwVertexTypeDesc储存弹性顶点格式旗标的组合,用来定义这些基本形状集合会用到的顶点格式。lpvVertices指到在基本形状序列中用到的顶点数组的指针。dwVertexCount储存了数组中画出的顶点数目。您可以指定的最大值是 D3DMAXNUMVERTICES(65,535)。dwFlags将本参数设为0可在绘制基本形状时不用等待,如果设为 D3DDP_WAIT,则使得方法会在回传前保持等待,直到多边形 完成绘制。预设情形下,这个方法会在将多边形传送到视讯卡后立刻回传。 可利用D3DDP_WAIT旗标值来除错。程序不应在绘制前使用 D3DDP_WAIT旗标来等待场景更新。DrawPrimitiveStridedIDirect3DDevice7:DrawPrimitiveStrided方法是用间插顶点数组绘出多个几何形状。您必须检查想绘制的顶点是否使用了所指定的格式。因为Direct3D不会检查顶点大小和间插是否符合已设定的弹性顶点格式,您必须自行确认,否则就可能发生内存错误。这里是方法的函式宣告:HRESULT DrawPrimitiveStrided(D3DPRIMITIVETYPE dptPrimitiveType,DWORD dwVertexTypeDesc,LPD3DDRAWPRIMITIVESTRIDEDDATA lpVertexArray,DWORD dwVertexCount,DWORD dwFlags);参数 说明dptPrimitiveType这个指令要绘制的基本形状型态。这个参数必须是 D3DPRIMITIVETYPE列举型态成员之一。dwVertexTypeDesc描述顶点格式的弹性顶点格式旗标的组合。lpVertexArrayD3DDRAWPRIMITIVESTRIDEDDATA结构的地址,这个结构中 包含了基本形状的顶点组件指针和内存间插值,这个参数的格 式是由dwVertexTypeDesc中的旗标所设定。dwVertexCountlpVertexArray数组中的顶点数目。可容许的最大顶点数是D3DMAXNUMVERTICES(0xFFFF)。dwFlags设为0可在绘制基本形状时不用等待,如果使用D3DDP_WAIT旗标,则使得方法会在回传前保持等待,直到多边形完成绘制, 而不会在多边形传送到视讯卡后立刻回传。(对场景撷取卡而言,当卡响应时方法会立刻回传。) 本旗标值通常是来除错。程序不应用D3DDP_WAIT旗标来等待 场景更新后再继续。DrawPrimitiveVBIDirect3DDevice7:DrawPrimitiveVB方法是用顶点缓冲区的顶点数组绘出多个几何基本形状。这里是方法的函式宣告:HRESULT DrawPrimitiveVB(D3DPRIMITIVETYPE d3dptPrimitiveType ,LPDIRECT3DVERTEXBUFFER7 lpd3dVertexBuffer,DWORD dwStartVertex ,DWORD dwNumVertices ,DWORD dwFlags);参数 说明pptPrimitiveType这个指令要绘制的基本形状型态。这个参数必须是 D3DPRIMITIVETYPE列举型态成员之一。lpd3dVertexBuffer包含了顶点数组的顶点缓冲区的IDirect3DVertexBuffer7接口地址。顶点可以是已转换或未转换,最佳化或未最佳化。dwStartVertex在基本形状中的第一个顶点的索引值。最大可能启始索引是D3DMAXNUMVERTICES(0xFFFF)。在除错过程中,如果指定 一个超过此极值的启始索引值时,会造成方法失败且传回 DDERR_INVALIDPARAMS。dwNumVertices绘制的顶点数。可容许的最大顶点数是D3DMAXNUMVERTICES (0xFFFF)。dwFlags设为0可在绘制基本形状时不用等待,如果使用D3DDP_WAIT 旗标,则使得方法会在回传前保持等待,直到多边形完成绘制, 而不会在多边形传送到视讯卡后立刻回传。(对场景撷取卡而 言,当卡响应时方法会立刻回传。) 本旗标值通常是来除错。程序不应用D3DDP_WAIT旗标来等待 场景更新后再继续。DrawIndexedPrimitiveIDirect3DDevice7:DrawIndexedPrimitive方法在绘制指定的几何基本形状时,会依据对顶点数组所作的索引而非直接使用某个顶点数组。以下是本方法的函式宣告:HRESULT IDirect3DDevice7:DrawIndexedPrimitive(D3DPRIMITIVETYPE d3dptPrimitiveType ,DWORD dwVertexTypeDesc,LPVOID lpvVertices,DWORD dwVertexCount,LPWORD lpwIndices,DWORD dwIndexCount,DWORD dwFlags);参数 说明d3dptPrimitiveType这个指令要绘制的基本形状型态。这个参数必须是 D3DPRIMITIVETYPE列举型态成员之一。D3DPRIMITIVETYPE 的D3DPT_POINTLIST成员则没有索引。dwVertexTypeDesc储存了弹性顶点格式旗标的组合,用来定义这些基本形状集合会 用到的顶点格式。lpvVertices指到您在基本形状序列中要用到的顶点数组。dwVertexCount储存了lpvVertices参数指到数组中的顶点总数。lpwIndices指到某个WORD串行,在创造要绘制的几何形状时,这个串行可用作对顶点串行作索引。dwIndexCount定义用来创造几何形状的索引数目。可容许的最大索引数是D3DMAXNUMVERTICES(0xFFFF)。dwFlags将本参数设为0可在绘制基本形状时不用等待,如果设为 D3DDP_WAIT,则使得方法会在回传前保持等待,直到多边形 完成绘制。预设情形下,这个方法会在将多边形传送到视讯卡后 立刻回传。 可利用D3DDP_WAIT旗标值来除错。程序不应在绘制前使用 D3DDP_WAIT旗标来等待场景更新。DrawIndexedPrimitiveStridedIDirect3DDevice7:DrawIndexedPrimitiveStrided方法允许您依据对间插顶点数组所作的索引来绘制一个几何基本形状。以下是本方法的函式宣告:HRESULT DrawIndexedPrimitiveStrided(D3DPRIMITIVETYPE d3dptPrimitiveType,DWORD dwVertexTypeDesc,LPD3DDRAWPRIMITIVESTRIDEDDATA lpVertexArray,DWORD dwVertexCount,LPWORD lpwIndices,DWORD dwIndexCount,DWORD dwFlags);参数 说明d3dptPrimitiveType这个指令要绘制的基本形状型态。这个参数必须是 D3DPRIMITIVETYPE列举型态成员之一。D3DPRIMITIVETYPE 的D3DPT_POINTLIST成员则没有索引。dwVertexTypeDesc描述基本形状的顶点格式的弹性顶点格式旗标组合。lpVertexArrayD3DDRAWPRIMITIVESTRIDEDDATA结构的地址,这个结构中 包含了基本形状的顶点组件的指针和内存间插,这个参数的格 式是由dwVertexTypeDesc中的旗标所设定。dwVertexCount定义串行中的顶点数目。这个参数的用法和Idirect3DDevice7: DrawPrimitive方法中的dwVertexCount参数不同。在那个方 法中,dwVertexCount参数是指要画的顶点数,但这里则是代 表了lpVertexArray参数指到的数组中的顶点总数。当您呼叫 IDirect-3DDevice7:DrawIndexedPrimitiveStrided时,您会在 dwIndexCount参数中指定要画的顶点数目。lpwIndices指到某个WORD串行,在创造要绘制的几何形状时,这个串行可用作对指定的顶点串行作索引。dwIndexCount定义用来创造几何形状的索引数目。可容许的最大索引数是D3DMAXNUMVERTICES(0xFFFF)。dwFlags设为0可在绘制基本形状时不用等待,如果使用D3DDP_WAIT 旗标,则使得方法会在回传前保持等待,直到多边形完成绘制, 而不会在多边形传送到视讯卡后立刻回传。(对场景撷取卡而 言,当卡响应时方法会立刻回传。) 本旗标值通常是来除错。程序不应用D3DDP_WAIT旗标来等待 场景更新后再继续。DrawIndexedPrimitiveVBIDirect3DDevice7:DrawIndexedPrimitiveVB方法是依据对顶点缓冲区中顶点数组的索引来绘制一个几何基本形状。以下是本方法的函式宣告:HRESULT DrawIndexedPrimitiveVB(D3DPRIMITIVETYPE d3dptPrimitiveType,LPDIRECT3DVERTEXBUFFER7 lpd3dVertexBuffer,DWORD dwStartVertex,DWORD dwNumVertices,LPWORD lpwIndices,DWORD dwIndexCount,DWORD dwFlags);参数 说明d3dptPrimitiveType这个指令要绘制的基本形状型态。这个参数必须是D3DPRIMITIVETYPE列举型态成员之一。D3DPRIMITIVETYPE 的D3DPT_POINTLIST成员则没有索引。lpd3dVertexBuffer包含顶点数组的顶点缓冲区的IDirect3DVertexBuffer7接口的地址。dwStartVertex顶点缓冲区中第一个要绘制的顶点索引。dwNumVertices顶点缓冲区中要绘制的顶点总数。lpwIndices某个WORD数组的地址。这个数组是用来对顶点缓冲区中的顶 点作索引。数组中的值必须让顶点的索引结果落在范围 dwNumVertices0, -1中。dwIndexCount数组lpwIndices中的索引数目。可容许的最大索引数目是 D3DMAXNUMVERTICES(0xFFFF)。dwFlags设为0可在绘制基本形状时不用等待,如果使用D3DDP_WAIT 旗标,则使得方法会在回传前保持等待,直到多边形完成绘制,而不会在多边形传送到视讯卡后立刻回传。(对场景撷取卡而 言,当卡响应时方法会立刻回传。) 本旗标值通常是来除错。程序不应用D3DDP_WAIT旗标来等待 场景更新后再继续。基本形状的型态DrawPrimitive方法使用了D3DPRIMITIVETYPE列举型态来列出这个方法支持的所有基本形状。以下是型态的定义:typedef enum _D3DPRIMITIVETYPE D3DPT_POINTLIST =1,D3DPT_LINELIST =2,D3DPT_LINESTRIP =3,D3DPT_TRIANGLELIST =4,D3DPT_TRIANGLESTRIP =5,D3DPT_TRIANGLEFAN =6D3DPT_FORCE_DWORD =0x7fffffff,D3DPRIMITIVETYPE;这里是D3DPRIMITIVETYPE列举型态的成员: D3DPT_POINTLIST让DrawPrimitive方法绘制顶点成为一些独立点的集合。 D3DPT_LINELIST让DrawPrimitive方法绘制顶点成为独立直线段(isolated straight-line segment)的串行。您必须设定大于或等于2的偶数个顶点。 D3DPT_LINESTRIP让DrawPrimitive方法绘制顶点成为单一的polyline。您必须设定至少二个顶点。 D3DPT_TRIANGLELIST让DrawPrimitive方法绘制顶点成为连续的独立三角形。每三个顶点定义一个单一的三角形。您必须设定至少三个顶点并确定顶点数目是3的倍数。winding-order绘制状态定义了背面排除(backface culling,或称backface removal)的运作方式。(我们会在本章后面讨论背面排除和winding-order绘制状态) D3DPT_TRIANGLESTRIP让DrawPrimitive方法绘制顶点成为一个三角形的条。您必须提供至少三个顶点。DrawPrimitive方法会不依照顺序拿出偶数个三角形的顶点,以确保画三角形是依照顺时针方向开始。(要知道更多信息,请看本章后面的排除状态) D3DPT_TRIANGLEFAN让DrawPrimitive方法绘制顶点成为一个三角形扇。您必须定义至少三个顶点。 D3DPT_FORCE_DWORD强制列举型态为32位型态。下一段谈到了这些基本形状的型态,您可以用来建立您的程序中的3D内容。点串行您可以用第一个基本形状型态点串行(point list),来定义一群绘成独立点的顶点。您可以在3D场景中用点串行来表示如虚线的对象。要建立一个点串行,您需要填入一个顶点数组。以下的程序范例说明了如何去执行这个作业。虽然我是用一个简单的6元素串行,如果您想的话,您也可以用点串行来建立一个星场;当然串行中要有很多很多的点。我比较习惯用环绕着3D世界贴图方式的球体来创造星场,因为这样可以用贴图动画来创造出多种效果。const DWORD TOTAL_VERTICES =6;D3DVERTEX lpVertices TOTAL_VERTICES;.D3DVECTOR v1(-1,4,0);D3DVECTOR v2(2,-1,0);D3DVECTOR v3(1,3,0);D3DVECTOR v4(-3,-2,0);D3DVECTOR v5(3,2,0);D3DVECTOR v6(2,1,0);D3DVECTOR vNormal(0,0,-1);lpVertices 0 =D3DVERTEX(v1,vNormal,0,0);lpVertices 1 =D3DVERTEX(v2,vNormal,0,0);lpVertices 2 =D3DVERTEX(v3,vNormal,0,0);lpVertices 3 =D3DVERTEX(v4,vNormal,0,0);lpVertices 4 =D3DVERTEX(v5,vNormal,0,0);lpVertices 5 =D3DVERTEX(v6,vNormal,0,0);一旦您定义了点串行,您可以用之前说过的IDirect3DDevice7:DrawPrimitive方法来绘制出。以下是绘制点串行的程序代码。本章前面学过,任何对IDirect3DDevice7:DrawPrimitive的呼叫都必须落在呼叫IDirect3DDevice7:BeginScene和IDirect3DDevice7:EndScene中间。if (FAILED(lpDirect3DDevice7-BeginScene()/如果有错误时,在此处理。.if (FAILED(lpDirect3DDevice7-DrawPrimitive(D3DPT_POINTLIST,D3DFVF_VERTEX,lpVertices,TOTAL_VERTICES,0)/如果有错误时,在此处理。.if (FAILED(lpDirect3DDevice7-EndScene()/如果有错误时,在此处理。您可以将材质和贴图应用在点串行上,但是屏幕上的一个小像素无法适当的表示出贴图或材质。同时请记住,不论这些点距离摄影机有多远,他们的直径都是1个像素。如果想要有更大的点,您需要用小的三角形来表示。当绘制完成后,您可以看到一个像图6-2的场景。图6-2绘出的点串行线串行您可以用第二种基本形状型态线串行(line list),来定义一群直线段。您可以用这种型态来定义各种简单的单一线条对象。要建立一个线串行,只要仿照以下程序片段填入一个顶点数组即可。别忘了线串行中定义的顶点数量必须是大于或等于2的偶数。这个范例就是定义这三种线条的程序:const DWORD TOTAL_VERTICES =6;D3DVERTEX lpVertices TOTAL_VERTICES;. . .D3DVECTOR v1(-10,10,0);D3DVECTOR v2(-8,-5,0);D3DVECTOR v3(-4,3,0);D3DVECTOR v4(1,-6,0);D3DVECTOR v5(2,-1,0);D3DVECTOR v6(12,9,0);D3DVECTOR vNormal(0,0,-1);lpVertices 0 =D3DVERTEX(v1,vNormal,0,0);lpVertices 1 =D3DVERTEX(v2,vNormal,0,0);lpVertices 2 =D3DVERTEX(v3,vNormal,0,0);lpVertices 3 =D3DVERTEX(v4,vNormal,0,0);lpVertices 4 =D3DVERTEX(v5,vNormal,0,0);lpVertices 5 =D3DVERTEX(v6,vNormal,0,0);一旦您定义了线串行,您可以用IDirect3DDevice7:DrawPrimitive方法来绘制它,就好像绘制点串行时一样。绘制线串行的程序如下。当绘图作业完成后,您可以看到一个像图6-3的场景。if (FAILED(lpDirect3DDevice7-BeginScene()/如果有错误时,在此处理。.if (FAILED(lpDirect3DDevice7-DrawPrimitive(D3DPT_LINELIST,D3DFVF_VERTEX,lpVertices,TOTAL_VERTICES,0)/如果有错误时,在此处理。.if (FAILED(lpDirect3DDevice7-EndScene()/如果有错误时,在此处理。图6-3绘出的线串行如同点串行一样,您可以将材质和贴图应用在线串行上。就好像点的大小只有一个像素一样,线条也是只有一个像素宽。如果您需要绘制较宽的线,或是您希望宽度随线条离摄影机的距离而改变时,您应该改用窄三角形的组合来表示线条。线条块您可以用第三种基本形状型态线条块(line strip)来描述一连串相连的线段。您可以用线条块来建立开放的多边形换句话说,也就是最后的顶点和第一个顶点间没有用线段来连接的多边形。您可以像在点和线串行一样地填入某个顶点数组,以建立线条块。以下的程序范例说明了如何填入这个串行:const DWORD TOTAL_VERTICES =5;D3DVERTEX lpVertices TOTAL_VERTICES;.D3DVECTOR v1(-8,-8,0);D3DVECTOR v2(-3,-9,0);D3DVECTOR v3(-1,0,0);D3DVECTOR v4(9,-2,0);D3DVECTOR v5(7,-6,0);D3DVECTOR vNormal(0,0,-1);lpVertices 0 =D3DVERTEX(v1,vNormal,0,0);lpVertices 1 =D3DVERTEX(v2,vNormal,0,0);lpVertices 2 =D3DVERTEX(v3,vNormal,0,0);lpVertices 3 =D3DVERTEX(v4,vNormal,0,0);lpVertices 4 =D3DVERTEX(v5,vNormal,0,0);一旦您定义了线条块,您可以用IDirect3DDevice7:DrawPrimitive方法来绘制它,就好像绘制点和线串行时一样。以下这些程序是要绘制线条块,图6-4则是程序产生的线条块结果。if (FAILED(lpDirect3DDevice7-BeginScene()/如果有错误时,在此处理。.if (FAILED(lpDirect3DDevice7-DrawPrimitive(D3DPT_LINESTRIP,D3DFVF_VERTEX,lpVertices,TOTAL_VERTICES,0)/如果有错误时,在此处理。.if (FAILED(lpDirect3DDevice7-EndScene()/如果有错误时,在此处理。图6-4绘出的线条块三角形串行您可以用第四种基本形状型态三角形串行(triangle list),来创造独立三角形的串行。别忘了三角形串行所定义的顶点数量必须是3的倍数。您可以利用这种串行来建立由不连接的小块构成的对象。以下是定义了二个三角形的串行的程序:const DWORD TOTAL_VERTICES =6;D3DVERTEX lpVertices TOTAL_VERTICES;.D3DVECTOR v1(-10,-5,0);D3DVECTOR v2(-5,5,0);D3DVECTOR v3(0,-5,0);D3DVECTOR v4(1,-5,0);D3DVECTOR v5(6,5,0);D3DVECTOR v6(11,-5,0);D3DVECTOR vNormal(0,0,-1);lpVertices 0 =D3DVERTEX(v1,vNormal,0,0);lpVertices 1 =D3DVERTEX(v2,vNormal,0,0);lpVertices 2 =D3DVERTEX(v3,vNormal,0,0);lpVertices 3 =D3DVERTEX(v4,vNormal,0,0);lpVertices 4 =D3DVERTEX(v5,vNormal,0,0);lpVertices 5 =D3DVERTEX(v6,vNormal,0,0);像其它的基本形状一样,您可以用IDirect3DDevice7:DrawPrimitive方法来绘制三角形串行。以下的程序范例说明了如何绘制一个三角形串行。图6-5则是其结果。if (FAILED(lpDirect3DDevice7-BeginScene()/如果有错误时,在此处理。.if (FAILED(lpDirect3DDevice7-DrawPrimitive(D3DPT_TRIANGLELIST,D3DFVF_VERTEX,lpVertices,TOTAL_VERTICES,0)/如果有错误时,在此处理。.if (FAILED(lpDirect3DDevice7-EndScene()/如果有错误时,在此处理。图6-5绘出的三角形串行三角形条您可以用第五种基本形状型态三角形条(triangle strip),来创造一连串的相连的三角形。当你使用相连接的三角形时,程序必须一次指定共享的顶点。举例来说,图6-6中的三角形条只需要定义6个顶点即可,但它是由四个三角形所组成的。图6-6三角形条如图6-6所示,前三个三角形共享了v3,有二个三角形共享v4,依此类推等等。Direct3D的默认值会排除依逆时针顺序定义的三角形。因此Direct3D在绘制三角形条会不依顺序读入条块中偶数三角形的顶点。如果要绘制如图6-6的三角形条,Direct3D要依以下方式来读入顶点串行中的顶点:先是第一个三角形的v1、v2、v3;第二个三角形是v2、v4、v3;第三个三角形是v3、v4、v5;第四个三角形是v4、v6、v5,依此类推。这样做会使条块中面对摄影机的面会被看到,而背面则被排除。三角形条块可以有效利用内存和处理时间,所以尽可能地多加以运用。以下的程序段会填入一个顶点数组,以产生如图6-6的三角形条,就像针对其它基本形状的作法一样:const DWORD TOTAL_VERTICES=6;D3DVERTEX lpVertices TOTAL_VERTICES;.D3DVECTOR v1(-10,-5,0);D3DVECTOR v2(-5,7,0);D3DVECTOR v3(0,-1,0);D3DVECTOR v4(6,4,0);D3DVECTOR v5(11,-7,0);D3DVECTOR v6(9,9,0);D3DVECTOR vNormal(0,0,-1);lpVertices 0 =D3DVERTEX(v1,vNormal,0,0);lpVertices 1 =D3DVERTEX(v2,vNormal,0,0);lpVertices 2 =D3DVERTEX(v3,vNormal,0,0);lpVertices 3 =D3DVERTEX(v4,vNormal,0,0);lpVertices 4 =D3DVERTEX(v5,vNormal,0,0);lpVertices 5 =D3DVERTEX(v6,vNormal,0,0);下一个程序片段说明了如何用IDirect3DDevice7:DrawPrimitive方法来绘制一个三角形条,就像对其他的基本形状一样。图6-7呈现了绘制出的条。if (FAILED(lpDirect3DDevice7-BeginScene()/如果有错误时,在此处理。. . . if (FAILED(lpDirect3DDevice7-DrawPrimitive(D3DPT_TRIANGLESTRIP,D3DFVF_VERTEX,lpVertices,TOTAL_VERTICES,0)/如果有错误时,在此处理。.if (FAILED(lpDirect3DDevice7-EndScene()/如果有错误时,在此处理。图6-7绘出的三角形条三角形扇第六种基本形状型态三角形扇(triangle fan),有点像三角形条。差别在于这里的所有三角形会共享同一个顶点,如图6-8所示:图6-8三角形扇以下是填入一个定义三角形扇的数组的程序范例:const DWORD TOTAL_VERTICES =6;D3DVERTEX lpVertices TOTAL_VERTICES;.D3DVECTOR v1(-3,0,0);D3DVECTOR v2(1,4,0);D3DVECTOR v3(1.5,3,0);D3DVECTOR v4(2,1,0);D3DVECTOR v5(2,-1,0);D3DVECTOR v6(1.5,-3,0);D3DVECTOR v7(1,-4,0);D3DVECTOR vNormal(0,0,-1);lpVertices 0 =D3DVERTEX(v1,vNormal,0,0);lpVertices 1 =D3DVERTEX(v2,vNormal,0,0);lpVertices 2 =D3DVERTEX(v3,vNormal,0,0);lpVertices 3 =D3DVERTEX(v4,vNormal,0,0);lpVertices 4 =D3DVERTEX(v5,vNormal,0,0);lpVertices 5 =D3DVERTEX(v6,vNormal,0,0);lpVertices 6 =D3DVERTEX(v7,vNormal,0,0);以下的程序会用您曾经用过的IDirect3DDevice3:DrawPrimitive方法来绘制三角形扇,并指定D3DPT_TRIANGLEFAN作为第一个参数。图6-9显示了绘出的三角形扇。if (FAILED(lpDirect3DDevice7-BeginScene()/如果有错误时,在此处理。.if (FAILED(lpDirect3DDevice3-DrawPrimitive(D3DPT_TRIANGLEFAN,D3DFVF_VERTEX,lpVertices,TOTAL_VERTICES,0)/如果有错误时,在此处理。.if (FAILED(lpDirect3DDevice7-EndScene()/如果有错误时,在此处理。图6-9绘出的三角形扇设定绘制状态Direct3D装置拥有数十种可以改变的设定项,以决定基本形状的绘制方式。这些设定称为绘制状态(render state)。您可以用IDirect3D-Device7:SetRenderState来改变一个绘制状态。这个方法用D3DRENDERSTATETYPE列举型态的一个成员作为参数,并给指定绘制状态一个新值。第二个参数的意义则是依据dwRenderStateType设定的值而定。以下是本方法的函式宣告:HRESULT IDirect3DDevice7:SetRenderState(D3DRENDERSTATETYPE dwRenderStateType ,DWORD dwRenderState);参数 说明dwRenderStateType本函式所改变的装置状态变量。这个参数可以是 D3DRENDER-STATETYPE列举型态的任何成员。dwRenderStateDirect3Ddevice绘制状态的新值。这个值会依 dwRenderStateType 参数而定。所有的Direct3D绘制状态都有默认值,所以您不需要在开始绘制基本形状前先设定每个个别的绘制状态。您打算改变绘制状态时,必须考虑到您的程序需求。在某些情况下,您会在刚建立Direct3D装置时设定某个绘制状态。在其它状况下会在使用者改变程序的某个设定值或是绘制某个特别对象时去改变绘制状态。举例来说,以下的程序段会利用SetRenderState来设定排除、上色、和填充模式下的绘制状态,以及一个单纯场景的环境光强度。HRESULT CMyD3DApplication:Render()/清除检视埠。lpDev7-Clear(0,NULL,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 0x000000ff,1.0f,0L);DWORD dwCullMode =m_bCull ?D3DCULL_CCW :D3DCULL_NONE;DWORD dwShadeMode =m_bFlat ?D3DSHADE_FLAT :D3DSHADE_GOURAUD;DWORD dwFillMode =m_bWire ?D3DFILL_WIREFRAME :D3DFILL_SOLID;lpDev7-SetRenderState(D3DRENDERSTATE_CULLMODE,dwCullMode);lpDev7-SetRenderState(D3DRENDERSTATE_SHADEMODE,dwShadeMode);lpDev7-SetRenderState(D3DRENDERSTATE_FILLMODE,dwFillMode);lpDev7-SetRenderState(D3DRENDERSTATE_AMBIENT, RGBA_MAKE(128,128,128,128);/场景开始。if(SUCCEEDED(m_pd3dDevice-BeginScene()if(m_pFileObject) m_pFileObject-Render(m_pd3dDevice);/场景结束。m_pd3dDevice-EndScene();return S_OK;在绘制基本形状时,请牢记住3D加速硬件可以快速的处理一连串同样型态的基本形状,但是若改变必要的绘图型态时即会减慢下来。切换到不同的贴图对映会减慢绘制动作,改变绘制状态时也是。为了达到最佳的效能,试着一次绘制出所有共享同一贴图(最好是同样的绘制状态)的基本形状,再改变贴图(必要时包括绘制状态),再绘制更多基本形状,依此类推。以下的段落说明了您最可能采用的各种绘制状态。在后续的章节中,我们会涵盖这些状态的细节。但是目前我只会先快速简介这些可用的状态,让您可以开始了解这些命令如何搭配作用。Alpha混色状态藉由设定某些绘制状态,Alpha混色(也就是半透明对象的绘制)即可以发生作用。您可以
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024年注册土木工程师膨胀岩边坡支护锚索拉力计算练习
- 企业税务管理办法宣贯
- 青少年暑期心理健康教育指南
- 内科中毒总论
- 恢复健康能量语言课件
- 二金属有机化合物的结构与构型讲课文档
- ICU镇痛镇静讲课文档
- 幼儿园教师校车安全培训
- 心理健康复课课件
- 汽车维护与保养 课件 3.3《蓄电池的作用、类型及其型号》
- 医疗废物暂存间(处置室)清洁消毒记录表
- 小升初数学题型总结(8篇)
- JGJ94-2008建筑桩基技术规范
- 空调产品出货检验规范
- 2024贵州磷化(集团)有限责任公司招聘笔试参考题库附带答案详解
- 胎儿宫内治疗:问题与展望
- 新型农贸市场项目可行性研究报告
- 过度换气综合症业务学习课件
- GB/Z 43281-2023即时检验(POCT)设备监督员和操作员指南
- 低合金高强钢的焊接
- 农药经营56学时培训模拟试题
评论
0/150
提交评论