@openglobus/og 0.10.4 → 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 (172) hide show
  1. package/css/og.css +1 -1
  2. package/package.json +11 -9
  3. package/src/og/Extent.js +274 -273
  4. package/src/og/Globe.js +11 -3
  5. package/src/og/LonLat.js +152 -146
  6. package/src/og/Popup.js +2 -1
  7. package/src/og/camera/PlanetCamera.js +112 -38
  8. package/src/og/control/EarthNavigation.js +259 -0
  9. package/src/og/control/MouseNavigation.js +68 -40
  10. package/src/og/entity/EntityCollection.js +1 -1
  11. package/src/og/entity/LabelHandler.js +366 -74
  12. package/src/og/entity/Polyline.js +3 -2
  13. package/src/og/layer/CanvasTiles.js +32 -30
  14. package/src/og/layer/KML.js +159 -0
  15. package/src/og/layer/Vector.js +5 -0
  16. package/src/og/layer/index.js +2 -1
  17. package/src/og/math/Vec2.js +448 -448
  18. package/src/og/math/Vec3.js +759 -757
  19. package/src/og/math/Vec4.js +216 -215
  20. package/src/og/quadTree/Node.js +67 -13
  21. package/src/og/renderer/RendererEvents.js +21 -16
  22. package/src/og/scene/Planet.js +25 -10
  23. package/src/og/segment/Segment.js +3 -3
  24. package/src/og/segment/SegmentLonLat.js +7 -0
  25. package/src/og/terrain/GlobusTerrain.js +4 -0
  26. package/src/og/utils/FontAtlas.js +1 -0
  27. package/src/og/utils/GeoImageCreator.js +123 -121
  28. package/src/og/utils/Loader.js +81 -80
  29. package/src/og/utils/NormalMapCreator.js +320 -318
  30. package/src/og/utils/VectorTileCreator.js +251 -250
  31. package/src/og/webgl/Framebuffer.js +265 -264
  32. package/src/og/webgl/Handler.js +1022 -1001
  33. package/src/og/webgl/Multisample.js +169 -168
  34. package/src/og/webgl/ProgramController.js +113 -112
  35. package/types/Clock.d.ts +90 -0
  36. package/types/Deferred.d.ts +6 -0
  37. package/types/Events.d.ts +73 -0
  38. package/types/Extent.d.ts +162 -0
  39. package/types/Globe.d.ts +80 -0
  40. package/types/ImageCanvas.d.ts +121 -0
  41. package/types/Lock.d.ts +12 -0
  42. package/types/LonLat.d.ts +108 -0
  43. package/types/Popup.d.ts +38 -0
  44. package/types/QueueArray.d.ts +15 -0
  45. package/types/Rectangle.d.ts +74 -0
  46. package/types/Stack.d.ts +15 -0
  47. package/types/ajax.d.ts +24 -0
  48. package/types/arial.d.ts +48 -0
  49. package/types/astro/astro.d.ts +38 -0
  50. package/types/astro/earth.d.ts +6 -0
  51. package/types/astro/jd.d.ts +254 -0
  52. package/types/bv/Box.d.ts +25 -0
  53. package/types/bv/Sphere.d.ts +32 -0
  54. package/types/bv/index.d.ts +3 -0
  55. package/types/camera/Camera.d.ts +303 -0
  56. package/types/camera/Frustum.d.ts +129 -0
  57. package/types/camera/PlanetCamera.d.ts +222 -0
  58. package/types/camera/index.d.ts +3 -0
  59. package/types/cons.d.ts +40 -0
  60. package/types/control/CompassButton.d.ts +17 -0
  61. package/types/control/Control.d.ts +101 -0
  62. package/types/control/DebugInfo.d.ts +16 -0
  63. package/types/control/EarthCoordinates.d.ts +47 -0
  64. package/types/control/GeoImageDragControl.d.ts +6 -0
  65. package/types/control/KeyboardNavigation.d.ts +22 -0
  66. package/types/control/LayerSwitcher.d.ts +23 -0
  67. package/types/control/Lighting.d.ts +16 -0
  68. package/types/control/ScaleControl.d.ts +22 -0
  69. package/types/control/ShowFps.d.ts +12 -0
  70. package/types/control/SimpleNavigation.d.ts +28 -0
  71. package/types/control/Sun.d.ts +52 -0
  72. package/types/control/ToggleWireframe.d.ts +12 -0
  73. package/types/control/ZoomControl.d.ts +28 -0
  74. package/types/control/index.d.ts +15 -0
  75. package/types/ellipsoid/Ellipsoid.d.ts +142 -0
  76. package/types/ellipsoid/index.d.ts +3 -0
  77. package/types/ellipsoid/wgs84.d.ts +5 -0
  78. package/types/entity/BaseBillboard.d.ts +208 -0
  79. package/types/entity/Billboard.d.ts +94 -0
  80. package/types/entity/BillboardHandler.d.ts +74 -0
  81. package/types/entity/Entity.d.ts +330 -0
  82. package/types/entity/EntityCollection.d.ts +303 -0
  83. package/types/entity/Geometry.d.ts +72 -0
  84. package/types/entity/GeometryHandler.d.ts +76 -0
  85. package/types/entity/Label.d.ts +194 -0
  86. package/types/entity/LabelHandler.d.ts +24 -0
  87. package/types/entity/PointCloud.d.ts +174 -0
  88. package/types/entity/PointCloudHandler.d.ts +38 -0
  89. package/types/entity/Polyline.d.ts +303 -0
  90. package/types/entity/PolylineHandler.d.ts +18 -0
  91. package/types/entity/Ray.d.ts +123 -0
  92. package/types/entity/RayHandler.d.ts +67 -0
  93. package/types/entity/ShapeHandler.d.ts +22 -0
  94. package/types/entity/Strip.d.ts +118 -0
  95. package/types/entity/StripHandler.d.ts +38 -0
  96. package/types/entity/index.d.ts +8 -0
  97. package/types/index.core.d.ts +65 -0
  98. package/types/index.d.ts +45 -0
  99. package/types/index.webgl.d.ts +7 -0
  100. package/types/inherits.d.ts +4 -0
  101. package/types/input/input.d.ts +34 -0
  102. package/types/layer/BaseGeoImage.d.ts +106 -0
  103. package/types/layer/CanvasTiles.d.ts +75 -0
  104. package/types/layer/GeoImage.d.ts +65 -0
  105. package/types/layer/GeoTexture2d.d.ts +8 -0
  106. package/types/layer/GeoVideo.d.ts +80 -0
  107. package/types/layer/KML.d.ts +58 -0
  108. package/types/layer/WMS.d.ts +66 -0
  109. package/types/layer/XYZ.d.ts +126 -0
  110. package/types/layer/index.d.ts +10 -0
  111. package/types/light/LightSource.d.ts +177 -0
  112. package/types/math/Mat3.d.ts +53 -0
  113. package/types/math/Mat4.d.ts +157 -0
  114. package/types/math/Plane.d.ts +17 -0
  115. package/types/math/Vec2.d.ts +308 -0
  116. package/types/math/Vec3.d.ts +459 -0
  117. package/types/math/Vec4.d.ts +161 -0
  118. package/types/math/coder.d.ts +42 -0
  119. package/types/math/index.d.ts +11 -0
  120. package/types/math.d.ts +261 -0
  121. package/types/mercator.d.ts +92 -0
  122. package/types/proj/EPSG3857.d.ts +5 -0
  123. package/types/proj/EPSG4326.d.ts +5 -0
  124. package/types/quadTree/quadTree.d.ts +40 -0
  125. package/types/renderer/RendererEvents.d.ts +230 -0
  126. package/types/res/images.d.ts +3 -0
  127. package/types/scene/Axes.d.ts +11 -0
  128. package/types/scene/BaseNode.d.ts +60 -0
  129. package/types/scene/Planet.d.ts +572 -0
  130. package/types/scene/RenderNode.d.ts +143 -0
  131. package/types/scene/SkyBox.d.ts +10 -0
  132. package/types/scene/index.d.ts +4 -0
  133. package/types/segment/segmentHelper.d.ts +13 -0
  134. package/types/shaders/billboard.d.ts +3 -0
  135. package/types/shaders/depth.d.ts +2 -0
  136. package/types/shaders/drawnode.d.ts +7 -0
  137. package/types/shaders/label.d.ts +4 -0
  138. package/types/shaders/pointCloud.d.ts +2 -0
  139. package/types/shaders/polyline.d.ts +3 -0
  140. package/types/shaders/ray.d.ts +2 -0
  141. package/types/shaders/screenFrame.d.ts +2 -0
  142. package/types/shaders/shape.d.ts +4 -0
  143. package/types/shaders/skybox.d.ts +2 -0
  144. package/types/shaders/toneMapping.d.ts +2 -0
  145. package/types/shapes/BaseShape.d.ts +247 -0
  146. package/types/shapes/Sphere.d.ts +41 -0
  147. package/types/terrain/BilTerrain.d.ts +8 -0
  148. package/types/terrain/EmptyTerrain.d.ts +72 -0
  149. package/types/terrain/Geoid.d.ts +26 -0
  150. package/types/terrain/GlobusTerrain.d.ts +153 -0
  151. package/types/terrain/MapboxTerrain.d.ts +8 -0
  152. package/types/terrain/index.d.ts +5 -0
  153. package/types/utils/FontAtlas.d.ts +14 -0
  154. package/types/utils/GeoImageCreator.d.ts +29 -0
  155. package/types/utils/ImagesCacheManager.d.ts +10 -0
  156. package/types/utils/Loader.d.ts +25 -0
  157. package/types/utils/NormalMapCreator.d.ts +39 -0
  158. package/types/utils/PlainSegmentWorker.d.ts +10 -0
  159. package/types/utils/TerrainWorker.d.ts +9 -0
  160. package/types/utils/TextureAtlas.d.ts +111 -0
  161. package/types/utils/VectorTileCreator.d.ts +16 -0
  162. package/types/utils/colorTable.d.ts +143 -0
  163. package/types/utils/earcut.d.ts +6 -0
  164. package/types/utils/shared.d.ts +230 -0
  165. package/types/webgl/Framebuffer.d.ts +135 -0
  166. package/types/webgl/Handler.d.ts +372 -0
  167. package/types/webgl/Multisample.d.ts +89 -0
  168. package/types/webgl/Program.d.ts +155 -0
  169. package/types/webgl/ProgramController.d.ts +84 -0
  170. package/types/webgl/callbacks.d.ts +1 -0
  171. package/types/webgl/index.d.ts +6 -0
  172. package/types/webgl/types.d.ts +2 -0
@@ -1,1001 +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
- const Handler = function (id, params) {
37
-
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
- var 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
- Handler.getExtension = function (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
- const CONTEXT_TYPE = ["webgl2", "webgl"];
164
-
165
- /**
166
- * Returns a drawing context on the canvas, or null if the context identifier is not supported.
167
- * @param {Object} canvas - HTML canvas object.
168
- * @param {Object} [contextAttributes] - See canvas.getContext contextAttributes.
169
- * @returns {Object} -
170
- */
171
- Handler.getContext = function (canvas, contextAttributes) {
172
- var ctx = null;
173
-
174
- try {
175
- for (let i = 0; i < CONTEXT_TYPE.length; i++) {
176
- ctx = canvas.getContext(CONTEXT_TYPE[i], contextAttributes);
177
- if (ctx) {
178
- ctx.type = CONTEXT_TYPE[i];
179
- break;
180
- }
181
- }
182
- } catch (ex) {
183
- cons.logErr("exception during the GL context initialization");
184
- }
185
-
186
- if (!ctx) {
187
- cons.logErr("could not initialise WebGL");
188
- }
189
-
190
- return ctx;
191
- };
192
-
193
- /**
194
- * Sets animation frame function.
195
- * @public
196
- * @param {callback} callback - Frame callback.
197
- */
198
- Handler.prototype.setFrameCallback = function (callback) {
199
- callback && (this._frameCallback = callback);
200
- };
201
-
202
- /**
203
- * Creates NEAREST filter texture.
204
- * @public
205
- * @param {Object} image - Image or Canvas object.
206
- * @returns {Object} - WebGL texture object.
207
- */
208
- Handler.prototype.createTexture_n = function (image) {
209
- var gl = this.gl;
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
- //}
301
-
302
- /**
303
- * Creates Empty NEAREST filtered texture.
304
- * @public
305
- * @param {number} width - Empty texture width.
306
- * @param {number} height - Empty texture height.
307
- * @returns {Object} - WebGL texture object.
308
- */
309
- Handler.prototype.createEmptyTexture_n = function (width, height) {
310
- var gl = this.gl;
311
- var texture = gl.createTexture();
312
- gl.bindTexture(gl.TEXTURE_2D, texture);
313
- gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
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
- };
322
-
323
- /**
324
- * Creates empty LINEAR filtered texture.
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
- };
343
-
344
- /**
345
- * Creates LINEAR filter texture.
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
- };
362
-
363
- /**
364
- * Creates MIPMAP filter texture.
365
- * @public
366
- * @param {Object} image - Image or Canvas object.
367
- * @returns {Object} - WebGL texture object.
368
- */
369
- Handler.prototype.createTexture_mm = function (image) {
370
- var gl = this.gl;
371
- var texture = gl.createTexture();
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
- };
382
-
383
- /**
384
- * Creates ANISOTROPY filter texture.
385
- * @public
386
- * @param {Object} image - Image or Canvas object.
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
- };
403
-
404
- /**
405
- * Creates DEFAULT filter texture, ANISOTROPY is default.
406
- * @public
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
- };
413
-
414
- /**
415
- * Creates cube texture.
416
- * @public
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];
465
- }
466
- return texture;
467
- };
468
-
469
- /**
470
- * Adds shader program to the handler.
471
- * @public
472
- * @param {og.webgl.Program} program - Shader program.
473
- * @param {boolean} [notActivate] - If it's true program will not compile.
474
- * @return {og.webgl.Program} -
475
- */
476
- Handler.prototype.addProgram = function (program, notActivate) {
477
- if (!this.programs[program.name]) {
478
- var sc = new ProgramController(this, program);
479
- this.programs[program.name] = sc;
480
- this._initProgramController(sc);
481
- if (notActivate) {
482
- sc._activated = false;
483
- }
484
- } else {
485
- console.log("og.webgl.Handler:284 - shader program: '" + program.name + "' is allready exists.");
486
- }
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
-
499
- /**
500
- * Adds shader programs to the handler.
501
- * @public
502
- * @param {Array.<og.webgl.Program>} programsArr - Shader program array.
503
- */
504
- Handler.prototype.addPrograms = function (programsArr) {
505
- for (var i = 0; i < programsArr.length; i++) {
506
- this.addProgram(programsArr[i]);
507
- }
508
- };
509
-
510
- /**
511
- * Used in addProgram
512
- * @private
513
- * @param {og.webgl.ProgramController} sc - Program controller
514
- */
515
- Handler.prototype._initProgramController = function (sc) {
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
- }
526
- }
527
- };
528
-
529
- /**
530
- * Used in init function.
531
- * @private
532
- */
533
- Handler.prototype._initPrograms = function () {
534
- for (var p in this.programs) {
535
- this._initProgramController(this.programs[p]);
536
- }
537
- };
538
-
539
- /**
540
- * Initialize additional WebGL extensions.
541
- * @public
542
- * @param {string} extensionStr - Extension name.
543
- * @param {boolean} showLog - Show logging.
544
- * @return {Object} -
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
- }
554
- }
555
- return this.extensions && this.extensions[extensionStr];
556
- };
557
-
558
- /**
559
- * Main function that initialize handler.
560
- * @public
561
- */
562
- Handler.prototype.initialize = function () {
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;
570
- }
571
-
572
- this.gl = Handler.getContext(this.canvas, this._params.context);
573
- this._initialized = true;
574
-
575
- /** Sets deafult extensions */
576
- this._params.extensions.push("EXT_texture_filter_anisotropic");
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");
586
- }
587
-
588
- var i = this._params.extensions.length;
589
- while (i--) {
590
- this.initializeExtension(this._params.extensions[i], true);
591
- }
592
-
593
- if (!this.extensions.EXT_texture_filter_anisotropic) {
594
- this.createTexture = this.createTexture_mm;
595
- }
596
-
597
- /** Initilalize shaders and rendering parameters*/
598
- this._initPrograms();
599
- this._setDefaults();
600
- };
601
-
602
- /**
603
- * Sets default gl render parameters. Used in init function.
604
- * @private
605
- */
606
- Handler.prototype._setDefaults = function () {
607
- this.activateDepthTest();
608
- this.setSize(this.canvas.clientWidth || this._params.width, this.canvas.clientHeight || this._params.height);
609
- this.gl.frontFace(this.gl.CCW);
610
- this.gl.cullFace(this.gl.BACK);
611
- this.activateFaceCulling();
612
- this.deactivateBlending();
613
- var that = this;
614
- this.createDefaultTexture({ color: "rgba(0,0,0,0.0)" }, function (t) {
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
- };
685
-
686
- /**
687
- * Load stream ARRAY buffer.
688
- * @public
689
- * @param {Array.<number>} array - Input array.
690
- * @param {number} itemSize - Array item size.
691
- * @param {number} numItems - Items quantity.
692
- * @param {number} [usage=STATIC_DRAW] - Parameter of the bufferData call can be one of STATIC_DRAW, DYNAMIC_DRAW, or STREAM_DRAW.
693
- * @return {Object} -
694
- */
695
- Handler.prototype.setStreamArrayBuffer = function (buffer, array, offset = 0) {
696
- let gl = this.gl;
697
- gl.bindBuffer(this.gl.ARRAY_BUFFER, buffer);
698
- gl.bufferSubData(this.gl.ARRAY_BUFFER, offset, array);
699
- gl.bindBuffer(this.gl.ARRAY_BUFFER, null);
700
- return buffer;
701
- };
702
-
703
- /**
704
- * Creates ARRAY buffer.
705
- * @public
706
- * @param {Array.<number>} array - Input array.
707
- * @param {number} itemSize - Array item size.
708
- * @param {number} numItems - Items quantity.
709
- * @param {number} [usage=STATIC_DRAW] - Parameter of the bufferData call can be one of STATIC_DRAW, DYNAMIC_DRAW, or STREAM_DRAW.
710
- * @return {Object} -
711
- */
712
- Handler.prototype.createArrayBuffer = function (array, itemSize, numItems, usage) {
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
- };
721
-
722
- /**
723
- * Creates ELEMENT ARRAY buffer.
724
- * @public
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
- };
740
-
741
- /**
742
- * Sets handler canvas size.
743
- * @public
744
- * @param {number} w - Canvas width.
745
- * @param {number} h - Canvas height.
746
- */
747
- Handler.prototype.setSize = function (w, h) {
748
-
749
- if (w > MAX_SIZE) {
750
- w = MAX_SIZE;
751
- }
752
-
753
- if (h > MAX_SIZE) {
754
- h = MAX_SIZE;
755
- }
756
-
757
- this._params.width = w;
758
- this._params.height = h;
759
- this.canvas.width = w;
760
- this.canvas.height = h;
761
- this._oneByHeight = 1 / h;
762
-
763
- this.gl && this.gl.viewport(0, 0, w, h);
764
- this.onCanvasResize && this.onCanvasResize(this.canvas);
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
- };
775
-
776
- /**
777
- * Returns context screen height.
778
- * @public
779
- * @returns {number} -
780
- */
781
- Handler.prototype.getHeight = function () {
782
- return this.canvas.height;
783
- };
784
-
785
- /**
786
- * Returns canvas aspect ratio.
787
- * @public
788
- * @returns {number} -
789
- */
790
- Handler.prototype.getClientAspect = function () {
791
- return this.canvas.clientWidth / this.canvas.clientHeight;
792
- };
793
-
794
- /**
795
- * Returns screen center coordinates.
796
- * @public
797
- * @returns {number} -
798
- */
799
- Handler.prototype.getCenter = function () {
800
- var c = this.canvas;
801
- return new Vec2(Math.round(c.width * 0.5), Math.round(c.height * 0.5));
802
- };
803
-
804
- /**
805
- * Draw single frame.
806
- * @public
807
- * @param {number} now - Frame current time milliseconds.
808
- */
809
- Handler.prototype.drawFrame = function () {
810
-
811
- /** Calculating frame time */
812
- var now = window.performance.now();
813
- this.deltaTime = now - this._lastAnimationFrameTime;
814
- this._lastAnimationFrameTime = now;
815
-
816
- this.defaultClock._tick(this.deltaTime);
817
-
818
- for (var i = 0; i < this._clocks.length; i++) {
819
- this._clocks[i]._tick(this.deltaTime);
820
- }
821
-
822
- /** Canvas resize checking */
823
- var canvas = this.canvas;
824
- if (canvas.clientWidth !== canvas.width ||
825
- canvas.clientHeight !== canvas.height) {
826
- this.setSize(canvas.clientWidth, canvas.clientHeight);
827
- }
828
-
829
- /** Draw frame */
830
- this._frameCallback();
831
- };
832
-
833
- /**
834
- * Clearing gl frame.
835
- * @public
836
- */
837
- Handler.prototype.clearFrame = function () {
838
- var gl = this.gl;
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();
852
- }
853
- };
854
-
855
- Handler.prototype.stop = function () {
856
- if (this._requestAnimationFrameId) {
857
- window.cancelAnimationFrame(this._requestAnimationFrameId);
858
- this._requestAnimationFrameId = null;
859
- }
860
- };
861
-
862
- /**
863
- * Make animation.
864
- * @private
865
- */
866
- Handler.prototype._animationFrameCallback = function () {
867
- this._requestAnimationFrameId = window.requestAnimationFrame(() => {
868
- this.drawFrame();
869
- this._animationFrameCallback();
870
- });
871
- };
872
-
873
- /**
874
- * Creates default texture object
875
- * @public
876
- * @param {Object} [params] - Texture parameters:
877
- * @param {Array.<number, number, number, number>} [params.color] - Texture RGBA color
878
- * @param {number} [params.url] - Texture source url
879
- * @param {callback} success - Creation callback
880
- */
881
- Handler.prototype.createDefaultTexture = function (params, success) {
882
- var imgCnv;
883
- var texture;
884
- if (params && params.color) {
885
- imgCnv = new ImageCanvas(2, 2);
886
- imgCnv.fillColor(params.color);
887
- texture = this.createTexture_n(imgCnv._canvas);
888
- texture.default = true;
889
- success(texture);
890
- } else if (params && params.url) {
891
- var img = new Image();
892
- var that = this;
893
- img.onload = function () {
894
- texture = that.createTexture(this);
895
- texture.default = true;
896
- 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);
905
- }
906
- };
907
-
908
- /**
909
- * @public
910
- */
911
- Handler.prototype.destroy = function () {
912
-
913
- var gl = this.gl;
914
-
915
- this.stop();
916
-
917
- for (var p in this.programs) {
918
- this.removeProgram(p);
919
- }
920
-
921
- gl.deleteTexture(this.transparentTexture);
922
- this.transparentTexture = null;
923
-
924
- this.framebufferStack = null;
925
- this.framebufferStack = new Stack();
926
-
927
- if (this.canvas.parentNode) {
928
- this.canvas.parentNode.removeChild(this.canvas);
929
- }
930
- this.canvas.width = 1;
931
- this.canvas.height = 1;
932
- this.canvas = null;
933
-
934
- var numAttribs = gl.getParameter(gl.MAX_VERTEX_ATTRIBS);
935
- var tmp = gl.createBuffer();
936
- gl.bindBuffer(gl.ARRAY_BUFFER, tmp);
937
- for (let ii = 0; ii < numAttribs; ++ii) {
938
- gl.disableVertexAttribArray(ii);
939
- gl.vertexAttribPointer(ii, 4, gl.FLOAT, false, 0, 0);
940
- gl.vertexAttrib1f(ii, 0);
941
- }
942
- gl.deleteBuffer(tmp);
943
-
944
- var numTextureUnits = gl.getParameter(gl.MAX_TEXTlURE_IMAGE_UNITS);
945
- for (let ii = 0; ii < numTextureUnits; ++ii) {
946
- gl.activeTexture(gl.TEXTURE0 + ii);
947
- gl.bindTexture(gl.TEXTURE_CUBE_MAP, null);
948
- gl.bindTexture(gl.TEXTURE_2D, null);
949
- }
950
-
951
- gl.activeTexture(gl.TEXTURE0);
952
- gl.useProgram(null);
953
- gl.bindBuffer(gl.ARRAY_BUFFER, null);
954
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
955
- gl.bindFramebuffer(gl.FRAMEBUFFER, null);
956
- gl.bindRenderbuffer(gl.RENDERBUFFER, null);
957
- gl.disable(gl.BLEND);
958
- gl.disable(gl.CULL_FACE);
959
- gl.disable(gl.DEPTH_TEST);
960
- gl.disable(gl.DITHER);
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;
996
- }
997
- }
998
- }
999
- };
1000
-
1001
- 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 };