假设我有以下 AoSoA 格式的简化结构来表示顶点或点:
struct VertexData
{
float px[4]; // position x
float py[4]; // position y
};
也就是说,VertexData
的每个实例存储 4 个顶点。我见过的几乎所有 OpenGL 示例都使用传统的 AoS 布局,但这对我来说不是一个选择。我无法更改实际结构,而且我也希望避免在渲染之前将数据转换为 AoS 格式。
那么,当数据以这种方式组织时,是否可以指示 OpenGL 读取顶点数据?如果可以,我应该查看哪些 GL 函数?在我看来,问题是让 OpenGL 意识到 VertexData.px[i]
与 VertexData.py[i]
配对,这两个值应该形成一个顶点/点。
说明1:最后会有一个数组VertexData
,例如:std::vector<VertexData>
。 std::vector
的大小那么将是total number of vertices / 4
.
说明 2:AoSoA = 数组结构的数组。
更新:请参阅 How do I draw vertices that are stored in a SSBO?了解如何绘制以 AoSoA 格式存储在 SSBO 中的顶点。
最佳答案
OpenGL 的 vertex array formats专为......数据数组而设计。每个单独的数组/缓冲区绑定(bind)可以具有相当大的跨度。但步幅,即从一个顶点数据(对于该属性)到下一个顶点数据的距离,对于数组中的每个顶点都是相同的;这就是它成为数组的原因。你的步伐不是恒定的。有时是 4 个字节,有时是 16 个字节。
因此基于硬件的顶点拉动在这里不会有帮助。
有一个选项无论您做什么都可以工作:编程顶点拉动。也就是说,完全忽略顶点属性数组。将您的“顶点缓冲区”绑定(bind)为 SSBOs到您的着色器,并使用 gl_VertexID
获取您想要的任何数据。在 GLSL 中看起来像这样:
struct Vertex4
{
float px[4]; // position x
float py[4]; // position y
};
layout(std430) readonly buffer VertexData
{
Vertex4 vertices[];
};
void main()
{
int dataIx = gl_VertexID / 4;
int vertexIx = gl_VertexID % 4;
vec2 my_position = vec2(vertices[dataIx].px[vertexIx], vertices[dataIx].py[vertexIx]);
}
这将比任何基于几何着色器的解决方案更快,因为 GS 基本上会破坏性能。
如果您无权访问SSBOs ,因为您的硬件无法处理它们,您可以使用 buffer textures相反。
关于c++ - OpenGL 和加载/读取 AoSoA(混合 SoA)格式的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59616117/