假设我有以下 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 = 数组结构数组。
Update: See 如何绘制存储在 SSBO 中的顶点? https://stackoverflow.com/questions/59637006/how-do-i-draw-vertices-that-are-stored-in-a-ssbo了解如何绘制以 AoSoA 格式存储在 SSBO 中的顶点。
OpenGL的顶点数组格式 https://www.khronos.org/opengl/wiki/Vertex_Specification设计用于...arrays数据的。每个单独的数组/缓冲区绑定可以具有相当大的跨度。但步幅,即从一个顶点数据(对于该属性)到下一个顶点数据的距离,对于数组中的每个顶点都是相同的;这就是它成为数组的原因。你的步伐不是恒定的。有时是 4 个字节,有时是 16 个字节。
因此基于硬件的顶点拉动在这里不会有帮助。
无论您做什么,有一个选项都可以使用:编程顶点拉动。也就是说,完全忽略顶点属性数组。将您的“顶点缓冲区”绑定为SSBOs https://www.khronos.org/opengl/wiki/Shader_Storage_Buffer_Object到你的着色器,并使用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 https://www.khronos.org/opengl/wiki/Shader_Storage_Buffer_Object,因为你的硬件无法处理它们,你可以使用缓冲纹理 https://www.khronos.org/opengl/wiki/Buffer_Texture反而。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)