Vue与WebGL结合--绘制不同大小的点

本文将点的尺寸变量传入顶点着色器,并将顶点坐标和尺寸数据存放在同一个缓冲区中进行渲染,达到绘制不同大小的点的目的,本文部分代码源自《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 float a_pointSize;
                        void main(){
                        gl_Position = a_Position;
                        gl_PointSize = a_pointSize;
                        }`,
      FSHEADER_SOURCE: `precision mediump float;                      
                        void main(){
                        gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
                        }`,
      gl: null   
    };
  },
  methods: {
    setBuffer: function(gl) {
      let vertices = new Float32Array([0, 0.5, 10.0,  //第一个点,前两个数字表示位置,第三个数字表示大小
                                       -0.5, -0.5,  20.0,
                                       0.5, -0.5,  30.0 ]);
      let n = 3; // 点的个数

     
      const fSize = vertices.BYTES_PER_ELEMENT;  //每个元素占的大小
      // 创建缓冲区
      let vertexBuffer = gl.createBuffer();
      if (!vertexBuffer) {
        console.log("Failed to create the buffer object");
        return -1;
      }

      // 绑定缓冲区
      gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
      // 将数据写入缓冲区
      gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

      let a_Position = gl.getAttribLocation(gl.program, "a_Position");
      if (a_Position < 0) {
         console.log("a_Position failed");       
        return -1;
      }

      let a_pointSize = this.gl.getAttribLocation(gl.program,"a_pointSize");
      if (a_pointSize < 0) { 
        console.log("a_pointSize failed");          
        return -1;
      }

      //  将缓冲区对象分配给attribute对象
      gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, fSize*3, 0);
      gl.vertexAttribPointer(a_pointSize, 1, gl.FLOAT, false, fSize*3, fSize*2);
    
      // 开启attribute对象
      gl.enableVertexAttribArray(a_Position);
      gl.enableVertexAttribArray(a_pointSize);

      // Unbind the buffer object
      gl.bindBuffer(gl.ARRAY_BUFFER, null);

      return n;
    },

    setGL: function() {
      this.gl = this.$refs.myglCanvas.getContext("webgl");
    }
  },
  mounted() {
    this.setGL();

    Tools.initShaders(this.gl, this.VSHEADER_SOURCE, this.FSHEADER_SOURCE);
    let pointCount = this.setBuffer(this.gl);
    if(pointCount < 0 ){
      console.log("set points failed");
      return;
    }
    
    //设置背景色
    this.gl.clearColor(0.0, 0.0, 0.0, 1);
    //设置缓冲区颜色
    this.gl.clear(this.gl.COLOR_BUFFER_BIT);
    //绘制点
    this.gl.drawArrays(this.gl.POINTS, 0, pointCount);
  }
};
</script>

<style scoped>
</style>

14行 在顶点着色器中定义点的尺寸变量 a_pointSize,数据类型为float;

28-30行  初始化顶点数据,共3个点。这里z默认为0,前两个值表示点的x、y坐标,第三个值为点的尺寸大小;

34行 获取点数组中每个元素所占的大小;

35-57行 创建缓冲区、绑定缓冲区、将数据写入缓冲区;

60-61行 将缓冲区对象分配给attribute,这里采用了vertexAttribPointer的步进和偏移。vertexAttribPointer函数的各参数含义如下:

68行 解绑缓冲区;

92行  绘制点;

运行代码,效果如下:

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

<think>嗯,用户的问题是关于在Vue-Cesium中如何创建带有指定ID的图形元素。首先,我需要回忆一下Vue-Cesium的基本结构和Cesium的组件。根据提供的引用内容,Cesium的核心组件包括Viewer、Entities等,其中Entities用于表示3D场景中的图形对象。用户可能需要在Vue项目中使用这些组件,并且希望给生成的图形元素指定唯一的ID以便后续管理。 首先,用户可能需要了解如何在Vue-Cesium中初始化Viewer。引用[3]提到,Viewer是Cesium应用程序的基础,因此需要确保正确创建Viewer实例。然后,用户需要添加Entities并设置ID。根据引用[1],Entities是管理图形对象的关键部分,所以应该使用Entities的API来创建图形,并指定id属性。 接下来,我需要考虑如何将Cesium的EntitiesVue的响应式数据结合Vue-Cesium可能提供了相关的组件或方法,例如vc-viewer和vc-entity,这些组件应该允许通过props传递参数,如id、position、shape等。用户需要知道如何在模板中正确使用这些组件,并绑定数据。 另外,用户提到的指定ID可能涉及在创建Entity时设置id字段。根据Cesium的文档,每个Entity都可以有一个唯一的id,这样可以通过viewer.entities.getById(id)来获取和操作该实体。因此,在代码示例中需要展示如何设置id属性,并演示如何通过ID检索实体。 还要注意,Vue-Cesium可能需要特定的导入和初始化步骤,例如在main.js中安装插件,或者在组件中引入所需的模块。引用[3]中的示例提到创建Viewer的过程,这可能Vue的组件生命周期相关,比如在mounted钩子中初始化Cesium相关操作。 此外,用户可能需要处理动态生成的图形元素,因此需要说明如何利用Vue的响应式系统来管理Entities。例如,使用v-for循环生成多个实体,每个实体都有唯一的ID,并且在需要时更新或删除特定ID的实体。 最后,应该考虑错误处理和调试。例如,如果指定的ID已存在,Cesium是否会抛出错误?用户可能需要避免重复ID,或者在覆盖现有实体时进行适当处理。引用[4]中提到的示例表达式可能对定义颜色或正则表达式有帮助,但当前问题主要关注ID的设置,这部分可能不需要涉及。 总结步骤应该是:初始化Viewer,使用vc-entity组件创建实体并指定id,展示如何通过ID获取实体,以及如何处理动态添加和删除。同时,代码示例需要符合Vue的单文件组件结构,并正确使用Vue-Cesium的指令和组件。</think>在 Vue-Cesium 中创建带有指定 ID 的图形元素需要结合 Vue 的响应式特性和 Cesium Entities 的标识管理机制。以下是实现步骤: ### 1. 初始化 Viewer 组件 首先在 Vue 组件中初始化 Cesium Viewer,这是所有图形操作的基础: ```javascript // 组件模板 <template> <vc-viewer ref="viewer" :shouldAnimate="true"> <!-- 图形元素将在此处插入 --> </vc-viewer> </template> // 组件脚本 mounted() { this.viewer = this.$refs.viewer.cesiumObject } ``` 该 Viewer 包含 WebGL 渲染流程和场景管理能力[^1][^3] ### 2. 创建带 ID 的图形元素 使用 `vc-entity` 组件创建图形时,通过 `id` 属性指定唯一标识: ```javascript <template> <vc-entity :id="'MARKER_001'" :position="[116.39, 39.9, 0]" :billboard="{ image: 'pin.png', scale: 0.5 }"> </vc-entity> </template> ``` 此处创建了一个带地理坐标的标记,其 ID 为 `MARKER_001` ### 3. 实体操作接口 通过 Cesium API 实现实体管理: ```javascript // 获取指定ID实体 const entity = this.viewer.entities.getById('MARKER_001') // 更新实体属性 entity.position = Cesium.Cartesian3.fromDegrees(121.47, 31.23) // 删除实体 this.viewer.entities.remove(entity) ``` 该操作基于 Cesium 的实体管理架构 ### 4. 动态生成实体 结合 Vue 的响应式系统实现动态实体生成: ```javascript data() { return { entities: [ { id: 'POLYGON_01', coordinates: [...] }, { id: 'LINE_02', positions: [...] } ] } } // 模板中使用v-for生成 <vc-entity v-for="item in entities" :key="item.id" :id="item.id" :polygon="{ hierarchy: item.coordinates, material: Cesium.Color.RED }"> </vc-entity> ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值