@openglobus/og 0.10.3 → 0.10.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/css/og.css +1 -1
- package/package.json +4 -4
- package/src/og/Extent.js +274 -273
- package/src/og/Globe.js +11 -3
- package/src/og/LonLat.js +148 -147
- package/src/og/camera/PlanetCamera.js +110 -38
- package/src/og/control/EarthNavigation.js +259 -0
- package/src/og/control/MouseNavigation.js +68 -40
- package/src/og/layer/CanvasTiles.js +32 -30
- package/src/og/layer/KML.js +157 -0
- package/src/og/quadTree/Node.js +72 -19
- package/src/og/renderer/RendererEvents.js +21 -16
- package/src/og/scene/Planet.js +7 -2
- package/src/og/segment/Segment.js +2 -4
- package/src/og/utils/FontAtlas.js +1 -0
- package/src/og/{segment → utils}/PlainSegmentWorker.js +425 -407
- package/src/og/webgl/Handler.js +866 -845
package/src/og/webgl/Handler.js
CHANGED
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
* @module og/webgl/Handler
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
"use strict";
|
|
6
6
|
|
|
7
|
-
import { cons } from
|
|
8
|
-
import { Clock } from
|
|
9
|
-
import { ImageCanvas } from
|
|
10
|
-
import { isEmpty } from
|
|
11
|
-
import { ProgramController } from
|
|
12
|
-
import { Stack } from
|
|
13
|
-
import { Vec2 } from
|
|
7
|
+
import { cons } from "../cons.js";
|
|
8
|
+
import { Clock } from "../Clock.js";
|
|
9
|
+
import { ImageCanvas } from "../ImageCanvas.js";
|
|
10
|
+
import { isEmpty } from "../utils/shared.js";
|
|
11
|
+
import { ProgramController } from "./ProgramController.js";
|
|
12
|
+
import { Stack } from "../Stack.js";
|
|
13
|
+
import { Vec2 } from "../math/Vec2.js";
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* Maximum texture image size.
|
|
@@ -33,969 +33,990 @@ const vendorPrefixes = ["", "WEBKIT_", "MOZ_"];
|
|
|
33
33
|
* @param {Object} [param.scontext] - Native WebGL context attributes. See https://www.khronos.org/registry/webgl/specs/latest/1.0/#WEBGLCONTEXTATTRIBUTES
|
|
34
34
|
* @param {Array.<string>} [params.extensions] - Additional WebGL extension list. Available by default: EXT_texture_filter_anisotropic.
|
|
35
35
|
*/
|
|
36
|
-
|
|
36
|
+
class Handler {
|
|
37
|
+
constructor(id, params) {
|
|
38
|
+
params = params || {};
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Application default timer.
|
|
42
|
+
* @public
|
|
43
|
+
* @type {og.Clock}
|
|
44
|
+
*/
|
|
45
|
+
this.defaultClock = new Clock();
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Custom timers.
|
|
49
|
+
* @protected
|
|
50
|
+
* @type{og.Clock[]}
|
|
51
|
+
*/
|
|
52
|
+
this._clocks = [];
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Draw frame time in milliseconds.
|
|
56
|
+
* @public
|
|
57
|
+
* @readonly
|
|
58
|
+
* @type {number}
|
|
59
|
+
*/
|
|
60
|
+
this.deltaTime = 0;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* WebGL rendering canvas element.
|
|
64
|
+
* @public
|
|
65
|
+
* @type {Object}
|
|
66
|
+
*/
|
|
67
|
+
this.canvas = null;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* WebGL context.
|
|
71
|
+
* @public
|
|
72
|
+
* @type {Object}
|
|
73
|
+
*/
|
|
74
|
+
this.gl = null;
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Shader program controller list.
|
|
78
|
+
* @public
|
|
79
|
+
* @type {Object.<og.webgl.ProgramController>}
|
|
80
|
+
*/
|
|
81
|
+
this.programs = {};
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Current active shader program controller.
|
|
85
|
+
* @public
|
|
86
|
+
* @type {og.webgl.ProgramController}
|
|
87
|
+
*/
|
|
88
|
+
this.activeProgram = null;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Handler parameters.
|
|
92
|
+
* @private
|
|
93
|
+
* @type {Object}
|
|
94
|
+
*/
|
|
95
|
+
this._params = params || {};
|
|
96
|
+
this._params.anisotropy = this._params.anisotropy || 8;
|
|
97
|
+
let w = this._params.width;
|
|
98
|
+
if (w > MAX_SIZE) {
|
|
99
|
+
w = MAX_SIZE;
|
|
100
|
+
}
|
|
101
|
+
this._params.width = w || 256;
|
|
37
102
|
|
|
38
|
-
|
|
103
|
+
var h = this._params.height;
|
|
104
|
+
if (h > MAX_SIZE) {
|
|
105
|
+
h = MAX_SIZE;
|
|
106
|
+
}
|
|
107
|
+
this._params.height = h || 256;
|
|
108
|
+
this._params.context = this._params.context || {};
|
|
109
|
+
this._params.extensions = this._params.extensions || [];
|
|
110
|
+
this._oneByHeight = 1 / this._params.height;
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Current WebGL extensions. Becomes here after context initialization.
|
|
114
|
+
* @public
|
|
115
|
+
* @type {Object}
|
|
116
|
+
*/
|
|
117
|
+
this.extensions = {};
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* HTML Canvas object id.
|
|
121
|
+
* @private
|
|
122
|
+
* @type {Object}
|
|
123
|
+
*/
|
|
124
|
+
this._id = id;
|
|
125
|
+
|
|
126
|
+
this._lastAnimationFrameTime = 0;
|
|
127
|
+
|
|
128
|
+
this._initialized = false;
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Animation frame function assigned from outside(Ex. from Renderer).
|
|
132
|
+
* @private
|
|
133
|
+
* @type {frameCallback}
|
|
134
|
+
*/
|
|
135
|
+
this._frameCallback = function () {};
|
|
136
|
+
|
|
137
|
+
this.transparentTexture = null;
|
|
138
|
+
|
|
139
|
+
this.framebufferStack = new Stack();
|
|
140
|
+
|
|
141
|
+
if (params.autoActivate || isEmpty(params.autoActivate)) {
|
|
142
|
+
this.initialize();
|
|
143
|
+
}
|
|
144
|
+
}
|
|
39
145
|
|
|
40
146
|
/**
|
|
41
|
-
*
|
|
42
|
-
* @
|
|
43
|
-
* @
|
|
147
|
+
* The return value is null if the extension is not supported, or an extension object otherwise.
|
|
148
|
+
* @param {Object} gl - WebGl context pointer.
|
|
149
|
+
* @param {String} name - Extension name.
|
|
150
|
+
* @returns {Object} -
|
|
44
151
|
*/
|
|
45
|
-
|
|
152
|
+
static getExtension(gl, name) {
|
|
153
|
+
var i, ext;
|
|
154
|
+
for (i in vendorPrefixes) {
|
|
155
|
+
ext = gl.getExtension(vendorPrefixes[i] + name);
|
|
156
|
+
if (ext) {
|
|
157
|
+
return ext;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
46
162
|
|
|
47
163
|
/**
|
|
48
|
-
*
|
|
49
|
-
* @
|
|
50
|
-
* @
|
|
164
|
+
* Returns a drawing context on the canvas, or null if the context identifier is not supported.
|
|
165
|
+
* @param {Object} canvas - HTML canvas object.
|
|
166
|
+
* @param {Object} [contextAttributes] - See canvas.getContext contextAttributes.
|
|
167
|
+
* @returns {Object} -
|
|
51
168
|
*/
|
|
52
|
-
|
|
169
|
+
static getContext(canvas, contextAttributes) {
|
|
170
|
+
const CONTEXT_TYPE = ["webgl2", "webgl"];
|
|
171
|
+
var ctx = null;
|
|
172
|
+
|
|
173
|
+
try {
|
|
174
|
+
for (let i = 0; i < CONTEXT_TYPE.length; i++) {
|
|
175
|
+
ctx = canvas.getContext(CONTEXT_TYPE[i], contextAttributes);
|
|
176
|
+
if (ctx) {
|
|
177
|
+
ctx.type = CONTEXT_TYPE[i];
|
|
178
|
+
break;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
} catch (ex) {
|
|
182
|
+
cons.logErr("exception during the GL context initialization");
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
if (!ctx) {
|
|
186
|
+
cons.logErr("could not initialise WebGL");
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
return ctx;
|
|
190
|
+
}
|
|
53
191
|
|
|
54
192
|
/**
|
|
55
|
-
*
|
|
193
|
+
* Sets animation frame function.
|
|
56
194
|
* @public
|
|
57
|
-
* @
|
|
58
|
-
* @type {number}
|
|
195
|
+
* @param {callback} callback - Frame callback.
|
|
59
196
|
*/
|
|
60
|
-
|
|
197
|
+
setFrameCallback(callback) {
|
|
198
|
+
callback && (this._frameCallback = callback);
|
|
199
|
+
}
|
|
61
200
|
|
|
62
201
|
/**
|
|
63
|
-
*
|
|
202
|
+
* Creates NEAREST filter texture.
|
|
64
203
|
* @public
|
|
65
|
-
* @
|
|
204
|
+
* @param {Object} image - Image or Canvas object.
|
|
205
|
+
* @returns {Object} - WebGL texture object.
|
|
66
206
|
*/
|
|
67
|
-
|
|
207
|
+
createTexture_n(image) {
|
|
208
|
+
var gl = this.gl;
|
|
209
|
+
var texture = gl.createTexture();
|
|
210
|
+
gl.bindTexture(gl.TEXTURE_2D, texture);
|
|
211
|
+
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
|
|
212
|
+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
|
|
213
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
|
|
214
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
|
|
215
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
216
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
217
|
+
gl.bindTexture(gl.TEXTURE_2D, null);
|
|
218
|
+
return texture;
|
|
219
|
+
}
|
|
68
220
|
|
|
69
221
|
/**
|
|
70
|
-
*
|
|
222
|
+
* Creates empty texture.
|
|
71
223
|
* @public
|
|
72
|
-
* @
|
|
224
|
+
* @param {Number} [width=1] - Specifies the width of the texture image..
|
|
225
|
+
* @param {Number} [height=1] - Specifies the width of the texture image..
|
|
226
|
+
* @param {String} [filter="NEAREST"] - Specifies GL_TEXTURE_MIN(MAX)_FILTER texture value.
|
|
227
|
+
* @param {String} [internalFormat="RGBA"] - Specifies the color components in the texture.
|
|
228
|
+
* @param {String} [format="RGBA"] - Specifies the format of the texel data.
|
|
229
|
+
* @param {String} [type="UNSIGNED_BYTE"] - Specifies the data type of the texel data.
|
|
230
|
+
* @param {Number} [levels=0] - Specifies the level-of-detail number. Level 0 is the base image level. Level n is the nth mipmap reduction image.
|
|
231
|
+
* @returns {Object} - WebGL texture object.
|
|
73
232
|
*/
|
|
74
|
-
|
|
233
|
+
createEmptyTexture2DExt(
|
|
234
|
+
width = 1,
|
|
235
|
+
height = 1,
|
|
236
|
+
filter = "NEAREST",
|
|
237
|
+
internalFormat = "RGBA",
|
|
238
|
+
format = "RGBA",
|
|
239
|
+
type = "UNSIGNED_BYTE",
|
|
240
|
+
level = 0
|
|
241
|
+
) {
|
|
242
|
+
var gl = this.gl;
|
|
243
|
+
var texture = gl.createTexture();
|
|
244
|
+
gl.bindTexture(gl.TEXTURE_2D, texture);
|
|
245
|
+
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
|
|
246
|
+
|
|
247
|
+
gl.texImage2D(
|
|
248
|
+
gl.TEXTURE_2D,
|
|
249
|
+
level,
|
|
250
|
+
gl[internalFormat.toUpperCase()],
|
|
251
|
+
width,
|
|
252
|
+
height,
|
|
253
|
+
0,
|
|
254
|
+
gl[format.toUpperCase()],
|
|
255
|
+
gl[type.toUpperCase()],
|
|
256
|
+
null
|
|
257
|
+
);
|
|
258
|
+
|
|
259
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl[filter.toUpperCase()]);
|
|
260
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl[filter.toUpperCase()]);
|
|
261
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
262
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
263
|
+
|
|
264
|
+
gl.bindTexture(gl.TEXTURE_2D, null);
|
|
265
|
+
return texture;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
///**
|
|
269
|
+
// * Creates Empty half float texture.
|
|
270
|
+
// * @public
|
|
271
|
+
// * @param {number} width - Empty texture width.
|
|
272
|
+
// * @param {number} height - Empty texture height.
|
|
273
|
+
// * @returns {Object} - WebGL half float texture object.
|
|
274
|
+
// */
|
|
275
|
+
//createEmptyTexture_hf(width, height) {
|
|
276
|
+
// var gl = this.gl;
|
|
277
|
+
// var texture = gl.createTexture();
|
|
278
|
+
// gl.bindTexture(gl.TEXTURE_2D, texture);
|
|
279
|
+
// gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
|
|
280
|
+
// gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.HALF_FLOAT_OES, null);
|
|
281
|
+
// //gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
|
|
282
|
+
// //gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
|
|
283
|
+
// //gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
284
|
+
// //gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
285
|
+
// gl.bindTexture(gl.TEXTURE_2D, null);
|
|
286
|
+
// return texture;
|
|
287
|
+
//}
|
|
288
|
+
|
|
289
|
+
///**
|
|
290
|
+
// * Creates Empty float texture.
|
|
291
|
+
// * @public
|
|
292
|
+
// * @param {number} width - Empty texture width.
|
|
293
|
+
// * @param {number} height - Empty texture height.
|
|
294
|
+
// * @returns {Object} - WebGL float texture object.
|
|
295
|
+
// */
|
|
296
|
+
//createEmptyTexture_f(width, height) {
|
|
297
|
+
// var gl = this.gl;
|
|
298
|
+
// var texture = gl.createTexture();
|
|
299
|
+
// gl.bindTexture(gl.TEXTURE_2D, texture);
|
|
300
|
+
// gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
|
|
301
|
+
// gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.FLOAT, null);
|
|
302
|
+
// //gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
|
|
303
|
+
// //gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
|
|
304
|
+
// //gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
305
|
+
// //gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
306
|
+
// gl.bindTexture(gl.TEXTURE_2D, null);
|
|
307
|
+
// return texture;
|
|
308
|
+
//}
|
|
75
309
|
|
|
76
310
|
/**
|
|
77
|
-
*
|
|
311
|
+
* Creates Empty NEAREST filtered texture.
|
|
78
312
|
* @public
|
|
79
|
-
* @
|
|
313
|
+
* @param {number} width - Empty texture width.
|
|
314
|
+
* @param {number} height - Empty texture height.
|
|
315
|
+
* @returns {Object} - WebGL texture object.
|
|
80
316
|
*/
|
|
81
|
-
|
|
317
|
+
createEmptyTexture_n(width, height) {
|
|
318
|
+
var gl = this.gl;
|
|
319
|
+
var texture = gl.createTexture();
|
|
320
|
+
gl.bindTexture(gl.TEXTURE_2D, texture);
|
|
321
|
+
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
|
|
322
|
+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
|
|
323
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
|
|
324
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
|
|
325
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
326
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
327
|
+
gl.bindTexture(gl.TEXTURE_2D, null);
|
|
328
|
+
return texture;
|
|
329
|
+
}
|
|
82
330
|
|
|
83
331
|
/**
|
|
84
|
-
*
|
|
332
|
+
* Creates empty LINEAR filtered texture.
|
|
85
333
|
* @public
|
|
86
|
-
* @
|
|
334
|
+
* @param {number} width - Empty texture width.
|
|
335
|
+
* @param {number} height - Empty texture height.
|
|
336
|
+
* @returns {Object} - WebGL texture object.
|
|
87
337
|
*/
|
|
88
|
-
|
|
338
|
+
createEmptyTexture_l(width, height) {
|
|
339
|
+
var gl = this.gl;
|
|
340
|
+
var texture = gl.createTexture();
|
|
341
|
+
gl.bindTexture(gl.TEXTURE_2D, texture);
|
|
342
|
+
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
|
|
343
|
+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
|
|
344
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
|
345
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
|
346
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
347
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
348
|
+
gl.bindTexture(gl.TEXTURE_2D, null);
|
|
349
|
+
return texture;
|
|
350
|
+
}
|
|
89
351
|
|
|
90
352
|
/**
|
|
91
|
-
*
|
|
92
|
-
* @
|
|
93
|
-
* @
|
|
353
|
+
* Creates LINEAR filter texture.
|
|
354
|
+
* @public
|
|
355
|
+
* @param {Object} image - Image or Canvas object.
|
|
356
|
+
* @returns {Object} - WebGL texture object.
|
|
94
357
|
*/
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
358
|
+
createTexture_l(image) {
|
|
359
|
+
var gl = this.gl;
|
|
360
|
+
var texture = gl.createTexture();
|
|
361
|
+
gl.bindTexture(gl.TEXTURE_2D, texture);
|
|
362
|
+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
|
|
363
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
|
364
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
|
365
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
366
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
367
|
+
gl.bindTexture(gl.TEXTURE_2D, null);
|
|
368
|
+
return texture;
|
|
100
369
|
}
|
|
101
|
-
this._params.width = w || 256;
|
|
102
370
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
371
|
+
/**
|
|
372
|
+
* Creates MIPMAP filter texture.
|
|
373
|
+
* @public
|
|
374
|
+
* @param {Object} image - Image or Canvas object.
|
|
375
|
+
* @returns {Object} - WebGL texture object.
|
|
376
|
+
*/
|
|
377
|
+
createTexture_mm(image) {
|
|
378
|
+
var gl = this.gl;
|
|
379
|
+
var texture = gl.createTexture();
|
|
380
|
+
gl.bindTexture(gl.TEXTURE_2D, texture);
|
|
381
|
+
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
|
|
382
|
+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
|
|
383
|
+
gl.generateMipmap(gl.TEXTURE_2D);
|
|
384
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
|
|
385
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
386
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
387
|
+
gl.bindTexture(gl.TEXTURE_2D, null);
|
|
388
|
+
return texture;
|
|
106
389
|
}
|
|
107
|
-
this._params.height = h || 256;
|
|
108
|
-
this._params.context = this._params.context || {};
|
|
109
|
-
this._params.extensions = this._params.extensions || [];
|
|
110
|
-
this._oneByHeight = 1 / this._params.height;
|
|
111
390
|
|
|
112
391
|
/**
|
|
113
|
-
*
|
|
392
|
+
* Creates ANISOTROPY filter texture.
|
|
114
393
|
* @public
|
|
115
|
-
* @
|
|
394
|
+
* @param {Object} image - Image or Canvas object.
|
|
395
|
+
* @returns {Object} - WebGL texture object.
|
|
116
396
|
*/
|
|
117
|
-
|
|
397
|
+
createTexture_a(image) {
|
|
398
|
+
var gl = this.gl;
|
|
399
|
+
var texture = gl.createTexture();
|
|
400
|
+
gl.bindTexture(gl.TEXTURE_2D, texture);
|
|
401
|
+
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
|
|
402
|
+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
|
|
403
|
+
gl.generateMipmap(gl.TEXTURE_2D);
|
|
404
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
|
|
405
|
+
gl.texParameterf(
|
|
406
|
+
gl.TEXTURE_2D,
|
|
407
|
+
this.extensions.EXT_texture_filter_anisotropic.TEXTURE_MAX_ANISOTROPY_EXT,
|
|
408
|
+
this._params.anisotropy
|
|
409
|
+
);
|
|
410
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
411
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
412
|
+
gl.bindTexture(gl.TEXTURE_2D, null);
|
|
413
|
+
return texture;
|
|
414
|
+
}
|
|
118
415
|
|
|
119
416
|
/**
|
|
120
|
-
*
|
|
121
|
-
* @
|
|
122
|
-
* @
|
|
417
|
+
* Creates DEFAULT filter texture, ANISOTROPY is default.
|
|
418
|
+
* @public
|
|
419
|
+
* @param {Object} image - Image or Canvas object.
|
|
420
|
+
* @returns {Object} - WebGL texture object.
|
|
123
421
|
*/
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
this._initialized = false;
|
|
422
|
+
createTexture(image) {
|
|
423
|
+
return this.createTexture_a(image);
|
|
424
|
+
}
|
|
129
425
|
|
|
130
426
|
/**
|
|
131
|
-
*
|
|
132
|
-
* @
|
|
133
|
-
* @
|
|
427
|
+
* Creates cube texture.
|
|
428
|
+
* @public
|
|
429
|
+
* @param {Object.<string>} params - Face image urls:
|
|
430
|
+
* @param {string} params.px - Positive X or right image url.
|
|
431
|
+
* @param {string} params.nx - Negative X or left image url.
|
|
432
|
+
* @param {string} params.py - Positive Y or up image url.
|
|
433
|
+
* @param {string} params.ny - Negative Y or bottom image url.
|
|
434
|
+
* @param {string} params.pz - Positive Z or face image url.
|
|
435
|
+
* @param {string} params.nz - Negative Z or back image url.
|
|
436
|
+
* @returns {Object} - WebGL texture object.
|
|
134
437
|
*/
|
|
135
|
-
|
|
438
|
+
loadCubeMapTexture(params) {
|
|
439
|
+
var gl = this.gl;
|
|
440
|
+
var texture = gl.createTexture();
|
|
441
|
+
gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture);
|
|
442
|
+
gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
443
|
+
gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
444
|
+
gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
|
445
|
+
gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
|
446
|
+
|
|
447
|
+
var faces = [
|
|
448
|
+
[params.px, gl.TEXTURE_CUBE_MAP_POSITIVE_X],
|
|
449
|
+
[params.nx, gl.TEXTURE_CUBE_MAP_NEGATIVE_X],
|
|
450
|
+
[params.py, gl.TEXTURE_CUBE_MAP_POSITIVE_Y],
|
|
451
|
+
[params.ny, gl.TEXTURE_CUBE_MAP_NEGATIVE_Y],
|
|
452
|
+
[params.pz, gl.TEXTURE_CUBE_MAP_POSITIVE_Z],
|
|
453
|
+
[params.nz, gl.TEXTURE_CUBE_MAP_NEGATIVE_Z]
|
|
454
|
+
];
|
|
455
|
+
|
|
456
|
+
var imageCanvas = new ImageCanvas();
|
|
457
|
+
imageCanvas.fillEmpty();
|
|
458
|
+
var emptyImage = imageCanvas.getImage();
|
|
459
|
+
|
|
460
|
+
for (let i = 0; i < faces.length; i++) {
|
|
461
|
+
let face = faces[i][1];
|
|
462
|
+
gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture);
|
|
463
|
+
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
|
|
464
|
+
gl.texImage2D(face, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, emptyImage);
|
|
465
|
+
}
|
|
136
466
|
|
|
137
|
-
|
|
467
|
+
for (let i = 0; i < faces.length; i++) {
|
|
468
|
+
let face = faces[i][1];
|
|
469
|
+
let image = new Image();
|
|
470
|
+
image.crossOrigin = "";
|
|
471
|
+
image.onload = (function (texture, face, image) {
|
|
472
|
+
return function () {
|
|
473
|
+
gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture);
|
|
474
|
+
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
|
|
475
|
+
gl.texImage2D(face, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
|
|
476
|
+
};
|
|
477
|
+
})(texture, face, image);
|
|
478
|
+
image.src = faces[i][0];
|
|
479
|
+
}
|
|
480
|
+
return texture;
|
|
481
|
+
}
|
|
138
482
|
|
|
139
|
-
|
|
483
|
+
/**
|
|
484
|
+
* Adds shader program to the handler.
|
|
485
|
+
* @public
|
|
486
|
+
* @param {og.webgl.Program} program - Shader program.
|
|
487
|
+
* @param {boolean} [notActivate] - If it's true program will not compile.
|
|
488
|
+
* @return {og.webgl.Program} -
|
|
489
|
+
*/
|
|
490
|
+
addProgram(program, notActivate) {
|
|
491
|
+
if (!this.programs[program.name]) {
|
|
492
|
+
var sc = new ProgramController(this, program);
|
|
493
|
+
this.programs[program.name] = sc;
|
|
494
|
+
this._initProgramController(sc);
|
|
495
|
+
if (notActivate) {
|
|
496
|
+
sc._activated = false;
|
|
497
|
+
}
|
|
498
|
+
} else {
|
|
499
|
+
console.log(
|
|
500
|
+
"og.webgl.Handler:284 - shader program: '" + program.name + "' is allready exists."
|
|
501
|
+
);
|
|
502
|
+
}
|
|
503
|
+
return program;
|
|
504
|
+
}
|
|
140
505
|
|
|
141
|
-
|
|
142
|
-
|
|
506
|
+
/**
|
|
507
|
+
* Removes shader program from handler.
|
|
508
|
+
* @public
|
|
509
|
+
* @param {String} name - Shader program name.
|
|
510
|
+
*/
|
|
511
|
+
removeProgram(name) {
|
|
512
|
+
this.programs[name] && this.programs[name].remove();
|
|
143
513
|
}
|
|
144
|
-
};
|
|
145
514
|
|
|
146
|
-
/**
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
for (i in vendorPrefixes) {
|
|
155
|
-
ext = gl.getExtension(vendorPrefixes[i] + name);
|
|
156
|
-
if (ext) {
|
|
157
|
-
return ext;
|
|
515
|
+
/**
|
|
516
|
+
* Adds shader programs to the handler.
|
|
517
|
+
* @public
|
|
518
|
+
* @param {Array.<og.webgl.Program>} programsArr - Shader program array.
|
|
519
|
+
*/
|
|
520
|
+
addPrograms(programsArr) {
|
|
521
|
+
for (var i = 0; i < programsArr.length; i++) {
|
|
522
|
+
this.addProgram(programsArr[i]);
|
|
158
523
|
}
|
|
159
524
|
}
|
|
160
|
-
return null;
|
|
161
|
-
};
|
|
162
525
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
ctx.type = CONTEXT_TYPE[i];
|
|
179
|
-
break;
|
|
526
|
+
/**
|
|
527
|
+
* Used in addProgram
|
|
528
|
+
* @private
|
|
529
|
+
* @param {og.webgl.ProgramController} sc - Program controller
|
|
530
|
+
*/
|
|
531
|
+
_initProgramController(sc) {
|
|
532
|
+
if (this._initialized) {
|
|
533
|
+
sc.initialize();
|
|
534
|
+
if (!this.activeProgram) {
|
|
535
|
+
this.activeProgram = sc;
|
|
536
|
+
sc.activate();
|
|
537
|
+
} else {
|
|
538
|
+
sc.deactivate();
|
|
539
|
+
this.activeProgram._program.enableAttribArrays();
|
|
540
|
+
this.activeProgram._program.use();
|
|
180
541
|
}
|
|
181
542
|
}
|
|
182
|
-
} catch (ex) {
|
|
183
|
-
cons.logErr("exception during the GL context initialization");
|
|
184
543
|
}
|
|
185
544
|
|
|
186
|
-
|
|
187
|
-
|
|
545
|
+
/**
|
|
546
|
+
* Used in init function.
|
|
547
|
+
* @private
|
|
548
|
+
*/
|
|
549
|
+
_initPrograms() {
|
|
550
|
+
for (var p in this.programs) {
|
|
551
|
+
this._initProgramController(this.programs[p]);
|
|
552
|
+
}
|
|
188
553
|
}
|
|
189
554
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
var texture = gl.createTexture();
|
|
211
|
-
gl.bindTexture(gl.TEXTURE_2D, texture);
|
|
212
|
-
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
|
|
213
|
-
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
|
|
214
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
|
|
215
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
|
|
216
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
217
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
218
|
-
gl.bindTexture(gl.TEXTURE_2D, null);
|
|
219
|
-
return texture;
|
|
220
|
-
};
|
|
221
|
-
|
|
222
|
-
/**
|
|
223
|
-
* Creates empty texture.
|
|
224
|
-
* @public
|
|
225
|
-
* @param {Number} [width=1] - Specifies the width of the texture image..
|
|
226
|
-
* @param {Number} [height=1] - Specifies the width of the texture image..
|
|
227
|
-
* @param {String} [filter="NEAREST"] - Specifies GL_TEXTURE_MIN(MAX)_FILTER texture value.
|
|
228
|
-
* @param {String} [internalFormat="RGBA"] - Specifies the color components in the texture.
|
|
229
|
-
* @param {String} [format="RGBA"] - Specifies the format of the texel data.
|
|
230
|
-
* @param {String} [type="UNSIGNED_BYTE"] - Specifies the data type of the texel data.
|
|
231
|
-
* @param {Number} [levels=0] - Specifies the level-of-detail number. Level 0 is the base image level. Level n is the nth mipmap reduction image.
|
|
232
|
-
* @returns {Object} - WebGL texture object.
|
|
233
|
-
*/
|
|
234
|
-
Handler.prototype.createEmptyTexture2DExt = function (
|
|
235
|
-
width = 1,
|
|
236
|
-
height = 1,
|
|
237
|
-
filter = "NEAREST",
|
|
238
|
-
internalFormat = "RGBA",
|
|
239
|
-
format = "RGBA",
|
|
240
|
-
type = "UNSIGNED_BYTE",
|
|
241
|
-
level = 0
|
|
242
|
-
) {
|
|
243
|
-
var gl = this.gl;
|
|
244
|
-
var texture = gl.createTexture();
|
|
245
|
-
gl.bindTexture(gl.TEXTURE_2D, texture);
|
|
246
|
-
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
|
|
247
|
-
|
|
248
|
-
gl.texImage2D(gl.TEXTURE_2D, level, gl[internalFormat.toUpperCase()], width, height, 0,
|
|
249
|
-
gl[format.toUpperCase()], gl[type.toUpperCase()], null);
|
|
250
|
-
|
|
251
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl[filter.toUpperCase()]);
|
|
252
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl[filter.toUpperCase()]);
|
|
253
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
254
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
255
|
-
|
|
256
|
-
gl.bindTexture(gl.TEXTURE_2D, null);
|
|
257
|
-
return texture;
|
|
258
|
-
};
|
|
259
|
-
|
|
260
|
-
///**
|
|
261
|
-
// * Creates Empty half float texture.
|
|
262
|
-
// * @public
|
|
263
|
-
// * @param {number} width - Empty texture width.
|
|
264
|
-
// * @param {number} height - Empty texture height.
|
|
265
|
-
// * @returns {Object} - WebGL half float texture object.
|
|
266
|
-
// */
|
|
267
|
-
//Handler.prototype.createEmptyTexture_hf = function (width, height) {
|
|
268
|
-
// var gl = this.gl;
|
|
269
|
-
// var texture = gl.createTexture();
|
|
270
|
-
// gl.bindTexture(gl.TEXTURE_2D, texture);
|
|
271
|
-
// gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
|
|
272
|
-
// gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.HALF_FLOAT_OES, null);
|
|
273
|
-
// //gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
|
|
274
|
-
// //gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
|
|
275
|
-
// //gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
276
|
-
// //gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
277
|
-
// gl.bindTexture(gl.TEXTURE_2D, null);
|
|
278
|
-
// return texture;
|
|
279
|
-
//}
|
|
280
|
-
|
|
281
|
-
///**
|
|
282
|
-
// * Creates Empty float texture.
|
|
283
|
-
// * @public
|
|
284
|
-
// * @param {number} width - Empty texture width.
|
|
285
|
-
// * @param {number} height - Empty texture height.
|
|
286
|
-
// * @returns {Object} - WebGL float texture object.
|
|
287
|
-
// */
|
|
288
|
-
//Handler.prototype.createEmptyTexture_f = function (width, height) {
|
|
289
|
-
// var gl = this.gl;
|
|
290
|
-
// var texture = gl.createTexture();
|
|
291
|
-
// gl.bindTexture(gl.TEXTURE_2D, texture);
|
|
292
|
-
// gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
|
|
293
|
-
// gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.FLOAT, null);
|
|
294
|
-
// //gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
|
|
295
|
-
// //gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
|
|
296
|
-
// //gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
297
|
-
// //gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
298
|
-
// gl.bindTexture(gl.TEXTURE_2D, null);
|
|
299
|
-
// return texture;
|
|
300
|
-
//}
|
|
555
|
+
/**
|
|
556
|
+
* Initialize additional WebGL extensions.
|
|
557
|
+
* @public
|
|
558
|
+
* @param {string} extensionStr - Extension name.
|
|
559
|
+
* @param {boolean} showLog - Show logging.
|
|
560
|
+
* @return {Object} -
|
|
561
|
+
*/
|
|
562
|
+
initializeExtension(extensionStr, showLog) {
|
|
563
|
+
if (!(this.extensions && this.extensions[extensionStr])) {
|
|
564
|
+
var ext = Handler.getExtension(this.gl, extensionStr);
|
|
565
|
+
if (ext) {
|
|
566
|
+
this.extensions[extensionStr] = ext;
|
|
567
|
+
} else if (showLog) {
|
|
568
|
+
console.log(
|
|
569
|
+
"og.webgl.Handler: extension '" + extensionStr + "' doesn't initialize."
|
|
570
|
+
);
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
return this.extensions && this.extensions[extensionStr];
|
|
574
|
+
}
|
|
301
575
|
|
|
302
|
-
/**
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
|
|
315
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
|
|
316
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
|
|
317
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
318
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
319
|
-
gl.bindTexture(gl.TEXTURE_2D, null);
|
|
320
|
-
return texture;
|
|
321
|
-
};
|
|
576
|
+
/**
|
|
577
|
+
* Main function that initialize handler.
|
|
578
|
+
* @public
|
|
579
|
+
*/
|
|
580
|
+
initialize() {
|
|
581
|
+
if (this._id) {
|
|
582
|
+
this.canvas = document.getElementById(this._id);
|
|
583
|
+
} else {
|
|
584
|
+
this.canvas = document.createElement("canvas");
|
|
585
|
+
this.canvas.width = this._params.width;
|
|
586
|
+
this.canvas.height = this._params.height;
|
|
587
|
+
}
|
|
322
588
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
* @public
|
|
326
|
-
* @param {number} width - Empty texture width.
|
|
327
|
-
* @param {number} height - Empty texture height.
|
|
328
|
-
* @returns {Object} - WebGL texture object.
|
|
329
|
-
*/
|
|
330
|
-
Handler.prototype.createEmptyTexture_l = function (width, height) {
|
|
331
|
-
var gl = this.gl;
|
|
332
|
-
var texture = gl.createTexture();
|
|
333
|
-
gl.bindTexture(gl.TEXTURE_2D, texture);
|
|
334
|
-
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
|
|
335
|
-
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
|
|
336
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
|
337
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
|
338
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
339
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
340
|
-
gl.bindTexture(gl.TEXTURE_2D, null);
|
|
341
|
-
return texture;
|
|
342
|
-
};
|
|
589
|
+
this.gl = Handler.getContext(this.canvas, this._params.context);
|
|
590
|
+
this._initialized = true;
|
|
343
591
|
|
|
344
|
-
/**
|
|
345
|
-
|
|
346
|
-
* @public
|
|
347
|
-
* @param {Object} image - Image or Canvas object.
|
|
348
|
-
* @returns {Object} - WebGL texture object.
|
|
349
|
-
*/
|
|
350
|
-
Handler.prototype.createTexture_l = function (image) {
|
|
351
|
-
var gl = this.gl;
|
|
352
|
-
var texture = gl.createTexture();
|
|
353
|
-
gl.bindTexture(gl.TEXTURE_2D, texture);
|
|
354
|
-
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
|
|
355
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
|
356
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
|
357
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
358
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
359
|
-
gl.bindTexture(gl.TEXTURE_2D, null);
|
|
360
|
-
return texture;
|
|
361
|
-
};
|
|
592
|
+
/** Sets deafult extensions */
|
|
593
|
+
this._params.extensions.push("EXT_texture_filter_anisotropic");
|
|
362
594
|
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
gl.bindTexture(gl.TEXTURE_2D, texture);
|
|
373
|
-
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
|
|
374
|
-
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
|
|
375
|
-
gl.generateMipmap(gl.TEXTURE_2D);
|
|
376
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
|
|
377
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
378
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
379
|
-
gl.bindTexture(gl.TEXTURE_2D, null);
|
|
380
|
-
return texture;
|
|
381
|
-
};
|
|
595
|
+
if (this.gl.type === "webgl") {
|
|
596
|
+
this._params.extensions.push("OES_standard_derivatives");
|
|
597
|
+
this._params.extensions.push("OES_element_index_uint");
|
|
598
|
+
this._params.extensions.push("WEBGL_depth_texture");
|
|
599
|
+
//this._params.extensions.push("EXT_frag_depth");
|
|
600
|
+
} else {
|
|
601
|
+
this._params.extensions.push("EXT_color_buffer_float");
|
|
602
|
+
this._params.extensions.push("OES_texture_float_linear");
|
|
603
|
+
}
|
|
382
604
|
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
* @returns {Object} - WebGL texture object.
|
|
388
|
-
*/
|
|
389
|
-
Handler.prototype.createTexture_a = function (image) {
|
|
390
|
-
var gl = this.gl;
|
|
391
|
-
var texture = gl.createTexture();
|
|
392
|
-
gl.bindTexture(gl.TEXTURE_2D, texture);
|
|
393
|
-
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
|
|
394
|
-
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
|
|
395
|
-
gl.generateMipmap(gl.TEXTURE_2D);
|
|
396
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
|
|
397
|
-
gl.texParameterf(gl.TEXTURE_2D, this.extensions.EXT_texture_filter_anisotropic.TEXTURE_MAX_ANISOTROPY_EXT, this._params.anisotropy);
|
|
398
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
399
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
400
|
-
gl.bindTexture(gl.TEXTURE_2D, null);
|
|
401
|
-
return texture;
|
|
402
|
-
};
|
|
605
|
+
var i = this._params.extensions.length;
|
|
606
|
+
while (i--) {
|
|
607
|
+
this.initializeExtension(this._params.extensions[i], true);
|
|
608
|
+
}
|
|
403
609
|
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
* @param {Object} image - Image or Canvas object.
|
|
408
|
-
* @returns {Object} - WebGL texture object.
|
|
409
|
-
*/
|
|
410
|
-
Handler.prototype.createTexture = function (image) {
|
|
411
|
-
return this.createTexture_a(image);
|
|
412
|
-
};
|
|
610
|
+
if (!this.extensions.EXT_texture_filter_anisotropic) {
|
|
611
|
+
this.createTexture = this.createTexture_mm;
|
|
612
|
+
}
|
|
413
613
|
|
|
414
|
-
/**
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
* @param {Object.<string>} params - Face image urls:
|
|
418
|
-
* @param {string} params.px - Positive X or right image url.
|
|
419
|
-
* @param {string} params.nx - Negative X or left image url.
|
|
420
|
-
* @param {string} params.py - Positive Y or up image url.
|
|
421
|
-
* @param {string} params.ny - Negative Y or bottom image url.
|
|
422
|
-
* @param {string} params.pz - Positive Z or face image url.
|
|
423
|
-
* @param {string} params.nz - Negative Z or back image url.
|
|
424
|
-
* @returns {Object} - WebGL texture object.
|
|
425
|
-
*/
|
|
426
|
-
Handler.prototype.loadCubeMapTexture = function (params) {
|
|
427
|
-
var gl = this.gl;
|
|
428
|
-
var texture = gl.createTexture();
|
|
429
|
-
gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture);
|
|
430
|
-
gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
431
|
-
gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
432
|
-
gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
|
433
|
-
gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
|
434
|
-
|
|
435
|
-
var faces = [[params.px, gl.TEXTURE_CUBE_MAP_POSITIVE_X],
|
|
436
|
-
[params.nx, gl.TEXTURE_CUBE_MAP_NEGATIVE_X],
|
|
437
|
-
[params.py, gl.TEXTURE_CUBE_MAP_POSITIVE_Y],
|
|
438
|
-
[params.ny, gl.TEXTURE_CUBE_MAP_NEGATIVE_Y],
|
|
439
|
-
[params.pz, gl.TEXTURE_CUBE_MAP_POSITIVE_Z],
|
|
440
|
-
[params.nz, gl.TEXTURE_CUBE_MAP_NEGATIVE_Z]];
|
|
441
|
-
|
|
442
|
-
var imageCanvas = new ImageCanvas();
|
|
443
|
-
imageCanvas.fillEmpty();
|
|
444
|
-
var emptyImage = imageCanvas.getImage();
|
|
445
|
-
|
|
446
|
-
for (let i = 0; i < faces.length; i++) {
|
|
447
|
-
let face = faces[i][1];
|
|
448
|
-
gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture);
|
|
449
|
-
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
|
|
450
|
-
gl.texImage2D(face, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, emptyImage);
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
for (let i = 0; i < faces.length; i++) {
|
|
454
|
-
let face = faces[i][1];
|
|
455
|
-
let image = new Image();
|
|
456
|
-
image.crossOrigin = '';
|
|
457
|
-
image.onload = (function (texture, face, image) {
|
|
458
|
-
return function () {
|
|
459
|
-
gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture);
|
|
460
|
-
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
|
|
461
|
-
gl.texImage2D(face, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
|
|
462
|
-
};
|
|
463
|
-
}(texture, face, image));
|
|
464
|
-
image.src = faces[i][0];
|
|
614
|
+
/** Initilalize shaders and rendering parameters*/
|
|
615
|
+
this._initPrograms();
|
|
616
|
+
this._setDefaults();
|
|
465
617
|
}
|
|
466
|
-
return texture;
|
|
467
|
-
};
|
|
468
618
|
|
|
469
|
-
/**
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
this.
|
|
480
|
-
this.
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
619
|
+
/**
|
|
620
|
+
* Sets default gl render parameters. Used in init function.
|
|
621
|
+
* @private
|
|
622
|
+
*/
|
|
623
|
+
_setDefaults() {
|
|
624
|
+
this.activateDepthTest();
|
|
625
|
+
this.setSize(
|
|
626
|
+
this.canvas.clientWidth || this._params.width,
|
|
627
|
+
this.canvas.clientHeight || this._params.height
|
|
628
|
+
);
|
|
629
|
+
this.gl.frontFace(this.gl.CCW);
|
|
630
|
+
this.gl.cullFace(this.gl.BACK);
|
|
631
|
+
this.activateFaceCulling();
|
|
632
|
+
this.deactivateBlending();
|
|
633
|
+
var that = this;
|
|
634
|
+
this.createDefaultTexture({ color: "rgba(0,0,0,0.0)" }, function (t) {
|
|
635
|
+
that.transparentTexture = t;
|
|
636
|
+
});
|
|
486
637
|
}
|
|
487
|
-
return program;
|
|
488
|
-
};
|
|
489
|
-
|
|
490
|
-
/**
|
|
491
|
-
* Removes shader program from handler.
|
|
492
|
-
* @public
|
|
493
|
-
* @param {String} name - Shader program name.
|
|
494
|
-
*/
|
|
495
|
-
Handler.prototype.removeProgram = function (name) {
|
|
496
|
-
this.programs[name] && this.programs[name].remove();
|
|
497
|
-
};
|
|
498
638
|
|
|
499
|
-
/**
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
for (var i = 0; i < programsArr.length; i++) {
|
|
506
|
-
this.addProgram(programsArr[i]);
|
|
639
|
+
/**
|
|
640
|
+
* Activate depth test.
|
|
641
|
+
* @public
|
|
642
|
+
*/
|
|
643
|
+
activateDepthTest() {
|
|
644
|
+
this.gl.enable(this.gl.DEPTH_TEST);
|
|
507
645
|
}
|
|
508
|
-
};
|
|
509
646
|
|
|
510
|
-
/**
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
if (this._initialized) {
|
|
517
|
-
sc.initialize();
|
|
518
|
-
if (!this.activeProgram) {
|
|
519
|
-
this.activeProgram = sc;
|
|
520
|
-
sc.activate();
|
|
521
|
-
} else {
|
|
522
|
-
sc.deactivate();
|
|
523
|
-
this.activeProgram._program.enableAttribArrays();
|
|
524
|
-
this.activeProgram._program.use();
|
|
525
|
-
}
|
|
647
|
+
/**
|
|
648
|
+
* Deactivate depth test.
|
|
649
|
+
* @public
|
|
650
|
+
*/
|
|
651
|
+
deactivateDepthTest() {
|
|
652
|
+
this.gl.disable(this.gl.DEPTH_TEST);
|
|
526
653
|
}
|
|
527
|
-
};
|
|
528
654
|
|
|
529
|
-
/**
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
this._initProgramController(this.programs[p]);
|
|
655
|
+
/**
|
|
656
|
+
* Activate face culling.
|
|
657
|
+
* @public
|
|
658
|
+
*/
|
|
659
|
+
activateFaceCulling() {
|
|
660
|
+
this.gl.enable(this.gl.CULL_FACE);
|
|
536
661
|
}
|
|
537
|
-
};
|
|
538
662
|
|
|
539
|
-
/**
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
*/
|
|
546
|
-
Handler.prototype.initializeExtension = function (extensionStr, showLog) {
|
|
547
|
-
if (!(this.extensions && this.extensions[extensionStr])) {
|
|
548
|
-
var ext = Handler.getExtension(this.gl, extensionStr);
|
|
549
|
-
if (ext) {
|
|
550
|
-
this.extensions[extensionStr] = ext;
|
|
551
|
-
} else if (showLog) {
|
|
552
|
-
console.log("og.webgl.Handler: extension '" + extensionStr + "' doesn't initialize.");
|
|
553
|
-
}
|
|
663
|
+
/**
|
|
664
|
+
* Deactivate face cullting.
|
|
665
|
+
* @public
|
|
666
|
+
*/
|
|
667
|
+
deactivateFaceCulling() {
|
|
668
|
+
this.gl.disable(this.gl.CULL_FACE);
|
|
554
669
|
}
|
|
555
|
-
return this.extensions && this.extensions[extensionStr];
|
|
556
|
-
};
|
|
557
670
|
|
|
558
|
-
/**
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
if (this._id) {
|
|
565
|
-
this.canvas = document.getElementById(this._id);
|
|
566
|
-
} else {
|
|
567
|
-
this.canvas = document.createElement("canvas");
|
|
568
|
-
this.canvas.width = this._params.width;
|
|
569
|
-
this.canvas.height = this._params.height;
|
|
671
|
+
/**
|
|
672
|
+
* Activate blending.
|
|
673
|
+
* @public
|
|
674
|
+
*/
|
|
675
|
+
activateBlending() {
|
|
676
|
+
this.gl.enable(this.gl.BLEND);
|
|
570
677
|
}
|
|
571
678
|
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
if (this.gl.type === "webgl") {
|
|
579
|
-
this._params.extensions.push("OES_standard_derivatives");
|
|
580
|
-
this._params.extensions.push("OES_element_index_uint");
|
|
581
|
-
this._params.extensions.push("WEBGL_depth_texture");
|
|
582
|
-
//this._params.extensions.push("EXT_frag_depth");
|
|
583
|
-
} else {
|
|
584
|
-
this._params.extensions.push("EXT_color_buffer_float");
|
|
585
|
-
this._params.extensions.push("OES_texture_float_linear");
|
|
679
|
+
/**
|
|
680
|
+
* Deactivate blending.
|
|
681
|
+
* @public
|
|
682
|
+
*/
|
|
683
|
+
deactivateBlending() {
|
|
684
|
+
this.gl.disable(this.gl.BLEND);
|
|
586
685
|
}
|
|
587
686
|
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
687
|
+
/**
|
|
688
|
+
* Creates STREAM_DRAW ARRAY buffer.
|
|
689
|
+
* @public
|
|
690
|
+
* @param {Array.<number>} array - Input array.
|
|
691
|
+
* @param {number} itemSize - Array item size.
|
|
692
|
+
* @param {number} numItems - Items quantity.
|
|
693
|
+
* @param {number} [usage=STATIC_DRAW] - Parameter of the bufferData call can be one of STATIC_DRAW, DYNAMIC_DRAW, or STREAM_DRAW.
|
|
694
|
+
* @return {Object} -
|
|
695
|
+
*/
|
|
696
|
+
createStreamArrayBuffer(itemSize, numItems, usage, bites = 4) {
|
|
697
|
+
var buffer = this.gl.createBuffer();
|
|
698
|
+
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, buffer);
|
|
699
|
+
this.gl.bufferData(
|
|
700
|
+
this.gl.ARRAY_BUFFER,
|
|
701
|
+
numItems * itemSize * bites,
|
|
702
|
+
usage || this.gl.STREAM_DRAW
|
|
703
|
+
);
|
|
704
|
+
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null);
|
|
705
|
+
buffer.itemSize = itemSize;
|
|
706
|
+
buffer.numItems = numItems;
|
|
707
|
+
return buffer;
|
|
591
708
|
}
|
|
592
709
|
|
|
593
|
-
|
|
594
|
-
|
|
710
|
+
/**
|
|
711
|
+
* Load stream ARRAY buffer.
|
|
712
|
+
* @public
|
|
713
|
+
* @param {Array.<number>} array - Input array.
|
|
714
|
+
* @param {number} itemSize - Array item size.
|
|
715
|
+
* @param {number} numItems - Items quantity.
|
|
716
|
+
* @param {number} [usage=STATIC_DRAW] - Parameter of the bufferData call can be one of STATIC_DRAW, DYNAMIC_DRAW, or STREAM_DRAW.
|
|
717
|
+
* @return {Object} -
|
|
718
|
+
*/
|
|
719
|
+
setStreamArrayBuffer(buffer, array, offset = 0) {
|
|
720
|
+
let gl = this.gl;
|
|
721
|
+
gl.bindBuffer(this.gl.ARRAY_BUFFER, buffer);
|
|
722
|
+
gl.bufferSubData(this.gl.ARRAY_BUFFER, offset, array);
|
|
723
|
+
gl.bindBuffer(this.gl.ARRAY_BUFFER, null);
|
|
724
|
+
return buffer;
|
|
595
725
|
}
|
|
596
726
|
|
|
597
|
-
/**
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
}
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
that.transparentTexture = t;
|
|
616
|
-
});
|
|
617
|
-
};
|
|
618
|
-
|
|
619
|
-
/**
|
|
620
|
-
* Activate depth test.
|
|
621
|
-
* @public
|
|
622
|
-
*/
|
|
623
|
-
Handler.prototype.activateDepthTest = function () {
|
|
624
|
-
this.gl.enable(this.gl.DEPTH_TEST);
|
|
625
|
-
};
|
|
626
|
-
|
|
627
|
-
/**
|
|
628
|
-
* Deactivate depth test.
|
|
629
|
-
* @public
|
|
630
|
-
*/
|
|
631
|
-
Handler.prototype.deactivateDepthTest = function () {
|
|
632
|
-
this.gl.disable(this.gl.DEPTH_TEST);
|
|
633
|
-
};
|
|
634
|
-
|
|
635
|
-
/**
|
|
636
|
-
* Activate face culling.
|
|
637
|
-
* @public
|
|
638
|
-
*/
|
|
639
|
-
Handler.prototype.activateFaceCulling = function () {
|
|
640
|
-
this.gl.enable(this.gl.CULL_FACE);
|
|
641
|
-
};
|
|
642
|
-
|
|
643
|
-
/**
|
|
644
|
-
* Deactivate face cullting.
|
|
645
|
-
* @public
|
|
646
|
-
*/
|
|
647
|
-
Handler.prototype.deactivateFaceCulling = function () {
|
|
648
|
-
this.gl.disable(this.gl.CULL_FACE);
|
|
649
|
-
};
|
|
650
|
-
|
|
651
|
-
/**
|
|
652
|
-
* Activate blending.
|
|
653
|
-
* @public
|
|
654
|
-
*/
|
|
655
|
-
Handler.prototype.activateBlending = function () {
|
|
656
|
-
this.gl.enable(this.gl.BLEND);
|
|
657
|
-
};
|
|
658
|
-
|
|
659
|
-
/**
|
|
660
|
-
* Deactivate blending.
|
|
661
|
-
* @public
|
|
662
|
-
*/
|
|
663
|
-
Handler.prototype.deactivateBlending = function () {
|
|
664
|
-
this.gl.disable(this.gl.BLEND);
|
|
665
|
-
};
|
|
666
|
-
|
|
667
|
-
/**
|
|
668
|
-
* Creates STREAM_DRAW ARRAY buffer.
|
|
669
|
-
* @public
|
|
670
|
-
* @param {Array.<number>} array - Input array.
|
|
671
|
-
* @param {number} itemSize - Array item size.
|
|
672
|
-
* @param {number} numItems - Items quantity.
|
|
673
|
-
* @param {number} [usage=STATIC_DRAW] - Parameter of the bufferData call can be one of STATIC_DRAW, DYNAMIC_DRAW, or STREAM_DRAW.
|
|
674
|
-
* @return {Object} -
|
|
675
|
-
*/
|
|
676
|
-
Handler.prototype.createStreamArrayBuffer = function (itemSize, numItems, usage, bites = 4) {
|
|
677
|
-
var buffer = this.gl.createBuffer();
|
|
678
|
-
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, buffer);
|
|
679
|
-
this.gl.bufferData(this.gl.ARRAY_BUFFER, numItems * itemSize * bites, usage || this.gl.STREAM_DRAW);
|
|
680
|
-
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null);
|
|
681
|
-
buffer.itemSize = itemSize;
|
|
682
|
-
buffer.numItems = numItems;
|
|
683
|
-
return buffer;
|
|
684
|
-
};
|
|
727
|
+
/**
|
|
728
|
+
* Creates ARRAY buffer.
|
|
729
|
+
* @public
|
|
730
|
+
* @param {Array.<number>} array - Input array.
|
|
731
|
+
* @param {number} itemSize - Array item size.
|
|
732
|
+
* @param {number} numItems - Items quantity.
|
|
733
|
+
* @param {number} [usage=STATIC_DRAW] - Parameter of the bufferData call can be one of STATIC_DRAW, DYNAMIC_DRAW, or STREAM_DRAW.
|
|
734
|
+
* @return {Object} -
|
|
735
|
+
*/
|
|
736
|
+
createArrayBuffer(array, itemSize, numItems, usage) {
|
|
737
|
+
var buffer = this.gl.createBuffer();
|
|
738
|
+
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, buffer);
|
|
739
|
+
this.gl.bufferData(this.gl.ARRAY_BUFFER, array, usage || this.gl.STATIC_DRAW);
|
|
740
|
+
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null);
|
|
741
|
+
buffer.itemSize = itemSize;
|
|
742
|
+
buffer.numItems = numItems;
|
|
743
|
+
return buffer;
|
|
744
|
+
}
|
|
685
745
|
|
|
686
|
-
/**
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
746
|
+
/**
|
|
747
|
+
* Creates ELEMENT ARRAY buffer.
|
|
748
|
+
* @public
|
|
749
|
+
* @param {Array.<number>} array - Input array.
|
|
750
|
+
* @param {number} itemSize - Array item size.
|
|
751
|
+
* @param {number} numItems - Items quantity.
|
|
752
|
+
* @param {number} [usage=STATIC_DRAW] - Parameter of the bufferData call can be one of STATIC_DRAW, DYNAMIC_DRAW, or STREAM_DRAW.
|
|
753
|
+
* @return {Object} -
|
|
754
|
+
*/
|
|
755
|
+
createElementArrayBuffer(array, itemSize, numItems, usage) {
|
|
756
|
+
var buffer = this.gl.createBuffer();
|
|
757
|
+
this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, buffer);
|
|
758
|
+
this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER, array, usage || this.gl.STATIC_DRAW);
|
|
759
|
+
this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, null);
|
|
760
|
+
buffer.itemSize = itemSize;
|
|
761
|
+
buffer.numItems = numItems || array.length;
|
|
762
|
+
return buffer;
|
|
763
|
+
}
|
|
702
764
|
|
|
703
|
-
/**
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
var buffer = this.gl.createBuffer();
|
|
714
|
-
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, buffer);
|
|
715
|
-
this.gl.bufferData(this.gl.ARRAY_BUFFER, array, usage || this.gl.STATIC_DRAW);
|
|
716
|
-
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null);
|
|
717
|
-
buffer.itemSize = itemSize;
|
|
718
|
-
buffer.numItems = numItems;
|
|
719
|
-
return buffer;
|
|
720
|
-
};
|
|
765
|
+
/**
|
|
766
|
+
* Sets handler canvas size.
|
|
767
|
+
* @public
|
|
768
|
+
* @param {number} w - Canvas width.
|
|
769
|
+
* @param {number} h - Canvas height.
|
|
770
|
+
*/
|
|
771
|
+
setSize(w, h) {
|
|
772
|
+
if (w > MAX_SIZE) {
|
|
773
|
+
w = MAX_SIZE;
|
|
774
|
+
}
|
|
721
775
|
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
* @param {Array.<number>} array - Input array.
|
|
726
|
-
* @param {number} itemSize - Array item size.
|
|
727
|
-
* @param {number} numItems - Items quantity.
|
|
728
|
-
* @param {number} [usage=STATIC_DRAW] - Parameter of the bufferData call can be one of STATIC_DRAW, DYNAMIC_DRAW, or STREAM_DRAW.
|
|
729
|
-
* @return {Object} -
|
|
730
|
-
*/
|
|
731
|
-
Handler.prototype.createElementArrayBuffer = function (array, itemSize, numItems, usage) {
|
|
732
|
-
var buffer = this.gl.createBuffer();
|
|
733
|
-
this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, buffer);
|
|
734
|
-
this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER, array, usage || this.gl.STATIC_DRAW);
|
|
735
|
-
this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, null);
|
|
736
|
-
buffer.itemSize = itemSize;
|
|
737
|
-
buffer.numItems = numItems || array.length;
|
|
738
|
-
return buffer;
|
|
739
|
-
};
|
|
776
|
+
if (h > MAX_SIZE) {
|
|
777
|
+
h = MAX_SIZE;
|
|
778
|
+
}
|
|
740
779
|
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
*/
|
|
747
|
-
Handler.prototype.setSize = function (w, h) {
|
|
780
|
+
this._params.width = w;
|
|
781
|
+
this._params.height = h;
|
|
782
|
+
this.canvas.width = w;
|
|
783
|
+
this.canvas.height = h;
|
|
784
|
+
this._oneByHeight = 1 / h;
|
|
748
785
|
|
|
749
|
-
|
|
750
|
-
|
|
786
|
+
this.gl && this.gl.viewport(0, 0, w, h);
|
|
787
|
+
this.onCanvasResize && this.onCanvasResize(this.canvas);
|
|
751
788
|
}
|
|
752
789
|
|
|
753
|
-
|
|
754
|
-
|
|
790
|
+
/**
|
|
791
|
+
* Returns context screen width.
|
|
792
|
+
* @public
|
|
793
|
+
* @returns {number} -
|
|
794
|
+
*/
|
|
795
|
+
getWidth() {
|
|
796
|
+
return this.canvas.width;
|
|
755
797
|
}
|
|
756
798
|
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
};
|
|
766
|
-
|
|
767
|
-
/**
|
|
768
|
-
* Returns context screen width.
|
|
769
|
-
* @public
|
|
770
|
-
* @returns {number} -
|
|
771
|
-
*/
|
|
772
|
-
Handler.prototype.getWidth = function () {
|
|
773
|
-
return this.canvas.width;
|
|
774
|
-
};
|
|
799
|
+
/**
|
|
800
|
+
* Returns context screen height.
|
|
801
|
+
* @public
|
|
802
|
+
* @returns {number} -
|
|
803
|
+
*/
|
|
804
|
+
getHeight() {
|
|
805
|
+
return this.canvas.height;
|
|
806
|
+
}
|
|
775
807
|
|
|
776
|
-
/**
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
}
|
|
808
|
+
/**
|
|
809
|
+
* Returns canvas aspect ratio.
|
|
810
|
+
* @public
|
|
811
|
+
* @returns {number} -
|
|
812
|
+
*/
|
|
813
|
+
getClientAspect() {
|
|
814
|
+
return this.canvas.clientWidth / this.canvas.clientHeight;
|
|
815
|
+
}
|
|
784
816
|
|
|
785
|
-
/**
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
817
|
+
/**
|
|
818
|
+
* Returns screen center coordinates.
|
|
819
|
+
* @public
|
|
820
|
+
* @returns {number} -
|
|
821
|
+
*/
|
|
822
|
+
getCenter() {
|
|
823
|
+
var c = this.canvas;
|
|
824
|
+
return new Vec2(Math.round(c.width * 0.5), Math.round(c.height * 0.5));
|
|
825
|
+
}
|
|
793
826
|
|
|
794
|
-
/**
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
827
|
+
/**
|
|
828
|
+
* Draw single frame.
|
|
829
|
+
* @public
|
|
830
|
+
* @param {number} now - Frame current time milliseconds.
|
|
831
|
+
*/
|
|
832
|
+
drawFrame() {
|
|
833
|
+
/** Calculating frame time */
|
|
834
|
+
var now = window.performance.now();
|
|
835
|
+
this.deltaTime = now - this._lastAnimationFrameTime;
|
|
836
|
+
this._lastAnimationFrameTime = now;
|
|
803
837
|
|
|
804
|
-
|
|
805
|
-
* Draw single frame.
|
|
806
|
-
* @public
|
|
807
|
-
* @param {number} now - Frame current time milliseconds.
|
|
808
|
-
*/
|
|
809
|
-
Handler.prototype.drawFrame = function () {
|
|
838
|
+
this.defaultClock._tick(this.deltaTime);
|
|
810
839
|
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
this._lastAnimationFrameTime = now;
|
|
840
|
+
for (var i = 0; i < this._clocks.length; i++) {
|
|
841
|
+
this._clocks[i]._tick(this.deltaTime);
|
|
842
|
+
}
|
|
815
843
|
|
|
816
|
-
|
|
844
|
+
/** Canvas resize checking */
|
|
845
|
+
var canvas = this.canvas;
|
|
846
|
+
if (canvas.clientWidth !== canvas.width || canvas.clientHeight !== canvas.height) {
|
|
847
|
+
this.setSize(canvas.clientWidth, canvas.clientHeight);
|
|
848
|
+
}
|
|
817
849
|
|
|
818
|
-
|
|
819
|
-
this.
|
|
850
|
+
/** Draw frame */
|
|
851
|
+
this._frameCallback();
|
|
820
852
|
}
|
|
821
853
|
|
|
822
|
-
/**
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
854
|
+
/**
|
|
855
|
+
* Clearing gl frame.
|
|
856
|
+
* @public
|
|
857
|
+
*/
|
|
858
|
+
clearFrame() {
|
|
859
|
+
var gl = this.gl;
|
|
860
|
+
this.gl.clearColor(0.0, 0.0, 0.0, 1.0);
|
|
861
|
+
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
|
827
862
|
}
|
|
828
863
|
|
|
829
|
-
/**
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
this.gl.clearColor(0.0, 0.0, 0.0, 1.0);
|
|
840
|
-
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
|
841
|
-
};
|
|
842
|
-
|
|
843
|
-
/**
|
|
844
|
-
* Starts animation loop.
|
|
845
|
-
* @public
|
|
846
|
-
*/
|
|
847
|
-
Handler.prototype.start = function () {
|
|
848
|
-
if (!this._requestAnimationFrameId && this._initialized) {
|
|
849
|
-
this._lastAnimationFrameTime = window.performance.now();
|
|
850
|
-
this.defaultClock.setDate(new Date());
|
|
851
|
-
this._animationFrameCallback();
|
|
864
|
+
/**
|
|
865
|
+
* Starts animation loop.
|
|
866
|
+
* @public
|
|
867
|
+
*/
|
|
868
|
+
start() {
|
|
869
|
+
if (!this._requestAnimationFrameId && this._initialized) {
|
|
870
|
+
this._lastAnimationFrameTime = window.performance.now();
|
|
871
|
+
this.defaultClock.setDate(new Date());
|
|
872
|
+
this._animationFrameCallback();
|
|
873
|
+
}
|
|
852
874
|
}
|
|
853
|
-
};
|
|
854
875
|
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
876
|
+
stop() {
|
|
877
|
+
if (this._requestAnimationFrameId) {
|
|
878
|
+
window.cancelAnimationFrame(this._requestAnimationFrameId);
|
|
879
|
+
this._requestAnimationFrameId = null;
|
|
880
|
+
}
|
|
859
881
|
}
|
|
860
|
-
};
|
|
861
882
|
|
|
862
|
-
/**
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
}
|
|
883
|
+
/**
|
|
884
|
+
* Make animation.
|
|
885
|
+
* @private
|
|
886
|
+
*/
|
|
887
|
+
_animationFrameCallback() {
|
|
888
|
+
this._requestAnimationFrameId = window.requestAnimationFrame(() => {
|
|
889
|
+
this.drawFrame();
|
|
890
|
+
this._animationFrameCallback();
|
|
891
|
+
});
|
|
892
|
+
}
|
|
872
893
|
|
|
873
|
-
/**
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
894
|
+
/**
|
|
895
|
+
* Creates default texture object
|
|
896
|
+
* @public
|
|
897
|
+
* @param {Object} [params] - Texture parameters:
|
|
898
|
+
* @param {Array.<number, number, number, number>} [params.color] - Texture RGBA color
|
|
899
|
+
* @param {number} [params.url] - Texture source url
|
|
900
|
+
* @param {callback} success - Creation callback
|
|
901
|
+
*/
|
|
902
|
+
createDefaultTexture(params, success) {
|
|
903
|
+
var imgCnv;
|
|
904
|
+
var texture;
|
|
905
|
+
if (params && params.color) {
|
|
906
|
+
imgCnv = new ImageCanvas(2, 2);
|
|
907
|
+
imgCnv.fillColor(params.color);
|
|
908
|
+
texture = this.createTexture_n(imgCnv._canvas);
|
|
909
|
+
texture.default = true;
|
|
910
|
+
success(texture);
|
|
911
|
+
} else if (params && params.url) {
|
|
912
|
+
var img = new Image();
|
|
913
|
+
var that = this;
|
|
914
|
+
img.onload = function () {
|
|
915
|
+
texture = that.createTexture(this);
|
|
916
|
+
texture.default = true;
|
|
917
|
+
success(texture);
|
|
918
|
+
};
|
|
919
|
+
img.src = params.url;
|
|
920
|
+
} else {
|
|
921
|
+
imgCnv = new ImageCanvas(2, 2);
|
|
922
|
+
imgCnv.fillColor("#C5C5C5");
|
|
923
|
+
texture = this.createTexture_n(imgCnv._canvas);
|
|
895
924
|
texture.default = true;
|
|
896
925
|
success(texture);
|
|
897
|
-
}
|
|
898
|
-
img.src = params.url;
|
|
899
|
-
} else {
|
|
900
|
-
imgCnv = new ImageCanvas(2, 2);
|
|
901
|
-
imgCnv.fillColor("#C5C5C5");
|
|
902
|
-
texture = this.createTexture_n(imgCnv._canvas);
|
|
903
|
-
texture.default = true;
|
|
904
|
-
success(texture);
|
|
926
|
+
}
|
|
905
927
|
}
|
|
906
|
-
};
|
|
907
928
|
|
|
908
|
-
/**
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
929
|
+
/**
|
|
930
|
+
* @public
|
|
931
|
+
*/
|
|
932
|
+
destroy() {
|
|
933
|
+
var gl = this.gl;
|
|
934
|
+
|
|
935
|
+
this.stop();
|
|
912
936
|
|
|
913
|
-
|
|
937
|
+
for (var p in this.programs) {
|
|
938
|
+
this.removeProgram(p);
|
|
939
|
+
}
|
|
914
940
|
|
|
915
|
-
|
|
941
|
+
gl.deleteTexture(this.transparentTexture);
|
|
942
|
+
this.transparentTexture = null;
|
|
916
943
|
|
|
917
|
-
|
|
918
|
-
this.
|
|
919
|
-
}
|
|
944
|
+
this.framebufferStack = null;
|
|
945
|
+
this.framebufferStack = new Stack();
|
|
920
946
|
|
|
921
|
-
|
|
922
|
-
|
|
947
|
+
if (this.canvas.parentNode) {
|
|
948
|
+
this.canvas.parentNode.removeChild(this.canvas);
|
|
949
|
+
}
|
|
950
|
+
this.canvas.width = 1;
|
|
951
|
+
this.canvas.height = 1;
|
|
952
|
+
this.canvas = null;
|
|
953
|
+
|
|
954
|
+
var numAttribs = gl.getParameter(gl.MAX_VERTEX_ATTRIBS);
|
|
955
|
+
var tmp = gl.createBuffer();
|
|
956
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, tmp);
|
|
957
|
+
for (let ii = 0; ii < numAttribs; ++ii) {
|
|
958
|
+
gl.disableVertexAttribArray(ii);
|
|
959
|
+
gl.vertexAttribPointer(ii, 4, gl.FLOAT, false, 0, 0);
|
|
960
|
+
gl.vertexAttrib1f(ii, 0);
|
|
961
|
+
}
|
|
962
|
+
gl.deleteBuffer(tmp);
|
|
923
963
|
|
|
924
|
-
|
|
925
|
-
|
|
964
|
+
var numTextureUnits = gl.getParameter(gl.MAX_TEXTlURE_IMAGE_UNITS);
|
|
965
|
+
for (let ii = 0; ii < numTextureUnits; ++ii) {
|
|
966
|
+
gl.activeTexture(gl.TEXTURE0 + ii);
|
|
967
|
+
gl.bindTexture(gl.TEXTURE_CUBE_MAP, null);
|
|
968
|
+
gl.bindTexture(gl.TEXTURE_2D, null);
|
|
969
|
+
}
|
|
926
970
|
|
|
927
|
-
|
|
928
|
-
|
|
971
|
+
gl.activeTexture(gl.TEXTURE0);
|
|
972
|
+
gl.useProgram(null);
|
|
973
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, null);
|
|
974
|
+
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
|
|
975
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
|
976
|
+
gl.bindRenderbuffer(gl.RENDERBUFFER, null);
|
|
977
|
+
gl.disable(gl.BLEND);
|
|
978
|
+
gl.disable(gl.CULL_FACE);
|
|
979
|
+
gl.disable(gl.DEPTH_TEST);
|
|
980
|
+
gl.disable(gl.DITHER);
|
|
981
|
+
gl.disable(gl.SCISSOR_TEST);
|
|
982
|
+
gl.blendColor(0, 0, 0, 0);
|
|
983
|
+
gl.blendEquation(gl.FUNC_ADD);
|
|
984
|
+
gl.blendFunc(gl.ONE, gl.ZERO);
|
|
985
|
+
gl.clearColor(0, 0, 0, 0);
|
|
986
|
+
gl.clearDepth(1);
|
|
987
|
+
gl.clearStencil(-1);
|
|
988
|
+
|
|
989
|
+
this.gl = null;
|
|
990
|
+
|
|
991
|
+
this._initialized = false;
|
|
929
992
|
}
|
|
930
|
-
this.canvas.width = 1;
|
|
931
|
-
this.canvas.height = 1;
|
|
932
|
-
this.canvas = null;
|
|
933
993
|
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
gl.vertexAttribPointer(ii, 4, gl.FLOAT, false, 0, 0);
|
|
940
|
-
gl.vertexAttrib1f(ii, 0);
|
|
994
|
+
addClock(clock) {
|
|
995
|
+
if (!clock.__handler) {
|
|
996
|
+
clock.__handler = this;
|
|
997
|
+
this._clocks.push(clock);
|
|
998
|
+
}
|
|
941
999
|
}
|
|
942
|
-
gl.deleteBuffer(tmp);
|
|
943
1000
|
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
gl.bindTexture(gl.TEXTURE_2D, null);
|
|
1001
|
+
addClocks(clockArr) {
|
|
1002
|
+
for (var i = 0; i < clockArr.length; i++) {
|
|
1003
|
+
this.addClock(clockArr[i]);
|
|
1004
|
+
}
|
|
949
1005
|
}
|
|
950
1006
|
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
gl.disable(gl.SCISSOR_TEST);
|
|
962
|
-
gl.blendColor(0, 0, 0, 0);
|
|
963
|
-
gl.blendEquation(gl.FUNC_ADD);
|
|
964
|
-
gl.blendFunc(gl.ONE, gl.ZERO);
|
|
965
|
-
gl.clearColor(0, 0, 0, 0);
|
|
966
|
-
gl.clearDepth(1);
|
|
967
|
-
gl.clearStencil(-1);
|
|
968
|
-
|
|
969
|
-
this.gl = null;
|
|
970
|
-
|
|
971
|
-
this._initialized = false;
|
|
972
|
-
};
|
|
973
|
-
|
|
974
|
-
Handler.prototype.addClock = function (clock) {
|
|
975
|
-
if (!clock.__handler) {
|
|
976
|
-
clock.__handler = this;
|
|
977
|
-
this._clocks.push(clock);
|
|
978
|
-
}
|
|
979
|
-
};
|
|
980
|
-
|
|
981
|
-
Handler.prototype.addClocks = function (clockArr) {
|
|
982
|
-
for (var i = 0; i < clockArr.length; i++) {
|
|
983
|
-
this.addClock(clockArr[i]);
|
|
984
|
-
}
|
|
985
|
-
};
|
|
986
|
-
|
|
987
|
-
Handler.prototype.removeClock = function (clock) {
|
|
988
|
-
if (clock.__handler) {
|
|
989
|
-
var c = this._clocks;
|
|
990
|
-
var i = c.length;
|
|
991
|
-
while (i--) {
|
|
992
|
-
if (c[i].equal(clock)) {
|
|
993
|
-
clock.__handler = null;
|
|
994
|
-
c.splice(i, 1);
|
|
995
|
-
break;
|
|
1007
|
+
removeClock(clock) {
|
|
1008
|
+
if (clock.__handler) {
|
|
1009
|
+
var c = this._clocks;
|
|
1010
|
+
var i = c.length;
|
|
1011
|
+
while (i--) {
|
|
1012
|
+
if (c[i].equal(clock)) {
|
|
1013
|
+
clock.__handler = null;
|
|
1014
|
+
c.splice(i, 1);
|
|
1015
|
+
break;
|
|
1016
|
+
}
|
|
996
1017
|
}
|
|
997
1018
|
}
|
|
998
1019
|
}
|
|
999
|
-
}
|
|
1020
|
+
}
|
|
1000
1021
|
|
|
1001
|
-
export { Handler };
|
|
1022
|
+
export { Handler };
|