• WebGL学习笔记(三):绘制一个三角形


      1 <!DOCTYPE html>
      2 <html lang="en">
      3 
      4 <head>
      5     <meta charset="UTF-8">
      6     <meta name="viewport" content="width=device-width, initial-scale=1.0">
      7     <meta http-equiv="X-UA-Compatible" content="ie=edge">
      8     <title>WebGL</title>
      9 
     10     <!-- 顶点着色器 -->
     11     <script id="shader-vs" type="x-shader/x-vertex">
     12         attribute vec3 aVertexPosition;
     13 
     14         void main() {
     15             // 直接将外部传入的顶点坐标作为最终坐标
     16             gl_Position = vec4(aVertexPosition, 1.0);
     17         }
     18     </script>
     19 
     20     <!-- 片段着色器 -->
     21     <script id="shader-fs" type="x-shader/x-fragment">
     22         // 设定 float 的精度, 这里我们使用中等精度
     23         precision mediump float;
     24 
     25         void main() {
     26             // 输出为纯白色
     27             gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
     28         }
     29     </script>
     30 
     31     <script>
     32         var gl;
     33         var canvas;
     34         var shaderProgram;
     35         var vertexBuffer;
     36 
     37         function createGLContext(canvas) {
     38             var names = ["webgl", "experimental-webgl"];
     39             var context = null;
     40             for (var i = 0; i < names.length; i++) {
     41                 try {
     42                     context = canvas.getContext(names[i]);
     43                 } catch (e) { }
     44                 if (context) {
     45                     break;
     46                 }
     47             }
     48             if (context) {
     49                 // 添加动态属性记录画布的大小
     50                 context.viewportWidth = canvas.width;
     51                 context.viewportHeight = canvas.height;
     52             } else {
     53                 alert("Failed to create WebGL context!");
     54             }
     55             return context;
     56         }
     57 
     58         function setupShaders() {
     59             // 从 DOM 上创建对应的着色器
     60             vertexShader = loadShaderFromDOM("shader-vs");
     61             fragmentShader = loadShaderFromDOM("shader-fs");
     62 
     63             // 创建程序并连接着色器
     64             shaderProgram = gl.createProgram();
     65             gl.attachShader(shaderProgram, vertexShader);
     66             gl.attachShader(shaderProgram, fragmentShader);
     67             gl.linkProgram(shaderProgram);
     68 
     69             // 连接失败的检测
     70             if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
     71                 alert("Failed to setup shaders");
     72             }
     73 
     74             // 使用着色器
     75             gl.useProgram(shaderProgram);
     76 
     77             // 创建动态属性获取着色器中 aVertexPosition 属性的位置
     78             shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
     79         }
     80 
     81         function loadShaderFromDOM(id) {
     82             // 获取 DOM
     83             var shaderScript = document.getElementById(id);
     84 
     85             if (!shaderScript) {
     86                 return null;
     87             }
     88 
     89             // 获取着色器代码
     90             var shaderSource = "";
     91             var currentChild = shaderScript.firstChild;
     92             while (currentChild) {
     93                 if (currentChild.nodeType == 3) { // 3 corresponds to TEXT_NODE
     94                     shaderSource += currentChild.textContent;
     95                 }
     96                 currentChild = currentChild.nextSibling;
     97             }
     98 
     99             // 创建着色器
    100             var shader;
    101             if (shaderScript.type == "x-shader/x-fragment") {
    102                 shader = gl.createShader(gl.FRAGMENT_SHADER);
    103             } else if (shaderScript.type == "x-shader/x-vertex") {
    104                 shader = gl.createShader(gl.VERTEX_SHADER);
    105             } else {
    106                 return null;
    107             }
    108 
    109             // 编译着色器
    110             gl.shaderSource(shader, shaderSource);
    111             gl.compileShader(shader);
    112 
    113             // 判断编译是否成功
    114             if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
    115                 alert(gl.getShaderInfoLog(shader));
    116                 return null;
    117             }
    118             return shader;
    119         }
    120 
    121         function setupBuffers() {
    122             // 创建顶点缓冲
    123             vertexBuffer = gl.createBuffer();
    124             // 绑定顶点缓冲
    125             gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
    126             // 定义顶点数据
    127             var triangleVertices = [
    128                 0.0, 0.5, 0.0,
    129                 -0.5, -0.5, 0.0,
    130                 0.5, -0.5, 0.0
    131             ];
    132             // 提交顶点数据
    133             gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(triangleVertices), gl.STATIC_DRAW);
    134             vertexBuffer.itemSize = 3;
    135             vertexBuffer.numberOfItems = 3;
    136         }
    137 
    138         function draw() {
    139             // 设置视口大小, 使用像素, 调整该大小不影响显示内容,只影响图像在 Canvas 上显示的位置和尺寸
    140             gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
    141             // 清除颜色缓冲
    142             gl.clear(gl.COLOR_BUFFER_BIT);
    143             // 将提交的顶点数据绑定到着色器的 aVertexPosition 属性
    144             gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, vertexBuffer.itemSize, gl.FLOAT, false, 0, 0);
    145             // 开启属性 aVertexPosition 的使用
    146             gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);
    147             // 绘制图像
    148             gl.drawArrays(gl.TRIANGLES, 0, vertexBuffer.numberOfItems);
    149         }
    150 
    151         function startup() {
    152             canvas = document.getElementById("myGLCanvas");
    153             gl = createGLContext(canvas);
    154             setupShaders();
    155             setupBuffers();
    156             // 定义清除颜色缓冲之后的填充色为黑色
    157             gl.clearColor(0.0, 0.0, 0.0, 1.0);
    158             draw();
    159         }
    160     </script>
    161 </head>
    162 
    163 <body onload="startup();">
    164     <canvas id="myGLCanvas" width="500" height="500"></canvas>
    165 </body>
    166 
    167 </html>
  • 相关阅读:
    推荐几款很棒的 JavaScript 表单美化和验证插件
    开源来自百度商业前端数据可视化团队的超漂亮动态图表--ECharts
    两种高性能 I/O 设计模式 Reactor 和 Proactor
    基本排序算法:Python实现
    局域网聊天软件(winsocket)
    MFC控件(8):command button与syslink control
    Linux python2.4升级到2.7
    调色板QPalette类用法详解(附实例、源码)(很清楚:窗口背景色 前景色 按钮的颜色 按钮文本的颜色 )
    在IT公司,project manager 基本上和秘书,助理什么的差不多
    Qt之OpenSSL(有pro文件的路径格式,以及对libeay32和ssleay32的引用)
  • 原文地址:https://www.cnblogs.com/hammerc/p/11201022.html
Copyright © 2020-2023  润新知