天天看点

值得注意的函数: DrawIndexedPrimitive

它的全部申明是: HRESULT DrawIndexedPrimitive (

D3DPRIMITIVETYPE Type,

INT BaseVertexIndex, UINT MinIndex,

UINT NumVertices, UINT StartIndex,

UINT PrimitiveCounts);

查阅DirectX 9的SDK, 关于他的文档为下:

Parameters

Type :[in] Member of the D3DPRIMITIVETYPE enumerated type, describing the type of primitive to render. D3DPT_POINTLIST is not supported with this method. See Remarks.

BaseVertexIndex :[in] Offset from the start of the vertex buffer to the first vertex. See Scenario 4.

MinIndex :[in] Minimum vertex index for vertices used during this call. This is a zero based index relative to BaseVertexIndex.

NumVertices :[in] Number of vertices used during this call. The first vertex is located at index: BaseVertexIndex + MinIndex.

StartIndex :[in] Index of the first index to use when accesssing the vertex buffer. Beginning at StartIndex to index vertices from the vertex buffer.

PrimitiveCount :[in] Number of primitives to render. The number of vertices used is a function of the primitive count and the primitive type. The maximum number of primitives allowed is determined by checking the MaxPrimitiveCount member of the D3DCAPS9 structure.

Return Values :if the method succeeds, the return value is D3D_OK. If the method fails, the return value can be the following: D3DERR_INVALIDCALL.

Type是需要渲染的方式,BaseVertexIndex是开始渲染的Vertex与VertexBuffers起点的距离,MinIndex是在这个基础上从第几个开始渲染. NumVertices是需要渲染的Vertex个数.PrimitiveCount是需要渲染三角形的个数. 如果函数执行成功,返回D3D_OK,如果失败返回D3DERR_INVALIDCALL.

SDK上面大概就是这样讲,我需要渲染一个圆柱体,我的基础想法是:先渲染上面的圆,然后再渲染下面的圆,用的方式都是D3DPT_TRIANGLEFAN,每个圆各自有36个点,加圆心每个圆37个点.于是NumVertices赋为37. 好,运行.恩,不错,没有问题, So far so good.

然后我用D3DPT_TRIANGLESTRIPE方式渲染圆柱体的侧面, 两个圆上的Vertex数目相加,恩是74,Ok, 运行............不对,为什么多了那么多被渲染的三角形? 难道是我Index没有算对? 于是又Debug, 搞了两天, 确信侧面上的Index没有错误,那为什么会多出被渲染的三角形,而且他们的坐标仿佛是随机的, 因为有任务,我最初绕过了这个问题,用DrawPrimitive函数渲染侧面. 后来我给技术主管谈到这个问题,他叫我一定要弄清楚原因, Ok,那继续,为什么,为什么,为什么, 又看技术文档,又到网络上参考相关文档,同时自己也在拿数据试验. 最后偶然发现当NumVertices即使小于36圆柱侧面依然能够被完全渲染,同时多余的三角减少.那我用10呢, 哇!多余三角数减少,如果5呢,更少了,1呢? 多余三角几乎完全消失!圆柱体被完整渲染! 那我用0呢? 侧面消失!

这说明什么?这说明NumVertices实际是指新的需要被渲染Vertex个数,如何理解?简单的说就是没有被存储在显卡RAM内的Vertex个数.

Ok,看来用0不行,只有用1,但还是会出现一个随机三角,怎么办? 那只有人为制造一个没有意义的三角,三个顶点在同样一个位置.最后运行,Ok,Done.

但还是有点不爽,为什么?因为输入了1个无用Vertex,那这样吧,先渲染顶部圆,再渲染侧面,最后输入1个Vertex:底部圆的圆心点,用D3DPT_TRIANGLEFANFAN方式渲染. 啊!没有多余Vertex,渲染正确!

从这个例子看得到什么结论?

NumVertices

[in] Number of vertices used during this call. The first vertex is located at index: BaseVertexIndex + MinIndex.

这句解释里就没有new这个单词! 但我能够怪微软吗? 答案是:不能,只能怪自己!

为什么? DrawIndexedPrimitive和DrawPrimitive有什么区别? 深沉一点讲就是不用从内存传输拥有同样坐标和其他属性的Vertex到你显卡上,那你说NumVertices不应该是新的Vertice个数那因该是什么?如果是全部个数有什么意义?没有意义. 从另外一个方面讲, 你决定了渲染方式与渲染三角的个数,就间接告诉D3Ddevice需要渲染Vertex个数,你再输入个数不就重复了? 去掉具有同样作用的函数参数是程序员的基本要求,难道微软的牛人些还做不到这点.

从这两个方面讲我都应该早点意识到问题的根源,这就又牵掣到方法论了.同时说明微软的文档对阅读的读者有一定要求:你是在只其所以然的基础下查看他的文档而知其然.呵呵,听起来挺矛盾的.

Ok,暂时写道这里

继续阅读