【发布时间】:2019-06-24 11:35:46
【问题描述】:
你好,我一直在学习 webgl。
我一直在阅读这本名为 Real-Time 3D Graphics with WebGL 2 的书,这里说这个顶点数组对象允许我们将一组缓冲区的所有顶点/索引绑定信息存储在一个易于管理的对象中。
它为 VAO 提供了这个示例。
function initBuffers() {
/*
V0 V3
(-0.5, 0.5, 0) (0.5, 0.5, 0)
X---------------------X
| |
| |
| (0, 0) |
| |
| |
X---------------------X
V1 V2
(-0.5, -0.5, 0) (0.5, -0.5, 0)
*/
const vertices = [
-0.5, 0.5, 0,
-0.5, -0.5, 0,
0.5, -0.5, 0,
0.5, 0.5, 0
];
// Indices defined in counter-clockwise order
indices = [0, 1, 2, 0, 2, 3];
// Create VAO instance
squareVAO = gl.createVertexArray();
// Bind it so we can work on it
gl.bindVertexArray(squareVAO);
const squareVertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
// Provide instructions for VAO to use data later in draw
gl.enableVertexAttribArray(program.aVertexPosition);
gl.vertexAttribPointer(program.aVertexPosition, 3, gl.FLOAT, false, 0, 0);
// Setting up the IBO
squareIndexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, squareIndexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
// Clean
gl.bindVertexArray(null);
gl.bindBuffer(gl.ARRAY_BUFFER, null);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
}
// We call draw to render to our canvas
function draw() {
// Clear the scene
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
// Bind the VAO
gl.bindVertexArray(squareVAO);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, squareIndexBuffer);
// Draw to the scene using triangle primitives
gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0);
// Clean
gl.bindVertexArray(null);
gl.bindBuffer(gl.ARRAY_BUFFER, null);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
}
// Entry point to our application
function init() {
// Retrieve the canvas
const canvas = utils.getCanvas('webgl-canvas');
// Set the canvas to the size of the screen
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
// Retrieve a WebGL context
gl = utils.getGLContext(canvas);
// Set the clear color to be black
gl.clearColor(0, 0, 0, 1);
// Call the functions in an appropriate order
initProgram();
initBuffers();
draw();
}
这里的问题是,我们在draw()中绑定VAO后是否需要gl.bindBuffer();?
我查看了这个链接What are Vertex Arrays in OpenGL & WebGL2?,上面写着
At draw time it then only takes one call to gl.bindVertexArray to setup all the attributes and the ELEMENT_ARRAY_BUFFER。所以我想在我们将VAO绑定到draw()之后就不需要gl.bindBuffer();了吗?
教科书上的代码是否具有误导性?
【问题讨论】: