webGL bindBuffer无法正常工作

时间:2017-01-05 11:25:43

标签: javascript webgl

在尝试在webgl中显示几个不同形状的对象时,我发现只有最新创建的缓冲区才能在渲染时使用。这看起来很奇怪,因为我在每次渲染之前绑定当前缓冲区:

gl.useProgram(this.program);
gl.enableVertexAttribArray(this.a_Position);
gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);

gl.uniformMatrix4fv(this.u_ModelMatrix, false, MVPMatrix.elements);
gl.uniform4fv(this.u_FragColor, this.color);

gl.drawArrays(gl.TRIANGLES, 0, 6);
gl.disableVertexAttribArray(this.a_Position);
gl.bindBuffer(gl.ARRAY_BUFFER, null);

因此,为了测试最基本的示例,我尝试在彼此之后创建两个缓冲区,并查看将使用哪个缓冲区:

var buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.enableVertexAttribArray(this.a_Position);
// gl.enableVertexAttribArray(this.a_UV);
gl.vertexAttribPointer(this.a_Position, 3, gl.FLOAT, false, 3*4, 0);
// gl.vertexAttribPointer(this.a_UV, 2, gl.FLOAT, false, 5*4, 3*4);
gl.bufferData(
    gl.ARRAY_BUFFER,
    new Float32Array([
         0.5,  0.5, 0,
        -0.5, -0.5, 0,
         0.5, -0.5, 0,
         0.5,  0.5, 0,
        -0.5,  0.5, 0,
        -0.5, -0.5, 0
    ]),
    gl.STATIC_DRAW
);
gl.bindBuffer(gl.ARRAY_BUFFER, null);

var buffer2 = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer2);
gl.enableVertexAttribArray(this.a_Position);
gl.vertexAttribPointer(this.a_Position, 3, gl.FLOAT, false, 3*4, 0);
gl.bufferData(
    gl.ARRAY_BUFFER,
    new Float32Array([
         1,  0.5, 0,
        -0, -0.5, 0,
         1, -0.5, 0,
         1,  0.5, 0,
        -0,  0.5, 0,
        -0, -0.5, 0
    ]),
   gl.STATIC_DRAW
);
this.buffer = buffer;

结果是每次都渲染后一个缓冲区(buffer2)。这是为什么?我错过了什么?

1 个答案:

答案 0 :(得分:1)

顶点属性指针是缓冲区不是本地的全局状态,当数据设置为缓冲区时,无需设置顶点属性指针。

vertexAttribPointer调用基本上告诉GPU“嘿,位置从0开始,每个都有3个浮点数”,GPU通过将属性指针设置为currently bound buffer address +来服从attribute offset,但是当您更改缓冲区时,此指针保持不变,仍然指向该“旧”缓冲区,您需要通过另一次调用vertexAttribPointer来更新它。

因此,您的缓冲区初始化代码变为:

var buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(
    gl.ARRAY_BUFFER,
    new Float32Array([
         0.5,  0.5, 0,
        -0.5, -0.5, 0,
         0.5, -0.5, 0,
         0.5,  0.5, 0,
        -0.5,  0.5, 0,
        -0.5, -0.5, 0
    ]),
    gl.STATIC_DRAW
);

在渲染代码中,然后将顶点属性指针设置为主动绑定缓冲区:

gl.useProgram(this.program);
gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);
gl.enableVertexAttribArray(this.a_Position);

// Set vertex attribute pointer to current buffer
// Note: I adjusted the stride to 0 to make sense
//       in the context of this question/answer
gl.vertexAttribPointer(this.a_Position, 3, gl.FLOAT, false, 0, 0);

gl.uniformMatrix4fv(this.u_ModelMatrix, false, MVPMatrix.elements);
gl.uniform4fv(this.u_FragColor, this.color);
gl.drawArrays(gl.TRIANGLES, 0, 6);