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
|
var w = 1.0
document.getElementById("slider").addEventListener('change',(event)=>{
w = event.target.value
box.draw({
top : 0.5, // x
bottom : -0.5, // x
left : -0.5, // y
right : 0.5, // y
w : w, // w - 放大这个盒子
depth : 0, // z
color : [1, 0.4, 0.4, 1] // red
});
box.draw({
top : 0.9, // x
bottom : 0, // x
left : -0.9, // y
right : 0.9, // y
w : w, // w - 放大这个盒子
depth : 0.5, // z
color : [0.4, 1, 0.4, 1] // green
});
box.draw({
top : 1, // x
bottom : -1, // x
left : -1, // y
right : 1, // y
w : w, // w - 放大这个盒子
depth : 0.5, // z
color : [0.4, 0.4, 1, 1] // blue
});
});
function WebGLBox() {
// 设置 canvas 和 WebGL 上下文
this.canvas = document.getElementById('canvas');
// let width = d3.select("#content").node().getBoundingClientRect().width
this.canvas.width = 800;
this.canvas.height = 400;
this.gl = MDN.createContext(canvas);
var gl = this.gl;
// 设置一个 WebGL 程序,任何 MDN 对象相关的部分在本文之外定义
var vertexShader = `
// The individual position vertex
attribute vec4 position;
void main() {
// the gl_Position is the final position in clip space after the vertex shader modifies it
gl_Position = position;
}
`
var fragmentShader = `
precision mediump float;
uniform vec4 color;
void main() {
gl_FragColor = color;
}
`
this.webglProgram = MDN.createWebGLProgramFromContent(gl,vertexShader,fragmentShader);
gl.useProgram(this.webglProgram);
// 保存 attribute 和 uniform 位置
this.positionLocation = gl.getAttribLocation(this.webglProgram, 'position');
this.colorLocation = gl.getUniformLocation(this.webglProgram, 'color');
// 告诉 WebGL 在绘制时测试深度,所以如果一个正方形后面有另一个正方形
// 另一个正方形不会被绘制
gl.enable(gl.DEPTH_TEST);
}
WebGLBox.prototype.draw = function(settings) {
// 创建一下 attribute 数据; 这些是最终绘制到屏幕上的三角形
// 有两个形成一个正方形
var data = new Float32Array([
//Triangle 1
settings.left, settings.bottom, settings.depth, settings.w,
settings.right, settings.bottom, settings.depth, settings.w,
settings.left, settings.top, settings.depth, settings.w,
//Triangle 2
settings.left, settings.top, settings.depth, settings.w,
settings.right, settings.bottom, settings.depth, settings.w,
settings.right, settings.top, settings.depth, settings.w
]);
// 使用 WebGL 将其绘制到屏幕上
// 性能要点:为每个绘制创建新的缓冲器很慢
// 这个方法仅用于说明
var gl = this.gl;
// 创建一个缓冲区并绑定数据
var buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW);
// 设置指向 attribute 数据的指针(三角形)
gl.enableVertexAttribArray(this.positionLocation);
gl.vertexAttribPointer(this.positionLocation, 4, gl.FLOAT, false, 0, 0);
// 设置将在所有三角形之间共享的 color uniform
gl.uniform4fv(this.colorLocation, settings.color);
// 在屏幕上绘制该三角形
gl.drawArrays(gl.TRIANGLES, 0, 6);
}
var box = new WebGLBox();
box.draw({
top : 0.5, // x
bottom : -0.5, // x
left : -0.5, // y
right : 0.5, // y
w : w, // w - 放大这个盒子
depth : 0, // z
color : [1, 0.4, 0.4, 1] // red
});
box.draw({
top : 0.9, // x
bottom : 0, // x
left : -0.9, // y
right : 0.9, // y
w : w, // w - 放大这个盒子
depth : 0.5, // z
color : [0.4, 1, 0.4, 1] // green
});
box.draw({
top : 1, // x
bottom : -1, // x
left : -1, // y
right : 1, // y
w : w, // w - 放大这个盒子
depth : -1.5, // z
color : [0.4, 0.4, 1, 1] // blue
});
|