在OpenGL中绘制凹多边形

6
我需要在OpenGL中绘制一个凹多边形。
该多边形由一系列点组成其外环,以及定义其内部环(排除区域)的点列表的列表。

我已经可以处理排除区域,因此也需要绘制没有内部环的多边形的解决方案。

使用Boost.Geometry的解决方案将很好,因为我已经在我的应用程序中大量使用它。

我需要这在iPhone上工作,即OpenGL ES(具有固定管道的旧版本)。

我该如何做到这一点?

4个回答

6

试试OpenGL的细分功能。使用它可以将复杂的多边形转换为一组三角形,然后直接渲染。

编辑(针对评论进行回应):OpenGL ES不支持细分函数。在这种情况下,如果多边形是静态数据,则可以在桌面或笔记本电脑上使用OpenGL离线生成细分。

如果形状是动态的,那么在OpenGL ES中就没有办法了。然而,有许多库(例如CGAL)可以执行相同的功能。


3
不是,那是OpenGL ES,它不提供镶嵌函数。如果你需要在iPhone上实现这个功能,你应该修改问题以明确表达。 - Marcelo Cantos
你知道是否可以使用Boost完成吗?如果不行,我将采用离线计算,因为形状不是动态的。 - Daniel
我对Boost.Geometry一无所知。该项目的当前状态不太乐观,但如果这只是一次性的练习,那么可能并不是什么问题。再考虑一下,也许有工具可以在不编写任何代码的情况下执行镶嵌操作(尽管我不知道有哪些)。 - Marcelo Cantos

2
这是一种有点复杂且资源消耗较高的方法,但是任何凹多边形都可以通过以下步骤绘制(请注意此方法肯定适用于平面多边形,但我也假设您尝试在平面表面或2D直角模式下绘制):
  • 启用模板测试,并使用glStencilFunc(GL_ALWAYS,1,0xFFFF)
  • 禁用颜色掩码以防止不必要的绘制:glColorMask(0,0,0,0)
  • 我认为您的顶点以double数组或其他形式存在(强烈建议使用此方法多次绘制相同的多边形,但glList或glBegin-glEnd也可用)
  • 设置glStencilOp(GL_KEEP,GL_KEEP,GL_INCR)
  • 将多边形绘制为GL_TRIANGLE_FAN

现在,在模板层上,您具有设置位> 0的三角形组成的多边形。诀窍在于,所有有效的多边形区域都填充有mod2 = 1的值,这是因为三角形风扇沿着多边形表面扫描,如果所选的三角形具有多边形外部的区域,它将被绘制两次(一次在当前顺序,然后在下一次绘制时,当绘制有效区域时)。这可能会发生很多次,但是在所有情况下,像素外部的像素都会被画偶数次,像素内部则被画奇数次。 某些异常情况可能会发生,当像素顺序导致外部区域不再重复绘制时。为了过滤这些情况,必须绘制反向顶点数组(在切换顺序时,所有这些情况都可以正常工作): -设置glStencilFunc(GL.GL_EQUAL,1,1)以防止在反向方向上发生这些错误(仅可绘制首次绘制的多边形内部的区域,因此不会出现在另一个方向上发生的错误,从逻辑上讲,这生成了两个半解的交集) -按相反的顺序绘制多边形,保持glStencilFunc以增加扫描像素值 现在,我们有一个正确的模板层,其中pixel_value%2 = 1的像素在像素真正在多边形内部时。最后一步是绘制多边形本身: -设置glColorMask(1,1,1,1)以绘制可见的多边形 -保持glStencilFunc(GL_EQUAL,1,1)以绘制正确的像素 -以相同模式绘制多边形(顶点数组等),或者如果您不使用照明/纹理绘制,则可以绘制单个整个屏幕矩形(比绘制所有顶点更快,并且仅设置有效的多边形像素)

如果一切顺利,多边形将被正确绘制,请确保在此函数之后重置模板使用(模板测试)和/或清除模板缓冲区,如果您还将其用于其他目的。


0

查看 Glues,它具有处理凹多边形的镶嵌函数。


0
我为一个小型图形库编写了一个Java类,它正好可以做到你所需要的,你可以在这里查看它:

https://github.com/DzzD/TiGL/blob/main/android/src/fr/dzzd/tigl/PolygonTriangulate.java

它接收两个浮点数数组(顶点和UV)作为输入,并返回重新排序的相同顶点和UV,以便绘制成三角形列表。

如果您想要排除一个或多个区域,只需通过连接一个顶点将两个多边形(主多边形+孔)连接在一起,您将得到一个可以像任何其他多边形一样进行三角剖分的单个多边形。

就像这样: enter image description here

为了更好地理解,放大后看起来像这样: enter image description here

最后只是一个单独的多边形。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接