Knowledge points
New drawing function
gl.drawElements();
gl.drawArrays()
directly calls the vertex array data, every time a straight line is drawn, two vertices need to be defined.
gl.drawElements()
uses an index array to access the vertex data in the vertex array, can reuse the vertex data.index array and vertex array
// 8 vertex coordinate arrays var data=new Float32Array([ 0.5, 0.5, 0.5,//vertex 0 -0.5, 0.5, 0.5,//vertex 1 -0.5, -0.5, 0.5,//vertex 2 0.5, -0.5, 0.5, // Vertex 3 0.5, 0.5, -0.5, //vertex 4 -0.5, 0.5, -0.5,//vertex 5 -0.5, -0.5, -0.5,//vertex 6 0.5, -0.5, -0.5, // Vertex 7 ]); // Vertex index array var indexes = new Uint8Array([ //The first four points correspond to the index value 0, 1, 2, 3,//gl.LINE_LOOP mode draws a rectangular frame with four points //The last four vertices correspond to index values 4, 5, 6, 7,//gl.LINE_LOOP mode draws a rectangular frame with four points //The corresponding index value of the corresponding point before and after 0, 4, // two points draw a straight line 1, 5,//two points draw a straight line 2, 6,//two points draw a straight line 3, 7//Two points draw a straight line ]);Create a buffer of array indices
To operate the data of the index array, you need to add the data to the buffer (the vertex array must also be added to the buffer, which requires two buffer objects)
//Create a vertex buffer object var buffer = gl. createBuffer(); // bind the buffer object gl.bindBuffer(gl.ARRAY_BUFFER, buffer); //The vertex array data data is passed into the buffer gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW); //Create index buffer object var indexesBuffer = gl. createBuffer(); // bind the buffer object gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexesBuffer); //The index array indexes data is passed into the buffer gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indexes, gl.STATIC_DRAW); //The data in the buffer is passed to the position variable apos according to certain rules gl.vertexAttribPointer(aposLocation, 3, gl.FLOAT, false, 0, 0); //Allow data transfer gl.enableVertexAttribArray(aposLocation);
The use of drawElements() adds a data type setting parameter,
gl.UNSIGNED_BYTE.
After the data is processed, it can be rendered by drawElements()
. (replaces
drawArrays() method)
//LINE_LOOP mode draws the first four points gl.drawElements(gl.LINE_LOOP,4,gl.UNSIGNED_BYTE,0); //LINE_LOOP mode draws four points starting from the fifth point gl.drawElements(gl.LINE_LOOP,4,gl.UNSIGNED_BYTE,4); //8 points after drawing in LINES mode gl.drawElements(gl.LINES, 8, gl.UNSIGNED_BYTE, 8);Parameter 1: mode drawing mode (gl.LINE_LOOP, gl.LINES, gl.TRIANGLES, etc.)
Parameter 2: count number of vertices drawn (integer)
Parameter 3: type data type
gl.UNSIGNED_BYTE corresponds to Uint8Array,
gl.UNSIGNED_SHORT corresponds to Uint16Array
Parameter 4: Offset from which point to start drawing (integer, in bytes)
Note: count and offset refer to the index array of vertices
Summary:
Purpose: To solve the redundancy problem of vertex array data data,
① Define vertex array data, index array indexes,
② Create the buffer object of the vertex array and the index array and pass in the data (2 buffer objects),
③ Use gl.drawElements() to replace gl.drawArrays() to render graphics
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> </head> <body> <canvas id="webgl" width="500" height="500" style="background-color: #0d72da"></canvas> <script> var canvasElement = document. getElementById('webgl'); var gl = canvasElement. getContext('webgl'); //Vertex shader source code var vertexShaderSource = '' + //attribute declares the vec4 type variable apos 'attribute vec4 apos;' + 'void main(){' + //Set the geometry axis rotation angle to 30 degrees, and convert the angle value to a floating point value 'float radian = radians(30.0);' + // Solve the cosine value of the rotation angle 'float cos = cos(radian);' + // Solve the sine of the rotation angle 'float sin = sin(radian);' + //Refer to the calculation data above to create a rotation matrix around the x-axis // 1 0 0 0 // 0 cosα sinα 0 // 0 - sinα cosα 0 // 0 0 0 1 'mat4 mx = mat4(1,0,0,0,0,cos,-sin,0,0,sin,cos,0,0,0,0,1);' + //Refer to the calculation data above to create a rotation matrix around the y-axis // cosβ 0 sinβ 0 // 0 1 0 0 //-sinβ 0 cosβ 0 // 0 0 0 1 'mat4 my = mat4(cos,0,-sin,0, 0,1,0,0, sin,0,cos,0, 0,0,0,1);' + //Multiplication of two rotation matrices and vertex homogeneous coordinates ' gl_Position = mx*my*apos;' + '}'; //Fragment shader source code var fragShaderSource = '' + 'void main(){' + ' gl_FragColor = vec4(1.0,0.0,0.0,1.0);' + '}'; //Initialize the shader var program = initShader(gl, vertexShaderSource, fragShaderSource); // Get the position variable apos of the vertex shader var aposLocation = gl. getAttribLocation(program, 'apos'); // 8 vertex coordinate arrays var data = new Float32Array([ 0.5, 0.5, 0.5,//vertex 0 -0.5, 0.5, 0.5,//vertex 1 -0.5, -0.5, 0.5,//vertex 2 0.5, -0.5, 0.5, // Vertex 3 0.5, 0.5, -0.5, //vertex 4 -0.5, 0.5, -0.5,//vertex 5 -0.5, -0.5, -0.5,//vertex 6 0.5, -0.5, -0.5, // Vertex 7 ]); // Vertex index array var indexes = new Uint8Array([ //The first four points correspond to the index value 0, 1, 2, 3,//gl.LINE_LOOP mode draws a rectangular frame with four points //The last four vertices correspond to index values 4, 5, 6, 7,//gl.LINE_LOOP mode draws a rectangular frame with four points //The corresponding index value of the corresponding point before and after 0, 4, // two points draw a straight line 1, 5,//two points draw a straight line 2, 6,//two points draw a straight line 3, 7//Two points draw a straight line ]); //Create a vertex buffer object var buffer = gl. createBuffer(); // bind the buffer object gl.bindBuffer(gl.ARRAY_BUFFER, buffer); //The vertex array data data is passed into the buffer gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW); //Create index buffer object var indexesBuffer = gl. createBuffer(); // bind the buffer object gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexesBuffer); //The index array indexes data is passed into the buffer gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indexes, gl.STATIC_DRAW); //The data in the buffer is passed to the position variable apos according to certain rules gl.vertexAttribPointer(aposLocation, 3, gl.FLOAT, false, 0, 0); //Allow data transfer gl. enableVertexAttribArray(aposLocation); //LINE_LOOP mode draws the first four points gl.drawElements(gl.LINE_LOOP, 4, gl.UNSIGNED_BYTE, 0); //LINE_LOOP mode draws four points starting from the fifth point gl.drawElements(gl.LINE_LOOP, 4, gl.UNSIGNED_BYTE, 4); //8 points after drawing in LINES mode gl. drawElements(gl. LINES, 8, gl. UNSIGNED_BYTE, 8); //declare initialization shader function function initShader(gl, vertexShaderSource, fragmentShaderSource) { var vertexShader = gl.createShader(gl.VERTEX_SHADER); var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); gl. shaderSource(vertexShader, vertexShaderSource); gl. shaderSource(fragmentShader, fragmentShaderSource); gl. compileShader(vertexShader); gl. compileShader(fragmentShader); var program = gl. createProgram(); gl. attachShader(program, vertexShader); gl. attachShader(program, fragmentShader); gl. linkProgram(program); gl. useProgram(program); return program; } </script> </body> </html>
Impression