Skip to content

Commit c82157b

Browse files
committed
绘制变换三角形
1 parent 015a838 commit c82157b

File tree

10 files changed

+283
-1
lines changed

10 files changed

+283
-1
lines changed

docs/WebGL/Chapter2.md

Lines changed: 283 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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+
### 移动、旋转和缩放

docs/WebGL/images/Rectangle.png

5.42 KB
Loading

docs/WebGL/images/Triangle_fan.png

6.34 KB
Loading
1.09 MB
Loading
328 KB
Loading
440 KB
Loading

docs/WebGL/images/line.png

6.36 KB
Loading

docs/WebGL/images/line_loop.png

6.84 KB
Loading

docs/WebGL/images/line_strip.png

6.32 KB
Loading

docs/WebGL/images/triangles.png

6.83 KB
Loading

0 commit comments

Comments
 (0)