Vue与WebGL结合--MVP矩阵

12 篇文章 1 订阅

本文主要介绍MVP矩阵,MVP矩阵实际上是由模型矩阵、视图矩阵以及投影矩阵组合而成,主要用于调整模型位置、观察模型位置以及相机投影信息。文中部分代码源自《WebGL编程指南》。

代码如下:

<template>
  <div>
    <canvas ref="myglCanvas" width="400" height="400"></canvas>
  </div>
</template>

<script>
import Tools from "../lib/tools";
export default {
  name: "glCanvas",
  data() {
    return {
      VSHEADER_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;
                        }`,
      FSHEADER_SOURCE: `precision mediump float;
                        varying vec4 v_color;
                        void main(){
                        gl_FragColor = v_color;
                        }`,

      gl: null
    };
  },
  methods: {
    setBufferAndMatrix: function(gl) {
      let verticesColors = new Float32Array([
        0.0,  1.0,  -4.0,  0.4,  1.0,  0.4, // The back green one
        -0.5, -1.0,  -4.0,  0.4,  1.0,  0.4,
        0.5, -1.0,  -4.0,  1.0,  0.4,  0.4, 

        0.0,  1.0,  -2.0,  1.0,  1.0,  0.4, // The middle yellow one
        -0.5, -1.0,  -2.0,  1.0,  1.0,  0.4,
        0.5, -1.0,  -2.0,  1.0,  0.4,  0.4, 

        0.0,  1.0,   0.0,  0.4,  0.4,  1.0,  // The front blue one 
        -0.5, -1.0,   0.0,  0.4,  0.4,  1.0,
        0.5, -1.0,   0.0,  1.0,  0.4,  0.4, 
      ]);
      let n = 9;

      // Create a buffer object
      let vertexColorbuffer = gl.createBuffer();
      if (!vertexColorbuffer) {
        console.log("Failed to create the buffer object");
        return -1;
      }

      // Write the vertex information and enable it
      gl.bindBuffer(gl.ARRAY_BUFFER, vertexColorbuffer);
      gl.bufferData(gl.ARRAY_BUFFER, verticesColors, gl.STATIC_DRAW);

      let FSIZE = verticesColors.BYTES_PER_ELEMENT;

      this.initBuffer(gl,"a_Position",3,FSIZE*6,0);
      this.initBuffer(gl,"a_Color",3,FSIZE*6,FSIZE*3);

      this.setMatrix(gl);

      return n;
    },
    drawTriangles:function(gl){
        //设置缓冲区及矩阵
        let n = this.setBufferAndMatrix(gl);
        if(n<0){
            console.log("设置缓冲区错误");
            return;
        }

        gl.clearColor(0, 0, 0, 1);
        gl.clear(gl.COLOR_BUFFER_BIT);   // Clear <canvas>
        gl.drawArrays(gl.TRIANGLES, 0, n);   // Draw the triangles

    },
    setMatrix:function(gl){
        //获取着色器中的mvp矩阵变量
        let u_mvpMatrix = gl.getUniformLocation(gl.program, 'u_mvpMatrix');
      
        if (!u_mvpMatrix) { 
            console.log('获取着色器中的mvp矩阵变量错误');
            return;
        }

        //创建mvp三个矩阵
        let modelMatrix = mat4.create(); // 模型矩阵
        let viewMatrix = mat4.create(); // 视图矩阵
        let projMatrix = mat4.create();  // 投影矩阵

        //沿x轴平移0.75单位
        mat4.translate(modelMatrix, modelMatrix, [0.75,0,0]);
        //设置视图矩阵
        mat4.lookAt(viewMatrix, [0,0,5], [0,0,-100], [0,1,0]);

        //获取画布的宽高
        let canvasWidth = this.$refs.myglCanvas.width;
        let canvasHeight = this.$refs.myglCanvas.height;
       
        //将角度转为弧度
        const angleRad =30 * Math.PI / 180;
        //设置投影矩阵
        mat4.perspective(projMatrix, angleRad, canvasWidth/canvasHeight, 1, 100);
        //mvp矩阵
        let mv_Matrix = mat4.create();
        let mvp_Matrix = mat4.create();
        mat4.mul(mv_Matrix, viewMatrix,modelMatrix);
        mat4.mul(mvp_Matrix, projMatrix,mv_Matrix);
        
        //将mvp矩阵传递给着色器
        gl.uniformMatrix4fv(u_mvpMatrix,false,mvp_Matrix);  
    },
    /**
     * 初始化缓冲区
     * paramStr  变量名
     * count     对象个数
     * stride    步长
     * offset    偏移量
     */
    initBuffer:function(gl,paramStr,count,stride,offset){
      let a_param = this.gl.getAttribLocation(gl.program,paramStr);
      if (a_param < 0) { 
        console.log(paramStr+" failed");          
        return -1;
      }
      //  将缓冲区对象分配给attribute对象
      gl.vertexAttribPointer(a_param, count, gl.FLOAT, false, stride, offset);
      // 开启attribute对象
      gl.enableVertexAttribArray(a_param);

    },
    setGL: function() {
      this.gl = this.$refs.myglCanvas.getContext("webgl");
    }
  },
  mounted() {
    this.setGL();
    Tools.initShaders(this.gl, this.VSHEADER_SOURCE, this.FSHEADER_SOURCE);
    this.drawTriangles(this.gl);
  }
};
</script>

<style scoped>
</style>

15行 在顶点着色器中设置u_mvpMatrix变量;

80-115行 设置MVP矩阵信息,代码中的矩阵操作引用的是gl-martix库;不会配置的可以联系我。

运行代码,效果如下

更多内容请扫码关注我的微信公众号,或者在微信里搜索公众号webgis学习,我会不定期更新自己的web方面的学习心得。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值