c++ - OpenGL 和加载/读取 AoSoA(混合 SoA)格式的数据

标签 c++ opengl

假设我有以下 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/

相关文章:

c++ - 双向链表父指针改变

c++ - libjingle的XmppPump编译问题

C++ 枚举重新定义和 C++0x

java - 从符号到地形的 Worldwind 线

c++ - valgrind 发现错误将指针传递给函数,但当代码在同一范围内时没有错误

c++ - crypt(3) 导致段错误

opengl - 将 OpenGL 渲染保存到视频

web-applications - JOGL-它有效吗?问题+评论和经验

opengl - 与保留模式 OpenGL3 相比,WebGL2 在哪些方面是直接的?

opengl - 如何在 C++ 中的 OS X Mavericks 中设置 OpenGL 4.1 渲染上下文?