值得注意的函數: 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,暫時寫道這裏

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章