2008-09-18 53 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

相关问题