3

所以我正在查看关于命令 glVertexAttribPointer 的另一个 SO 问题,我遇到了一些困惑。这个问题的公认答案解释说,

但是当您进行调用时,还有一个额外的隐含状态也存储在属性 0 中:数据是从当前绑定到 GL_ARRAY_BUFFER 的缓冲区中读取的

这对我来说很有意义,但是如果我有多个绑定为的缓冲区GL_ARRAY_BUFFER怎么办?该方法如何glVertexAttribPointer()知道要设置哪个属性?

例如,在我的代码中,我正在绘制一个渐变三角形。为此,我创建了 2 个 VBO,一个带有数组中的颜色数据,另一个带有顶点位置。

glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);
    static const GLfloat points[] = {
    //data here
    };
    static const GLfloat colors[] = {
      //data here
    };
    glGenBuffers(1, &buffer);
    glBindBuffer(GL_ARRAY_BUFFER, buffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
    vs = glCreateShader(GL_VERTEX_SHADER);
    fs = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(vs, 1, &vertexShaderData, NULL);
    glShaderSource(fs, 1, &fragShaderData, NULL);
    glCompileShader(vs);
    glCompileShader(fs);
    sp=glCreateProgram();
    glBindFragDataLocation(sp, 0, "outColor");
    glAttachShader(sp, vs);
    glAttachShader(sp, fs);
    glLinkProgram(sp);
    glUseProgram(sp);
    glGenBuffers(1, &colorBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, colorBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW);
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(1);
    glDrawArrays(GL_TRIANGLES, 0, 9);

当我调用命令时,我在哪里指定使用哪个缓冲区?

4

1 回答 1

5

这对我来说很有意义,但是如果我有多个绑定为 GL_ARRAY_BUFFER 的缓冲区怎么办?

那是不可能的。当您将缓冲区(或任何 OpenGL 对象)绑定到目标时,它会自动取消绑定之前的任何内容。

OpenGL 对象目标就像全局变量。当您将全局整数设置为 3 时会发生什么?它的旧值已经消失了。

glVertexAttribPointer始终使用当前绑定到的任何缓冲区GL_ARRAY_BUFFER。因此,在您的第一次通话中,它将使用buffer. 在您的第二次通话中,它将使用colorBuffer.

这就是为什么重要的是要记住它对当前绑定glVertexAttribPointer的内容进行操作。因为即使在绑定并将其设置为由属性 1 使用后,属性 0仍会从.colorBufferbuffer

因此,虽然您不能将多个缓冲区绑定到GL_ARRAY_BUFFER,但您可以使用多个缓冲区作为顶点数据的源。

于 2016-06-21T18:50:58.657 回答