【问题标题】:Opengl storing all vertex data using 1 bufferOpengl使用1个缓冲区存储所有顶点数据
【发布时间】:2015-03-11 13:35:26
【问题描述】:

我用我所有的顶点数据(位置、纹理坐标、法线)创建了 1 个浮点缓冲区和 1 个 vbo,它们的存储方式如下:

            bf.put(vertices[i].position.x);
            bf.put(vertices[i].position.y);
            bf.put(vertices[i].position.z);
            bf.put(vertices[i].texCoords.x);
            bf.put(vertices[i].texCoords.y);
            bf.put(vertices[i].normals.x);
            bf.put(vertices[i].normals.y);
            bf.put(vertices[i].normals.z);

如何使用 glVertexAttribPointer 将它们传递给着色器?

是否可以这样做:

 glEnableVertexAttribArray(0);

            glBindBuffer(GL_ARRAY_BUFFER, vbo);
            glVertexAttribPointer(/*arguments for sending position*/);
 glEnableVertexAttribArray(1);

            glBindBuffer(GL_ARRAY_BUFFER, vbo);
            glVertexAttribPointer(/*arguments for sending texture coordinates*/);

glEnableVertexAttribArray(2);

            glBindBuffer(GL_ARRAY_BUFFER, vbo);
            glVertexAttribPointer(/*arguments for sending normals*/);

?

如果是,那么请帮助我理解 glVertexAttribPointer 以及我应该输入哪些参数。

【问题讨论】:

  • 参数见documentation
  • 我已阅读文档,但无法使用 vbo 使其工作,我需要一个示例。

标签: java lwjgl


【解决方案1】:

您用于属性的数据排列通常称为“交错”,实际上是在 VBO 中存储多个属性的推荐方式。它有利于本地数据访问,因为一个顶点的所有属性在内存中彼此相邻,这反过来往往会导致高缓存命中率。

让我们看看glVertexAttribPointer() 的签名,然后更详细地解释这些参数。我故意不会复制文档中的解释,希望其他措辞可以帮助您更好地理解它们。在LWJGL中,定义为:

static void glVertexAttribPointer(
    int index, int size, int type, boolean normalized,
    int stride, long pointerOffset)
  • index:顶点属性在顶点着色器中的位置,用glBindAttribLocation() 指定,用glGetAttribLocation() 获得,或用location 布局限定符在着色器代码中指定。
  • size:属性中的组件数。例如。 3 表示具有 3 个坐标的位置,2 表示具有 2 个分量的纹理坐标,等等。
  • type:属性类型。主要是GL_FLOAT
  • normalized:浮点属性无关紧要,如果您开始使用整数类型属性,请阅读它。
  • stride:后续顶点之间的字节间距。除非您在顶点之间有填充(这种情况很少见),否则这与顶点的大小(以字节为单位)相同。
  • pointerOffset:由于历史原因,它的名称中有“指针”,但实际上是属性第一次出现相对于缓冲区开始的字节偏移量。在交错排列中,这对应于顶点内属性的偏移量,以字节为单位。

在您的情况下,stride 将是 32,因为每个顶点由 8 个浮点分量组成,每个分量为 4 个字节。

pointerOffset 是第一个属性的 0,然后是其余所有属性的相对字节偏移量,这导致其余两个属性为 12 和 20。

这会调用您的示例:

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * 4, 0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 8 * 4, 3 * 4);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 8 * 4, (3 + 2) * 4);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-26
    • 2011-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多