29 WebGL Draws Cubes and Specifies Colors for Each Surface of Cubes

Vertex shader calculates vertex by vertex and receives vertex by vertex information. If we want to specify the color of the surface, we need to define the color to the vertex. For example, if we want to define a triangle as a color, we must have the color of all three vertices as a color.

But you will find that a vertex of a cube will be used in three faces, and defining a color will definitely affect the other side. To solve this problem, we need to create multiple vertices with the same vertex coordinates (although this will cause some redundancy).


In this case, the triangle list, i.e. the sequence of vertex index values, points to a different set of vertices for each face and does not share a vertex with the front surface and the upper surface. In this way, the aforementioned effect can be achieved, and different monochromes can be applied to each surface.



<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Title</title>
    <style>
        body {
            margin: 0;
            text-align: center;
        }

        #canvas {
            margin: 0;
        }
    </style>
</head>
<body onload="main()">
<canvas id="canvas" height="800" width="1200"></canvas>
</body>
<script src="lib/webgl-utils.js"></script>
<script src="lib/webgl-debug.js"></script>
<script src="lib/cuon-utils.js"></script>
<script src="lib/cuon-matrix.js"></script>
<script>
    //Vertex Shader
    var VSHADER_SOURCE = "" +
        "attribute vec4 a_Position;\n" +
        "attribute vec4 a_Color;\n" +
        "uniform mat4 u_ModelViewMatrix;\n" +
        "varying vec4 v_Color;\n" +
        "void main(){" +
        "   gl_Position = u_ModelViewMatrix * a_Position;\n" +
        "   v_Color = a_Color;\n" +
        "}\n";

    //Fragment Shader
    var FSHADER_SOURCE = "" +
        "#ifdef GL_ES\n" +
        "precision mediump float;\n" +
        "#endif\n" +
        "varying vec4 v_Color;\n" +
        "void main(){" +
        "   gl_FragColor = v_Color;\n" +
        "}\n";

    //Declare the relevant variables required by js
    var canvas = document.getElementById("canvas");
    var gl = getWebGLContext(canvas);

    function main() {
        if (!gl) {
            console.log("Your browser does not support it WebGL");
            return;
        }

        //Initialization shader
        if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
            console.log("Unable to initialize shader");
            return;
        }

        var n = initVertexBuffers(gl);
        if (n < 0) {
            console.log("Unable to create buffer");
            return;
        }

        //Information about setting perspective matrix
        var u_ModelViewMatrix = gl.getUniformLocation(gl.program, "u_ModelViewMatrix");
        if (u_ModelViewMatrix < 0) {
            console.log("Unable to obtain the storage location of matrix variables");
            return;
        }

        //Set the background color
        gl.clearColor(0.0, 0.0, 0.0, 1.0);

        //Initialization of Entry Scene
        draw(gl, n, u_ModelViewMatrix);
    }

    function draw(gl, n, u_ModelViewMatrix) {
        //Set up the relevant information of the view matrix (view, line of sight, top direction)
        var viewMatrix = new Matrix4();
        viewMatrix.setLookAt(3,3,7,0,0,0,0,1,0);

        //Setting up the Relevant Information of Model Matrix
        var modelMatrix = new Matrix4();
        modelMatrix.setRotate(0, 0, 0, 1);

        //Setting Perspective Projection Matrix
        var projMatrix = new Matrix4();
        projMatrix.setPerspective(30,canvas.width/canvas.height,1,100);

        //Calculate the model view matrix viewMatrix. multiply (model Matrix) equivalent to u_ViewMatrix * u_Model Matrix in the shader
        var modeViewMatrix = projMatrix.multiply(viewMatrix.multiply(modelMatrix));

        //Pass the attempt matrix to the u_ViewMatrix variable
        gl.uniformMatrix4fv(u_ModelViewMatrix, false, modeViewMatrix.elements);

        //Open Hidden Surface Clearance
        gl.enable(gl.DEPTH_TEST);

        //Clear the color and depth buffer
        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

        //Drawing Graphics
        gl.drawElements(gl.TRIANGLES,n,gl.UNSIGNED_BYTE,0);

    }

    function initVertexBuffers(gl) {
        // Create a cube
        //    v6----- v5
        //   /|      /|
        //  v1------v0|
        //  | |     | |
        //  | |v7---|-|v4
        //  |/      |/
        //  v2------v3

        var vertices = new Float32Array([   // Vertex position coordinate data
            1.0, 1.0, 1.0,  -1.0, 1.0, 1.0,  -1.0,-1.0, 1.0,   1.0,-1.0, 1.0,  // v0-v1-v2-v3 front
            1.0, 1.0, 1.0,   1.0,-1.0, 1.0,   1.0,-1.0,-1.0,   1.0, 1.0,-1.0,  // v0-v3-v4-v5 right
            1.0, 1.0, 1.0,   1.0, 1.0,-1.0,  -1.0, 1.0,-1.0,  -1.0, 1.0, 1.0,  // v0-v5-v6-v1 up
            -1.0, 1.0, 1.0,  -1.0, 1.0,-1.0,  -1.0,-1.0,-1.0,  -1.0,-1.0, 1.0,  // v1-v6-v7-v2 left
            -1.0,-1.0,-1.0,   1.0,-1.0,-1.0,   1.0,-1.0, 1.0,  -1.0,-1.0, 1.0,  // v7-v4-v3-v2 down
            1.0,-1.0,-1.0,  -1.0,-1.0,-1.0,  -1.0, 1.0,-1.0,   1.0, 1.0,-1.0   // v4-v7-v6-v5 back
        ]);

        var colors = new Float32Array([     // The color of the vertex
            0.4, 0.4, 0.4,  0.4, 0.4, 0.4,  0.4, 0.4, 0.4,  0.4, 0.4, 0.4,  // v0-v1-v2-v3 front(blue)
            0.9, 0.9, 0.9,  0.9, 0.9, 0.9,  0.9, 0.9, 0.9,  0.9, 0.9, 0.9,  // v0-v3-v4-v5 right(green)
            0.6, 0.6, 0.6,  0.6, 0.6, 0.6,  0.6, 0.6, 0.6,  0.6, 0.6, 0.6,  // v0-v5-v6-v1 up(red)
            0.1, 0.1, 0.1,  0.1, 0.1, 0.1,  0.1, 0.1, 0.1,  0.1, 0.1, 0.1,  // v1-v6-v7-v2 left
            0.5, 0.5, 0.5,  0.5, 0.5, 0.5,  0.5, 0.5, 0.5,  0.5, 0.5, 0.5,  // v7-v4-v3-v2 down
            0.8, 0.8, 0.8,  0.8, 0.8, 0.8,  0.8, 0.8, 0.8,  0.8, 0.8, 0.8   // v4-v7-v6-v5 back
        ]);

        var indices = new Uint8Array([       // Drawn Index
            0, 1, 2,   0, 2, 3,    // front
            4, 5, 6,   4, 6, 7,    // right
            8, 9,10,   8,10,11,    // up
            12,13,14,  12,14,15,    // left
            16,17,18,  16,18,19,    // down
            20,21,22,  20,22,23     // back
        ]);

        //Creating Buffer Objects
        initArrayBuffer(gl,vertices,3,gl.FLOAT,"a_Position");

        initArrayBuffer(gl,colors,3,gl.FLOAT,"a_Color");

        //Write vertex index data to buffer objects
        var indexBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,indexBuffer);
        gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,indices,gl.STATIC_DRAW);

        return indices.length;
    }

    function initArrayBuffer(gl,data,num,type,attribute) {
        //Creating Buffer Objects
        var buffer = gl.createBuffer();
        if (!buffer) {
            console.log("Buffer object cannot be created");
            return -1;
        }

        //Binding Buffer Objects and Writing Data
        gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
        gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW);

        //Getting the position of vertex position variable
        var a_attribue = gl.getAttribLocation(gl.program, attribute);
        if (a_attribue < 0) {
            console.log("Storage variable unable to obtain vertex location");
            return -1;
        }

        //Allocate the vertex data of the location and open it
        gl.vertexAttribPointer(a_attribue, num, type, false, 0, 0);
        gl.enableVertexAttribArray(a_attribue);
    }
</script>
</html>
Although this example uses gl.drawElements(), it uses 24 vertices. Using gl.drawArrays() draws 36 vertices. It doesn't seem to save much memory overhead. However, in actual production, it is worthwhile to use gl.drawElements().

In this way, we have achieved the drawing of the same color surface.



Keywords: Attribute IE Fragment

Added by lentin64 on Tue, 25 Jun 2019 20:45:24 +0300