@@ -278,4 +278,286 @@ gl.vertexAttribPointer()方法解决了这个问题,他可以将整个缓冲
278278| INVALID_OPERATION | 不存在当前程序 |
279279| INVALID_VALUE | location大于等于attribute变量的最大数目(默认为8)。或者stride或offset是负值› |
280280
281- ![ 原理图] ( ./images/bufferObjectToAttribute.png )
281+ ![ 原理图] ( ./images/bufferObjectToAttribute.png )
282+
283+
284+ ### 开启attribute变量(gl.enableVertexAttribArray())
285+
286+ 为了是顶点着色器能够访问缓冲区内的数据,需要使用` gl.enableVertexAttribArray() ` 方法来开启` attribute ` 变量
287+
288+ ` gl.enableVertexAttribArray(a_Position); ` 这个函数是处理的缓冲区,而不是 顶点数组
289+
290+ | 参数 | 描述 |
291+ | ---------------| ------------------------------------|
292+ | location | 指定attribute变量的存储位置 |
293+ | 返回值 | 无 |
294+ | 错误 | 描述 |
295+ | INVALID_VALUE | location大于等于attribute变量的最大数目(默认为8) |
296+
297+ ![ 原理图] ( ./images/enableVertexAttribArray.png )
298+
299+ 也可以使用 ` gl.disableVertexAttribArray() ` 来关闭分配
300+
301+ | 参数 | 描述 |
302+ | ---------------| -------------------------------------|
303+ | location | 指定attribute变量的存储位置 |
304+ | 返回值 | 无 |
305+ | 错误 | 描述 |
306+ | INVALID_VALUE | location 大于等于attribute变量的最大数量(默认为8) |
307+
308+
309+ ### 绘制点
310+
311+ ` gl.drawArrays(mode, first, count) `
312+
313+ | 参数 | 描述 |
314+ | -------| -----------------------------------------------------------------------------------------------------------------------|
315+ | mode | 指定绘制的方式,可以接收以下常量符号:gl.POINTS, gl.LINES, gl.LINE_STRIP, gl.LINE_LOOP, gl.TRIANGLES, gl.TRIANGLE_STRIP, gl.TRIANGLE_FAN |
316+ | first | 指定从哪个顶点开始绘制(整型数) |
317+ | count | 指定绘制需要用到多少个顶点(整型数) |
318+
319+
320+
321+ ** ` gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0) ` 完整流程图**
322+
323+ ![ 效果图] ( ./images/completeProcess.png )
324+
325+ ## 绘制三角形
326+
327+ ``` js
328+ const VSHADER_SOURCE =
329+ ' attribute vec4 a_Position;\n ' +
330+ ' void main() {\n ' +
331+ ' gl_Position = a_Position;\n ' +
332+ ' gl_PointSize = 10.0;\n ' + // [!code --]
333+ ' }\n '
334+ const FSHADER_SOURCE =
335+ ' void main() {\n ' +
336+ ' gl_FragColor = vec4(1.0, 1.0, 0.0,1.0);\n ' +
337+ ' }\n '
338+
339+
340+ function main () {
341+ var canvas = document .getElementById (' webgl' )
342+ var gl = getWebGLContext (canvas)
343+ if (! gl) {
344+ console .error (' Failed to get the rendering context for WebGL' )
345+ return ;
346+ }
347+
348+ // 初始化着色器
349+ if (! initShaders (gl, VSHADER_SOURCE , FSHADER_SOURCE )) {
350+ console .error (' Failed to initialize shaders.' )
351+ return ;
352+ }
353+
354+ // 设置顶点着色器
355+ var n = initVertexBuffers (gl);
356+
357+ if (n < 0 ) {
358+ console .error (' Failed to set the positions of the vertices' )
359+ return ;
360+ }
361+
362+ // // 获取attribut变量的存储位置
363+ var a_Position = gl .getAttribLocation (gl .program , ' a_Position' )
364+ //
365+ // var u_FragColor = gl.getUniformLocation(gl.program, 'u_FragColor')
366+ if (a_Position < 0 ) {
367+ console .error (' Failed to get the storage location of a_Position' )
368+ return ;
369+ }
370+ //
371+ // canvas.onmousedown = function (ev) {click(ev, gl, canvas, a_Position, u_FragColor)}
372+
373+
374+
375+ // gl.vertexAttrib3f(a_Position, 0.0, 0.0, 0.0)
376+
377+ // 设置canvas背景色
378+ gl .clearColor (0.0 ,0.0 ,0.0 ,1.0 )
379+
380+ // 清空canvas
381+ gl .clear (gl .COLOR_BUFFER_BIT );
382+
383+ // 绘制
384+ gl .drawArrays (gl .POINTS , 0 , n) // [!code ++]
385+ gl .drawArrays (gl .TRIANGLES , 0 , n) // [!code --]
386+
387+
388+ }
389+
390+ function initVertexBuffers (gl ) {
391+ var vertices = new Float32Array ([
392+ 0.0 , 0.5 , - 0.5 , - 0.5 , 0.5 , - 0.5
393+ ])
394+ var n = 3 // 点的个数
395+
396+ // 创建缓冲区对象
397+ var vertexBuffer = gl .createBuffer ();
398+ if (! vertexBuffer) {
399+ console .error (' Failed to create the buffer object' )
400+ return - 1 ;
401+ }
402+
403+ // 将缓冲区对象绑定到目标
404+ gl .bindBuffer (gl .ARRAY_BUFFER , vertexBuffer)
405+
406+ // 向缓冲区对象中写入数据
407+ gl .bufferData (gl .ARRAY_BUFFER , vertices, gl .STATIC_DRAW );
408+
409+ var a_Position = gl .getAttribLocation (gl .program , ' a_Position' );
410+
411+ // 将缓冲区对象分配给a_Position变量
412+ gl .vertexAttribPointer (a_Position, 2 , gl .FLOAT , false , 0 , 0 )
413+
414+ // 连接a_Position变量与分配给它的缓冲对象
415+ gl .enableVertexAttribArray (a_Position)
416+ return n
417+ }
418+
419+ ```
420+
421+ ![ 效果图] ( ./images/triangles.png )
422+
423+
424+ ` gl.drawArrays(gl.TRIANGLES, 0, n) `
425+
426+ gl.drawArrays()方法的第一个参数 mode 改为gl.TRIANGLES, 就相当于告诉WebGL, 从缓冲区中的第1个顶点开始,使顶点着色器执行3次,用这3个顶点绘制出一个三角形
427+
428+ gl.drawArrays() 即强大又灵活,通过给第一个参数指定不同的值,就能以7种不同的方式来绘制图形。
429+
430+ ** WebGL可以绘制的基本图形**
431+
432+ | 基本图形 | 参数mode | 描述 |
433+ | :------| :--------------------:| :------------------------------------------------------------------------------------------------------------------------|
434+ | 点 | gl.POINTS | 一系列点,绘制在v0、v1、v2...处 |
435+ | 线段 | gl.LINES | 一系列单独的线段,绘制在(v0, v1)、(v2, v3)、(v4,v5)...处,<br /> 如果点的个数是奇数,最好一个将被忽略 |
436+ | 线条 | gl.LINE_STRIP | 一系列连接的线段,被绘制在(v0,v1)、(v1、v2)、(v2,v3)...处,<br />第一个点是第一条线段的起点,第二个点是第一条线段的终点和第二条线段的起点...<br />一次类推。最后一个点是最后一条线段的终点 |
437+ | 回路 | gl.LINE_LOOP | 一系列连接的线段。与gl.LINE_STRIP绘制的线条相比,增加了一条从最后一个<br />点到第一个点的线段。 |
438+ | 三角形 | gl.TRIANGLES | 一系列单独的三角形,绘制在(v0,v1,v2)、(v3, v4,v5)...处。如果<br />点的个数不是3的整数倍,最后剩下的一个或两个点将被忽略 |
439+ | 三角带 | gl.TRIANGLES_STRIP | 一系列条带状的三角形,前三个点构成了第一个三角形,从第2个点开始的三个点<br />‘成了第2个三角形,以此类推。这些三角形被绘制在(v0,v1,v2)、(v2,v1,v3)、<br />(v2,v3、v4)...处 |
440+ | 三角扇 | gl.TRIANGLES_FAN | 一系列三角形组成的类似与扇形的图形。前三个点构成了第一个三角形,接下来的<br />一个点和前一个三角形的最后一条边组成接下来的一个三角形。这些三角形被绘制<br />在(v0,v1,v2)、(v0,v2,v3)、(v0、v3、v4)...处 |
441+
442+
443+ ![ 示例图] ( ./images/gl.drawArraysMode.png )
444+
445+
446+ 修改例中的` gl.drawArrays(gl.LINES, 0, n) `
447+
448+ ![ 效果图] ( ./images/line.png )
449+
450+ 修改例中的` gl.drawArrays(gl.LINE_STRIP, 0, n) `
451+
452+ ![ 效果图] ( ./images/line_strip.png )
453+
454+ 修改例中的` gl.drawArrays(gl.LINE_LOOP, 0, n) `
455+
456+ ![ 效果图] ( ./images/line_loop.png )
457+
458+
459+ ## Rectangle
460+
461+ ``` js
462+ const VSHADER_SOURCE =
463+ ' attribute vec4 a_Position;\n ' +
464+ ' void main() {\n ' +
465+ ' gl_Position = a_Position;\n ' +
466+ // 'gl_PointSize = 10.0;\n' +
467+ ' }\n '
468+ const FSHADER_SOURCE =
469+ ' void main() {\n ' +
470+ ' gl_FragColor = vec4(1.0, 1.0, 0.0,1.0);\n ' +
471+ ' }\n '
472+
473+
474+ function main () {
475+ var canvas = document .getElementById (' webgl' )
476+ var gl = getWebGLContext (canvas)
477+ if (! gl) {
478+ console .error (' Failed to get the rendering context for WebGL' )
479+ return ;
480+ }
481+
482+ // 初始化着色器
483+ if (! initShaders (gl, VSHADER_SOURCE , FSHADER_SOURCE )) {
484+ console .error (' Failed to initialize shaders.' )
485+ return ;
486+ }
487+
488+ // 设置顶点着色器
489+ var n = initVertexBuffers (gl);
490+
491+ if (n < 0 ) {
492+ console .error (' Failed to set the positions of the vertices' )
493+ return ;
494+ }
495+
496+ // // 获取attribut变量的存储位置
497+ var a_Position = gl .getAttribLocation (gl .program , ' a_Position' )
498+ //
499+ // var u_FragColor = gl.getUniformLocation(gl.program, 'u_FragColor')
500+ if (a_Position < 0 ) {
501+ console .error (' Failed to get the storage location of a_Position' )
502+ return ;
503+ }
504+ //
505+ // canvas.onmousedown = function (ev) {click(ev, gl, canvas, a_Position, u_FragColor)}
506+
507+
508+
509+ // gl.vertexAttrib3f(a_Position, 0.0, 0.0, 0.0)
510+
511+ // 设置canvas背景色
512+ gl .clearColor (0.0 ,0.0 ,0.0 ,1.0 )
513+
514+ // 清空canvas
515+ gl .clear (gl .COLOR_BUFFER_BIT );
516+
517+ // 绘制三个点
518+ gl .drawArrays (gl .TRIANGLE_STRIP , 0 , n)
519+
520+
521+ }
522+
523+ function initVertexBuffers (gl ) {
524+ var vertices = new Float32Array ([
525+ 0.0 , 0.5 , - 0.5 , - 0.5 , 0.5 , - 0.5 // [!code --]
526+ - 0.5 , 0.5 , - 0.5 , - 0.5 , 0.5 , 0.5 , 0.5 , - 0.5 // [!code ++]
527+ ])
528+ var n = 3 // 点的个数 // [!code --]
529+ var n = 4 // 点的个数 // [!code ++]
530+ // 创建缓冲区对象
531+ var vertexBuffer = gl .createBuffer ();
532+ if (! vertexBuffer) {
533+ console .error (' Failed to create the buffer object' )
534+ return - 1 ;
535+ }
536+
537+ // 将缓冲区对象绑定到目标
538+ gl .bindBuffer (gl .ARRAY_BUFFER , vertexBuffer)
539+
540+ // 向缓冲区对象中写入数据
541+ gl .bufferData (gl .ARRAY_BUFFER , vertices, gl .STATIC_DRAW );
542+
543+ var a_Position = gl .getAttribLocation (gl .program , ' a_Position' );
544+
545+ // 将缓冲区对象分配给a_Position变量
546+ gl .vertexAttribPointer (a_Position, 2 , gl .FLOAT , false , 0 , 0 )
547+
548+ // 连接a_Position变量与分配给它的缓冲对象
549+ gl .enableVertexAttribArray (a_Position)
550+ return n
551+ }
552+
553+ ```
554+
555+ ![ 效果图] ( ./images/Rectangle.png )
556+
557+
558+ ` gl.drawArrays(gl.TRIANGLE_FAN, 0, n) `
559+
560+ ![ 效果图] ( ./images/Triangle_fan.png )
561+
562+
563+ ### 移动、旋转和缩放
0 commit comments