OpenGL和以AoSoA(混合SoA)格式加载/读取数据 [英] OpenGL and loading/reading data in AoSoA (hybrid SoA) format

查看:161
本文介绍了OpenGL和以AoSoA(混合SoA)格式加载/读取数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我具有AoSoA格式的以下简化结构来表示顶点或点:

Let's assume I have the following simplified structure in AoSoA format to represent a vertex or point:

struct VertexData
{
    float px[4]; // position x
    float py[4]; // position y
};

也就是说,每个VertexData实例都存储4个顶点.我见过的几乎所有OpenGL示例都使用传统的AoS布局,但这不是我的选择.我无法更改实际结构,并且还希望避免在渲染之前将数据转换为AoS格式.

That is, each instance of VertexData is storing 4 vertices. Almost all OpenGL examples I've seen use the traditional AoS layout, but that is not an option for me. I can't change the actual structures, and I would also like to avoid converting the data into AoS format before rendering.

那么,当以这种方式组织数据时,是否可以指示OpenGL读取顶点数据,如果是这样,我应该研究哪些GL功能?如我所见,问题是使OpenGL意识到VertexData.px[i]VertexData.py[i]配对的事实,并且这两个值应该形成一个顶点/点.

So, is it possible to instruct OpenGL to read the vertex data when the data is organized this way, and if so, which GL functions should I look into? The problem as I see it, is to make OpenGL aware of the fact that VertexData.px[i] is paired with VertexData.py[i], and those two values should form a vertex/point.

说明1 :最后会有一个VertexData数组,例如:std::vector<VertexData>.这样,std::vector的大小将为total number of vertices / 4.

Clarification 1: In the end, there will be an array of VertexData, for example: std::vector<VertexData>. The size of the std::vector would then be total number of vertices / 4.

说明2 :AoSoA =数组结构的数组.

Clarification 2: AoSoA = Array of Structure of Arrays.

更新:请参见

Update: See How do I draw vertices that are stored in a SSBO? for on how to draw vertices that are stored in a SSBO in AoSoA format.

推荐答案

OpenGL的顶点数组格式专为... 数组数据而设计.每个单独的数组/缓冲区绑定可以具有较大的步幅.但是这一步,从一个顶点的数据(针对该属性)到下一个顶点的距离,对于数组中的每个顶点都是相同的.这就是使它成为数组的原因.你的步伐不是恒定的.有时是4个字节,有时是16个字节.

OpenGL's vertex array formats are designed for... arrays of data. Each individual array/buffer binding can have a stride of substantial size. But that stride, the distance from one vertex's data (for that attribute) to the next, is the same for every vertex in the array; that's what makes it an array. Your stride is not constant. Sometimes, it is 4 bytes and sometimes it's 16.

因此,基于硬件的顶点拉对这里无济于事.

So hardware-based vertex pulling isn't going to be helpful here.

有一个选项无论您做什么都可以使用:程序化顶点拉动.也就是说,完全忽略顶点属性数组.将您的顶点缓冲区"作为 SSBO 绑定到着色器,然后使用gl_VertexID提取所需的任何数据.在GLSL中看起来像这样:

There is one option that will work no matter what you do: programmatic vertex pulling. That is, ignore vertex attribute arrays altogether. Bind your "vertex buffers" as SSBOs to your shader, and use gl_VertexID to fetch whichever data you want. That would look something like this in 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基本上可以杀死性能.

This will be faster than any geometry shader based solution, since GS's basically kill performance.

如果您无权访问 SSBO ,因为您的硬件可以要处理它们,您可以改用缓冲区纹理.

If you don't have access to SSBOs, because your hardware can't handle them, you can use buffer textures instead.

这篇关于OpenGL和以AoSoA(混合SoA)格式加载/读取数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆