Rectangles can be drawn in a variety of ways. Here are my top 5 ways to draw. Rectangles are drawn on the basis of triangles. So the code doesn’t change much, the only difference is that when you construct the data, you need a different number of vertices.
- Vertex shader code
<script id="vertexShader" type="x-shader/x-vertex">
//attribute declares the vec3 type variable apos
attribute vec3 apos;
void main() {
// Vertex coordinates apOS is assigned to the built-in variable gl_Position
// Process data vertex by vertex
gl_Position = vec4(apos,1.0);
}
</script>
Copy the code
- Chip shader code
<script id="fragmentShader" type="x-shader/x-fragment">
void main() {
// Process the data bit by bit with all pixels set to red
gl_FragColor = vec4(1.0.0.0.0.0.1.0);
}
</script>
Copy the code
- Javascript code
WebGL
Context retrieval
function init() { const canvas = document.getElementById('webgl'); const gl = canvas.getContext('webgl'); // Create a shader program const program = initShader(gl); const count= assignValue(gl,program); render(gl,count); } Copy the code
- Declare the initialization shader function
function initShader(gl) { // Vertex shader source code const vertexShaderSource = document.getElementById('vertexShader').innerText; // Chip shader source code const fragmentShaderSource = document.getElementById('fragmentShader').innerText; const vertexShader = gl.createShader(gl.VERTEX_SHADER); const 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; } Copy the code
- Shader code variable assignment
V0->V1->V2; V0->V1->V2; Lower triangle V0->V4->V1; Right triangle V0->V3->V4; Top triangle V0->V4-V1. const positions = new Float32Array([ //V0 -0.5.0.5.1.0.1.0.0.0.1.0.//V1 0.5.0.5.1.0.0.0.0.0.1.0.//V2 0.5, -0.5.1.0.1.0.0.0.1.0.//V3 -0.5.0.5.1.0.0.0.0.0.1.0.//V4 0.5, -0.5.0.0.0.0.1.0.1.0.//V5 -0.5, -0.5.0.0.1.0.0.0.1.0,]);const a_Position = gl.getAttribLocation(program, 'a_Position'); const a_Color = gl.getAttribLocation(program, 'a_Color'); gl.enableVertexAttribArray(a_Position); gl.enableVertexAttribArray(a_Color); // Create buffer let buffer = gl.createBuffer(); // Bind buffer is the current buffer gl.bindBuffer(gl.ARRAY_BUFFER, buffer); // Sets how the a_Position property reads data from the buffer gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false.24.0); // Sets how the a_Color property reads data from the buffer gl.vertexAttribPointer(a_Color, 4, gl.FLOAT, false.24.8); // Pass data to the buffer gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW); return positions.length / 6; Copy the code
WebGL
Rendering function
function render(program, gl) { // Get the vertex shader's location variable apos, that is, aposLocation points to the apOS variable. const aposLocation = gl.getAttribLocation(program, "apos"); // Array constructor Float32Array creates an array of vertices const data = new Float32Array([-0.5.0.5.0.0.0.5.0.5.0.0.0.5, -0.5.0.0, -0.5.0.5.0.0.0.5, -0.5.0.0, -0.5, -0.5.0.0,]);// Create a buffer object const buffer = gl.createBuffer(); // Bind buffer objects to activate buffer gl.bindBuffer(gl.ARRAY_BUFFER, buffer); // The vertex array data is passed into the buffer gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW); // Allow data transfer gl.enableVertexAttribArray(aposLocation); // 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); // Set the canvas color gl.clearColor(0.0.0.0.0.0.0.3); gl.clear(gl.COLOR_BUFFER_BIT); // Start drawing graph data.length/3 indicates the number of top data gl.drawArrays(gl.TRIANGLES, 0, data.length/3); } Copy the code
The main differences between the following methods of drawing rectangles lie in the data construction and drawing methods.
1, the conventional way
- The data structure
// Define four triangles with six vertices that make up the rectangle
let positions = new Float32Array([
//V0
-0.5.0.5.1.0.1.0.0.0.1.0.//V1
0.5.0.5.1.0.0.0.0.0.1.0.//V2
0.5, -0.5.1.0.1.0.0.0.1.0.//V3
-0.5.0.5.1.0.0.0.0.0.1.0.//V4
0.5, -0.5.0.0.0.0.1.0.1.0.//V5
-0.5, -0.5.0.0.1.0.0.0.1.0,]);Copy the code
- Draw the way
// Start drawing graph data.length/3 indicates the number of top data
gl.drawArrays(gl.TRIANGLES, 0, data.length/3);
Copy the code
The renderings are as follows:
2. Triangle fan
In this way, when drawing a triangle, the first two vertices of the next triangle are drawn. The first vertex is determined to be the first vertex of the triangle, and the second vertex is the last vertex of the previous triangle.
- The data structure
// Define four triangles with six vertices that make up the rectangle
let positions = new Float32Array([
//V0
-0.5.0.5.1.0.1.0.0.0.1.0.//V1
0.5.0.5.1.0.0.0.0.0.1.0.//V2
0.5, -0.5.1.0.1.0.0.0.1.0.//V3
-0.5, -0.5.0.0.1.0.0.0.1.0,]);Copy the code
- Draw the way
// Start drawing graph data.length/3 indicates the number of top data
gl.drawArrays(gl.TRIANGLE_FAN, 0, data.length/3);
Copy the code
The renderings are as follows:
3. Triangle belt
In this way, when drawing a triangle, the first two vertices of the next triangle are the last two vertices of the previous triangle.
- The data structure
// Define four triangles with six vertices that make up the rectangle
const positions = new Float32Array([
//V0
0.5.0.5.1.0.0.0.0.0.1.0.//V1
-0.5.0.5.1.0.1.0.0.0.1.0.//V2
0.5, -0.5.1.0.1.0.0.0.1.0.//V3
-0.5, -0.5.0.0.1.0.0.0.1.0,]);Copy the code
- Draw the way
// Draw method with 6 data per row
gl.drawArrays(gl.TRIANGLE_STRIP, 0, positions.length / 6);
Copy the code
The renderings are as follows:
4. Close the line segment
- The data structure
// Define the four vertices that make up the rectangle
const positions = new Float32Array([
//V0
0.5.0.5.1.0.0.0.0.0.1.0.//V1
-0.5.0.5.1.0.1.0.0.0.1.0.//V2
-0.5, -0.5.0.0.1.0.0.0.1.0.//V3
0.5, -0.5.1.0.1.0.0.0.1.0,]);Copy the code
- Draw the way
// Draw method with 6 data per row
gl.drawArrays(gl.LINE_LOOP, 0, positions.length/6);
Copy the code
5. Vertex index
Vertex indexes differ in the way buffer data is constructed and rendered.
- The data structure
// Create a buffer
function assignValue(gl, program) {
// Define four triangles with six vertices that make up the rectangle
const positions = new Float32Array([
//V0
-0.5.0.5.1.0.1.0.0.0.1.0.//V1
0.5.0.5.1.0.0.0.0.0.1.0.//V2
0.5, -0.5.1.0.1.0.0.0.1.0.//v3
-0.5, -0.5.0.0.1.0.0.0.1.0,]);// Create a vertex buffer object
let vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);
const indexes = new Uint8Array([0.1.2.0.2.3]);
// Create an index buffer object
var indexesBuffer = gl.createBuffer();
// Bind the buffer object
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexesBuffer);
// Index array indexes data is passed into the buffer
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indexes, gl.STATIC_DRAW);
let a_Position = gl.getAttribLocation(program, 'a_Position');
let a_Color = gl.getAttribLocation(program, 'a_Color');
gl.enableVertexAttribArray(a_Position);
gl.enableVertexAttribArray(a_Color);
// Sets how the a_Position property reads data from the buffer
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false.24.0);
// Sets how the a_Color property reads data from the buffer
gl.vertexAttribPointer(a_Color, 4, gl.FLOAT, false.24.8);
return indexes.length;
}
Copy the code
- Draw the way
So, say, say, say, say, say, say, say, say, say, say, say, say, say, say, say, say, say, say, say, say, say, say, say, say, say, say, say, say, say, say, say, say, say.Copy the code
The renderings are as follows:
reference
WebGL Zero Basic Tutorial (Guo Longbang); Introduction to WebGL and Practice WebGL official documentation