IBO 中的三倍序列如何工作?

Posted

技术标签:

【中文标题】IBO 中的三倍序列如何工作?【英文标题】:How are tripled sequence in IBO working? 【发布时间】:2017-10-01 11:33:21 【问题描述】:

我正在分析一个混淆的 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)

如您所见,406392108 等索引增加了三倍,因此既不设置 GL_TRIANGLESGL_TRIANGLE_STRIPGL_TRIANGLE_FANGL_QUADSGL_QUAD_STRIP 也不设置GL_POLYGONglDrawElements 将无法正常工作。

在 IBO 中是否有某种高级技术可以使用三重排序索引?这是什么意思?它用于什么原因?

【问题讨论】:

你需要了解这个索引数组的实际使用情况。请注意,不必有单个绘图调用将整个数组作为相同的原始类型使用。另请注意,零面积三角形有一些模糊的用例(如三角形带中的翻转边缘)。另请注意,其中可能只是退化的原语。 【参考方案1】:

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

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

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

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

在同一个绘图调用中处理多个条带的更现代的方法是使用primitive restart indices。但目前的索引列表足以与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);
  

【讨论】:

以上是关于IBO 中的三倍序列如何工作?的主要内容,如果未能解决你的问题,请参考以下文章

python的while循环小红8岁,妈妈38岁,多少年后妈妈的年龄是小明的三倍?

使用流分析读取时,事件中心输入大小数据的输出大小是输出大小的三倍

MT300余弦的三倍角公式

VAO 中的 C++ GLSL 多个 IBO

问题为什么 System.Timers.Timer 更改间隔时间后的第一次触发时间是设定时间的三倍?...

儿童吸收辐射是成人的三倍多,进口三文鱼问题频发,谨慎食用