IBO 中的三重序列如何运作?
How are tripled sequence in IBO working?
我正在分析经过混淆处理的 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
、63
、92
和 108
等索引增加了三倍,因此 GL_TRIANGLES
、[=16= 都不设置]、GL_TRIANGLE_FAN
、GL_QUADS
、GL_QUAD_STRIP
或 GL_POLYGON
至 glDrawElements
将无法正常工作。
是否有某种高级技术可以在 IBO 中使用三重序列索引?这是什么意思?它的用途是什么?
像这样的重复索引表明三角形带的积极优化。重复索引会创建退化三角形:面积为零的三角形。由于它们没有可见区域,因此不会被渲染。它们的存在使您可以从一个三角形带跳到下一个三角形带,而无需发出另一个绘制命令。
所以双索引通常用于将两个条带缝合在一起。它生成的两个三角形不会被渲染。
但是,由于 strips work with the winding order 的方式,三角形的面可能会出现错误。也就是说,如果你用双索引将两个条带缝合在一起,第二个条带将以比它想要的相反的缠绕顺序开始。
这就是 三重 索引的用武之地。第三个索引固定了目标条带中三角形的缠绕顺序。它生成的三个额外的三角形将不会被渲染。
在同一个绘图调用中处理多个条带的更现代的方法是使用 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);
}
}
我正在分析经过混淆处理的 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
、63
、92
和 108
等索引增加了三倍,因此 GL_TRIANGLES
、[=16= 都不设置]、GL_TRIANGLE_FAN
、GL_QUADS
、GL_QUAD_STRIP
或 GL_POLYGON
至 glDrawElements
将无法正常工作。
是否有某种高级技术可以在 IBO 中使用三重序列索引?这是什么意思?它的用途是什么?
像这样的重复索引表明三角形带的积极优化。重复索引会创建退化三角形:面积为零的三角形。由于它们没有可见区域,因此不会被渲染。它们的存在使您可以从一个三角形带跳到下一个三角形带,而无需发出另一个绘制命令。
所以双索引通常用于将两个条带缝合在一起。它生成的两个三角形不会被渲染。
但是,由于 strips work with the winding order 的方式,三角形的面可能会出现错误。也就是说,如果你用双索引将两个条带缝合在一起,第二个条带将以比它想要的相反的缠绕顺序开始。
这就是 三重 索引的用武之地。第三个索引固定了目标条带中三角形的缠绕顺序。它生成的三个额外的三角形将不会被渲染。
在同一个绘图调用中处理多个条带的更现代的方法是使用 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);
}
}