zoukankan      html  css  js  c++  java
  • WEBGL学习【七】画布绘图

    主要是对WEBGL的绘图部分进行了进一步加强的认识和理解

    <!DOCTYPE HTML>
    <html lang="en">
    <head>
        <title>WEBGL高级编程----绘制六边形</title>
        <meta charset="utf-8">
        <script id="shader-vs" type="x-shader/x-vertex">
          attribute vec3 aVertexPosition;
          attribute vec4 aVertexColor;
          varying vec4 vColor;
    
          void main() {
            vColor = aVertexColor;
            gl_Position = vec4(aVertexPosition, 1.0);
          }
    
        </script>
    
        <script id="shader-fs" type="x-shader/x-fragment">
          precision mediump float;
    
          varying vec4 vColor;
          void main() {
            gl_FragColor = vColor;
          }
    
        </script>
    
        <!--引入我的库文件-->
        <script src="./lib/webgl-debug.js"></script>
    
        <script type="text/javascript">
            var gl;
            var canvas;
            var shaderProgram;
            //六边形顶点缓冲区
            var hexagonVertexBuffer;
            //坐标系缓冲区
            var xyCordBuffer;
            //三角形顶点位置缓冲区
            var triangleVertexBuffer;
            var triangleVertexBufferTwo;
            //三角形颜色缓冲区
            var triangleVertexColorBuffer;
            //三角形带1
            var stripVertexBuffer;
    
            //创建我的上下文句柄
            function createGLContext(canvas) {
                var names = ["webgl", "experimental-webgl"];
                var context = null;
                for (var i = 0; i < names.length; i++) {
                    try {
                        context = canvas.getContext(names[i]);
                    } catch (e) {
                    }
                    if (context) {
                        break;
                    }
                }
                if (context) {
                    context.viewportWidth = canvas.width;
                    context.viewportHeight = canvas.height;
                } else {
                    alert("Failed to create WebGL context!");
                }
                return context;
            }
    
            //JavaScript代码中通过DOM加载着色器
            function loadShaderFromDOM(id) {
                var shaderScript = document.getElementById(id);
    
                // If we don't find an element with the specified id
                // we do an early exit
                if (!shaderScript) {
                    return null;
                }
    
                // Loop through the children for the found DOM element and
                // build up the shader source code as a string
                var shaderSource = "";
                var currentChild = shaderScript.firstChild;
                while (currentChild) {
                    if (currentChild.nodeType == 3) { // 3 corresponds to TEXT_NODE
                        shaderSource += currentChild.textContent;
                    }
                    currentChild = currentChild.nextSibling;
                }
    
                var shader;
                if (shaderScript.type == "x-shader/x-fragment") {
                    shader = gl.createShader(gl.FRAGMENT_SHADER);
                } else if (shaderScript.type == "x-shader/x-vertex") {
                    shader = gl.createShader(gl.VERTEX_SHADER);
                } else {
                    return null;
                }
    
                gl.shaderSource(shader, shaderSource);
                gl.compileShader(shader);
    
                if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
                    alert(gl.getShaderInfoLog(shader));
                    return null;
                }
                return shader;
            }
    
            //设置我的着色器
            function setupShaders() {
                var vertexShader = loadShaderFromDOM("shader-vs");
                var fragmentShader = loadShaderFromDOM("shader-fs");
    
                shaderProgram = gl.createProgram();
                gl.attachShader(shaderProgram, vertexShader);
                gl.attachShader(shaderProgram, fragmentShader);
                gl.linkProgram(shaderProgram);
    
                if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
                    alert("Failed to setup shaders");
                }
    
                gl.useProgram(shaderProgram);
    
                shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
                shaderProgram.vertexColorAttribute = gl.getAttribLocation(shaderProgram, "aVertexColor");
    
                gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);
            }
    
            //设置我的缓冲区
            function setupBuffers() {
                //创建六边形
                hexagonVertexBuffer = gl.createBuffer();
                gl.bindBuffer(gl.ARRAY_BUFFER, hexagonVertexBuffer);
                var hexagonVertices = [
                    -0.3, 0.6, 0.0, //v0
                    -0.4, 0.8, 0.0, //v1
                    -0.6, 0.8, 0.0, //v2
                    -0.7, 0.6, 0.0, //v3
                    -0.6, 0.4, 0.0, //v4
                    -0.4, 0.4, 0.0, //v5
                    -0.3, 0.6, 0.0, //v6
                ];
                gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(hexagonVertices), gl.STATIC_DRAW);
                hexagonVertexBuffer.itemSize = 3;
                hexagonVertexBuffer.numberOfItems = 7;
    
    
    
                //绘制一个坐标系
                xyCordBuffer = gl.createBuffer();
                gl.bindBuffer(gl.ARRAY_BUFFER, xyCordBuffer);
                var xyCordVertices = [
                    -1.0, 0.0, 0.0,
                    1.0, 0.0, 0.0,
                    0.0, -1.0, 0.0,
                    0.0, 1.0, 0.0
                ];
                gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(xyCordVertices), gl.STATIC_DRAW);
                xyCordBuffer.itemSize = 3;
                xyCordBuffer.numberOfItems = 4;
    
    
                //绘制一个三角形
                triangleVertexBuffer = gl.createBuffer();
                gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexBuffer);
                var triangleVertices = [
                    0.3, 0.4, 0.0, //v0
                    0.7, 0.4, 0.0, //v1
                    0.5, 0.8, 0.0, //v2
                ];
                gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(triangleVertices), gl.STATIC_DRAW);
                triangleVertexBuffer.itemSize = 3;
                triangleVertexBuffer.numberOfItems = 3;
    
                //绘制一个三角形
                triangleVertexBufferTwo = gl.createBuffer();
                gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexBufferTwo);
                var triangleVerticesTwo = [
                    0.0, 0.2, 0.0, //v0
                    -0.2, -0.2, 0.0, //v1
                    0.2, -0.2, 0.0, //v2
                ];
                gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(triangleVerticesTwo), gl.STATIC_DRAW);
                triangleVertexBufferTwo.itemSize = 3;
                triangleVertexBufferTwo.numberOfItems = 3;
    
                //创建三角形颜色数组
                triangleVertexColorBuffer = gl.createBuffer();
                gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexColorBuffer);
                var colors = [
                    1.0, 0.0, 0.0, 1.0, //v0
                    0.0, 1.0, 0.0, 1.0, //v1
                    0.0, 0.0, 1.0, 1.0  //v2
                ];
                gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
                triangleVertexColorBuffer.itemSize = 4;
                triangleVertexColorBuffer.numberOfItems = 3;
    
                //绘制一个三角形带1
                stripVertexBuffer = gl.createBuffer();
                gl.bindBuffer(gl.ARRAY_BUFFER, stripVertexBuffer);
                //绘制两条
                var stripVertices = [
                    -0.5, 0.2, 0.0, //v0
                    -0.4, 0.0, 0.0, //v1
                    -0.3, 0.2, 0.0, //v2
                    -0.2, 0.0, 0.0, //v3
                    -0.1, 0.2, 0.0, //v4
                    0.0, 0.0, 0.0, //v5
                    0.1, 0.2, 0.0, //v6
                    0.2, 0.0, 0.0, //v7
                    0.3, 0.2, 0.0, //v8
                    0.4, 0.0, 0.0, //v9
                    0.5, 0.2, 0.0, //v10
    
                    // start second strip
                    -0.5, -0.3, 0.0, //v11
                    -0.4, -0.5, 0.0, //v12
                    -0.3, -0.3, 0.0, //v13
                    -0.2, -0.5, 0.0, //v14
                    -0.1, -0.3, 0.0, //v15
                    0.0, -0.5, 0.0, //v16
                    0.1, -0.3, 0.0, //v17
                    0.2, -0.5, 0.0, //v18
                    0.3, -0.3, 0.0, //v19
                    0.4, -0.5, 0.0, //v20
                    0.5, -0.3, 0.0  //v21
                ];
                gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(stripVertices), gl.STATIC_DRAW);
                stripVertexBuffer.itemSize = 3;
                stripVertexBuffer.numberOfItems = 22;
    
                //创建三角形条带缓冲区(元素数组缓冲)
                stripElementBuffer = gl.createBuffer();
                gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, stripElementBuffer);
                //注意顶点索引的数量与【组绕顺序】有关,默认是逆时针方向为正方向
                //【记住:如果三角形数量为奇数,就必须增加三个索引,从而会出现5个退化三角形;
                //      如果三角形数量为偶数,就必须增加两个索引, 从而会出现4个退化三角形;
                //      否则,就会出现组绕三角形的逆时针/顺时针混乱的问题【记住了嘛?】
                //             var indices = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
                    10, 11, 11,// 3 extra indices for the degenerate triangles(这里共计有五个退化了的三角形)
                    11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21];
    
                gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
    
                stripElementBuffer.numberOfItems = 25;
            }
    
    
    
            //绘图函数
            function draw() {
                //设置视口,清空深度缓存
                gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
                gl.clear(gl.COLOR_BUFFER_BIT);
    
                // Draw the hexagon
                // We disable the vertex attrib array since we want to use a
                // constant color for all vertices in the hexagon
                //将顶点的颜色设置为一个常量
                gl.disableVertexAttribArray(shaderProgram.vertexColorAttribute);
                //将顶点颜色设置为黑色
                gl.vertexAttrib4f(shaderProgram.vertexColorAttribute, 0.0, 0.0, 1.0, 1.0);
                //把六边形的坐标传给顶点着色器
                gl.bindBuffer(gl.ARRAY_BUFFER, hexagonVertexBuffer);
                gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute,
                    hexagonVertexBuffer.itemSize, gl.FLOAT, false, 0, 0);
                //绘制首尾相连的图形
                gl.drawArrays(gl.LINE_STRIP, 0, hexagonVertexBuffer.numberOfItems);
    
    
                //开始传值到顶点着色器
                gl.disableVertexAttribArray(shaderProgram.vertexColorAttribute);
                //这里可以给我的坐标系指定一个常量颜色(红色)
                gl.vertexAttrib4f(shaderProgram.vertexColorAttribute, 1.0, 0.0, 0.0, 1.0);
                gl.bindBuffer(gl.ARRAY_BUFFER, xyCordBuffer);
                gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute,
                    xyCordBuffer.itemSize, gl.FLOAT, false, 0, 0);
                gl.drawArrays(gl.LINES, 0, xyCordBuffer.numberOfItems);
    
    
                //绘制三角形(如果要从一个颜色数组去设置顶点的颜色这里需要开启,如果要通过常量去设置颜色,这里就需要关闭)
                gl.disableVertexAttribArray(shaderProgram.vertexColorAttribute);
                gl.vertexAttrib4f(shaderProgram.vertexColorAttribute, 0.0, 1.0, 0.0, 1.0);
                gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexBuffer);
                //每一个位置信息需要triangleVertexBuffer.itemSize个参数信息来表示
                gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute,
                    triangleVertexBuffer.itemSize, gl.FLOAT, false, 0, 0);
                gl.drawArrays(gl.TRIANGLES, 0, triangleVertexBuffer.numberOfItems);
    
                //再次绘制一个三角形(用颜色数组来绘制)
                gl.enableVertexAttribArray(shaderProgram.vertexColorAttribute);
                //传递顶点位置
                gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexBufferTwo);
                gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute,
                    triangleVertexBufferTwo.itemSize, gl.FLOAT, false, 0, 0);
                //传递顶点颜色
                gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexColorBuffer);
                gl.vertexAttribPointer(shaderProgram.vertexColorAttribute,
                    triangleVertexColorBuffer.itemSize, gl.FLOAT, false, 0, 0);
                gl.drawArrays(gl.TRIANGLES, 0, triangleVertexBuffer.numberOfItems);
    
                //开始绘制三角形带1
                /*gl.disableVertexAttribArray(shaderProgram.vertexColorAttribute);
                gl.bindBuffer(gl.ARRAY_BUFFER, stripVertexBuffer);
                gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute,
                    stripVertexBuffer.itemSize, gl.FLOAT, false, 0, 0);
                gl.vertexAttrib4f(shaderProgram.vertexColorAttribute, 1.0, 1.0, 0.0, 1.0);
                gl.drawArrays(gl.TRIANGLES, 0, stripVertexBuffer.numberOfItems);*/
    
                //begin to drawElements()
                //first put the vertexBuffer to the shader
                gl.disableVertexAttribArray(shaderProgram.vertexColorAttribute);
                gl.bindBuffer(gl.ARRAY_BUFFER, stripVertexBuffer);
                gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute,
                    stripVertexBuffer.itemSize, gl.FLOAT, false, 0, 0);
                gl.vertexAttrib4f(shaderProgram.vertexColorAttribute, 1.0, 1.0, 0.0, 1.0);
                gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, stripElementBuffer);
                gl.drawElements(gl.TRIANGLE_STRIP, stripElementBuffer.numberOfItems, gl.UNSIGNED_SHORT, 0);
    
    
                //set the color of help line(black color )
                gl.vertexAttrib4f(shaderProgram.vertexColorAttribute, 1.0, 0.0, 0.0, 1.0);
                // Draw help lines to easier see the triangles
                // that build up the triangle-strip
                gl.drawArrays(gl.LINE_STRIP, 0, 11);
                gl.drawArrays(gl.LINE_STRIP, 11, 11);
            }
    
            function startup() {
                canvas = document.getElementById("myGLCanvas");
                gl = WebGLDebugUtils.makeDebugContext(createGLContext(canvas));
                setupShaders();
                setupBuffers();
                gl.clearColor(1.0, 1.0, 1.0, 1.0);
    
    
                //逆时针方向是前面
                gl.frontFace(gl.CW);
                //激活背面剔除功能
                gl.enable(gl.CULL_FACE);
                //WEBGL剔除背面三角形
                gl.cullFace(gl.FRONT);
    
                draw();
            }
        </script>
    
    </head>
    
    <body onload="startup();">
    <canvas id="myGLCanvas" width="500" height="500" style="border: 2px solid springgreen;"></canvas>
    </body>
    
    </html>
    

  • 相关阅读:
    201521123065《java程序设计》第14周学习总结
    201521123065《java程序设计》第13周学习总结
    201521123065《java程序设计》第12周学习总结
    选择器
    浮动布局
    定位布局—position
    软工个人总结
    个人作业4——alpha阶段个人小结
    软件工程个人作业3
    结队编程
  • 原文地址:https://www.cnblogs.com/52tech/p/9325118.html
Copyright © 2011-2022 走看看