1# WebGL开发指导 2 3## 场景介绍 4 5WebGL主要帮助开发者在前端开发中完成图形图像的相关处理,比如绘制彩色图形等。 6 7> **说明:** 8> 9> 目前该功能仅支持使用兼容JS的类Web开发范式开发。 10 11 12## 接口说明 13 14**表1** WebGL主要接口列表 15 16| 接口名 | 描述 | 17| -------- | -------- | 18| canvas.getContext | 获取canvas对象上下文。 | 19| webgl.createBuffer(): WebGLBuffer \| null | 创建与初始化WebGL数据缓冲区。 | 20| webgl.bindBuffer(target: GLenum, buffer: WebGLBuffer \| null): void | 将WebGL数据缓冲区与目标进行绑定。 | 21| webgl.bufferData(target: GLenum, srcData: ArrayBufferView, usage: GLenum, srcOffset: GLuint, length?: GLuint): void | 创建并初始化WebGL的数据存储区。 | 22| webgl.getAttribLocation(program: WebGLProgram, name: string): GLint | 从给定WebGL着色程序中获取着色器中attribute变量的地址。 | 23| webgl.vertexAttribPointer(index GLuint, size: GLint, type: GLenum, normalized: GLboolean, stride: GLsizei, offset: GLintptr): void | 将缓冲区对象分配给变量。 | 24| webgl.enableVertexAttribArray(index: GLuint): void | 连接变量与分配给它的缓冲区对象。 | 25| webgl.clearColor(red: GLclampf, green:GLclampf, blue: GLclampf, alpha: GLclampf): void | 清空<canvas>指定的颜色。 | 26| webgl.clear(mask: GLbitfield): void | 清空<canvas>。 | 27| webgl.drawArrays(mode: GLenum, first:;GLint, count: GLsizei): void | 执行数据绘制。 | 28| webgl.flush(): void | 刷新数据至GPU,清空缓冲区。 | 29| webgl.createProgram(): WebGLProgram \| null | 创建着色器程序对象。 | 30 31 32## 开发步骤 33 34以下分别展示无着色器绘制2D图形和着色器绘制彩色三角形的两个场景示例及开发过程。 35 36> ![icon-note.gif](public_sys-resources/icon-note.gif) **说明:** 37> 使用WebGL开发时,为保证界面图形显示效果,请使用真机运行。 38 39 40### 无着色器绘制2D图形 41 42此场景为未使用WebGL绘制的2D图形(CPU绘制非GPU绘制)。开发示例如下: 43 441. 创建页面布局。index.hml示例如下: 45 ``` 46 <div class="container"> 47 <canvas ref="canvas1" style="width : 400px; height : 200px; background-color : lightyellow;"></canvas> 48 <button class="btn-button" onclick="BtnDraw2D">BtnDraw2D</button> 49 </div> 50 ``` 51 522. 设置页面样式。index.css示例如下: 53 ``` 54 .container { 55 flex-direction: column; 56 justify-content: center; 57 align-items: center; 58 } 59 .btn-button { 60 margin: 1px; 61 height: 40px; 62 width: 220px; 63 background-color: lightblue; 64 font-size: 20px; 65 text-color: blue; 66 } 67 ``` 68 693. 编辑JavaScript代码文件,增加2D绘制逻辑代码。index.js示例如下: 70 ``` 71 // index.js 72 export default {//NAPI交互代码 73 data: { 74 title: "DEMO BY TEAMOL", 75 fit:"cover", 76 fits: ["cover", "contain", "fill", "none", "scale-down"] 77 }, 78 onInit() { 79 this.title = this.$t('strings.world'); 80 }, 81 BtnDraw2D(){ 82 // 获取canvas元素 83 const canvas = this.$refs.canvas1; 84 // 获取2D上下文 85 const ctx = canvas.getContext('2d'); 86 87 // 执行CPU绘制函数 88 // Set line width 89 ctx.lineWidth = 10; 90 // Wall 91 ctx.strokeRect(75, 140, 150, 110); 92 // Door 93 ctx.fillRect(130, 190, 40, 60); 94 // Roof 95 ctx.beginPath(); 96 ctx.moveTo(50, 140); 97 ctx.lineTo(150, 60); 98 ctx.lineTo(250, 140); 99 ctx.closePath(); 100 ctx.stroke(); 101 } 102 } 103 ``` 104 105**图1** 点击按钮绘制2D图形的效果图 106 107![zh-cn_image_0000001192269746](figures/zh-cn_image_0000001192269746.gif) 108 109 110### 着色器绘制彩色三角形 111 112此场景为使用WebGL绘制的彩色三角形图形(GPU绘制)。开发示例如下: 113 114 1151. 创建页面布局。index.hml示例如下: 116 ``` 117 <div class="container"> 118 <canvas ref="canvas1" style="width : 400px; height : 200px; background-color : lightyellow;"></canvas> 119 <button class="btn-button" onclick="BtnColorTriangle">BtnColorTriangle</button> 120 </div> 121 ``` 122 1232. 设置页面样式。index.css示例如下: 124 ``` 125 .container { 126 flex-direction: column; 127 justify-content: center; 128 align-items: center; 129 } 130 .btn-button { 131 margin: 1px; 132 height: 40px; 133 width: 220px; 134 background-color: lightblue; 135 font-size: 20px; 136 text-color: blue; 137 } 138 ``` 139 1403. 编辑JavaScript代码文件,增加彩色三角形绘制逻辑代码。index.js示例如下: 141 ``` 142 // index.js 143 144 // WebGL相关预定义 145 var gl = { 146 DEPTH_BUFFER_BIT: 0x00000100, 147 STENCIL_BUFFER_BIT: 0x00000400, 148 COLOR_BUFFER_BIT: 0x00004000, 149 POINTS: 0x0000, 150 LINES: 0x0001, 151 LINE_LOOP: 0x0002, 152 LINE_STRIP: 0x0003, 153 TRIANGLES: 0x0004, 154 TRIANGLE_STRIP: 0x0005, 155 TRIANGLE_FAN: 0x0006, 156 ZERO: 0, 157 ONE: 1, 158 SRC_COLOR: 0x0300, 159 ONE_MINUS_SRC_COLOR: 0x0301, 160 SRC_ALPHA: 0x0302, 161 ONE_MINUS_SRC_ALPHA: 0x0303, 162 DST_ALPHA: 0x0304, 163 ONE_MINUS_DST_ALPHA: 0x0305, 164 DST_COLOR: 0x0306, 165 ONE_MINUS_DST_COLOR: 0x0307, 166 SRC_ALPHA_SATURATE: 0x0308, 167 FUNC_ADD: 0x8006, 168 BLEND_EQUATION: 0x8009, 169 BLEND_EQUATION_RGB: 0x8009, 170 BLEND_EQUATION_ALPHA: 0x883D, 171 FUNC_SUBTRACT: 0x800A, 172 FUNC_REVERSE_SUBTRACT: 0x800B, 173 BLEND_DST_RGB: 0x80C8, 174 BLEND_SRC_RGB: 0x80C9, 175 BLEND_DST_ALPHA: 0x80CA, 176 BLEND_SRC_ALPHA: 0x80CB, 177 CONSTANT_COLOR: 0x8001, 178 ONE_MINUS_CONSTANT_COLOR: 0x8002, 179 CONSTANT_ALPHA: 0x8003, 180 ONE_MINUS_CONSTANT_ALPHA: 0x8004, 181 BLEND_COLOR: 0x8005, 182 ARRAY_BUFFER: 0x8892, 183 ELEMENT_ARRAY_BUFFER: 0x8893, 184 ARRAY_BUFFER_BINDING: 0x8894, 185 ELEMENT_ARRAY_BUFFER_BINDING: 0x8895, 186 STREAM_DRAW: 0x88E0, 187 STATIC_DRAW: 0x88E4, 188 DYNAMIC_DRAW: 0x88E8, 189 BUFFER_SIZE: 0x8764, 190 BUFFER_USAGE: 0x8765, 191 CURRENT_VERTEX_ATTRIB: 0x8626, 192 FRONT: 0x0404, 193 BACK: 0x0405, 194 FRONT_AND_BACK: 0x0408, 195 CULL_FACE: 0x0B44, 196 BLEND: 0x0BE2, 197 DITHER: 0x0BD0, 198 STENCIL_TEST: 0x0B90, 199 DEPTH_TEST: 0x0B71, 200 SCISSOR_TEST: 0x0C11, 201 POLYGON_OFFSET_FILL: 0x8037, 202 SAMPLE_ALPHA_TO_COVERAGE: 0x809E, 203 SAMPLE_COVERAGE: 0x80A0, 204 NO_ERROR: 0, 205 INVALID_ENUM: 0x0500, 206 INVALID_VALUE: 0x0501, 207 INVALID_OPERATION: 0x0502, 208 OUT_OF_MEMORY: 0x0505, 209 CW: 0x0900, 210 CCW: 0x0901, 211 LINE_WIDTH: 0x0B21, 212 ALIASED_POINT_SIZE_RANGE: 0x846D, 213 ALIASED_LINE_WIDTH_RANGE: 0x846E, 214 CULL_FACE_MODE: 0x0B45, 215 FRONT_FACE: 0x0B46, 216 DEPTH_RANGE: 0x0B70, 217 DEPTH_WRITEMASK: 0x0B72, 218 DEPTH_CLEAR_VALUE: 0x0B73, 219 DEPTH_FUNC: 0x0B74, 220 STENCIL_CLEAR_VALUE: 0x0B91, 221 STENCIL_FUNC: 0x0B92, 222 STENCIL_FAIL: 0x0B94, 223 STENCIL_PASS_DEPTH_FAIL: 0x0B95, 224 STENCIL_PASS_DEPTH_PASS: 0x0B96, 225 STENCIL_REF: 0x0B97, 226 STENCIL_VALUE_MASK: 0x0B93, 227 STENCIL_WRITEMASK: 0x0B98, 228 STENCIL_BACK_FUNC: 0x8800, 229 STENCIL_BACK_FAIL: 0x8801, 230 STENCIL_BACK_PASS_DEPTH_FAIL: 0x8802, 231 STENCIL_BACK_PASS_DEPTH_PASS: 0x8803, 232 STENCIL_BACK_REF: 0x8CA3, 233 STENCIL_BACK_VALUE_MASK: 0x8CA4, 234 STENCIL_BACK_WRITEMASK: 0x8CA5, 235 VIEWPORT: 0x0BA2, 236 SCISSOR_BOX: 0x0C10, 237 COLOR_CLEAR_VALUE: 0x0C22, 238 COLOR_WRITEMASK: 0x0C23, 239 UNPACK_ALIGNMENT: 0x0CF5, 240 PACK_ALIGNMENT: 0x0D05, 241 MAX_TEXTURE_SIZE: 0x0D33, 242 MAX_VIEWPORT_DIMS: 0x0D3A, 243 SUBPIXEL_BITS: 0x0D50, 244 RED_BITS: 0x0D52, 245 GREEN_BITS: 0x0D53, 246 BLUE_BITS: 0x0D54, 247 ALPHA_BITS: 0x0D55, 248 DEPTH_BITS: 0x0D56, 249 STENCIL_BITS: 0x0D57, 250 POLYGON_OFFSET_UNITS: 0x2A00, 251 POLYGON_OFFSET_FACTOR: 0x8038, 252 TEXTURE_BINDING_2D: 0x8069, 253 SAMPLE_BUFFERS: 0x80A8, 254 SAMPLES: 0x80A9, 255 RGBA8: 0x8058, 256 SAMPLE_COVERAGE_VALUE: 0x80AA, 257 SAMPLE_COVERAGE_INVERT: 0x80AB, 258 COMPRESSED_TEXTURE_FORMATS: 0x86A3, 259 DONT_CARE: 0x1100, 260 FASTEST: 0x1101, 261 NICEST: 0x1102, 262 GENERATE_MIPMAP_HINT: 0x8192, 263 BYTE: 0x1400, 264 UNSIGNED_BYTE: 0x1401, 265 SHORT: 0x1402, 266 UNSIGNED_SHORT: 0x1403, 267 INT: 0x1404, 268 UNSIGNED_INT: 0x1405, 269 FLOAT: 0x1406, 270 DEPTH_COMPONENT: 0x1902, 271 ALPHA: 0x1906, 272 RGB: 0x1907, 273 RGBA: 0x1908, 274 LUMINANCE: 0x1909, 275 LUMINANCE_ALPHA: 0x190A, 276 UNSIGNED_SHORT_4_4_4_4: 0x8033, 277 UNSIGNED_SHORT_5_5_5_1: 0x8034, 278 UNSIGNED_SHORT_5_6_5: 0x8363, 279 FRAGMENT_SHADER: 0x8B30, 280 VERTEX_SHADER: 0x8B31, 281 MAX_VERTEX_ATTRIBS: 0x8869, 282 MAX_VERTEX_UNIFORM_VECTORS: 0x8DFB, 283 MAX_VARYING_VECTORS: 0x8DFC, 284 MAX_COMBINED_TEXTURE_IMAGE_UNITS: 0x8B4D, 285 MAX_VERTEX_TEXTURE_IMAGE_UNITS: 0x8B4C, 286 MAX_TEXTURE_IMAGE_UNITS: 0x8872, 287 MAX_FRAGMENT_UNIFORM_VECTORS: 0x8DFD, 288 SHADER_TYPE: 0x8B4F, 289 DELETE_STATUS: 0x8B80, 290 LINK_STATUS: 0x8B82, 291 VALIDATE_STATUS: 0x8B83, 292 ATTACHED_SHADERS: 0x8B85, 293 ACTIVE_UNIFORMS: 0x8B86, 294 ACTIVE_ATTRIBUTES: 0x8B89, 295 SHADING_LANGUAGE_VERSION: 0x8B8C, 296 CURRENT_PROGRAM: 0x8B8D, 297 NEVER: 0x0200, 298 LESS: 0x0201, 299 EQUAL: 0x0202, 300 LEQUAL: 0x0203, 301 GREATER: 0x0204, 302 NOTEQUAL: 0x0205, 303 GEQUAL: 0x0206, 304 ALWAYS: 0x0207, 305 KEEP: 0x1E00, 306 REPLACE: 0x1E01, 307 INCR: 0x1E02, 308 DECR: 0x1E03, 309 INVERT: 0x150A, 310 INCR_WRAP: 0x8507, 311 DECR_WRAP: 0x8508, 312 VENDOR: 0x1F00, 313 RENDERER: 0x1F01, 314 VERSION: 0x1F02, 315 NEAREST: 0x2600, 316 LINEAR: 0x2601, 317 NEAREST_MIPMAP_NEAREST: 0x2700, 318 LINEAR_MIPMAP_NEAREST: 0x2701, 319 NEAREST_MIPMAP_LINEAR: 0x2702, 320 LINEAR_MIPMAP_LINEAR: 0x2703, 321 TEXTURE_MAG_FILTER: 0x2800, 322 TEXTURE_MIN_FILTER: 0x2801, 323 TEXTURE_WRAP_S: 0x2802, 324 TEXTURE_WRAP_T: 0x2803, 325 TEXTURE_2D: 0x0DE1, 326 TEXTURE: 0x1702, 327 TEXTURE_CUBE_MAP: 0x8513, 328 TEXTURE_BINDING_CUBE_MAP: 0x8514, 329 TEXTURE_CUBE_MAP_POSITIVE_X: 0x8515, 330 TEXTURE_CUBE_MAP_NEGATIVE_X: 0x8516, 331 TEXTURE_CUBE_MAP_POSITIVE_Y: 0x8517, 332 TEXTURE_CUBE_MAP_NEGATIVE_Y: 0x8518, 333 TEXTURE_CUBE_MAP_POSITIVE_Z: 0x8519, 334 TEXTURE_CUBE_MAP_NEGATIVE_Z: 0x851A, 335 MAX_CUBE_MAP_TEXTURE_SIZE: 0x851C, 336 TEXTURE0: 0x84C0, 337 TEXTURE1: 0x84C1, 338 TEXTURE2: 0x84C2, 339 TEXTURE3: 0x84C3, 340 TEXTURE4: 0x84C4, 341 TEXTURE5: 0x84C5, 342 TEXTURE6: 0x84C6, 343 TEXTURE7: 0x84C7, 344 TEXTURE8: 0x84C8, 345 TEXTURE9: 0x84C9, 346 TEXTURE10: 0x84CA, 347 TEXTURE11: 0x84CB, 348 TEXTURE12: 0x84CC, 349 TEXTURE13: 0x84CD, 350 TEXTURE14: 0x84CE, 351 TEXTURE15: 0x84CF, 352 TEXTURE16: 0x84D0, 353 TEXTURE17: 0x84D1, 354 TEXTURE18: 0x84D2, 355 TEXTURE19: 0x84D3, 356 TEXTURE20: 0x84D4, 357 TEXTURE21: 0x84D5, 358 TEXTURE22: 0x84D6, 359 TEXTURE23: 0x84D7, 360 TEXTURE24: 0x84D8, 361 TEXTURE25: 0x84D9, 362 TEXTURE26: 0x84DA, 363 TEXTURE27: 0x84DB, 364 TEXTURE28: 0x84DC, 365 TEXTURE29: 0x84DD, 366 TEXTURE30: 0x84DE, 367 TEXTURE31: 0x84DF, 368 ACTIVE_TEXTURE: 0x84E0, 369 REPEAT: 0x2901, 370 CLAMP_TO_EDGE: 0x812F, 371 MIRRORED_REPEAT: 0x8370, 372 FLOAT_VEC2: 0x8B50, 373 FLOAT_VEC3: 0x8B51, 374 FLOAT_VEC4: 0x8B52, 375 INT_VEC2: 0x8B53, 376 INT_VEC3: 0x8B54, 377 INT_VEC4: 0x8B55, 378 BOOL: 0x8B56, 379 BOOL_VEC2: 0x8B57, 380 BOOL_VEC3: 0x8B58, 381 BOOL_VEC4: 0x8B59, 382 FLOAT_MAT2: 0x8B5A, 383 FLOAT_MAT3: 0x8B5B, 384 FLOAT_MAT4: 0x8B5C, 385 SAMPLER_2D: 0x8B5E, 386 SAMPLER_CUBE: 0x8B60, 387 VERTEX_ATTRIB_ARRAY_ENABLED: 0x8622, 388 VERTEX_ATTRIB_ARRAY_SIZE: 0x8623, 389 VERTEX_ATTRIB_ARRAY_STRIDE: 0x8624, 390 VERTEX_ATTRIB_ARRAY_TYPE: 0x8625, 391 VERTEX_ATTRIB_ARRAY_NORMALIZED: 0x886A, 392 VERTEX_ATTRIB_ARRAY_POINTER: 0x8645, 393 VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: 0x889F, 394 IMPLEMENTATION_COLOR_READ_TYPE: 0x8B9A, 395 IMPLEMENTATION_COLOR_READ_FORMAT: 0x8B9B, 396 COMPILE_STATUS: 0x8B81, 397 LOW_FLOAT: 0x8DF0, 398 MEDIUM_FLOAT: 0x8DF1, 399 HIGH_FLOAT: 0x8DF2, 400 LOW_INT: 0x8DF3, 401 MEDIUM_INT: 0x8DF4, 402 HIGH_INT: 0x8DF5, 403 FRAMEBUFFER: 0x8D40, 404 RENDERBUFFER: 0x8D41, 405 RGBA4: 0x8056, 406 RGB5_A1: 0x8057, 407 RGB565: 0x8D62, 408 DEPTH_COMPONENT16: 0x81A5, 409 STENCIL_INDEX8: 0x8D48, 410 DEPTH_STENCIL: 0x84F9, 411 RENDERBUFFER_WIDTH: 0x8D42, 412 RENDERBUFFER_HEIGHT: 0x8D43, 413 RENDERBUFFER_INTERNAL_FORMAT: 0x8D44, 414 RENDERBUFFER_RED_SIZE: 0x8D50, 415 RENDERBUFFER_GREEN_SIZE: 0x8D51, 416 RENDERBUFFER_BLUE_SIZE: 0x8D52, 417 RENDERBUFFER_ALPHA_SIZE: 0x8D53, 418 RENDERBUFFER_DEPTH_SIZE: 0x8D54, 419 RENDERBUFFER_STENCIL_SIZE: 0x8D55, 420 FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: 0x8CD0, 421 FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: 0x8CD1, 422 FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL: 0x8CD2, 423 FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: 0x8CD3, 424 COLOR_ATTACHMENT0: 0x8CE0, 425 DEPTH_ATTACHMENT: 0x8D00, 426 STENCIL_ATTACHMENT: 0x8D20, 427 DEPTH_STENCIL_ATTACHMENT: 0x821A, 428 NONE: 0, 429 FRAMEBUFFER_COMPLETE: 0x8CD5, 430 FRAMEBUFFER_INCOMPLETE_ATTACHMENT: 0x8CD6, 431 FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: 0x8CD7, 432 FRAMEBUFFER_INCOMPLETE_DIMENSIONS: 0x8CD9, 433 FRAMEBUFFER_UNSUPPORTED: 0x8CDD, 434 FRAMEBUFFER_BINDING: 0x8CA6, 435 RENDERBUFFER_BINDING: 0x8CA7, 436 MAX_RENDERBUFFER_SIZE: 0x84E8, 437 INVALID_FRAMEBUFFER_OPERATION: 0x0506, 438 UNPACK_FLIP_Y_WEBGL: 0x9240, 439 UNPACK_PREMULTIPLY_ALPHA_WEBGL: 0x9241, 440 CONTEXT_LOST_WEBGL: 0x9242, 441 UNPACK_COLORSPACE_CONVERSION_WEBGL: 0x9243, 442 BROWSER_DEFAULT_WEBGL: 0x9244, 443 TEXTURE_MAX_LOD: 0x813B, 444 TEXTURE_BASE_LEVEL: 0x813C, 445 TEXTURE_IMMUTABLE_FORMAT: 0x912F, 446 UNIFORM_BLOCK_BINDING: 0x8A3F, 447 UNIFORM_BLOCK_DATA_SIZE: 0x8A40, 448 UNIFORM_BLOCK_ACTIVE_UNIFORMS: 0x8A42, 449 UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES: 0x8A43, 450 UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER: 0x8A44, 451 UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER: 0x8A46, 452 RED: 0x1903, 453 PIXEL_UNPACK_BUFFER: 0x88EC, 454 RGB8: 0x8051, 455 R16F: 0x822D, 456 COPY_WRITE_BUFFER: 0x8F37, 457 TEXTURE_3D: 0x806F, 458 COMPRESSED_R11_EAC: 0x9270, 459 COPY_READ_BUFFER: 0x8F36, 460 TRANSFORM_FEEDBACK_BUFFER: 0x8C8E, 461 TRANSFORM_FEEDBACK_BUFFER_BINDING: 0x8C8F, 462 TRANSFORM_FEEDBACK_BUFFER_SIZE: 0x8C85, 463 TRANSFORM_FEEDBACK_BUFFER_START: 0x8C84, 464 UNIFORM_BUFFER_BINDING: 0x8A28, 465 UNIFORM_BUFFER_SIZE: 0x8A2A, 466 UNIFORM_BUFFER_START: 0x8A29, 467 DYNAMIC_READ: 0x88E9, 468 READ_FRAMEBUFFER: 0x8CA8, 469 COLOR_ATTACHMENT1: 0x8CE1, 470 INTERLEAVED_ATTRIBS: 0x8C8C, 471 UNIFORM_OFFSET: 0x8A3B, 472 UNIFORM_TYPE: 0x8A37, 473 UNIFORM_SIZE: 0x8A38, 474 UNIFORM_BLOCK_INDEX: 0x8A3A, 475 UNIFORM_ARRAY_STRIDE: 0x8A3C, 476 UNIFORM_MATRIX_STRIDE: 0x8A3D, 477 UNIFORM_IS_ROW_MAJOR: 0x8A3E, 478 TEXTURE_MAX_ANISOTROPY_EXT: 0x84FE 479 } 480 481 // 顶点着色器程序 482 var VSHADER_SOURCE = 483 'attribute vec4 a_Position;\n' + // attribute variable 484 'attribute vec4 a_Color;\n' + 485 'varying vec4 v_Color;\n' + 486 'void main() {\n' + 487 ' gl_Position = a_Position;\n' + // Set the vertex coordinates of the point 488 ' v_Color = a_Color;\n' + 489 '}\n'; 490 491 // 片元着色器程序 492 var FSHADER_SOURCE = 493 'precision mediump float;\n' + 494 'varying vec4 v_Color;\n' + 495 'void main() {\n' + 496 ' gl_FragColor = v_Color;\n' + 497 '}\n'; 498 499 function initVertexBuffers(gl) { 500 // 顶点坐标和颜色 501 var verticesColors = new Float32Array([ 502 0.0, -0.5, 1.0, 0.0, 0.0, 503 -0.5, -0.8, 0.0, 1.0, 0.0, 504 0.5, -0.8, 0.0, 0.0, 1.0, 505 ]); 506 507 var n = 3; // 点的个数 508 var FSIZE = verticesColors.BYTES_PER_ELEMENT; //数组中每个元素的字节数 509 510 // 创建缓冲区对象 511 var vertexBuffer = gl.createBuffer(); 512 if (!vertexBuffer) { 513 console.log('Failed to create the buffer object'); 514 return -1; 515 } 516 517 // 将缓冲区对象绑定到目标 518 gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); 519 // 向缓冲区对象写入数据 520 gl.bufferData(gl.ARRAY_BUFFER, verticesColors.buffer, gl.STATIC_DRAW); 521 522 // 获取着色器中attribute变量a_Position的地址 523 var a_Position = gl.getAttribLocation(gl.program, 'a_Position'); 524 if (a_Position < 0) { 525 console.log('Failed to get the storage location of a_Position'); 526 return -1; 527 } 528 // 将缓冲区对象分配给a_Position变量 529 gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 5 * FSIZE, 0); 530 531 // 连接a_Position变量与分配给它的缓冲区对象 532 gl.enableVertexAttribArray(a_Position); 533 534 // 获取着色器中attribute变量a_Color的地址 535 var a_Color = gl.getAttribLocation(gl.program, 'a_Color'); 536 if (a_Color < 0) { 537 console.log('Failed to get the storage location of a_Color'); 538 return -1; 539 } 540 // 将缓冲区对象分配给a_Color变量 541 gl.vertexAttribPointer(a_Color, 3, gl.FLOAT, false, FSIZE * 5, FSIZE * 2); 542 543 // 连接a_Color变量与分配给它的缓冲区对象 544 gl.enableVertexAttribArray(a_Color); 545 546 // 解除绑定 547 gl.bindBuffer(gl.ARRAY_BUFFER, null); 548 549 return n; 550 } 551 552 /** 553 * Creates a program object and makes it as the current object. 554 * @param gl Indicates the WebGL context. 555 * @param vshader Indicates a vertex shader program (string). 556 * @param fshader Indicates a fragment shader program (string). 557 * @return Returns true if the WebGLProgram object was created and successfully made as the current object; returns false otherwise. 558 */ 559 function initShaders(gl, vshader, fshader) { 560 var program = createProgram(gl, vshader, fshader); 561 console.log("======createProgram program: " + program); 562 563 if (!program) { 564 console.log('Failed to create program'); 565 return false; 566 } 567 gl.useProgram(program); 568 gl.program = program; 569 570 return true; 571 } 572 573 /** 574 * Creates a linked program object. 575 * @param gl Indicates the WebGL context. 576 * @param vshader Indicates a vertex shader program (string). 577 * @param fshader Indicates a fragment shader program (string). 578 * @return Returns the created program object if the operation is successful; returns null otherwise. 579 */ 580 function createProgram(gl, vshader, fshader) { 581 console.log("======createProgram start======"); 582 // Create shader object 583 var vertexShader = loadShader(gl, gl.VERTEX_SHADER, vshader); 584 console.log("======vertexShader: " + vertexShader); 585 var fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fshader); 586 if (!vertexShader || !fragmentShader) { 587 return null; 588 } 589 590 // Create a program object. 591 var program = gl.createProgram(); 592 console.log("======createProgram program: " + program); 593 594 if (!program) { 595 return null; 596 } 597 598 // Attach the shader objects. 599 gl.attachShader(program, vertexShader); 600 gl.attachShader(program, fragmentShader); 601 602 // Link the program object. 603 gl.linkProgram(program); 604 605 // Check the result of linking. 606 var linked = gl.getProgramParameter(program, 0x8B82); 607 console.log("======getProgramParameter linked: " + linked); 608 609 if (!linked) { 610 var error = gl.getProgramInfoLog(program); 611 console.log('Failed to link the program: ' + error); 612 gl.deleteProgram(program); 613 gl.deleteShader(fragmentShader); 614 gl.deleteShader(vertexShader); 615 return null; 616 } 617 return program; 618 } 619 620 /** 621 * Creates a shader object. 622 * @param gl Indicates the WebGL context. 623 * @param type Indicates the type of the shader object to be created. 624 * @param source Indicates the shader program (string). 625 * @return Returns the created shader object if the operation is successful; returns false otherwise. 626 */ 627 function loadShader(gl, type, source) { 628 console.log("======into loadShader===="); 629 // Create shader object 630 var shader = gl.createShader(type); 631 if (shader == null) { 632 console.log('Failed to create the shader.'); 633 return null; 634 } 635 636 // Set the shader program. 637 gl.shaderSource(shader, source); 638 639 // Compile the shader. 640 gl.compileShader(shader); 641 642 // Check the result of compilation. 643 var compiled = gl.getShaderParameter(shader, gl.COMPILE_STATUS); 644 if (!compiled) { 645 var error = gl.getShaderInfoLog(shader); 646 console.log('Failed to compile the shader: ' + error); 647 gl.deleteShader(shader); 648 return null; 649 } 650 651 return shader; 652 } 653 654 export default { 655 data: { 656 title: "DEMO BY TEAMOL", 657 fit:"cover", 658 fits: ["cover", "contain", "fill", "none", "scale-down"] 659 } 660 ,onInit() { 661 this.title = this.$t('strings.world'); 662 } 663 ,BtnColorTriangle() { 664 // 获取canvas元素 665 const el = this.$refs.canvas1; 666 // 获取webgl上下文 667 var gl = el.getContext('webgl'); 668 669 if (!gl) { 670 console.log('Failed to get the rendering context for WebGL'); 671 return; 672 } 673 674 // 初始化着色器 675 if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) { 676 console.log('Failed to initialize shaders.'); 677 return; 678 } 679 680 // 设置顶点位置 681 var n = initVertexBuffers(gl); 682 if (n < 0) { 683 console.log('Failed to set the positions of the vertices'); 684 return; 685 } 686 687 // 指定清空<canvas>的颜色 688 gl.clearColor(0.0, 0.0, 0.0, 1.0); 689 690 // 清空<canvas> 691 gl.clear(gl.COLOR_BUFFER_BIT); 692 693 // 绘制三角形 694 gl.drawArrays(gl.TRIANGLES, 0, n); 695 696 //清buffer 697 gl.flush(); 698 } 699 } 700 ``` 701 702 703**图2** 点击按钮绘制彩色三角形的效果图 704 705![zh-cn_image_0000001192429306](figures/zh-cn_image_0000001192429306.gif) 706