2008-09-18 82 views
4

我想用C#和DirectX繪製多邊形畫凹多邊形是否有一個有效的簡單的方法在Direct3D

我得到的是一個文件指向的有序列表,我需要繪製在3d世界中的平面多邊形。

我可以加載點和繪製使用trianglefan和drawuserprimitives凸形狀。

當多邊形非常凹(這可能是)時,這顯然會導致不正確的結果。

我無法想象我這個問題作鬥爭的唯一的人(儘管我是一個GFX /新手的DirectX - 我的背景是在GUI \ Windows應用程序開發)。

任何人都可以指向我一個簡單的資源\教程\算法,可以幫助我嗎?

回答

3

的Direct3D只能畫三角形(當然,它可以畫線和點爲好,但這是除了點)。所以如果你想繪製比三角形更復雜的任何形狀,你必須繪製一組等於該形狀的觸摸三角形。

就你而言,這是一個凹多邊形三角測量問題。給定一堆頂點,你可以保持原樣,你只需要計算「索引緩衝區」(最簡單的情況下,每個三角形有三個索引,表示三角形使用哪個頂點)。然後通過放入頂點/索引緩衝區或使用DrawUserPrimitives進行繪製。

一些算法用於三角測量簡單(凸或凹,但沒有自交差或空穴)多邊形是在VTerrain site

我過去曾使用Ratcliff的代碼;非常簡單,效果很好。 VTerrain有一個死鏈接;代碼可以在here找到。這是C++,但將其移植到C#應該很簡單。

哦,不要使用三角形風扇。它們的使用非常有限,效率低下並即將消失(例如,Direct3D 10不再支持它們)。只需使用三角形列表。

2

三角形是他明顯的答案,但很難寫出一個堅實的三角形。除非你有兩個月的時間浪費,否則不要嘗試。

有幾個代碼可以幫助您:

GPC庫。使用非常簡單,但你可能不喜歡它的許可證:

http://www.cs.man.ac.uk/~toby/alan/software/gpc.html

還有三角:

http://www.cs.cmu.edu/~quake/triangle.html

握拳:

http://www.cosy.sbg.ac.at/~held/projects/triang/triang.html

另一個(和我的首選)將使用GLU tesselator。您可以很好地從DirectX程序加載和使用GLU庫。它不需要OpenGL上下文來使用它,它已經預裝在所有的Windows機器上。如果你想要源代碼,你可以從SGI參考實現中取消三角代碼。我做了一次,花了我幾個小時。

到目前爲止進行三角測量。還有一種不同的方式:你可以使用模板技巧。

一般的算法是這樣的:

  1. 禁用color-和深度寫道。啓用模板寫入並設置您的模板緩衝區,它將反轉當前的模板值。一點模具就足夠了。哦 - 你的模板緩衝區也應該被清除。

  2. 在屏幕上選取一個隨機點。任何會做。將此點稱爲您的錨點。

  3. 對於您的多邊形的每個邊緣,將從構建邊緣和錨點的兩個頂點構建一個三角形。畫出那個三角形。

  4. 一旦您繪製了所有這些三角形,關閉模板寫入,打開模板測試和顏色寫入,並繪製一個全屏四色選擇你的顏色。這將只填充凸多邊形內的像素。

將錨放入多邊形的中間並繪製一個與多邊形的邊界框一樣大的矩形是個好主意。這節省了一點點的填充。

順便說一句 - 模板技術也適用於自相交多邊形。

希望它能幫助, 尼爾斯

2

如果你能夠使用模板緩存,它不應該是很難做到的。這裏有一個通用算法:

Clear the stencil buffer to 1. 
Pick an arbitrary vertex v0, probably somewhere near the polygon to reduce floating-point errors. 
For each vertex v[i] of the polygon in clockwise order: 
    let s be the segment v[i]->v[i+1] (where i+1 will wrap to 0 when the last vertex is reached) 
    if v0 is to the "right" of s: 
     draw a triangle defined by s, v[i], v[i+1] that adds 1 to the stencil buffer 
    else 
     draw a triangle defined by s, v[i], v[i+1] that subtracts 1 from the stencil buffer 
end for 
fill the screen with the desired color/texture, testing for stencil buffer values >= 2. 

通過 「S的吧?」 我從別人開V站在[i]和的V字形[I + 1]的觀點的意思。這可以通過使用叉積進行測試:

交叉(V0 - v [I],V [I + 1] - v [I])> 0

0

我不得不爲一個項目執行此。我發現的最簡單的算法被稱爲「耳廓」。一個偉大的論文就在這裏:TriangulationByEarClipping.pdf

我帶了大約250行C++代碼和4個小時來實現它的蠻力版本。其他算法具有更好的性能,但這很容易實現和理解。

+0

FWIW:https://github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/math/EarClippingTriangulator.java但不處理自相交多邊形或孔。 – NateS 2013-08-27 16:51:04

相關問題