如何将四元组的大型数组转换为三角形基元?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何将四元组的大型数组转换为三角形基元?相关的知识,希望对你有一定的参考价值。
我有一个现有的系统,它提供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上的三角形。
首先,我想提一下,这不是我想回答的问题,但我想提供我目前的解决方案。这意味着,我仍在寻找“解决方案”,这是完全可以接受的解决方案。
在我的解决方案中,我决定使用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 );
以上是关于如何将四元组的大型数组转换为三角形基元?的主要内容,如果未能解决你的问题,请参考以下文章
四旋翼飞控里 为啥一定要用四元数?用欧拉角不一样吗? 就算用四元数也是将四元数转化为欧拉角进