-
Notifications
You must be signed in to change notification settings - Fork 108
/
lesson19.html
154 lines (140 loc) · 4.84 KB
/
lesson19.html
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
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>绘制球体</title>
<link rel="stylesheet" href="../css/common.css" />
</head>
<body>
<script src="../utils/webgl-helper.js"></script>
<script src="../utils/webgl-matrix.js"></script>
<script src="../utils/vector3.js"></script>
<script src="../utils/geometry.js"></script>
<script src="../utils/math.js"></script>
<!-- 顶点着色器源码 -->
<script type="shader-source" id="vertexShader">
precision mediump float;
attribute vec3 a_Position;
attribute vec4 a_Color;
varying vec4 v_Color;
uniform mat4 u_Matrix;
void main(){
gl_Position = u_Matrix * vec4(a_Position, 1);
v_Color = a_Color;
}
</script>
<!-- 片元着色器源码 -->
<script type="shader-source" id="fragmentShader">
precision mediump float;
varying vec4 v_Color;
void main(){
gl_FragColor = v_Color ;
}
</script>
<canvas id="canvas"></canvas>
<div class="operation-container">
<button id="switchButton">播放</button>
</div>
<script>
var Vector3 = window.lib3d.Vector3;
//获取canvas
var canvas = getCanvas('#canvas');
resizeCanvas(canvas);
//获取webgl绘图环境
var gl = getContext(canvas);
//创建着色器程序
var program = createSimpleProgramFromScript(
gl,
'vertexShader',
'fragmentShader'
);
//使用创建好的着色器程序
gl.useProgram(program);
//顶点信息
var sphere = createSphere(5, 12, 12);
sphere = transformIndicesToUnIndices(sphere);
createColorForVertex(sphere);
var positions = sphere.positions;
var indices = sphere.indices;
var colors = sphere.colors;
var a_Position = gl.getAttribLocation(program, 'a_Position');
var a_Color = gl.getAttribLocation(program, 'a_Color');
var u_Matrix = gl.getUniformLocation(program, 'u_Matrix');
var u_Texture = gl.getUniformLocation(program, 'u_Texture');
gl.enableVertexAttribArray(a_Position);
gl.enableVertexAttribArray(a_Color);
var aspect = canvas.clientWidth / canvas.clientHeight;
var fieldOfViewRadians = 60;
var projectionMatrix = matrix.perspective(
fieldOfViewRadians,
aspect,
1,
2000
);
var cameraPosition = new Vector3(0, 0, 20);
var target = new Vector3(0, 0, 0);
var up = new Vector3(0, 1, 0);
var cameraMatrix = matrix.lookAt(cameraPosition, target, up);
var viewMatrix = matrix.inverse(cameraMatrix);
var viewProjectionMatrix = matrix.multiply(projectionMatrix, viewMatrix);
gl.uniformMatrix4fv(u_Matrix, false, viewProjectionMatrix);
var buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);
gl.vertexAttribPointer(a_Position, 3, gl.FLOAT, false, 0, 0);
var colorBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW);
gl.vertexAttribPointer(a_Color, 4, gl.UNSIGNED_BYTE, true, 0, 0);
var indicesBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indicesBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
function render(gl) {
//用上一步设置的清空画布颜色清空画布。
gl.clear(gl.COLOR_BUFFER_BIT);
if (positions.length <= 0) {
return;
}
//绘制图元设置为三角形。
let primitiveType = gl.TRIANGLES;
gl.drawArrays(primitiveType, 0, sphere.positions.length / 3);
}
//设置清屏颜色
gl.clearColor(0, 0, 0, 1.0);
gl.enable(gl.DEPTH_TEST);
gl.enable(gl.CULL_FACE);
var yAngle = 0;
var xAngle = 0;
var timer = null;
var matrixX = matrix.identity();
var matrixY = matrix.identity();
switchButton.addEventListener('click', animate);
function animate(e) {
if (timer) {
clearInterval(timer);
timer = null;
} else {
timer = setInterval(() => {
yAngle += 1;
xAngle += 1;
matrixY = matrix.rotationY((Math.PI / 180) * yAngle, matrixY);
matrixX = matrix.rotateX(
matrixY,
(Math.PI / 180) * xAngle,
matrixX
);
gl.uniformMatrix4fv(
u_Matrix,
false,
matrix.multiply(viewProjectionMatrix, matrixX)
);
render(gl);
}, 50);
}
}
render(gl);
</script>
</body>
</html>