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