在尝试在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)。这是为什么?我错过了什么?
答案 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);