月球大数据地理空间分析展示平台-【前端】-月球2期前端
surprise
2023-11-03 34a81cb796b9a4e862b1598d4dea56c32a68ea07
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
/**
 * 一个用于 webgl 加载tin数据的 处理类
 * @wrriten {wangxu} on 2022/3/25
 */
import Matrix4 from "./cuon-matrix.js";
// 调试工具
// var SPECTOR = require("spectorjs");
// var spector = new SPECTOR.Spector();
// spector.displayUI();
class WebGLRenderer {
  constructor(options) {
    this.init(options);
  }
 
  /**
   * 初始化内容
   */
  init(options) {
    // 生成 可以被 截图的 canvas
    let mapDom = document.getElementById(options.mapID);
    let canvas = document.createElement("canvas", {
      preserveDrawingBuffer: true,
    });
    canvas.width = mapDom.clientWidth;
    canvas.height = mapDom.clientHeight;
 
    this.gl = canvas.getContext("webgl");
    this.canvas = canvas;
    this.tindata = options.tindata;
    this.program = this.gl.createProgram();
    this.__origin__resolution = options.originResolution;
    this.colormaker = options.colormaker;
 
    this.initShader(this.gl, this.program);
 
    this.linkShaderToProgram(this.gl, this.program);
 
    let count = this.initBufferData(this.gl, this.program);
    this.count = count;
 
    this.initModelMatrix(this.gl, this.program);
 
    this.renderElement(this.gl, this.count);
 
    console.log(this.canvas.toDataURL());
  }
 
  /**
   * 绘制图像
   */
  renderElement(gl, count) {
    gl.clearColor(0.0, 0.0, 0.0, 0.0);
    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
    var ext = gl.getExtension("OES_element_index_uint");
    gl.drawElements(gl.TRIANGLES, count, gl.UNSIGNED_INT, 0);
  }
 
  changeMatrix(frameState) {
    let { gl, program } = this;
    var calcMatrix = new Matrix4();
    let ratio = (
      this.__origin__resolution / frameState.viewState.resolution
    ).toFixed(2);
    let center = frameState.viewState.center;
    let extent = frameState.extent;
    let originDiff = (extent[2] - extent[0]) / 360.0;
    calcMatrix.scale(1 / originDiff, ratio, 1);
    calcMatrix.translate(-(center[0] / 180.0), -(center[1] / 90.0), 0);
    // calcMatrix.translate(-0.5 * 10,-0.5 * 10,0)
    var u_modelMatrix = gl.getUniformLocation(program, "u_modelMatrix");
    gl.uniformMatrix4fv(u_modelMatrix, false, calcMatrix.elements);
    gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
    gl.drawElements(gl.TRIANGLES, this.count, gl.UNSIGNED_INT, 0);
  }
 
  /**
   * 将shader 链接到 program
   */
  linkShaderToProgram(gl, program) {
    gl.linkProgram(program);
    gl.useProgram(program);
  }
 
  /**
   * 初始化 模型矩阵
   */
  initModelMatrix(gl, program) {
    let modelMatrix = new Matrix4();
    modelMatrix.scale(1, 1, 1);
    // 缓冲区重 存储 modelMatrix的索引位置
    let modelMatrixIndex = gl.getUniformLocation(program, "u_modelMatrix");
    // 往着色器中赋值
    gl.uniformMatrix4fv(modelMatrixIndex, false, modelMatrix.elements);
  }
 
  /**
   * 装载着色器
   */
  initShader(gl, program) {
    var vertexShaderSource =
      "attribute vec4 position;\n" +
      "attribute vec4 color;\n" +
      "uniform mat4 u_modelMatrix;\n" +
      "varying vec4 v_Color;\n" +
      "void main() {\n" +
      "v_Color = color;\n" +
      "gl_Position = u_modelMatrix * position;\n" +
      "}\n";
    var fragmentShaderSource =
      "#ifdef GL_ES\n" +
      "precision mediump float;\n" +
      "#endif\n" +
      "varying vec4 v_Color;\n" +
      "void main(){\n" +
      "   gl_FragColor = v_Color;\n" +
      "}\n";
 
    //从上面例子使用 createShader 函数。
    var vertexShader = gl.createShader(gl.VERTEX_SHADER);
    gl.shaderSource(vertexShader, vertexShaderSource);
    gl.compileShader(vertexShader);
    //从上面例子使用 createShader 函数。
    var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
    gl.shaderSource(fragmentShader, fragmentShaderSource);
    // 编译此 着色器
    gl.compileShader(fragmentShader);
 
    // 绑定预先存在的着色器 至program
    gl.attachShader(program, vertexShader);
    gl.attachShader(program, fragmentShader);
 
    // 调试代码,alert的内容为ERROR: 0:2:" :No precision specified for (float)
    if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
      alert(gl.getShaderInfoLog(fragmentShader));
    }
    // 调试代码,alert的内容为ERROR: 0:2:" :No precision specified for (float)
    if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
      alert(gl.getShaderInfoLog(vertexShader));
    }
  }
 
  /**
   * 初始化 缓冲数据
   * @param {*} gl
   * @param {*} program
   * @returns n 绘制的顶点个数
   */
  initBufferData(gl, program) {
    let dataLen = this.tindata.data.length;
    let data = this.tindata.data;
    let vertexPositions = [];
    let colors = [];
    for (let i = 0; i < dataLen; i++) {
      vertexPositions.push(data[i][0] / 180.0, data[i][1] / 90.0);
      colors.push(
        ...this.colormaker.makeColor(data[i][2]).map((e) => e / 255.0),
        1.0
      );
    }
    let indices = this.tindata.indices;
    var vertices = new Float32Array(vertexPositions);
    var n = indices.length; //点的个数
 
    //创建缓冲区对象
    var 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);
    //获取坐标点
    var a_Position = gl.getAttribLocation(program, "position");
    //将缓冲区对象分配给a_Position变量
    gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
    //连接a_Position变量与分配给它的缓冲区对象
    gl.enableVertexAttribArray(a_Position);
 
    // ------------------------------------
    var colorBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
    //获取顶点颜色苏哦因
    var __color = gl.getAttribLocation(program, "color");
    console.log(__color);
    //将缓冲区对象分配给a_Position变量
    gl.vertexAttribPointer(__color, 4, gl.FLOAT, false, 0, 0);
    //连接a_Position变量与分配给它的缓冲区对象
    gl.enableVertexAttribArray(__color);
 
    // -------------------------------------
 
    var indexBuffer = gl.createBuffer();
    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
    gl.bufferData(
      gl.ELEMENT_ARRAY_BUFFER,
      new Uint32Array(indices),
      gl.STATIC_DRAW
    );
    return n;
  }
}
 
export default WebGLRenderer;