JavaScript-WebGL2学习笔记

在前一篇WebGL的基础上修改了代码,使之符合WebGL2规范。

<html>
<head>
    <!--
        Date: 2018-3-16
        Author: kagula
        Prologue:
        WebGL2的例子
        Prologue:

        Description:
        網上太多WebGL資料,爲了避免混肴,我們在原本WebGL的基礎上瞭解WebGL2, 這裏還是用兩個三角形拼出一個彩色的正方形.

        Original:
        [1]https://my.oschina.net/thesadabc/blog/1592866

        測試環境
        [1]Chrome 65.0.3325.162
        [2]nginx  1.12.2
    -->
    <title>第一个Webgl2程序</title>

    <meta charset="utf-8">
    <!-- gl-matrix version 2.4.0 from http://glmatrix.net/ -->
    <script type="text/javascript" src="/gl-matrix-min.js"></script>

    <script type="text/javascript" src="/kagula/webgl_helper.js"></script>
</head>

<body>
    <canvas id="glCanvas" width="640" height="480"></canvas>
</body>

</html>

<script>
    main();

    //弄4个顶点, 4個顔色, 用来演示render流程!
    function initBuffers(gl) {
        // Create a buffer for the square's positions.
        const positionBuffer = gl.createBuffer();

        // Select the positionBuffer as the one to apply buffer
        // operations to from here out.
        gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);

        // Now create an array of positions for the square.
        const positions = [
           1.0, 1.0,
          -1.0, 1.0,
           1.0, -1.0,
          -1.0, -1.0,
        ];

        // Now pass the list of positions into WebGL to build the
        // shape. We do this by creating a Float32Array from the
        // JavaScript array, then use it to fill the current buffer.
        gl.bufferData(gl.ARRAY_BUFFER,
                      new Float32Array(positions),
                      gl.STATIC_DRAW);

        //給每個頂點弄一個顔色
        const colors = [
        1.0, 1.0, 1.0, 1.0,    // white
        1.0, 0.0, 0.0, 1.0,    // red
        0.0, 1.0, 0.0, 1.0,    // green
        0.0, 0.0, 1.0, 1.0,    // blue
        ];

        const colorBuffer = gl.createBuffer();//创建gl缓存,但是不指定缓存类型.
        gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);//指定olorBuffer的类型为gl.ARRAY_BUFFER
        //缓冲区对象中的数据只指定1次,但是常常使用。这种模式下,OpenGL会将数据放在能够快速渲染的地方。
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);

        return {
            position: positionBuffer,
            color: colorBuffer,
        };
    }
    
    function main() {
        //选择器的使用
        //http://www.runoob.com/jsref/met-document-queryselector.html
        const canvas = document.querySelector("#glCanvas");

        // Initialize the GL context
        //為了获取WebGL2上下文,getContext方法传入的参数是"webgl2",而不是"webgl".
        const gl = canvas.getContext("webgl2");

        // Only continue if WebGL is available and working
        if (!gl) {
            alert("Unable to initialize WebGL. Your browser or machine may not support it.");
            return;
        }

        //OpenGL ES 3.0 不支持多维数组
        //對傳入的數組大小有限制
        console.log("gl.MAX_VERTEX_UNIFORM_VECTORS=" + gl.MAX_VERTEX_UNIFORM_VECTORS + ", gl.MAX_FRAGMENT_UNIFORM_VECTORS=" + gl.MAX_FRAGMENT_UNIFORM_VECTORS);

        // Vertex shader program
        //WebGL2的着色器语言支持原本WebGL1的GLSL 100 ,同时也支持GLSL 300 es
        //要使用GLSL 300 es,需要在着色器代码中显示声明
        //版本声明的代码需要在顶点着色器和片元着色器中同时指定, 版本声明的代码必须严格在第一行.   
        //在webgl 1.0中 attribute表示输入,varying表示輸入輸出.
        //現在要改爲用/in out标记輸入,输出.
        const vsSource = `#version 300 es
        in vec4 aVertexPosition;
        in vec4 aVertexColor;//从外部拿到颜色,不做任何处理,丢给vColor.

        uniform mat4 uModelViewMatrix;
        uniform mat4 uProjectionMatrix;

        //从aVertexColor拿到的颜色直接给vColor,
        //由vColor传给Fragment Shader.
        out lowp vec4 vColor;

        void main() {
          gl_Position = uProjectionMatrix * uModelViewMatrix * aVertexPosition;
          vColor = aVertexColor;//什么都不做,只是为了把从外部得到的color传递给Fragment Shader.
        }
        `;

        // Fragment shader, 相当于pixel shader  
        //varying被in代替
        //在GLSL 100 中,我们通过给内置变量gl_FragColor赋值来设置片元的输出颜色
        //而在GLSL 300 es中,需要自己定义一个输出颜色的变量,并在main函数中设置颜色值
        const fsSource = `#version 300 es
        precision highp float;//必須要為float類型指定精度                              
        in lowp vec4 vColor;//从vertex shader得到的颜色放在这里。
        out vec4 myOutputColor;
        void main() {
          myOutputColor = vColor;
        }
        `;

        //装配shader到shaderProgram中去
        const shaderProgram = initShaderProgram(gl, vsSource, fsSource);

        //为了让外部的数据能统一传到shanderProgram中去,新建programInfo对象。
        //vertexPosition => aVertexPosition位置
        //projectionMatrix => uProjectionMatrix位置
        //modelViewMatrix => uModelViewMatrix位置
        //...
        const programInfo = {
            program: shaderProgram,
            attribLocations: {
                vertexPosition: gl.getAttribLocation(shaderProgram, 'aVertexPosition'),
                vertexColor: gl.getAttribLocation(shaderProgram, 'aVertexColor'),
            },
            uniformLocations: {
                projectionMatrix: gl.getUniformLocation(shaderProgram, 'uProjectionMatrix'),
                modelViewMatrix: gl.getUniformLocation(shaderProgram, 'uModelViewMatrix'),
            },
        };

        //initBuffers(gl)返回要render的vertex.
        drawScene(gl, programInfo, initBuffers(gl));
    }//main
</script>

猜你喜欢

转载自blog.csdn.net/lee353086/article/details/79610125