webGL 绑定缓冲区不工作
webGL bindBuffer not working
当试图在 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;
结果是后面的buffer,(buffer2)每次都被渲染。这是为什么?我错过了什么?
顶点属性指针是全局状态,不是缓冲区的局部状态,当您将数据设置到缓冲区时,无需设置顶点属性指针。
A vertexAttribPointer
调用基本上告诉 GPU "hey the positions start at 0 and are 3 floats each" 并且 GPU 通过将属性 pointer 设置为 currently bound buffer address
+ [=14 来服从=],但是,当您更改缓冲区时,此指针仍然指向 "old" 缓冲区,您需要通过另一个调用 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);
当试图在 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;
结果是后面的buffer,(buffer2)每次都被渲染。这是为什么?我错过了什么?
顶点属性指针是全局状态,不是缓冲区的局部状态,当您将数据设置到缓冲区时,无需设置顶点属性指针。
A vertexAttribPointer
调用基本上告诉 GPU "hey the positions start at 0 and are 3 floats each" 并且 GPU 通过将属性 pointer 设置为 currently bound buffer address
+ [=14 来服从=],但是,当您更改缓冲区时,此指针仍然指向 "old" 缓冲区,您需要通过另一个调用 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);