@openglobus/og 0.10.6 → 0.11.1

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.
Files changed (163) hide show
  1. package/package.json +10 -7
  2. package/src/og/Extent.js +1 -1
  3. package/src/og/LonLat.js +7 -2
  4. package/src/og/Popup.js +2 -1
  5. package/src/og/camera/PlanetCamera.js +4 -2
  6. package/src/og/entity/EntityCollection.js +1 -1
  7. package/src/og/entity/LabelHandler.js +366 -74
  8. package/src/og/entity/Polyline.js +3 -2
  9. package/src/og/layer/KML.js +7 -5
  10. package/src/og/layer/Vector.js +5 -0
  11. package/src/og/layer/index.js +2 -1
  12. package/src/og/math/Vec2.js +448 -448
  13. package/src/og/math/Vec3.js +759 -757
  14. package/src/og/math/Vec4.js +216 -215
  15. package/src/og/scene/Planet.js +14 -4
  16. package/src/og/segment/SegmentLonLat.js +7 -0
  17. package/src/og/terrain/GlobusTerrain.js +4 -0
  18. package/src/og/utils/GeoImageCreator.js +123 -121
  19. package/src/og/utils/Loader.js +81 -80
  20. package/src/og/utils/NormalMapCreator.js +320 -318
  21. package/src/og/utils/VectorTileCreator.js +251 -250
  22. package/src/og/webgl/Framebuffer.js +265 -264
  23. package/src/og/webgl/Handler.js +1022 -1022
  24. package/src/og/webgl/Multisample.js +169 -168
  25. package/src/og/webgl/ProgramController.js +113 -112
  26. package/types/Clock.d.ts +90 -0
  27. package/types/Deferred.d.ts +6 -0
  28. package/types/Events.d.ts +73 -0
  29. package/types/Extent.d.ts +162 -0
  30. package/types/Globe.d.ts +80 -0
  31. package/types/ImageCanvas.d.ts +121 -0
  32. package/types/Lock.d.ts +12 -0
  33. package/types/LonLat.d.ts +108 -0
  34. package/types/Popup.d.ts +38 -0
  35. package/types/QueueArray.d.ts +15 -0
  36. package/types/Rectangle.d.ts +74 -0
  37. package/types/Stack.d.ts +15 -0
  38. package/types/ajax.d.ts +24 -0
  39. package/types/arial.d.ts +48 -0
  40. package/types/astro/astro.d.ts +38 -0
  41. package/types/astro/earth.d.ts +6 -0
  42. package/types/astro/jd.d.ts +254 -0
  43. package/types/bv/Box.d.ts +25 -0
  44. package/types/bv/Sphere.d.ts +32 -0
  45. package/types/bv/index.d.ts +3 -0
  46. package/types/camera/Camera.d.ts +303 -0
  47. package/types/camera/Frustum.d.ts +129 -0
  48. package/types/camera/PlanetCamera.d.ts +222 -0
  49. package/types/camera/index.d.ts +3 -0
  50. package/types/cons.d.ts +40 -0
  51. package/types/control/CompassButton.d.ts +17 -0
  52. package/types/control/Control.d.ts +101 -0
  53. package/types/control/DebugInfo.d.ts +16 -0
  54. package/types/control/EarthCoordinates.d.ts +47 -0
  55. package/types/control/GeoImageDragControl.d.ts +6 -0
  56. package/types/control/KeyboardNavigation.d.ts +22 -0
  57. package/types/control/LayerSwitcher.d.ts +23 -0
  58. package/types/control/Lighting.d.ts +16 -0
  59. package/types/control/ScaleControl.d.ts +22 -0
  60. package/types/control/ShowFps.d.ts +12 -0
  61. package/types/control/SimpleNavigation.d.ts +28 -0
  62. package/types/control/Sun.d.ts +52 -0
  63. package/types/control/ToggleWireframe.d.ts +12 -0
  64. package/types/control/ZoomControl.d.ts +28 -0
  65. package/types/control/index.d.ts +15 -0
  66. package/types/ellipsoid/Ellipsoid.d.ts +142 -0
  67. package/types/ellipsoid/index.d.ts +3 -0
  68. package/types/ellipsoid/wgs84.d.ts +5 -0
  69. package/types/entity/BaseBillboard.d.ts +208 -0
  70. package/types/entity/Billboard.d.ts +94 -0
  71. package/types/entity/BillboardHandler.d.ts +74 -0
  72. package/types/entity/Entity.d.ts +330 -0
  73. package/types/entity/EntityCollection.d.ts +303 -0
  74. package/types/entity/Geometry.d.ts +72 -0
  75. package/types/entity/GeometryHandler.d.ts +76 -0
  76. package/types/entity/Label.d.ts +194 -0
  77. package/types/entity/LabelHandler.d.ts +24 -0
  78. package/types/entity/PointCloud.d.ts +174 -0
  79. package/types/entity/PointCloudHandler.d.ts +38 -0
  80. package/types/entity/Polyline.d.ts +303 -0
  81. package/types/entity/PolylineHandler.d.ts +18 -0
  82. package/types/entity/Ray.d.ts +123 -0
  83. package/types/entity/RayHandler.d.ts +67 -0
  84. package/types/entity/ShapeHandler.d.ts +22 -0
  85. package/types/entity/Strip.d.ts +118 -0
  86. package/types/entity/StripHandler.d.ts +38 -0
  87. package/types/entity/index.d.ts +8 -0
  88. package/types/index.core.d.ts +65 -0
  89. package/types/index.d.ts +45 -0
  90. package/types/index.webgl.d.ts +7 -0
  91. package/types/inherits.d.ts +4 -0
  92. package/types/input/input.d.ts +34 -0
  93. package/types/layer/BaseGeoImage.d.ts +106 -0
  94. package/types/layer/CanvasTiles.d.ts +75 -0
  95. package/types/layer/GeoImage.d.ts +65 -0
  96. package/types/layer/GeoTexture2d.d.ts +8 -0
  97. package/types/layer/GeoVideo.d.ts +80 -0
  98. package/types/layer/KML.d.ts +58 -0
  99. package/types/layer/WMS.d.ts +66 -0
  100. package/types/layer/XYZ.d.ts +126 -0
  101. package/types/layer/index.d.ts +10 -0
  102. package/types/light/LightSource.d.ts +177 -0
  103. package/types/math/Mat3.d.ts +53 -0
  104. package/types/math/Mat4.d.ts +157 -0
  105. package/types/math/Plane.d.ts +17 -0
  106. package/types/math/Vec2.d.ts +308 -0
  107. package/types/math/Vec3.d.ts +459 -0
  108. package/types/math/Vec4.d.ts +161 -0
  109. package/types/math/coder.d.ts +42 -0
  110. package/types/math/index.d.ts +11 -0
  111. package/types/math.d.ts +261 -0
  112. package/types/mercator.d.ts +92 -0
  113. package/types/proj/EPSG3857.d.ts +5 -0
  114. package/types/proj/EPSG4326.d.ts +5 -0
  115. package/types/quadTree/quadTree.d.ts +40 -0
  116. package/types/renderer/RendererEvents.d.ts +230 -0
  117. package/types/res/images.d.ts +3 -0
  118. package/types/scene/Axes.d.ts +11 -0
  119. package/types/scene/BaseNode.d.ts +60 -0
  120. package/types/scene/Planet.d.ts +572 -0
  121. package/types/scene/RenderNode.d.ts +143 -0
  122. package/types/scene/SkyBox.d.ts +10 -0
  123. package/types/scene/index.d.ts +4 -0
  124. package/types/segment/segmentHelper.d.ts +13 -0
  125. package/types/shaders/billboard.d.ts +3 -0
  126. package/types/shaders/depth.d.ts +2 -0
  127. package/types/shaders/drawnode.d.ts +7 -0
  128. package/types/shaders/label.d.ts +4 -0
  129. package/types/shaders/pointCloud.d.ts +2 -0
  130. package/types/shaders/polyline.d.ts +3 -0
  131. package/types/shaders/ray.d.ts +2 -0
  132. package/types/shaders/screenFrame.d.ts +2 -0
  133. package/types/shaders/shape.d.ts +4 -0
  134. package/types/shaders/skybox.d.ts +2 -0
  135. package/types/shaders/toneMapping.d.ts +2 -0
  136. package/types/shapes/BaseShape.d.ts +247 -0
  137. package/types/shapes/Sphere.d.ts +41 -0
  138. package/types/terrain/BilTerrain.d.ts +8 -0
  139. package/types/terrain/EmptyTerrain.d.ts +72 -0
  140. package/types/terrain/Geoid.d.ts +26 -0
  141. package/types/terrain/GlobusTerrain.d.ts +153 -0
  142. package/types/terrain/MapboxTerrain.d.ts +8 -0
  143. package/types/terrain/index.d.ts +5 -0
  144. package/types/utils/FontAtlas.d.ts +14 -0
  145. package/types/utils/GeoImageCreator.d.ts +29 -0
  146. package/types/utils/ImagesCacheManager.d.ts +10 -0
  147. package/types/utils/Loader.d.ts +25 -0
  148. package/types/utils/NormalMapCreator.d.ts +39 -0
  149. package/types/utils/PlainSegmentWorker.d.ts +10 -0
  150. package/types/utils/TerrainWorker.d.ts +9 -0
  151. package/types/utils/TextureAtlas.d.ts +111 -0
  152. package/types/utils/VectorTileCreator.d.ts +16 -0
  153. package/types/utils/colorTable.d.ts +143 -0
  154. package/types/utils/earcut.d.ts +6 -0
  155. package/types/utils/shared.d.ts +230 -0
  156. package/types/webgl/Framebuffer.d.ts +135 -0
  157. package/types/webgl/Handler.d.ts +372 -0
  158. package/types/webgl/Multisample.d.ts +89 -0
  159. package/types/webgl/Program.d.ts +155 -0
  160. package/types/webgl/ProgramController.d.ts +84 -0
  161. package/types/webgl/callbacks.d.ts +1 -0
  162. package/types/webgl/index.d.ts +6 -0
  163. package/types/webgl/types.d.ts +2 -0
@@ -1,1022 +1,1022 @@
1
- /**
2
- * @module og/webgl/Handler
3
- */
4
-
5
- "use strict";
6
-
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
-
15
- /**
16
- * Maximum texture image size.
17
- * @const
18
- * @type {number}
19
- */
20
- const MAX_SIZE = 4096;
21
-
22
- const vendorPrefixes = ["", "WEBKIT_", "MOZ_"];
23
-
24
- /**
25
- * A WebGL handler for accessing low-level WebGL capabilities.
26
- * @class
27
- * @param {string} id - Canvas element id that WebGL handler assing with. If it's null
28
- * or undefined creates hidden canvas and handler bacomes hidden.
29
- * @param {Object} [params] - Handler options:
30
- * @param {number} [params.anisotropy] - Anisitropy filter degree. 8 is default.
31
- * @param {number} [params.width] - Hidden handler width. 256 is default.
32
- * @param {number} [params.height] - Hidden handler height. 256 is default.
33
- * @param {Object} [param.scontext] - Native WebGL context attributes. See https://www.khronos.org/registry/webgl/specs/latest/1.0/#WEBGLCONTEXTATTRIBUTES
34
- * @param {Array.<string>} [params.extensions] - Additional WebGL extension list. Available by default: EXT_texture_filter_anisotropic.
35
- */
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;
102
-
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
- }
145
-
146
- /**
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} -
151
- */
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
- }
162
-
163
- /**
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} -
168
- */
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
- }
191
-
192
- /**
193
- * Sets animation frame function.
194
- * @public
195
- * @param {callback} callback - Frame callback.
196
- */
197
- setFrameCallback(callback) {
198
- callback && (this._frameCallback = callback);
199
- }
200
-
201
- /**
202
- * Creates NEAREST filter texture.
203
- * @public
204
- * @param {Object} image - Image or Canvas object.
205
- * @returns {Object} - WebGL texture object.
206
- */
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
- }
220
-
221
- /**
222
- * Creates empty texture.
223
- * @public
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.
232
- */
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
- //}
309
-
310
- /**
311
- * Creates Empty NEAREST filtered texture.
312
- * @public
313
- * @param {number} width - Empty texture width.
314
- * @param {number} height - Empty texture height.
315
- * @returns {Object} - WebGL texture object.
316
- */
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
- }
330
-
331
- /**
332
- * Creates empty LINEAR filtered texture.
333
- * @public
334
- * @param {number} width - Empty texture width.
335
- * @param {number} height - Empty texture height.
336
- * @returns {Object} - WebGL texture object.
337
- */
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
- }
351
-
352
- /**
353
- * Creates LINEAR filter texture.
354
- * @public
355
- * @param {Object} image - Image or Canvas object.
356
- * @returns {Object} - WebGL texture object.
357
- */
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;
369
- }
370
-
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;
389
- }
390
-
391
- /**
392
- * Creates ANISOTROPY filter texture.
393
- * @public
394
- * @param {Object} image - Image or Canvas object.
395
- * @returns {Object} - WebGL texture object.
396
- */
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
- }
415
-
416
- /**
417
- * Creates DEFAULT filter texture, ANISOTROPY is default.
418
- * @public
419
- * @param {Object} image - Image or Canvas object.
420
- * @returns {Object} - WebGL texture object.
421
- */
422
- createTexture(image) {
423
- return this.createTexture_a(image);
424
- }
425
-
426
- /**
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.
437
- */
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
- }
466
-
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
- }
482
-
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
- }
505
-
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();
513
- }
514
-
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]);
523
- }
524
- }
525
-
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();
541
- }
542
- }
543
- }
544
-
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
- }
553
- }
554
-
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
- }
575
-
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
- }
588
-
589
- this.gl = Handler.getContext(this.canvas, this._params.context);
590
- this._initialized = true;
591
-
592
- /** Sets deafult extensions */
593
- this._params.extensions.push("EXT_texture_filter_anisotropic");
594
-
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
- }
604
-
605
- var i = this._params.extensions.length;
606
- while (i--) {
607
- this.initializeExtension(this._params.extensions[i], true);
608
- }
609
-
610
- if (!this.extensions.EXT_texture_filter_anisotropic) {
611
- this.createTexture = this.createTexture_mm;
612
- }
613
-
614
- /** Initilalize shaders and rendering parameters*/
615
- this._initPrograms();
616
- this._setDefaults();
617
- }
618
-
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
- });
637
- }
638
-
639
- /**
640
- * Activate depth test.
641
- * @public
642
- */
643
- activateDepthTest() {
644
- this.gl.enable(this.gl.DEPTH_TEST);
645
- }
646
-
647
- /**
648
- * Deactivate depth test.
649
- * @public
650
- */
651
- deactivateDepthTest() {
652
- this.gl.disable(this.gl.DEPTH_TEST);
653
- }
654
-
655
- /**
656
- * Activate face culling.
657
- * @public
658
- */
659
- activateFaceCulling() {
660
- this.gl.enable(this.gl.CULL_FACE);
661
- }
662
-
663
- /**
664
- * Deactivate face cullting.
665
- * @public
666
- */
667
- deactivateFaceCulling() {
668
- this.gl.disable(this.gl.CULL_FACE);
669
- }
670
-
671
- /**
672
- * Activate blending.
673
- * @public
674
- */
675
- activateBlending() {
676
- this.gl.enable(this.gl.BLEND);
677
- }
678
-
679
- /**
680
- * Deactivate blending.
681
- * @public
682
- */
683
- deactivateBlending() {
684
- this.gl.disable(this.gl.BLEND);
685
- }
686
-
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;
708
- }
709
-
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;
725
- }
726
-
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
- }
745
-
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
- }
764
-
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
- }
775
-
776
- if (h > MAX_SIZE) {
777
- h = MAX_SIZE;
778
- }
779
-
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;
785
-
786
- this.gl && this.gl.viewport(0, 0, w, h);
787
- this.onCanvasResize && this.onCanvasResize(this.canvas);
788
- }
789
-
790
- /**
791
- * Returns context screen width.
792
- * @public
793
- * @returns {number} -
794
- */
795
- getWidth() {
796
- return this.canvas.width;
797
- }
798
-
799
- /**
800
- * Returns context screen height.
801
- * @public
802
- * @returns {number} -
803
- */
804
- getHeight() {
805
- return this.canvas.height;
806
- }
807
-
808
- /**
809
- * Returns canvas aspect ratio.
810
- * @public
811
- * @returns {number} -
812
- */
813
- getClientAspect() {
814
- return this.canvas.clientWidth / this.canvas.clientHeight;
815
- }
816
-
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
- }
826
-
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;
837
-
838
- this.defaultClock._tick(this.deltaTime);
839
-
840
- for (var i = 0; i < this._clocks.length; i++) {
841
- this._clocks[i]._tick(this.deltaTime);
842
- }
843
-
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
- }
849
-
850
- /** Draw frame */
851
- this._frameCallback();
852
- }
853
-
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);
862
- }
863
-
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
- }
874
- }
875
-
876
- stop() {
877
- if (this._requestAnimationFrameId) {
878
- window.cancelAnimationFrame(this._requestAnimationFrameId);
879
- this._requestAnimationFrameId = null;
880
- }
881
- }
882
-
883
- /**
884
- * Make animation.
885
- * @private
886
- */
887
- _animationFrameCallback() {
888
- this._requestAnimationFrameId = window.requestAnimationFrame(() => {
889
- this.drawFrame();
890
- this._animationFrameCallback();
891
- });
892
- }
893
-
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);
924
- texture.default = true;
925
- success(texture);
926
- }
927
- }
928
-
929
- /**
930
- * @public
931
- */
932
- destroy() {
933
- var gl = this.gl;
934
-
935
- this.stop();
936
-
937
- for (var p in this.programs) {
938
- this.removeProgram(p);
939
- }
940
-
941
- gl.deleteTexture(this.transparentTexture);
942
- this.transparentTexture = null;
943
-
944
- this.framebufferStack = null;
945
- this.framebufferStack = new Stack();
946
-
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);
963
-
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
- }
970
-
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;
992
- }
993
-
994
- addClock(clock) {
995
- if (!clock.__handler) {
996
- clock.__handler = this;
997
- this._clocks.push(clock);
998
- }
999
- }
1000
-
1001
- addClocks(clockArr) {
1002
- for (var i = 0; i < clockArr.length; i++) {
1003
- this.addClock(clockArr[i]);
1004
- }
1005
- }
1006
-
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
- }
1017
- }
1018
- }
1019
- }
1020
- }
1021
-
1022
- export { Handler };
1
+ /**
2
+ * @module og/webgl/Handler
3
+ */
4
+
5
+ "use strict";
6
+
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
+
15
+ /**
16
+ * Maximum texture image size.
17
+ * @const
18
+ * @type {number}
19
+ */
20
+ const MAX_SIZE = 4096;
21
+
22
+ const vendorPrefixes = ["", "WEBKIT_", "MOZ_"];
23
+
24
+ /**
25
+ * A WebGL handler for accessing low-level WebGL capabilities.
26
+ * @class
27
+ * @param {string} id - Canvas element id that WebGL handler assing with. If it's null
28
+ * or undefined creates hidden canvas and handler bacomes hidden.
29
+ * @param {Object} [params] - Handler options:
30
+ * @param {number} [params.anisotropy] - Anisitropy filter degree. 8 is default.
31
+ * @param {number} [params.width] - Hidden handler width. 256 is default.
32
+ * @param {number} [params.height] - Hidden handler height. 256 is default.
33
+ * @param {Object} [param.scontext] - Native WebGL context attributes. See https://www.khronos.org/registry/webgl/specs/latest/1.0/#WEBGLCONTEXTATTRIBUTES
34
+ * @param {Array.<string>} [params.extensions] - Additional WebGL extension list. Available by default: EXT_texture_filter_anisotropic.
35
+ */
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;
102
+
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
+ }
145
+
146
+ /**
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} -
151
+ */
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
+ }
162
+
163
+ /**
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} -
168
+ */
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
+ }
191
+
192
+ /**
193
+ * Sets animation frame function.
194
+ * @public
195
+ * @param {callback} callback - Frame callback.
196
+ */
197
+ setFrameCallback(callback) {
198
+ callback && (this._frameCallback = callback);
199
+ }
200
+
201
+ /**
202
+ * Creates NEAREST filter texture.
203
+ * @public
204
+ * @param {Object} image - Image or Canvas object.
205
+ * @returns {Object} - WebGL texture object.
206
+ */
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
+ }
220
+
221
+ /**
222
+ * Creates empty texture.
223
+ * @public
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.
232
+ */
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
+ //}
309
+
310
+ /**
311
+ * Creates Empty NEAREST filtered texture.
312
+ * @public
313
+ * @param {number} width - Empty texture width.
314
+ * @param {number} height - Empty texture height.
315
+ * @returns {Object} - WebGL texture object.
316
+ */
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
+ }
330
+
331
+ /**
332
+ * Creates empty LINEAR filtered texture.
333
+ * @public
334
+ * @param {number} width - Empty texture width.
335
+ * @param {number} height - Empty texture height.
336
+ * @returns {Object} - WebGL texture object.
337
+ */
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
+ }
351
+
352
+ /**
353
+ * Creates LINEAR filter texture.
354
+ * @public
355
+ * @param {Object} image - Image or Canvas object.
356
+ * @returns {Object} - WebGL texture object.
357
+ */
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;
369
+ }
370
+
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;
389
+ }
390
+
391
+ /**
392
+ * Creates ANISOTROPY filter texture.
393
+ * @public
394
+ * @param {Object} image - Image or Canvas object.
395
+ * @returns {Object} - WebGL texture object.
396
+ */
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
+ }
415
+
416
+ /**
417
+ * Creates DEFAULT filter texture, ANISOTROPY is default.
418
+ * @public
419
+ * @param {Object} image - Image or Canvas object.
420
+ * @returns {Object} - WebGL texture object.
421
+ */
422
+ createTexture(image) {
423
+ return this.createTexture_a(image);
424
+ }
425
+
426
+ /**
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.
437
+ */
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
+ }
466
+
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
+ }
482
+
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
+ }
505
+
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();
513
+ }
514
+
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]);
523
+ }
524
+ }
525
+
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();
541
+ }
542
+ }
543
+ }
544
+
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
+ }
553
+ }
554
+
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
+ }
575
+
576
+ /**
577
+ * Main function that initialize handler.
578
+ * @public
579
+ */
580
+ initialize() {
581
+
582
+ if (this._id) {
583
+ this.canvas = document.getElementById(this._id);
584
+ } else {
585
+ this.canvas = document.createElement("canvas");
586
+ this.canvas.width = this._params.width;
587
+ this.canvas.height = this._params.height;
588
+ }
589
+
590
+ this.gl = Handler.getContext(this.canvas, this._params.context);
591
+ this._initialized = true;
592
+
593
+ /** Sets deafult extensions */
594
+ this._params.extensions.push("EXT_texture_filter_anisotropic");
595
+
596
+ if (this.gl.type === "webgl") {
597
+ this._params.extensions.push("OES_standard_derivatives");
598
+ this._params.extensions.push("OES_element_index_uint");
599
+ this._params.extensions.push("WEBGL_depth_texture");
600
+ //this._params.extensions.push("EXT_frag_depth");
601
+ } else {
602
+ this._params.extensions.push("EXT_color_buffer_float");
603
+ this._params.extensions.push("OES_texture_float_linear");
604
+ }
605
+
606
+ var i = this._params.extensions.length;
607
+ while (i--) {
608
+ this.initializeExtension(this._params.extensions[i], true);
609
+ }
610
+
611
+ if (!this.extensions.EXT_texture_filter_anisotropic) {
612
+ this.createTexture = this.createTexture_mm;
613
+ }
614
+
615
+ /** Initilalize shaders and rendering parameters*/
616
+ this._initPrograms();
617
+ this._setDefaults();
618
+ }
619
+
620
+ /**
621
+ * Sets default gl render parameters. Used in init function.
622
+ * @private
623
+ */
624
+ _setDefaults() {
625
+ this.activateDepthTest();
626
+ this.setSize(
627
+ this.canvas.clientWidth || this._params.width,
628
+ this.canvas.clientHeight || this._params.height
629
+ );
630
+ this.gl.frontFace(this.gl.CCW);
631
+ this.gl.cullFace(this.gl.BACK);
632
+ this.activateFaceCulling();
633
+ this.deactivateBlending();
634
+ var that = this;
635
+ this.createDefaultTexture({ color: "rgba(0,0,0,0.0)" }, function (t) {
636
+ that.transparentTexture = t;
637
+ });
638
+ }
639
+
640
+ /**
641
+ * Activate depth test.
642
+ * @public
643
+ */
644
+ activateDepthTest() {
645
+ this.gl.enable(this.gl.DEPTH_TEST);
646
+ }
647
+
648
+ /**
649
+ * Deactivate depth test.
650
+ * @public
651
+ */
652
+ deactivateDepthTest() {
653
+ this.gl.disable(this.gl.DEPTH_TEST);
654
+ }
655
+
656
+ /**
657
+ * Activate face culling.
658
+ * @public
659
+ */
660
+ activateFaceCulling() {
661
+ this.gl.enable(this.gl.CULL_FACE);
662
+ }
663
+
664
+ /**
665
+ * Deactivate face cullting.
666
+ * @public
667
+ */
668
+ deactivateFaceCulling() {
669
+ this.gl.disable(this.gl.CULL_FACE);
670
+ }
671
+
672
+ /**
673
+ * Activate blending.
674
+ * @public
675
+ */
676
+ activateBlending() {
677
+ this.gl.enable(this.gl.BLEND);
678
+ }
679
+
680
+ /**
681
+ * Deactivate blending.
682
+ * @public
683
+ */
684
+ deactivateBlending() {
685
+ this.gl.disable(this.gl.BLEND);
686
+ }
687
+
688
+ /**
689
+ * Creates STREAM_DRAW ARRAY buffer.
690
+ * @public
691
+ * @param {Array.<number>} array - Input array.
692
+ * @param {number} itemSize - Array item size.
693
+ * @param {number} numItems - Items quantity.
694
+ * @param {number} [usage=STATIC_DRAW] - Parameter of the bufferData call can be one of STATIC_DRAW, DYNAMIC_DRAW, or STREAM_DRAW.
695
+ * @return {Object} -
696
+ */
697
+ createStreamArrayBuffer(itemSize, numItems, usage, bites = 4) {
698
+ var buffer = this.gl.createBuffer();
699
+ this.gl.bindBuffer(this.gl.ARRAY_BUFFER, buffer);
700
+ this.gl.bufferData(
701
+ this.gl.ARRAY_BUFFER,
702
+ numItems * itemSize * bites,
703
+ usage || this.gl.STREAM_DRAW
704
+ );
705
+ this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null);
706
+ buffer.itemSize = itemSize;
707
+ buffer.numItems = numItems;
708
+ return buffer;
709
+ }
710
+
711
+ /**
712
+ * Load stream ARRAY buffer.
713
+ * @public
714
+ * @param {Array.<number>} array - Input array.
715
+ * @param {number} itemSize - Array item size.
716
+ * @param {number} numItems - Items quantity.
717
+ * @param {number} [usage=STATIC_DRAW] - Parameter of the bufferData call can be one of STATIC_DRAW, DYNAMIC_DRAW, or STREAM_DRAW.
718
+ * @return {Object} -
719
+ */
720
+ setStreamArrayBuffer(buffer, array, offset = 0) {
721
+ let gl = this.gl;
722
+ gl.bindBuffer(this.gl.ARRAY_BUFFER, buffer);
723
+ gl.bufferSubData(this.gl.ARRAY_BUFFER, offset, array);
724
+ gl.bindBuffer(this.gl.ARRAY_BUFFER, null);
725
+ return buffer;
726
+ }
727
+
728
+ /**
729
+ * Creates ARRAY buffer.
730
+ * @public
731
+ * @param {Array.<number>} array - Input array.
732
+ * @param {number} itemSize - Array item size.
733
+ * @param {number} numItems - Items quantity.
734
+ * @param {number} [usage=STATIC_DRAW] - Parameter of the bufferData call can be one of STATIC_DRAW, DYNAMIC_DRAW, or STREAM_DRAW.
735
+ * @return {Object} -
736
+ */
737
+ createArrayBuffer(array, itemSize, numItems, usage) {
738
+ var buffer = this.gl.createBuffer();
739
+ this.gl.bindBuffer(this.gl.ARRAY_BUFFER, buffer);
740
+ this.gl.bufferData(this.gl.ARRAY_BUFFER, array, usage || this.gl.STATIC_DRAW);
741
+ this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null);
742
+ buffer.itemSize = itemSize;
743
+ buffer.numItems = numItems;
744
+ return buffer;
745
+ }
746
+
747
+ /**
748
+ * Creates ELEMENT ARRAY buffer.
749
+ * @public
750
+ * @param {Array.<number>} array - Input array.
751
+ * @param {number} itemSize - Array item size.
752
+ * @param {number} numItems - Items quantity.
753
+ * @param {number} [usage=STATIC_DRAW] - Parameter of the bufferData call can be one of STATIC_DRAW, DYNAMIC_DRAW, or STREAM_DRAW.
754
+ * @return {Object} -
755
+ */
756
+ createElementArrayBuffer(array, itemSize, numItems, usage) {
757
+ var buffer = this.gl.createBuffer();
758
+ this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, buffer);
759
+ this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER, array, usage || this.gl.STATIC_DRAW);
760
+ this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, null);
761
+ buffer.itemSize = itemSize;
762
+ buffer.numItems = numItems || array.length;
763
+ return buffer;
764
+ }
765
+
766
+ /**
767
+ * Sets handler canvas size.
768
+ * @public
769
+ * @param {number} w - Canvas width.
770
+ * @param {number} h - Canvas height.
771
+ */
772
+ setSize(w, h) {
773
+
774
+ if (w > MAX_SIZE) {
775
+ w = MAX_SIZE;
776
+ }
777
+
778
+ if (h > MAX_SIZE) {
779
+ h = MAX_SIZE;
780
+ }
781
+
782
+ this._params.width = w;
783
+ this._params.height = h;
784
+ this.canvas.width = w;
785
+ this.canvas.height = h;
786
+ this._oneByHeight = 1 / h;
787
+
788
+ this.gl && this.gl.viewport(0, 0, w, h);
789
+ this.onCanvasResize && this.onCanvasResize(this.canvas);
790
+ }
791
+
792
+ /**
793
+ * Returns context screen width.
794
+ * @public
795
+ * @returns {number} -
796
+ */
797
+ getWidth() {
798
+ return this.canvas.width;
799
+ }
800
+
801
+ /**
802
+ * Returns context screen height.
803
+ * @public
804
+ * @returns {number} -
805
+ */
806
+ getHeight() {
807
+ return this.canvas.height;
808
+ }
809
+
810
+ /**
811
+ * Returns canvas aspect ratio.
812
+ * @public
813
+ * @returns {number} -
814
+ */
815
+ getClientAspect() {
816
+ return this.canvas.clientWidth / this.canvas.clientHeight;
817
+ }
818
+
819
+ /**
820
+ * Returns screen center coordinates.
821
+ * @public
822
+ * @returns {number} -
823
+ */
824
+ getCenter() {
825
+ var c = this.canvas;
826
+ return new Vec2(Math.round(c.width * 0.5), Math.round(c.height * 0.5));
827
+ }
828
+
829
+ /**
830
+ * Draw single frame.
831
+ * @public
832
+ * @param {number} now - Frame current time milliseconds.
833
+ */
834
+ drawFrame() {
835
+ /** Calculating frame time */
836
+ var now = window.performance.now();
837
+ this.deltaTime = now - this._lastAnimationFrameTime;
838
+ this._lastAnimationFrameTime = now;
839
+
840
+ this.defaultClock._tick(this.deltaTime);
841
+
842
+ for (var i = 0; i < this._clocks.length; i++) {
843
+ this._clocks[i]._tick(this.deltaTime);
844
+ }
845
+
846
+ /** Canvas resize checking */
847
+ var canvas = this.canvas;
848
+ if (canvas.clientWidth !== canvas.width || canvas.clientHeight !== canvas.height) {
849
+ this.setSize(canvas.clientWidth, canvas.clientHeight);
850
+ }
851
+
852
+ /** Draw frame */
853
+ this._frameCallback();
854
+ }
855
+
856
+ /**
857
+ * Clearing gl frame.
858
+ * @public
859
+ */
860
+ clearFrame() {
861
+ var gl = this.gl;
862
+ this.gl.clearColor(0.0, 0.0, 0.0, 1.0);
863
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
864
+ }
865
+
866
+ /**
867
+ * Starts animation loop.
868
+ * @public
869
+ */
870
+ start() {
871
+ if (!this._requestAnimationFrameId && this._initialized) {
872
+ this._lastAnimationFrameTime = window.performance.now();
873
+ this.defaultClock.setDate(new Date());
874
+ this._animationFrameCallback();
875
+ }
876
+ }
877
+
878
+ stop() {
879
+ if (this._requestAnimationFrameId) {
880
+ window.cancelAnimationFrame(this._requestAnimationFrameId);
881
+ this._requestAnimationFrameId = null;
882
+ }
883
+ }
884
+
885
+ /**
886
+ * Make animation.
887
+ * @private
888
+ */
889
+ _animationFrameCallback() {
890
+ this._requestAnimationFrameId = window.requestAnimationFrame(() => {
891
+ this.drawFrame();
892
+ this._animationFrameCallback();
893
+ });
894
+ }
895
+
896
+ /**
897
+ * Creates default texture object
898
+ * @public
899
+ * @param {Object} [params] - Texture parameters:
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);
924
+ texture.default = true;
925
+ success(texture);
926
+ }
927
+ }
928
+
929
+ /**
930
+ * @public
931
+ */
932
+ destroy() {
933
+ var gl = this.gl;
934
+
935
+ this.stop();
936
+
937
+ for (var p in this.programs) {
938
+ this.removeProgram(p);
939
+ }
940
+
941
+ gl.deleteTexture(this.transparentTexture);
942
+ this.transparentTexture = null;
943
+
944
+ this.framebufferStack = null;
945
+ this.framebufferStack = new Stack();
946
+
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);
963
+
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
+ }
970
+
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;
992
+ }
993
+
994
+ addClock(clock) {
995
+ if (!clock.__handler) {
996
+ clock.__handler = this;
997
+ this._clocks.push(clock);
998
+ }
999
+ }
1000
+
1001
+ addClocks(clockArr) {
1002
+ for (var i = 0; i < clockArr.length; i++) {
1003
+ this.addClock(clockArr[i]);
1004
+ }
1005
+ }
1006
+
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
+ }
1017
+ }
1018
+ }
1019
+ }
1020
+ }
1021
+
1022
+ export { Handler };