• WebGL入门学习:绘制圆锥


    1、圆锥的几何构造

    从上面看:是一个圆,严格说是一个正N多边形,N值越大,越接近圆。绘制时要用三角函数计算正N多边形的N个顶点坐标。

     从侧面看是个三角形:最下面是一个顶点,和上面的正N多边形顶点相连构成圆锥网格。

    2、WebGL代码实现

    1)顶点着色器:

    const VSHADER_SOURCE = `
      attribute vec4 a_Position;
      attribute vec4 a_Color;
      uniform mat4 u_MvpMatrix;
      varying vec4 v_Color;
      void main() {
        gl_Position = u_MvpMatrix * a_Position;
        v_Color = a_Color;
      }`;
    

    2)片元着色器:

    const FSHADER_SOURCE = `
      #ifdef GL_ES
      precision mediump float;
      #endif
      varying vec4 v_Color;
      void main() {
        gl_FragColor = v_Color;
      }`;
    

      

    3)初始化顶点坐标缓冲区

    function initVertexBuffers(gl) {
      let radius = 1;
      let height = 2;
      let divideNum = 60;
      let theta = Math.PI * 2 / divideNum;
    
      /**
       *  
       *      4
       *   /    
       * 3        1
       *        /
       *     2 /
       *     /
       */    0
      let vertices = [0, -height / 2, 0];
      for (let i = 0; i < divideNum; i++) {
        let x = radius * Math.cos(theta * i);
        let z = radius * Math.sin(theta * i);
        vertices.push(x, height / 2, z);
      }
    
    
      let colors = [];
      let baseColor = [[1.0, 0.4, 0.4], [0.4, 1.0, 0.4], [0.4, 0.4, 1.0], [0.2, 0.4, 0.0], [0.4, 0.3, 0.8],[0.8, 1, 0.1] ];
    
      colors.push(1.0, 0.4, 0.4);
      for(let i=1; i<vertices.length; i++) {
        // let color = baseColor[Math.floor(Math.random()*6)];
        // colors = colors.concat(color);
        colors.push(0.4, 1.0, 0.4);
      }
    
    
      let indices = [];
      for(let i=1; i<=divideNum; i++) {
        if(i===divideNum){
          indices.push(0, i, 1);
        }else{
          indices.push(0, i, i+1);
        }
      }
    
      vertices = Float32Array.from(vertices);
      colors = Float32Array.from(colors);
      indices = Uint8Array.from(indices);
    
    
      // Create a buffer object
      var indexBuffer = gl.createBuffer();
      if (!indexBuffer)
        return -1;
    
      // Write the vertex coordinates and color to the buffer object
      if (!initArrayBuffer(gl, vertices, 3, gl.FLOAT, 'a_Position'))
        return -1;
    
      if (!initArrayBuffer(gl, colors, 3, gl.FLOAT, 'a_Color'))
        return -1;
    
      // Write the indices to the buffer object
      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) {
      var buffer = gl.createBuffer();   // Create a buffer object
      if (!buffer) {
        console.log('Failed to create the buffer object');
        return false;
      }
      // Write date into the buffer object
      gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
      gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW);
      // Assign the buffer object to the attribute variable
      var a_attribute = gl.getAttribLocation(gl.program, attribute);
      if (a_attribute < 0) {
        console.log('Failed to get the storage location of ' + attribute);
        return false;
      }
      gl.vertexAttribPointer(a_attribute, num, type, false, 0, 0);
      // Enable the assignment of the buffer object to the attribute variable
      gl.enableVertexAttribArray(a_attribute);
    
      return true;
    }
    

      

    3)初始化WebGL上下文,绘制圆锥

    function main() {
      // Retrieve <canvas> element
      var canvas = document.getElementById('webgl');
    
      // Get the rendering context for WebGL
      var gl = getWebGLContext(canvas);
      if (!gl) {
        console.log('Failed to get the rendering context for WebGL');
        return;
      }
    
      // Initialize shaders
      if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
        console.log('Failed to intialize shaders.');
        return;
      }
    
      // Set the vertex information
      var n = initVertexBuffers(gl);
      if (n < 0) {
        console.log('Failed to set the vertex information');
        return;
      }
    
      // Set the clear color and enable the depth test
      gl.clearColor(0.0, 0.0, 0.0, 1.0);
      gl.enable(gl.DEPTH_TEST);
    
      // Get the storage location of u_MvpMatrix
      var u_MvpMatrix = gl.getUniformLocation(gl.program, 'u_MvpMatrix');
      if (!u_MvpMatrix) {
        console.log('Failed to get the storage location of u_MvpMatrix');
        return;
      }
    
      // Set the eye point and the viewing volume
      var mvpMatrix = new Matrix4();
      mvpMatrix.setPerspective(30, 1, 1, 100);
      // mvpMatrix.lookAt(0, 2, 8, 0, 0, 0, 0, 2, 0);
      // mvpMatrix.lookAt(0, 6, 0, 0, 0, 0, 0, 0, -2);  //view from top
      // mvpMatrix.lookAt(0, 1, 5, 0, 0, 0, 0, 1, 0);    //view from front
      mvpMatrix.lookAt(0, 2, 5, 0, 0, 0, 0, 1, 0);    //view from front and more high
      // Pass the model view projection matrix to u_MvpMatrix
      gl.uniformMatrix4fv(u_MvpMatrix, false, mvpMatrix.elements);
    
      // Clear color and depth buffer
      gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
    
      // Draw the cube
      // gl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_BYTE, 0);
      gl.drawElements(gl.LINE_LOOP, n, gl.UNSIGNED_BYTE, 0);
    }
    

      

    4)HTML文件,这里的部分WebGL封装代码引用之《WebGL编程指南》

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="utf-8" />
        <title>Cone</title>
      </head>
      <body onload="main()">
        <canvas id="webgl" width="400" height="400">
        Please use a browser that supports "canvas"
        </canvas>
     
        <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 src="cone.js"></script>
      </body>
    </html>
    

      

     3、效果展示:

     

  • 相关阅读:
    近期文章与教程和其他情况说明
    Python从入门到精通--课程目录
    第四天:创建型模式--原型模式
    python api链接数据库
    Delphi 实现简易语音发音(基于TTS方式)
    delphi下运行vbscript脚本
    使用PaxScript为Delphi应用增加对脚本的支持
    delphi与javascript互通
    奇技淫巧之Delphi和JavaScript互通
    在delphi中执行javascript代码
  • 原文地址:https://www.cnblogs.com/davidxu/p/13797957.html
Copyright © 2020-2023  润新知