如何将四元组的大型数组转换为三角形基元?

问题描述 投票:1回答:1

我有一个现有的系统,它提供3D网格。提供的数据是具有3个分量(x,y,z)和索引列表的顶点坐标数组。问题是索引列表是四元素的连续数组。 我知道所有的四边形都有相同的绕线顺序(逆时针),但我没有关于四边形的更多信息。我对他们的关系或邻接并不了解。

由于我想使用核心配置文件进行渲染,我不能使用qazxsw poi原始类型。我必须将四边形转换为tringles。

当然,四元索引数组可以很容易地转换为三角形索引数组:

GL_QUAD

如果必须只进行一次,那就是解决方案。但是,meash数据并不是静态的。数据可以动态变化。数据不会每次都连续变化,但数据会无法预测且随机变化。

另一个简单的解决方案是创建一个顶点数组对象,它直接引用带有四边形的元素数组缓冲区,并使用std::vector<unsigned int> triangles; triangles.reserve( no_of_indices * 6 / 4 ); for ( int i = 0; i < no_of_indices; i += 4 ) { int tri[] = { quad[i], quad[i+1], quad[i+2], quad[i], quad[i+2], quad[i+3] }; triangles.insert(triangles.end(), tri, tri+6 ); } 基本类型在循环中绘制它们:

GL_TRIANGLE_FAN

但我希望有更好的解决方案。我正在寻找一种可能用一次绘制调用绘制四边形,或者将四边形转换为GPU上的三角形。

opengl glsl
1个回答
0
投票

首先,我想提一下,这不是我想回答的问题,但我想提供我目前的解决方案。这意味着,我仍在寻找“解决方案”,这是完全可以接受的解决方案。

在我的解决方案中,我决定使用Te I绘制大小为4的补丁:

for ( int i = 0; i < no_of_indices; i += 4 )
    glDrawElements( GL_TRIANGLE_FAN, 4, GL_UNSIGNED_INT, (void*)(sizeof(unsigned int) * 4) );

glPatchParameteri( GL_PATCH_VERTICES, self.__patch_vertices ) glDrawElements( GL_PATCHES, no_of_indices, GL_UNSIGNED_INT, 0 ) 有默认行为。补丁数据直接从顶点着色器调用传递到曲面细分基元生成。因此可以完全省略。

Tessellation Control Shader使用四边形补丁(Tessellation Evaluation Shader)创建2个三角形:

quads

另一种灵魂就是使用#version 450 layout(quads, ccw) in; in TInOut { vec3 pos; } inData[]; out TInOut { vec3 pos; } outData; uniform mat4 u_projectionMat44; void main() { const int inx_map[4] = int[4](0, 1, 3, 2); float i_quad = dot( vec2(1.0, 2.0), gl_TessCoord.xy ); int inx = inx_map[int(round(i_quad))]; outData.pos = inData[inx].pos; gl_Position = u_projectionMat44 * vec4( outData.pos, 1.0 ); } 。输入原始类型Geometry Shader提供4个顶点,可以映射到2个三角形(lines_adjacency)。当然这似乎是一个黑客,因为triangle_strip是一个完全不同于四边形的东西,但无论如何它都有效。

lines adjacency

几何着色器:

glDrawElements( GL_LINES_ADJACENCY, no_of_indices, GL_UNSIGNED_INT, 0 );
© www.soinside.com 2019 - 2024. All rights reserved.