3

我正在分析一个混淆的 OpenGL 应用程序。我想生成一个.obj描述应用程序中显示的多面模型的文件。

所以我冻结了应用程序并挖掘出在 VBO 和 IBO 中设置的值。但 IBO 设定的价值观比我预想的要神秘得多。价值是

0, 0, 1, 2, 3, 4, 5, 6, 7, 7, 5, 8, 3, 3, 9, 9, 10, 11, 12, 12, 10, 13, 14, 14, 10, 15, 16, 16, 17, 17, 7, 8, 8, 18, 18, 19, 20, 21, 21, 22, 22, 23, 24, 25, 25, 26, 26, 27, 28, 29, 29, 30, 30, 31, 32, 32, 33, 33, 34, 35, 36, 37, 38, 38, 36, 39, 34, 34, 40, 40, 40, 41, 42, 43, 44, 44, 45, 45, 46, 47, 48, 49, 49, 50, 50, 51, 52, 52, 53, 53, 54, 55, 55, 56, 56, 57, 58, 58, 59, 59, 60, 61, 62, 62, 63, 63, 63, 64, 65, 66, 67, 64, 68, 68, 69, 69, 70, 71, 72, 73, 74, 75, 76, 76, 77, 77, 78, 79, 80, 81, 82, 82, 80, 83, 83, 84, 84, 85, 86, 87, 88, 88, 89, 89, 90, 91, 91, 92, 92, 92, 93, 94, 95, 96, 96, 97, 97, 97, 98, 99, 100, 101, 102, 102, 100, 103, 103, 104, 104, 105, 106, 107, 107, 108, 108, 108, 109, 110, 111, 112, 112, 100, 100, 101, 113, 114, 114, ... (长度=10495)

如您所见,像 , 和 之类的索引增加40了三倍,因此既不设置, , , ,也不设置为将无法正常工作。6392108GL_TRIANGLESGL_TRIANGLE_STRIPGL_TRIANGLE_FANGL_QUADSGL_QUAD_STRIPGL_POLYGONglDrawElements

是否有某种先进的技术可以在 IBO 中使用三重排序索引?这是什么意思?它的用途是什么?

4

1 回答 1

5

像这样的重复索引表明三角形条带的积极优化。重复索引会创建退化三角形:面积为零的三角形。由于它们没有可见区域,因此它们不会被渲染。它们的存在是为了让您可以从一个三角形条跳到下一个,而无需发出另一个绘制命令。

因此,双索引通常用于将两个条带缝合在一起。它生成的两个三角形将不会被渲染。

但是,由于条带使用缠绕顺序的方式,三角形的饰面可能会不正确。也就是说,如果您将两个条带与双索引缝合在一起,则第二条带将以相反的缠绕顺序开始,而不是它想要的。

这就是三重索引的用武之地。第三个索引固定目标条中三角形的缠绕顺序。它生成的三个额外三角形将不会被渲染。

在同一个绘制调用中处理多个条带的更现代的方法是使用原始重启索引。但是目前的索引列表足以与GL_TRIANGLE_STRIP.

你可以很容易地阅读这个带状列表并将其处理成一系列单独的三角形(适用于GL_TRIANGLES)。只需查看 3 个顶点的每个序列,并将其输出到您的三角形缓冲区,只要它不是退化三角形即可。对于每个奇数三角形,您必须颠倒两个索引的顺序。代码看起来像这样:

const int num_faces = indices.size() - 2;
faces.reserve(num_faces);

for(auto i = 0; i < num_faces; ++i)
{
  Face f(indices[i], indices[i + 1], indices[i + 2]);

  //Don't add any degenerate faces.
  if(!(f[0] == f[1] || f[0] == f[2] || f[1] == f[2]))
  {
    if(i % 2 == 1) //Every odd-numbered face.
      std::swap(f[1], f[2]);

    faces.push_back(f);
  }
}
于 2017-10-01T15:26:09.230 回答