【问题标题】:How to restore CCW winding order after reflecting vertices in the x or y axis?在 x 或 y 轴上反射顶点后如何恢复 CCW 缠绕顺序?
【发布时间】:2016-07-13 18:23:54
【问题描述】:

我在 OpenGL 中使用名为vertices 的顶点数组和名为DRAW_ORDERfinal 索引缓冲区渲染一个多边形,逆时针旋转。我启用了背面剔除,并使用glDrawElements(GL_TRIANGLES, DRAW_ORDER.capacity(), GL_UNSIGNED_SHORT, DRAW_ORDER) 进行绘图调用。

当我通过矩阵变换在 x 或 y 轴上反射 vertices 时,多边形被剔除,因为反射反转了顶点的方向,因此它们不再匹配 DRAW_ORDER 的逆时针缠绕顺序。

我可以通过禁用剔除来防止该问题,但出于性能考虑,我宁愿找到一种方法来通过排列恢复vertices 的方向。例如,如果多边形是三角形,我可以简单地在反射后交换第二个和第三个顶点以恢复 CCW 方向。如何将此方法扩展到具有任意数量的顶点和索引的多边形?

  //PSEUDO-CODE FOR TRIANGLE:
    final DRAW_ORDER = {0,1,2};
    vertices = { {0,0}, {1,0}, {0,1} };
    reflect(vertices);
    swap(vertices,1,2);

编辑:这是一个似乎适用于凸多边形但不适用于凹多边形的解决方案。

    //Reverse the order of the vertices so, for example, 
    //vertices {v1,v2,v3,v4,v5} become {v5,v4,v3,v2,v1}
    for(int start = 0, end = vertices.length-1; start<end; start++, end--){
        swap(vertices,start,end);
    }

您可以在下图中看到该解决方案如何适用于椭圆(凸形)而不是星形(凹形)。

【问题讨论】:

  • 没有直接回答您的问题,但您是否考虑使用glFrontFace(GL_CW) 指定您的正面具有CW 绕组顺序?
  • 是的,但是我必须跟踪每个多边形的缠绕顺序,并在每次缠绕顺序发生变化时进行 gl 调用。到我这样做的时候,我想我还不如完全禁用剔除。
  • 这与您问题中的问题描述不符。在问题中,您说缠绕顺序发生了变化,因为您在转换中应用了反射。现在你是说每个多边形可以有不同的缠绕顺序?
  • 我所有的多边形都以逆时针缠绕顺序开始,但如果我反映其中任何一个,它们的缠绕顺序就会改变。例如,如果我有多边形 p1,..,p10 和反射 p10,那么 p1,...,p9 将具有 CCW 绕组顺序,而 p10 将具有 CW 绕组顺序。我想知道如何通过置换顶点来将 p10 的缠绕顺序恢复为 CCW。

标签: android opengl-es vertex-array index-buffer


【解决方案1】:

要通过索引的排列来反转缠绕顺序,您可以简单地反转索引的顺序。

因此,对于您的三角形示例,如果原始顺序是 (0, 1, 2),则相反的顺序是 (2, 1, 0)。由于所有循环排列对于定义多边形都是等效的,因此其他有效顺序为 (1, 0, 2) 和 (0, 2, 1)。但是使用相反的方法就可以了。

再举个例子,对于一个有 5 个顶点的多边形,使用索引 (3, 17, 6, 8, 11),反过来就是 (11, 8, 6, 17, 3),可以作为集合当您想要以相反的缠绕顺序渲染多边形时的索引。

【讨论】:

  • 您的解决方案有效,但我真的很想找到一个置换顶点而不是索引的解决方案。这样我就可以拥有一个静态的最终索引缓冲区,我的某种类型的所有多边形共享。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多