1 | (function (global, factory) {
|
2 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
3 | typeof define === 'function' && define.amd ? define(factory) :
|
4 | (global.createREGL = factory());
|
5 | }(this, (function () { 'use strict';
|
6 |
|
7 | var extend = function (base, opts) {
|
8 | var keys = Object.keys(opts)
|
9 | for (var i = 0; i < keys.length; ++i) {
|
10 | base[keys[i]] = opts[keys[i]]
|
11 | }
|
12 | return base
|
13 | }
|
14 |
|
15 | var VARIABLE_COUNTER = 0
|
16 |
|
17 | var DYN_FUNC = 0
|
18 |
|
19 | function DynamicVariable (type, data) {
|
20 | this.id = (VARIABLE_COUNTER++)
|
21 | this.type = type
|
22 | this.data = data
|
23 | }
|
24 |
|
25 | function escapeStr (str) {
|
26 | return str.replace(/\\/g, '\\\\').replace(/"/g, '\\"')
|
27 | }
|
28 |
|
29 | function splitParts (str) {
|
30 | if (str.length === 0) {
|
31 | return []
|
32 | }
|
33 |
|
34 | var firstChar = str.charAt(0)
|
35 | var lastChar = str.charAt(str.length - 1)
|
36 |
|
37 | if (str.length > 1 &&
|
38 | firstChar === lastChar &&
|
39 | (firstChar === '"' || firstChar === "'")) {
|
40 | return ['"' + escapeStr(str.substr(1, str.length - 2)) + '"']
|
41 | }
|
42 |
|
43 | var parts = /\[(false|true|null|\d+|'[^']*'|"[^"]*")\]/.exec(str)
|
44 | if (parts) {
|
45 | return (
|
46 | splitParts(str.substr(0, parts.index))
|
47 | .concat(splitParts(parts[1]))
|
48 | .concat(splitParts(str.substr(parts.index + parts[0].length)))
|
49 | )
|
50 | }
|
51 |
|
52 | var subparts = str.split('.')
|
53 | if (subparts.length === 1) {
|
54 | return ['"' + escapeStr(str) + '"']
|
55 | }
|
56 |
|
57 | var result = []
|
58 | for (var i = 0; i < subparts.length; ++i) {
|
59 | result = result.concat(splitParts(subparts[i]))
|
60 | }
|
61 | return result
|
62 | }
|
63 |
|
64 | function toAccessorString (str) {
|
65 | return '[' + splitParts(str).join('][') + ']'
|
66 | }
|
67 |
|
68 | function defineDynamic (type, data) {
|
69 | return new DynamicVariable(type, toAccessorString(data + ''))
|
70 | }
|
71 |
|
72 | function isDynamic (x) {
|
73 | return (typeof x === 'function' && !x._reglType) ||
|
74 | x instanceof DynamicVariable
|
75 | }
|
76 |
|
77 | function unbox (x, path) {
|
78 | if (typeof x === 'function') {
|
79 | return new DynamicVariable(DYN_FUNC, x)
|
80 | }
|
81 | return x
|
82 | }
|
83 |
|
84 | var dynamic = {
|
85 | DynamicVariable: DynamicVariable,
|
86 | define: defineDynamic,
|
87 | isDynamic: isDynamic,
|
88 | unbox: unbox,
|
89 | accessor: toAccessorString
|
90 | };
|
91 |
|
92 |
|
93 | var raf = {
|
94 | next: typeof requestAnimationFrame === 'function'
|
95 | ? function (cb) { return requestAnimationFrame(cb) }
|
96 | : function (cb) { return setTimeout(cb, 16) },
|
97 | cancel: typeof cancelAnimationFrame === 'function'
|
98 | ? function (raf) { return cancelAnimationFrame(raf) }
|
99 | : clearTimeout
|
100 | };
|
101 |
|
102 |
|
103 | var clock = (typeof performance !== 'undefined' && performance.now)
|
104 | ? function () { return performance.now() }
|
105 | : function () { return +(new Date()) };
|
106 |
|
107 | function createStringStore () {
|
108 | var stringIds = { '': 0 }
|
109 | var stringValues = ['']
|
110 | return {
|
111 | id: function (str) {
|
112 | var result = stringIds[str]
|
113 | if (result) {
|
114 | return result
|
115 | }
|
116 | result = stringIds[str] = stringValues.length
|
117 | stringValues.push(str)
|
118 | return result
|
119 | },
|
120 |
|
121 | str: function (id) {
|
122 | return stringValues[id]
|
123 | }
|
124 | }
|
125 | }
|
126 |
|
127 |
|
128 |
|
129 | function createCanvas (element, onDone, pixelRatio) {
|
130 | var canvas = document.createElement('canvas')
|
131 | extend(canvas.style, {
|
132 | border: 0,
|
133 | margin: 0,
|
134 | padding: 0,
|
135 | top: 0,
|
136 | left: 0
|
137 | })
|
138 | element.appendChild(canvas)
|
139 |
|
140 | if (element === document.body) {
|
141 | canvas.style.position = 'absolute'
|
142 | extend(element.style, {
|
143 | margin: 0,
|
144 | padding: 0
|
145 | })
|
146 | }
|
147 |
|
148 | function resize () {
|
149 | var w = window.innerWidth
|
150 | var h = window.innerHeight
|
151 | if (element !== document.body) {
|
152 | var bounds = element.getBoundingClientRect()
|
153 | w = bounds.right - bounds.left
|
154 | h = bounds.bottom - bounds.top
|
155 | }
|
156 | canvas.width = pixelRatio * w
|
157 | canvas.height = pixelRatio * h
|
158 | extend(canvas.style, {
|
159 | width: w + 'px',
|
160 | height: h + 'px'
|
161 | })
|
162 | }
|
163 |
|
164 | window.addEventListener('resize', resize, false)
|
165 |
|
166 | function onDestroy () {
|
167 | window.removeEventListener('resize', resize)
|
168 | element.removeChild(canvas)
|
169 | }
|
170 |
|
171 | resize()
|
172 |
|
173 | return {
|
174 | canvas: canvas,
|
175 | onDestroy: onDestroy
|
176 | }
|
177 | }
|
178 |
|
179 | function createContext (canvas, contextAttributes) {
|
180 | function get (name) {
|
181 | try {
|
182 | return canvas.getContext(name, contextAttributes)
|
183 | } catch (e) {
|
184 | return null
|
185 | }
|
186 | }
|
187 | return (
|
188 | get('webgl') ||
|
189 | get('experimental-webgl') ||
|
190 | get('webgl-experimental')
|
191 | )
|
192 | }
|
193 |
|
194 | function isHTMLElement (obj) {
|
195 | return (
|
196 | typeof obj.nodeName === 'string' &&
|
197 | typeof obj.appendChild === 'function' &&
|
198 | typeof obj.getBoundingClientRect === 'function'
|
199 | )
|
200 | }
|
201 |
|
202 | function isWebGLContext (obj) {
|
203 | return (
|
204 | typeof obj.drawArrays === 'function' ||
|
205 | typeof obj.drawElements === 'function'
|
206 | )
|
207 | }
|
208 |
|
209 | function parseExtensions (input) {
|
210 | if (typeof input === 'string') {
|
211 | return input.split()
|
212 | }
|
213 |
|
214 | return input
|
215 | }
|
216 |
|
217 | function getElement (desc) {
|
218 | if (typeof desc === 'string') {
|
219 |
|
220 | return document.querySelector(desc)
|
221 | }
|
222 | return desc
|
223 | }
|
224 |
|
225 | function parseArgs (args_) {
|
226 | var args = args_ || {}
|
227 | var element, container, canvas, gl
|
228 | var contextAttributes = {}
|
229 | var extensions = []
|
230 | var optionalExtensions = []
|
231 | var pixelRatio = (typeof window === 'undefined' ? 1 : window.devicePixelRatio)
|
232 | var profile = false
|
233 | var onDone = function (err) {
|
234 | if (err) {
|
235 |
|
236 | }
|
237 | }
|
238 | var onDestroy = function () {}
|
239 | if (typeof args === 'string') {
|
240 |
|
241 | element = document.querySelector(args)
|
242 |
|
243 | } else if (typeof args === 'object') {
|
244 | if (isHTMLElement(args)) {
|
245 | element = args
|
246 | } else if (isWebGLContext(args)) {
|
247 | gl = args
|
248 | canvas = gl.canvas
|
249 | } else {
|
250 |
|
251 | if ('gl' in args) {
|
252 | gl = args.gl
|
253 | } else if ('canvas' in args) {
|
254 | canvas = getElement(args.canvas)
|
255 | } else if ('container' in args) {
|
256 | container = getElement(args.container)
|
257 | }
|
258 | if ('attributes' in args) {
|
259 | contextAttributes = args.attributes
|
260 |
|
261 | }
|
262 | if ('extensions' in args) {
|
263 | extensions = parseExtensions(args.extensions)
|
264 | }
|
265 | if ('optionalExtensions' in args) {
|
266 | optionalExtensions = parseExtensions(args.optionalExtensions)
|
267 | }
|
268 | if ('onDone' in args) {
|
269 |
|
270 | onDone = args.onDone
|
271 | }
|
272 | if ('profile' in args) {
|
273 | profile = !!args.profile
|
274 | }
|
275 | if ('pixelRatio' in args) {
|
276 | pixelRatio = +args.pixelRatio
|
277 |
|
278 | }
|
279 | }
|
280 | } else {
|
281 |
|
282 | }
|
283 |
|
284 | if (element) {
|
285 | if (element.nodeName.toLowerCase() === 'canvas') {
|
286 | canvas = element
|
287 | } else {
|
288 | container = element
|
289 | }
|
290 | }
|
291 |
|
292 | if (!gl) {
|
293 | if (!canvas) {
|
294 |
|
295 | var result = createCanvas(container || document.body, onDone, pixelRatio)
|
296 | if (!result) {
|
297 | return null
|
298 | }
|
299 | canvas = result.canvas
|
300 | onDestroy = result.onDestroy
|
301 | }
|
302 |
|
303 | contextAttributes.premultipliedAlpha = contextAttributes.premultipliedAlpha || false
|
304 | gl = createContext(canvas, contextAttributes)
|
305 | }
|
306 |
|
307 | if (!gl) {
|
308 | onDestroy()
|
309 | onDone('webgl not supported, try upgrading your browser or graphics drivers http://get.webgl.org')
|
310 | return null
|
311 | }
|
312 |
|
313 | return {
|
314 | gl: gl,
|
315 | canvas: canvas,
|
316 | container: container,
|
317 | extensions: extensions,
|
318 | optionalExtensions: optionalExtensions,
|
319 | pixelRatio: pixelRatio,
|
320 | profile: profile,
|
321 | onDone: onDone,
|
322 | onDestroy: onDestroy
|
323 | }
|
324 | }
|
325 |
|
326 | function createExtensionCache (gl, config) {
|
327 | var extensions = {}
|
328 |
|
329 | function tryLoadExtension (name_) {
|
330 |
|
331 | var name = name_.toLowerCase()
|
332 | var ext
|
333 | try {
|
334 | ext = extensions[name] = gl.getExtension(name)
|
335 | } catch (e) {}
|
336 | return !!ext
|
337 | }
|
338 |
|
339 | for (var i = 0; i < config.extensions.length; ++i) {
|
340 | var name = config.extensions[i]
|
341 | if (!tryLoadExtension(name)) {
|
342 | config.onDestroy()
|
343 | config.onDone('"' + name + '" extension is not supported by the current WebGL context, try upgrading your system or a different browser')
|
344 | return null
|
345 | }
|
346 | }
|
347 |
|
348 | config.optionalExtensions.forEach(tryLoadExtension)
|
349 |
|
350 | return {
|
351 | extensions: extensions,
|
352 | restore: function () {
|
353 | Object.keys(extensions).forEach(function (name) {
|
354 | if (extensions[name] && !tryLoadExtension(name)) {
|
355 | throw new Error('(regl): error restoring extension ' + name)
|
356 | }
|
357 | })
|
358 | }
|
359 | }
|
360 | }
|
361 |
|
362 | function loop (n, f) {
|
363 | var result = Array(n)
|
364 | for (var i = 0; i < n; ++i) {
|
365 | result[i] = f(i)
|
366 | }
|
367 | return result
|
368 | }
|
369 |
|
370 | var GL_BYTE = 5120
|
371 | var GL_UNSIGNED_BYTE$1 = 5121
|
372 | var GL_SHORT = 5122
|
373 | var GL_UNSIGNED_SHORT = 5123
|
374 | var GL_INT = 5124
|
375 | var GL_UNSIGNED_INT = 5125
|
376 | var GL_FLOAT$1 = 5126
|
377 |
|
378 | function nextPow16 (v) {
|
379 | for (var i = 16; i <= (1 << 28); i *= 16) {
|
380 | if (v <= i) {
|
381 | return i
|
382 | }
|
383 | }
|
384 | return 0
|
385 | }
|
386 |
|
387 | function log2 (v) {
|
388 | var r, shift
|
389 | r = (v > 0xFFFF) << 4
|
390 | v >>>= r
|
391 | shift = (v > 0xFF) << 3
|
392 | v >>>= shift; r |= shift
|
393 | shift = (v > 0xF) << 2
|
394 | v >>>= shift; r |= shift
|
395 | shift = (v > 0x3) << 1
|
396 | v >>>= shift; r |= shift
|
397 | return r | (v >> 1)
|
398 | }
|
399 |
|
400 | function createPool () {
|
401 | var bufferPool = loop(8, function () {
|
402 | return []
|
403 | })
|
404 |
|
405 | function alloc (n) {
|
406 | var sz = nextPow16(n)
|
407 | var bin = bufferPool[log2(sz) >> 2]
|
408 | if (bin.length > 0) {
|
409 | return bin.pop()
|
410 | }
|
411 | return new ArrayBuffer(sz)
|
412 | }
|
413 |
|
414 | function free (buf) {
|
415 | bufferPool[log2(buf.byteLength) >> 2].push(buf)
|
416 | }
|
417 |
|
418 | function allocType (type, n) {
|
419 | var result = null
|
420 | switch (type) {
|
421 | case GL_BYTE:
|
422 | result = new Int8Array(alloc(n), 0, n)
|
423 | break
|
424 | case GL_UNSIGNED_BYTE$1:
|
425 | result = new Uint8Array(alloc(n), 0, n)
|
426 | break
|
427 | case GL_SHORT:
|
428 | result = new Int16Array(alloc(2 * n), 0, n)
|
429 | break
|
430 | case GL_UNSIGNED_SHORT:
|
431 | result = new Uint16Array(alloc(2 * n), 0, n)
|
432 | break
|
433 | case GL_INT:
|
434 | result = new Int32Array(alloc(4 * n), 0, n)
|
435 | break
|
436 | case GL_UNSIGNED_INT:
|
437 | result = new Uint32Array(alloc(4 * n), 0, n)
|
438 | break
|
439 | case GL_FLOAT$1:
|
440 | result = new Float32Array(alloc(4 * n), 0, n)
|
441 | break
|
442 | default:
|
443 | return null
|
444 | }
|
445 | if (result.length !== n) {
|
446 | return result.subarray(0, n)
|
447 | }
|
448 | return result
|
449 | }
|
450 |
|
451 | function freeType (array) {
|
452 | free(array.buffer)
|
453 | }
|
454 |
|
455 | return {
|
456 | alloc: alloc,
|
457 | free: free,
|
458 | allocType: allocType,
|
459 | freeType: freeType
|
460 | }
|
461 | }
|
462 |
|
463 | var pool = createPool()
|
464 |
|
465 |
|
466 | pool.zero = createPool()
|
467 |
|
468 | var GL_SUBPIXEL_BITS = 0x0D50
|
469 | var GL_RED_BITS = 0x0D52
|
470 | var GL_GREEN_BITS = 0x0D53
|
471 | var GL_BLUE_BITS = 0x0D54
|
472 | var GL_ALPHA_BITS = 0x0D55
|
473 | var GL_DEPTH_BITS = 0x0D56
|
474 | var GL_STENCIL_BITS = 0x0D57
|
475 |
|
476 | var GL_ALIASED_POINT_SIZE_RANGE = 0x846D
|
477 | var GL_ALIASED_LINE_WIDTH_RANGE = 0x846E
|
478 |
|
479 | var GL_MAX_TEXTURE_SIZE = 0x0D33
|
480 | var GL_MAX_VIEWPORT_DIMS = 0x0D3A
|
481 | var GL_MAX_VERTEX_ATTRIBS = 0x8869
|
482 | var GL_MAX_VERTEX_UNIFORM_VECTORS = 0x8DFB
|
483 | var GL_MAX_VARYING_VECTORS = 0x8DFC
|
484 | var GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS = 0x8B4D
|
485 | var GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS = 0x8B4C
|
486 | var GL_MAX_TEXTURE_IMAGE_UNITS = 0x8872
|
487 | var GL_MAX_FRAGMENT_UNIFORM_VECTORS = 0x8DFD
|
488 | var GL_MAX_CUBE_MAP_TEXTURE_SIZE = 0x851C
|
489 | var GL_MAX_RENDERBUFFER_SIZE = 0x84E8
|
490 |
|
491 | var GL_VENDOR = 0x1F00
|
492 | var GL_RENDERER = 0x1F01
|
493 | var GL_VERSION = 0x1F02
|
494 | var GL_SHADING_LANGUAGE_VERSION = 0x8B8C
|
495 |
|
496 | var GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT = 0x84FF
|
497 |
|
498 | var GL_MAX_COLOR_ATTACHMENTS_WEBGL = 0x8CDF
|
499 | var GL_MAX_DRAW_BUFFERS_WEBGL = 0x8824
|
500 |
|
501 | var GL_TEXTURE_2D = 0x0DE1
|
502 | var GL_TEXTURE_CUBE_MAP = 0x8513
|
503 | var GL_TEXTURE_CUBE_MAP_POSITIVE_X = 0x8515
|
504 | var GL_TEXTURE0 = 0x84C0
|
505 | var GL_RGBA = 0x1908
|
506 | var GL_FLOAT = 0x1406
|
507 | var GL_UNSIGNED_BYTE = 0x1401
|
508 | var GL_FRAMEBUFFER = 0x8D40
|
509 | var GL_FRAMEBUFFER_COMPLETE = 0x8CD5
|
510 | var GL_COLOR_ATTACHMENT0 = 0x8CE0
|
511 | var GL_COLOR_BUFFER_BIT$1 = 0x4000
|
512 |
|
513 | var wrapLimits = function (gl, extensions) {
|
514 | var maxAnisotropic = 1
|
515 | if (extensions.ext_texture_filter_anisotropic) {
|
516 | maxAnisotropic = gl.getParameter(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT)
|
517 | }
|
518 |
|
519 | var maxDrawbuffers = 1
|
520 | var maxColorAttachments = 1
|
521 | if (extensions.webgl_draw_buffers) {
|
522 | maxDrawbuffers = gl.getParameter(GL_MAX_DRAW_BUFFERS_WEBGL)
|
523 | maxColorAttachments = gl.getParameter(GL_MAX_COLOR_ATTACHMENTS_WEBGL)
|
524 | }
|
525 |
|
526 |
|
527 | var readFloat = !!extensions.oes_texture_float
|
528 | if (readFloat) {
|
529 | var readFloatTexture = gl.createTexture()
|
530 | gl.bindTexture(GL_TEXTURE_2D, readFloatTexture)
|
531 | gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_FLOAT, null)
|
532 |
|
533 | var fbo = gl.createFramebuffer()
|
534 | gl.bindFramebuffer(GL_FRAMEBUFFER, fbo)
|
535 | gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, readFloatTexture, 0)
|
536 | gl.bindTexture(GL_TEXTURE_2D, null)
|
537 |
|
538 | if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) !== GL_FRAMEBUFFER_COMPLETE) readFloat = false
|
539 |
|
540 | else {
|
541 | gl.viewport(0, 0, 1, 1)
|
542 | gl.clearColor(1.0, 0.0, 0.0, 1.0)
|
543 | gl.clear(GL_COLOR_BUFFER_BIT$1)
|
544 | var pixels = pool.allocType(GL_FLOAT, 4)
|
545 | gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_FLOAT, pixels)
|
546 |
|
547 | if (gl.getError()) readFloat = false
|
548 | else {
|
549 | gl.deleteFramebuffer(fbo)
|
550 | gl.deleteTexture(readFloatTexture)
|
551 |
|
552 | readFloat = pixels[0] === 1.0
|
553 | }
|
554 |
|
555 | pool.freeType(pixels)
|
556 | }
|
557 | }
|
558 |
|
559 |
|
560 | var isIE = typeof navigator !== 'undefined' && (/MSIE/.test(navigator.userAgent) || /Trident\//.test(navigator.appVersion) || /Edge/.test(navigator.userAgent))
|
561 |
|
562 | var npotTextureCube = true
|
563 |
|
564 | if (!isIE) {
|
565 | var cubeTexture = gl.createTexture()
|
566 | var data = pool.allocType(GL_UNSIGNED_BYTE, 36)
|
567 | gl.activeTexture(GL_TEXTURE0)
|
568 | gl.bindTexture(GL_TEXTURE_CUBE_MAP, cubeTexture)
|
569 | gl.texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 3, 3, 0, GL_RGBA, GL_UNSIGNED_BYTE, data)
|
570 | pool.freeType(data)
|
571 | gl.bindTexture(GL_TEXTURE_CUBE_MAP, null)
|
572 | gl.deleteTexture(cubeTexture)
|
573 | npotTextureCube = !gl.getError()
|
574 | }
|
575 |
|
576 | return {
|
577 |
|
578 | colorBits: [
|
579 | gl.getParameter(GL_RED_BITS),
|
580 | gl.getParameter(GL_GREEN_BITS),
|
581 | gl.getParameter(GL_BLUE_BITS),
|
582 | gl.getParameter(GL_ALPHA_BITS)
|
583 | ],
|
584 | depthBits: gl.getParameter(GL_DEPTH_BITS),
|
585 | stencilBits: gl.getParameter(GL_STENCIL_BITS),
|
586 | subpixelBits: gl.getParameter(GL_SUBPIXEL_BITS),
|
587 |
|
588 |
|
589 | extensions: Object.keys(extensions).filter(function (ext) {
|
590 | return !!extensions[ext]
|
591 | }),
|
592 |
|
593 |
|
594 | maxAnisotropic: maxAnisotropic,
|
595 |
|
596 |
|
597 | maxDrawbuffers: maxDrawbuffers,
|
598 | maxColorAttachments: maxColorAttachments,
|
599 |
|
600 |
|
601 | pointSizeDims: gl.getParameter(GL_ALIASED_POINT_SIZE_RANGE),
|
602 | lineWidthDims: gl.getParameter(GL_ALIASED_LINE_WIDTH_RANGE),
|
603 | maxViewportDims: gl.getParameter(GL_MAX_VIEWPORT_DIMS),
|
604 | maxCombinedTextureUnits: gl.getParameter(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS),
|
605 | maxCubeMapSize: gl.getParameter(GL_MAX_CUBE_MAP_TEXTURE_SIZE),
|
606 | maxRenderbufferSize: gl.getParameter(GL_MAX_RENDERBUFFER_SIZE),
|
607 | maxTextureUnits: gl.getParameter(GL_MAX_TEXTURE_IMAGE_UNITS),
|
608 | maxTextureSize: gl.getParameter(GL_MAX_TEXTURE_SIZE),
|
609 | maxAttributes: gl.getParameter(GL_MAX_VERTEX_ATTRIBS),
|
610 | maxVertexUniforms: gl.getParameter(GL_MAX_VERTEX_UNIFORM_VECTORS),
|
611 | maxVertexTextureUnits: gl.getParameter(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS),
|
612 | maxVaryingVectors: gl.getParameter(GL_MAX_VARYING_VECTORS),
|
613 | maxFragmentUniforms: gl.getParameter(GL_MAX_FRAGMENT_UNIFORM_VECTORS),
|
614 |
|
615 |
|
616 | glsl: gl.getParameter(GL_SHADING_LANGUAGE_VERSION),
|
617 | renderer: gl.getParameter(GL_RENDERER),
|
618 | vendor: gl.getParameter(GL_VENDOR),
|
619 | version: gl.getParameter(GL_VERSION),
|
620 |
|
621 |
|
622 | readFloat: readFloat,
|
623 | npotTextureCube: npotTextureCube
|
624 | }
|
625 | }
|
626 |
|
627 | var isTypedArray = function (x) {
|
628 | return (
|
629 | x instanceof Uint8Array ||
|
630 | x instanceof Uint16Array ||
|
631 | x instanceof Uint32Array ||
|
632 | x instanceof Int8Array ||
|
633 | x instanceof Int16Array ||
|
634 | x instanceof Int32Array ||
|
635 | x instanceof Float32Array ||
|
636 | x instanceof Float64Array ||
|
637 | x instanceof Uint8ClampedArray
|
638 | )
|
639 | }
|
640 |
|
641 | function isNDArrayLike (obj) {
|
642 | return (
|
643 | !!obj &&
|
644 | typeof obj === 'object' &&
|
645 | Array.isArray(obj.shape) &&
|
646 | Array.isArray(obj.stride) &&
|
647 | typeof obj.offset === 'number' &&
|
648 | obj.shape.length === obj.stride.length &&
|
649 | (Array.isArray(obj.data) ||
|
650 | isTypedArray(obj.data)))
|
651 | }
|
652 |
|
653 | var values = function (obj) {
|
654 | return Object.keys(obj).map(function (key) { return obj[key] })
|
655 | }
|
656 |
|
657 | var flattenUtils = {
|
658 | shape: arrayShape$1,
|
659 | flatten: flattenArray
|
660 | };
|
661 |
|
662 | function flatten1D (array, nx, out) {
|
663 | for (var i = 0; i < nx; ++i) {
|
664 | out[i] = array[i]
|
665 | }
|
666 | }
|
667 |
|
668 | function flatten2D (array, nx, ny, out) {
|
669 | var ptr = 0
|
670 | for (var i = 0; i < nx; ++i) {
|
671 | var row = array[i]
|
672 | for (var j = 0; j < ny; ++j) {
|
673 | out[ptr++] = row[j]
|
674 | }
|
675 | }
|
676 | }
|
677 |
|
678 | function flatten3D (array, nx, ny, nz, out, ptr_) {
|
679 | var ptr = ptr_
|
680 | for (var i = 0; i < nx; ++i) {
|
681 | var row = array[i]
|
682 | for (var j = 0; j < ny; ++j) {
|
683 | var col = row[j]
|
684 | for (var k = 0; k < nz; ++k) {
|
685 | out[ptr++] = col[k]
|
686 | }
|
687 | }
|
688 | }
|
689 | }
|
690 |
|
691 | function flattenRec (array, shape, level, out, ptr) {
|
692 | var stride = 1
|
693 | for (var i = level + 1; i < shape.length; ++i) {
|
694 | stride *= shape[i]
|
695 | }
|
696 | var n = shape[level]
|
697 | if (shape.length - level === 4) {
|
698 | var nx = shape[level + 1]
|
699 | var ny = shape[level + 2]
|
700 | var nz = shape[level + 3]
|
701 | for (i = 0; i < n; ++i) {
|
702 | flatten3D(array[i], nx, ny, nz, out, ptr)
|
703 | ptr += stride
|
704 | }
|
705 | } else {
|
706 | for (i = 0; i < n; ++i) {
|
707 | flattenRec(array[i], shape, level + 1, out, ptr)
|
708 | ptr += stride
|
709 | }
|
710 | }
|
711 | }
|
712 |
|
713 | function flattenArray (array, shape, type, out_) {
|
714 | var sz = 1
|
715 | if (shape.length) {
|
716 | for (var i = 0; i < shape.length; ++i) {
|
717 | sz *= shape[i]
|
718 | }
|
719 | } else {
|
720 | sz = 0
|
721 | }
|
722 | var out = out_ || pool.allocType(type, sz)
|
723 | switch (shape.length) {
|
724 | case 0:
|
725 | break
|
726 | case 1:
|
727 | flatten1D(array, shape[0], out)
|
728 | break
|
729 | case 2:
|
730 | flatten2D(array, shape[0], shape[1], out)
|
731 | break
|
732 | case 3:
|
733 | flatten3D(array, shape[0], shape[1], shape[2], out, 0)
|
734 | break
|
735 | default:
|
736 | flattenRec(array, shape, 0, out, 0)
|
737 | }
|
738 | return out
|
739 | }
|
740 |
|
741 | function arrayShape$1 (array_) {
|
742 | var shape = []
|
743 | for (var array = array_; array.length; array = array[0]) {
|
744 | shape.push(array.length)
|
745 | }
|
746 | return shape
|
747 | }
|
748 |
|
749 | var arrayTypes = {
|
750 | "[object Int8Array]": 5120,
|
751 | "[object Int16Array]": 5122,
|
752 | "[object Int32Array]": 5124,
|
753 | "[object Uint8Array]": 5121,
|
754 | "[object Uint8ClampedArray]": 5121,
|
755 | "[object Uint16Array]": 5123,
|
756 | "[object Uint32Array]": 5125,
|
757 | "[object Float32Array]": 5126,
|
758 | "[object Float64Array]": 5121,
|
759 | "[object ArrayBuffer]": 5121
|
760 | };
|
761 |
|
762 | var int8 = 5120;
|
763 | var int16 = 5122;
|
764 | var int32 = 5124;
|
765 | var uint8 = 5121;
|
766 | var uint16 = 5123;
|
767 | var uint32 = 5125;
|
768 | var float = 5126;
|
769 | var float32 = 5126;
|
770 | var glTypes = {
|
771 | int8: int8,
|
772 | int16: int16,
|
773 | int32: int32,
|
774 | uint8: uint8,
|
775 | uint16: uint16,
|
776 | uint32: uint32,
|
777 | float: float,
|
778 | float32: float32
|
779 | };
|
780 |
|
781 | var dynamic$1 = 35048;
|
782 | var stream = 35040;
|
783 | var usageTypes = {
|
784 | dynamic: dynamic$1,
|
785 | stream: stream,
|
786 | "static": 35044
|
787 | };
|
788 |
|
789 | var arrayFlatten = flattenUtils.flatten
|
790 | var arrayShape = flattenUtils.shape
|
791 |
|
792 | var GL_STATIC_DRAW = 0x88E4
|
793 | var GL_STREAM_DRAW = 0x88E0
|
794 |
|
795 | var GL_UNSIGNED_BYTE$2 = 5121
|
796 | var GL_FLOAT$2 = 5126
|
797 |
|
798 | var DTYPES_SIZES = []
|
799 | DTYPES_SIZES[5120] = 1
|
800 | DTYPES_SIZES[5122] = 2
|
801 | DTYPES_SIZES[5124] = 4
|
802 | DTYPES_SIZES[5121] = 1
|
803 | DTYPES_SIZES[5123] = 2
|
804 | DTYPES_SIZES[5125] = 4
|
805 | DTYPES_SIZES[5126] = 4
|
806 |
|
807 | function typedArrayCode (data) {
|
808 | return arrayTypes[Object.prototype.toString.call(data)] | 0
|
809 | }
|
810 |
|
811 | function copyArray (out, inp) {
|
812 | for (var i = 0; i < inp.length; ++i) {
|
813 | out[i] = inp[i]
|
814 | }
|
815 | }
|
816 |
|
817 | function transpose (
|
818 | result, data, shapeX, shapeY, strideX, strideY, offset) {
|
819 | var ptr = 0
|
820 | for (var i = 0; i < shapeX; ++i) {
|
821 | for (var j = 0; j < shapeY; ++j) {
|
822 | result[ptr++] = data[strideX * i + strideY * j + offset]
|
823 | }
|
824 | }
|
825 | }
|
826 |
|
827 | function wrapBufferState (gl, stats, config, destroyBuffer) {
|
828 | var bufferCount = 0
|
829 | var bufferSet = {}
|
830 |
|
831 | function REGLBuffer (type) {
|
832 | this.id = bufferCount++
|
833 | this.buffer = gl.createBuffer()
|
834 | this.type = type
|
835 | this.usage = GL_STATIC_DRAW
|
836 | this.byteLength = 0
|
837 | this.dimension = 1
|
838 | this.dtype = GL_UNSIGNED_BYTE$2
|
839 |
|
840 | this.persistentData = null
|
841 |
|
842 | if (config.profile) {
|
843 | this.stats = { size: 0 }
|
844 | }
|
845 | }
|
846 |
|
847 | REGLBuffer.prototype.bind = function () {
|
848 | gl.bindBuffer(this.type, this.buffer)
|
849 | }
|
850 |
|
851 | REGLBuffer.prototype.destroy = function () {
|
852 | destroy(this)
|
853 | }
|
854 |
|
855 | var streamPool = []
|
856 |
|
857 | function createStream (type, data) {
|
858 | var buffer = streamPool.pop()
|
859 | if (!buffer) {
|
860 | buffer = new REGLBuffer(type)
|
861 | }
|
862 | buffer.bind()
|
863 | initBufferFromData(buffer, data, GL_STREAM_DRAW, 0, 1, false)
|
864 | return buffer
|
865 | }
|
866 |
|
867 | function destroyStream (stream$$1) {
|
868 | streamPool.push(stream$$1)
|
869 | }
|
870 |
|
871 | function initBufferFromTypedArray (buffer, data, usage) {
|
872 | buffer.byteLength = data.byteLength
|
873 | gl.bufferData(buffer.type, data, usage)
|
874 | }
|
875 |
|
876 | function initBufferFromData (buffer, data, usage, dtype, dimension, persist) {
|
877 | var shape
|
878 | buffer.usage = usage
|
879 | if (Array.isArray(data)) {
|
880 | buffer.dtype = dtype || GL_FLOAT$2
|
881 | if (data.length > 0) {
|
882 | var flatData
|
883 | if (Array.isArray(data[0])) {
|
884 | shape = arrayShape(data)
|
885 | var dim = 1
|
886 | for (var i = 1; i < shape.length; ++i) {
|
887 | dim *= shape[i]
|
888 | }
|
889 | buffer.dimension = dim
|
890 | flatData = arrayFlatten(data, shape, buffer.dtype)
|
891 | initBufferFromTypedArray(buffer, flatData, usage)
|
892 | if (persist) {
|
893 | buffer.persistentData = flatData
|
894 | } else {
|
895 | pool.freeType(flatData)
|
896 | }
|
897 | } else if (typeof data[0] === 'number') {
|
898 | buffer.dimension = dimension
|
899 | var typedData = pool.allocType(buffer.dtype, data.length)
|
900 | copyArray(typedData, data)
|
901 | initBufferFromTypedArray(buffer, typedData, usage)
|
902 | if (persist) {
|
903 | buffer.persistentData = typedData
|
904 | } else {
|
905 | pool.freeType(typedData)
|
906 | }
|
907 | } else if (isTypedArray(data[0])) {
|
908 | buffer.dimension = data[0].length
|
909 | buffer.dtype = dtype || typedArrayCode(data[0]) || GL_FLOAT$2
|
910 | flatData = arrayFlatten(
|
911 | data,
|
912 | [data.length, data[0].length],
|
913 | buffer.dtype)
|
914 | initBufferFromTypedArray(buffer, flatData, usage)
|
915 | if (persist) {
|
916 | buffer.persistentData = flatData
|
917 | } else {
|
918 | pool.freeType(flatData)
|
919 | }
|
920 | } else {
|
921 |
|
922 | }
|
923 | }
|
924 | } else if (isTypedArray(data)) {
|
925 | buffer.dtype = dtype || typedArrayCode(data)
|
926 | buffer.dimension = dimension
|
927 | initBufferFromTypedArray(buffer, data, usage)
|
928 | if (persist) {
|
929 | buffer.persistentData = new Uint8Array(new Uint8Array(data.buffer))
|
930 | }
|
931 | } else if (isNDArrayLike(data)) {
|
932 | shape = data.shape
|
933 | var stride = data.stride
|
934 | var offset = data.offset
|
935 |
|
936 | var shapeX = 0
|
937 | var shapeY = 0
|
938 | var strideX = 0
|
939 | var strideY = 0
|
940 | if (shape.length === 1) {
|
941 | shapeX = shape[0]
|
942 | shapeY = 1
|
943 | strideX = stride[0]
|
944 | strideY = 0
|
945 | } else if (shape.length === 2) {
|
946 | shapeX = shape[0]
|
947 | shapeY = shape[1]
|
948 | strideX = stride[0]
|
949 | strideY = stride[1]
|
950 | } else {
|
951 |
|
952 | }
|
953 |
|
954 | buffer.dtype = dtype || typedArrayCode(data.data) || GL_FLOAT$2
|
955 | buffer.dimension = shapeY
|
956 |
|
957 | var transposeData = pool.allocType(buffer.dtype, shapeX * shapeY)
|
958 | transpose(transposeData,
|
959 | data.data,
|
960 | shapeX, shapeY,
|
961 | strideX, strideY,
|
962 | offset)
|
963 | initBufferFromTypedArray(buffer, transposeData, usage)
|
964 | if (persist) {
|
965 | buffer.persistentData = transposeData
|
966 | } else {
|
967 | pool.freeType(transposeData)
|
968 | }
|
969 | } else if (data instanceof ArrayBuffer) {
|
970 | buffer.dtype = GL_UNSIGNED_BYTE$2
|
971 | buffer.dimension = dimension
|
972 | initBufferFromTypedArray(buffer, data, usage)
|
973 | if (persist) {
|
974 | buffer.persistentData = new Uint8Array(new Uint8Array(data))
|
975 | }
|
976 | } else {
|
977 |
|
978 | }
|
979 | }
|
980 |
|
981 | function destroy (buffer) {
|
982 | stats.bufferCount--
|
983 |
|
984 |
|
985 | destroyBuffer(buffer)
|
986 |
|
987 | var handle = buffer.buffer
|
988 |
|
989 | gl.deleteBuffer(handle)
|
990 | buffer.buffer = null
|
991 | delete bufferSet[buffer.id]
|
992 | }
|
993 |
|
994 | function createBuffer (options, type, deferInit, persistent) {
|
995 | stats.bufferCount++
|
996 |
|
997 | var buffer = new REGLBuffer(type)
|
998 | bufferSet[buffer.id] = buffer
|
999 |
|
1000 | function reglBuffer (options) {
|
1001 | var usage = GL_STATIC_DRAW
|
1002 | var data = null
|
1003 | var byteLength = 0
|
1004 | var dtype = 0
|
1005 | var dimension = 1
|
1006 | if (Array.isArray(options) ||
|
1007 | isTypedArray(options) ||
|
1008 | isNDArrayLike(options) ||
|
1009 | options instanceof ArrayBuffer) {
|
1010 | data = options
|
1011 | } else if (typeof options === 'number') {
|
1012 | byteLength = options | 0
|
1013 | } else if (options) {
|
1014 |
|
1015 |
|
1016 | if ('data' in options) {
|
1017 |
|
1018 | data = options.data
|
1019 | }
|
1020 |
|
1021 | if ('usage' in options) {
|
1022 |
|
1023 | usage = usageTypes[options.usage]
|
1024 | }
|
1025 |
|
1026 | if ('type' in options) {
|
1027 |
|
1028 | dtype = glTypes[options.type]
|
1029 | }
|
1030 |
|
1031 | if ('dimension' in options) {
|
1032 |
|
1033 | dimension = options.dimension | 0
|
1034 | }
|
1035 |
|
1036 | if ('length' in options) {
|
1037 |
|
1038 | byteLength = options.length | 0
|
1039 | }
|
1040 | }
|
1041 |
|
1042 | buffer.bind()
|
1043 | if (!data) {
|
1044 |
|
1045 | if (byteLength) gl.bufferData(buffer.type, byteLength, usage)
|
1046 | buffer.dtype = dtype || GL_UNSIGNED_BYTE$2
|
1047 | buffer.usage = usage
|
1048 | buffer.dimension = dimension
|
1049 | buffer.byteLength = byteLength
|
1050 | } else {
|
1051 | initBufferFromData(buffer, data, usage, dtype, dimension, persistent)
|
1052 | }
|
1053 |
|
1054 | if (config.profile) {
|
1055 | buffer.stats.size = buffer.byteLength * DTYPES_SIZES[buffer.dtype]
|
1056 | }
|
1057 |
|
1058 | return reglBuffer
|
1059 | }
|
1060 |
|
1061 | function setSubData (data, offset) {
|
1062 |
|
1063 |
|
1064 | gl.bufferSubData(buffer.type, offset, data)
|
1065 | }
|
1066 |
|
1067 | function subdata (data, offset_) {
|
1068 | var offset = (offset_ || 0) | 0
|
1069 | var shape
|
1070 | buffer.bind()
|
1071 | if (isTypedArray(data) || data instanceof ArrayBuffer) {
|
1072 | setSubData(data, offset)
|
1073 | } else if (Array.isArray(data)) {
|
1074 | if (data.length > 0) {
|
1075 | if (typeof data[0] === 'number') {
|
1076 | var converted = pool.allocType(buffer.dtype, data.length)
|
1077 | copyArray(converted, data)
|
1078 | setSubData(converted, offset)
|
1079 | pool.freeType(converted)
|
1080 | } else if (Array.isArray(data[0]) || isTypedArray(data[0])) {
|
1081 | shape = arrayShape(data)
|
1082 | var flatData = arrayFlatten(data, shape, buffer.dtype)
|
1083 | setSubData(flatData, offset)
|
1084 | pool.freeType(flatData)
|
1085 | } else {
|
1086 |
|
1087 | }
|
1088 | }
|
1089 | } else if (isNDArrayLike(data)) {
|
1090 | shape = data.shape
|
1091 | var stride = data.stride
|
1092 |
|
1093 | var shapeX = 0
|
1094 | var shapeY = 0
|
1095 | var strideX = 0
|
1096 | var strideY = 0
|
1097 | if (shape.length === 1) {
|
1098 | shapeX = shape[0]
|
1099 | shapeY = 1
|
1100 | strideX = stride[0]
|
1101 | strideY = 0
|
1102 | } else if (shape.length === 2) {
|
1103 | shapeX = shape[0]
|
1104 | shapeY = shape[1]
|
1105 | strideX = stride[0]
|
1106 | strideY = stride[1]
|
1107 | } else {
|
1108 |
|
1109 | }
|
1110 | var dtype = Array.isArray(data.data)
|
1111 | ? buffer.dtype
|
1112 | : typedArrayCode(data.data)
|
1113 |
|
1114 | var transposeData = pool.allocType(dtype, shapeX * shapeY)
|
1115 | transpose(transposeData,
|
1116 | data.data,
|
1117 | shapeX, shapeY,
|
1118 | strideX, strideY,
|
1119 | data.offset)
|
1120 | setSubData(transposeData, offset)
|
1121 | pool.freeType(transposeData)
|
1122 | } else {
|
1123 |
|
1124 | }
|
1125 | return reglBuffer
|
1126 | }
|
1127 |
|
1128 | if (!deferInit) {
|
1129 | reglBuffer(options)
|
1130 | }
|
1131 |
|
1132 | reglBuffer._reglType = 'buffer'
|
1133 | reglBuffer._buffer = buffer
|
1134 | reglBuffer.subdata = subdata
|
1135 | if (config.profile) {
|
1136 | reglBuffer.stats = buffer.stats
|
1137 | }
|
1138 | reglBuffer.destroy = function () { destroy(buffer) }
|
1139 |
|
1140 | return reglBuffer
|
1141 | }
|
1142 |
|
1143 | function restoreBuffers () {
|
1144 | values(bufferSet).forEach(function (buffer) {
|
1145 | buffer.buffer = gl.createBuffer()
|
1146 | gl.bindBuffer(buffer.type, buffer.buffer)
|
1147 | gl.bufferData(
|
1148 | buffer.type, buffer.persistentData || buffer.byteLength, buffer.usage)
|
1149 | })
|
1150 | }
|
1151 |
|
1152 | if (config.profile) {
|
1153 | stats.getTotalBufferSize = function () {
|
1154 | var total = 0
|
1155 |
|
1156 | Object.keys(bufferSet).forEach(function (key) {
|
1157 | total += bufferSet[key].stats.size
|
1158 | })
|
1159 | return total
|
1160 | }
|
1161 | }
|
1162 |
|
1163 | return {
|
1164 | create: createBuffer,
|
1165 |
|
1166 | createStream: createStream,
|
1167 | destroyStream: destroyStream,
|
1168 |
|
1169 | clear: function () {
|
1170 | values(bufferSet).forEach(destroy)
|
1171 | streamPool.forEach(destroy)
|
1172 | },
|
1173 |
|
1174 | getBuffer: function (wrapper) {
|
1175 | if (wrapper && wrapper._buffer instanceof REGLBuffer) {
|
1176 | return wrapper._buffer
|
1177 | }
|
1178 | return null
|
1179 | },
|
1180 |
|
1181 | restore: restoreBuffers,
|
1182 |
|
1183 | _initBuffer: initBufferFromData
|
1184 | }
|
1185 | }
|
1186 |
|
1187 | var points = 0;
|
1188 | var point = 0;
|
1189 | var lines = 1;
|
1190 | var line = 1;
|
1191 | var triangles = 4;
|
1192 | var triangle = 4;
|
1193 | var primTypes = {
|
1194 | points: points,
|
1195 | point: point,
|
1196 | lines: lines,
|
1197 | line: line,
|
1198 | triangles: triangles,
|
1199 | triangle: triangle,
|
1200 | "line loop": 2,
|
1201 | "line strip": 3,
|
1202 | "triangle strip": 5,
|
1203 | "triangle fan": 6
|
1204 | };
|
1205 |
|
1206 | var GL_POINTS = 0
|
1207 | var GL_LINES = 1
|
1208 | var GL_TRIANGLES = 4
|
1209 |
|
1210 | var GL_BYTE$1 = 5120
|
1211 | var GL_UNSIGNED_BYTE$3 = 5121
|
1212 | var GL_SHORT$1 = 5122
|
1213 | var GL_UNSIGNED_SHORT$1 = 5123
|
1214 | var GL_INT$1 = 5124
|
1215 | var GL_UNSIGNED_INT$1 = 5125
|
1216 |
|
1217 | var GL_ELEMENT_ARRAY_BUFFER = 34963
|
1218 |
|
1219 | var GL_STREAM_DRAW$1 = 0x88E0
|
1220 | var GL_STATIC_DRAW$1 = 0x88E4
|
1221 |
|
1222 | function wrapElementsState (gl, extensions, bufferState, stats) {
|
1223 | var elementSet = {}
|
1224 | var elementCount = 0
|
1225 |
|
1226 | var elementTypes = {
|
1227 | 'uint8': GL_UNSIGNED_BYTE$3,
|
1228 | 'uint16': GL_UNSIGNED_SHORT$1
|
1229 | }
|
1230 |
|
1231 | if (extensions.oes_element_index_uint) {
|
1232 | elementTypes.uint32 = GL_UNSIGNED_INT$1
|
1233 | }
|
1234 |
|
1235 | function REGLElementBuffer (buffer) {
|
1236 | this.id = elementCount++
|
1237 | elementSet[this.id] = this
|
1238 | this.buffer = buffer
|
1239 | this.primType = GL_TRIANGLES
|
1240 | this.vertCount = 0
|
1241 | this.type = 0
|
1242 | }
|
1243 |
|
1244 | REGLElementBuffer.prototype.bind = function () {
|
1245 | this.buffer.bind()
|
1246 | }
|
1247 |
|
1248 | var bufferPool = []
|
1249 |
|
1250 | function createElementStream (data) {
|
1251 | var result = bufferPool.pop()
|
1252 | if (!result) {
|
1253 | result = new REGLElementBuffer(bufferState.create(
|
1254 | null,
|
1255 | GL_ELEMENT_ARRAY_BUFFER,
|
1256 | true,
|
1257 | false)._buffer)
|
1258 | }
|
1259 | initElements(result, data, GL_STREAM_DRAW$1, -1, -1, 0, 0)
|
1260 | return result
|
1261 | }
|
1262 |
|
1263 | function destroyElementStream (elements) {
|
1264 | bufferPool.push(elements)
|
1265 | }
|
1266 |
|
1267 | function initElements (
|
1268 | elements,
|
1269 | data,
|
1270 | usage,
|
1271 | prim,
|
1272 | count,
|
1273 | byteLength,
|
1274 | type) {
|
1275 | elements.buffer.bind()
|
1276 | var dtype
|
1277 | if (data) {
|
1278 | var predictedType = type
|
1279 | if (!type && (
|
1280 | !isTypedArray(data) ||
|
1281 | (isNDArrayLike(data) && !isTypedArray(data.data)))) {
|
1282 | predictedType = extensions.oes_element_index_uint
|
1283 | ? GL_UNSIGNED_INT$1
|
1284 | : GL_UNSIGNED_SHORT$1
|
1285 | }
|
1286 | bufferState._initBuffer(
|
1287 | elements.buffer,
|
1288 | data,
|
1289 | usage,
|
1290 | predictedType,
|
1291 | 3)
|
1292 | } else {
|
1293 | gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, byteLength, usage)
|
1294 | elements.buffer.dtype = dtype || GL_UNSIGNED_BYTE$3
|
1295 | elements.buffer.usage = usage
|
1296 | elements.buffer.dimension = 3
|
1297 | elements.buffer.byteLength = byteLength
|
1298 | }
|
1299 |
|
1300 | dtype = type
|
1301 | if (!type) {
|
1302 | switch (elements.buffer.dtype) {
|
1303 | case GL_UNSIGNED_BYTE$3:
|
1304 | case GL_BYTE$1:
|
1305 | dtype = GL_UNSIGNED_BYTE$3
|
1306 | break
|
1307 |
|
1308 | case GL_UNSIGNED_SHORT$1:
|
1309 | case GL_SHORT$1:
|
1310 | dtype = GL_UNSIGNED_SHORT$1
|
1311 | break
|
1312 |
|
1313 | case GL_UNSIGNED_INT$1:
|
1314 | case GL_INT$1:
|
1315 | dtype = GL_UNSIGNED_INT$1
|
1316 | break
|
1317 |
|
1318 | default:
|
1319 |
|
1320 | }
|
1321 | elements.buffer.dtype = dtype
|
1322 | }
|
1323 | elements.type = dtype
|
1324 |
|
1325 |
|
1326 |
|
1327 |
|
1328 |
|
1329 | var vertCount = count
|
1330 | if (vertCount < 0) {
|
1331 | vertCount = elements.buffer.byteLength
|
1332 | if (dtype === GL_UNSIGNED_SHORT$1) {
|
1333 | vertCount >>= 1
|
1334 | } else if (dtype === GL_UNSIGNED_INT$1) {
|
1335 | vertCount >>= 2
|
1336 | }
|
1337 | }
|
1338 | elements.vertCount = vertCount
|
1339 |
|
1340 |
|
1341 | var primType = prim
|
1342 | if (prim < 0) {
|
1343 | primType = GL_TRIANGLES
|
1344 | var dimension = elements.buffer.dimension
|
1345 | if (dimension === 1) primType = GL_POINTS
|
1346 | if (dimension === 2) primType = GL_LINES
|
1347 | if (dimension === 3) primType = GL_TRIANGLES
|
1348 | }
|
1349 | elements.primType = primType
|
1350 | }
|
1351 |
|
1352 | function destroyElements (elements) {
|
1353 | stats.elementsCount--
|
1354 |
|
1355 |
|
1356 | delete elementSet[elements.id]
|
1357 | elements.buffer.destroy()
|
1358 | elements.buffer = null
|
1359 | }
|
1360 |
|
1361 | function createElements (options, persistent) {
|
1362 | var buffer = bufferState.create(null, GL_ELEMENT_ARRAY_BUFFER, true)
|
1363 | var elements = new REGLElementBuffer(buffer._buffer)
|
1364 | stats.elementsCount++
|
1365 |
|
1366 | function reglElements (options) {
|
1367 | if (!options) {
|
1368 | buffer()
|
1369 | elements.primType = GL_TRIANGLES
|
1370 | elements.vertCount = 0
|
1371 | elements.type = GL_UNSIGNED_BYTE$3
|
1372 | } else if (typeof options === 'number') {
|
1373 | buffer(options)
|
1374 | elements.primType = GL_TRIANGLES
|
1375 | elements.vertCount = options | 0
|
1376 | elements.type = GL_UNSIGNED_BYTE$3
|
1377 | } else {
|
1378 | var data = null
|
1379 | var usage = GL_STATIC_DRAW$1
|
1380 | var primType = -1
|
1381 | var vertCount = -1
|
1382 | var byteLength = 0
|
1383 | var dtype = 0
|
1384 | if (Array.isArray(options) ||
|
1385 | isTypedArray(options) ||
|
1386 | isNDArrayLike(options)) {
|
1387 | data = options
|
1388 | } else {
|
1389 |
|
1390 | if ('data' in options) {
|
1391 | data = options.data
|
1392 |
|
1393 | }
|
1394 | if ('usage' in options) {
|
1395 |
|
1396 | usage = usageTypes[options.usage]
|
1397 | }
|
1398 | if ('primitive' in options) {
|
1399 |
|
1400 | primType = primTypes[options.primitive]
|
1401 | }
|
1402 | if ('count' in options) {
|
1403 |
|
1404 | vertCount = options.count | 0
|
1405 | }
|
1406 | if ('type' in options) {
|
1407 |
|
1408 | dtype = elementTypes[options.type]
|
1409 | }
|
1410 | if ('length' in options) {
|
1411 | byteLength = options.length | 0
|
1412 | } else {
|
1413 | byteLength = vertCount
|
1414 | if (dtype === GL_UNSIGNED_SHORT$1 || dtype === GL_SHORT$1) {
|
1415 | byteLength *= 2
|
1416 | } else if (dtype === GL_UNSIGNED_INT$1 || dtype === GL_INT$1) {
|
1417 | byteLength *= 4
|
1418 | }
|
1419 | }
|
1420 | }
|
1421 | initElements(
|
1422 | elements,
|
1423 | data,
|
1424 | usage,
|
1425 | primType,
|
1426 | vertCount,
|
1427 | byteLength,
|
1428 | dtype)
|
1429 | }
|
1430 |
|
1431 | return reglElements
|
1432 | }
|
1433 |
|
1434 | reglElements(options)
|
1435 |
|
1436 | reglElements._reglType = 'elements'
|
1437 | reglElements._elements = elements
|
1438 | reglElements.subdata = function (data, offset) {
|
1439 | buffer.subdata(data, offset)
|
1440 | return reglElements
|
1441 | }
|
1442 | reglElements.destroy = function () {
|
1443 | destroyElements(elements)
|
1444 | }
|
1445 |
|
1446 | return reglElements
|
1447 | }
|
1448 |
|
1449 | return {
|
1450 | create: createElements,
|
1451 | createStream: createElementStream,
|
1452 | destroyStream: destroyElementStream,
|
1453 | getElements: function (elements) {
|
1454 | if (typeof elements === 'function' &&
|
1455 | elements._elements instanceof REGLElementBuffer) {
|
1456 | return elements._elements
|
1457 | }
|
1458 | return null
|
1459 | },
|
1460 | clear: function () {
|
1461 | values(elementSet).forEach(destroyElements)
|
1462 | }
|
1463 | }
|
1464 | }
|
1465 |
|
1466 | var FLOAT = new Float32Array(1)
|
1467 | var INT = new Uint32Array(FLOAT.buffer)
|
1468 |
|
1469 | var GL_UNSIGNED_SHORT$3 = 5123
|
1470 |
|
1471 | function convertToHalfFloat (array) {
|
1472 | var ushorts = pool.allocType(GL_UNSIGNED_SHORT$3, array.length)
|
1473 |
|
1474 | for (var i = 0; i < array.length; ++i) {
|
1475 | if (isNaN(array[i])) {
|
1476 | ushorts[i] = 0xffff
|
1477 | } else if (array[i] === Infinity) {
|
1478 | ushorts[i] = 0x7c00
|
1479 | } else if (array[i] === -Infinity) {
|
1480 | ushorts[i] = 0xfc00
|
1481 | } else {
|
1482 | FLOAT[0] = array[i]
|
1483 | var x = INT[0]
|
1484 |
|
1485 | var sgn = (x >>> 31) << 15
|
1486 | var exp = ((x << 1) >>> 24) - 127
|
1487 | var frac = (x >> 13) & ((1 << 10) - 1)
|
1488 |
|
1489 | if (exp < -24) {
|
1490 |
|
1491 | ushorts[i] = sgn
|
1492 | } else if (exp < -14) {
|
1493 |
|
1494 | var s = -14 - exp
|
1495 | ushorts[i] = sgn + ((frac + (1 << 10)) >> s)
|
1496 | } else if (exp > 15) {
|
1497 |
|
1498 | ushorts[i] = sgn + 0x7c00
|
1499 | } else {
|
1500 |
|
1501 | ushorts[i] = sgn + ((exp + 15) << 10) + frac
|
1502 | }
|
1503 | }
|
1504 | }
|
1505 |
|
1506 | return ushorts
|
1507 | }
|
1508 |
|
1509 | function isArrayLike (s) {
|
1510 | return Array.isArray(s) || isTypedArray(s)
|
1511 | }
|
1512 |
|
1513 | var GL_COMPRESSED_TEXTURE_FORMATS = 0x86A3
|
1514 |
|
1515 | var GL_TEXTURE_2D$1 = 0x0DE1
|
1516 | var GL_TEXTURE_CUBE_MAP$1 = 0x8513
|
1517 | var GL_TEXTURE_CUBE_MAP_POSITIVE_X$1 = 0x8515
|
1518 |
|
1519 | var GL_RGBA$1 = 0x1908
|
1520 | var GL_ALPHA = 0x1906
|
1521 | var GL_RGB = 0x1907
|
1522 | var GL_LUMINANCE = 0x1909
|
1523 | var GL_LUMINANCE_ALPHA = 0x190A
|
1524 |
|
1525 | var GL_RGBA4 = 0x8056
|
1526 | var GL_RGB5_A1 = 0x8057
|
1527 | var GL_RGB565 = 0x8D62
|
1528 |
|
1529 | var GL_UNSIGNED_SHORT_4_4_4_4 = 0x8033
|
1530 | var GL_UNSIGNED_SHORT_5_5_5_1 = 0x8034
|
1531 | var GL_UNSIGNED_SHORT_5_6_5 = 0x8363
|
1532 | var GL_UNSIGNED_INT_24_8_WEBGL = 0x84FA
|
1533 |
|
1534 | var GL_DEPTH_COMPONENT = 0x1902
|
1535 | var GL_DEPTH_STENCIL = 0x84F9
|
1536 |
|
1537 | var GL_SRGB_EXT = 0x8C40
|
1538 | var GL_SRGB_ALPHA_EXT = 0x8C42
|
1539 |
|
1540 | var GL_HALF_FLOAT_OES = 0x8D61
|
1541 |
|
1542 | var GL_COMPRESSED_RGB_S3TC_DXT1_EXT = 0x83F0
|
1543 | var GL_COMPRESSED_RGBA_S3TC_DXT1_EXT = 0x83F1
|
1544 | var GL_COMPRESSED_RGBA_S3TC_DXT3_EXT = 0x83F2
|
1545 | var GL_COMPRESSED_RGBA_S3TC_DXT5_EXT = 0x83F3
|
1546 |
|
1547 | var GL_COMPRESSED_RGB_ATC_WEBGL = 0x8C92
|
1548 | var GL_COMPRESSED_RGBA_ATC_EXPLICIT_ALPHA_WEBGL = 0x8C93
|
1549 | var GL_COMPRESSED_RGBA_ATC_INTERPOLATED_ALPHA_WEBGL = 0x87EE
|
1550 |
|
1551 | var GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG = 0x8C00
|
1552 | var GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG = 0x8C01
|
1553 | var GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG = 0x8C02
|
1554 | var GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG = 0x8C03
|
1555 |
|
1556 | var GL_COMPRESSED_RGB_ETC1_WEBGL = 0x8D64
|
1557 |
|
1558 | var GL_UNSIGNED_BYTE$4 = 0x1401
|
1559 | var GL_UNSIGNED_SHORT$2 = 0x1403
|
1560 | var GL_UNSIGNED_INT$2 = 0x1405
|
1561 | var GL_FLOAT$3 = 0x1406
|
1562 |
|
1563 | var GL_TEXTURE_WRAP_S = 0x2802
|
1564 | var GL_TEXTURE_WRAP_T = 0x2803
|
1565 |
|
1566 | var GL_REPEAT = 0x2901
|
1567 | var GL_CLAMP_TO_EDGE = 0x812F
|
1568 | var GL_MIRRORED_REPEAT = 0x8370
|
1569 |
|
1570 | var GL_TEXTURE_MAG_FILTER = 0x2800
|
1571 | var GL_TEXTURE_MIN_FILTER = 0x2801
|
1572 |
|
1573 | var GL_NEAREST = 0x2600
|
1574 | var GL_LINEAR = 0x2601
|
1575 | var GL_NEAREST_MIPMAP_NEAREST = 0x2700
|
1576 | var GL_LINEAR_MIPMAP_NEAREST = 0x2701
|
1577 | var GL_NEAREST_MIPMAP_LINEAR = 0x2702
|
1578 | var GL_LINEAR_MIPMAP_LINEAR = 0x2703
|
1579 |
|
1580 | var GL_GENERATE_MIPMAP_HINT = 0x8192
|
1581 | var GL_DONT_CARE = 0x1100
|
1582 | var GL_FASTEST = 0x1101
|
1583 | var GL_NICEST = 0x1102
|
1584 |
|
1585 | var GL_TEXTURE_MAX_ANISOTROPY_EXT = 0x84FE
|
1586 |
|
1587 | var GL_UNPACK_ALIGNMENT = 0x0CF5
|
1588 | var GL_UNPACK_FLIP_Y_WEBGL = 0x9240
|
1589 | var GL_UNPACK_PREMULTIPLY_ALPHA_WEBGL = 0x9241
|
1590 | var GL_UNPACK_COLORSPACE_CONVERSION_WEBGL = 0x9243
|
1591 |
|
1592 | var GL_BROWSER_DEFAULT_WEBGL = 0x9244
|
1593 |
|
1594 | var GL_TEXTURE0$1 = 0x84C0
|
1595 |
|
1596 | var MIPMAP_FILTERS = [
|
1597 | GL_NEAREST_MIPMAP_NEAREST,
|
1598 | GL_NEAREST_MIPMAP_LINEAR,
|
1599 | GL_LINEAR_MIPMAP_NEAREST,
|
1600 | GL_LINEAR_MIPMAP_LINEAR
|
1601 | ]
|
1602 |
|
1603 | var CHANNELS_FORMAT = [
|
1604 | 0,
|
1605 | GL_LUMINANCE,
|
1606 | GL_LUMINANCE_ALPHA,
|
1607 | GL_RGB,
|
1608 | GL_RGBA$1
|
1609 | ]
|
1610 |
|
1611 | var FORMAT_CHANNELS = {}
|
1612 | FORMAT_CHANNELS[GL_LUMINANCE] =
|
1613 | FORMAT_CHANNELS[GL_ALPHA] =
|
1614 | FORMAT_CHANNELS[GL_DEPTH_COMPONENT] = 1
|
1615 | FORMAT_CHANNELS[GL_DEPTH_STENCIL] =
|
1616 | FORMAT_CHANNELS[GL_LUMINANCE_ALPHA] = 2
|
1617 | FORMAT_CHANNELS[GL_RGB] =
|
1618 | FORMAT_CHANNELS[GL_SRGB_EXT] = 3
|
1619 | FORMAT_CHANNELS[GL_RGBA$1] =
|
1620 | FORMAT_CHANNELS[GL_SRGB_ALPHA_EXT] = 4
|
1621 |
|
1622 | function objectName (str) {
|
1623 | return '[object ' + str + ']'
|
1624 | }
|
1625 |
|
1626 | var CANVAS_CLASS = objectName('HTMLCanvasElement')
|
1627 | var OFFSCREENCANVAS_CLASS = objectName('OffscreenCanvas')
|
1628 | var CONTEXT2D_CLASS = objectName('CanvasRenderingContext2D')
|
1629 | var BITMAP_CLASS = objectName('ImageBitmap')
|
1630 | var IMAGE_CLASS = objectName('HTMLImageElement')
|
1631 | var VIDEO_CLASS = objectName('HTMLVideoElement')
|
1632 |
|
1633 | var PIXEL_CLASSES = Object.keys(arrayTypes).concat([
|
1634 | CANVAS_CLASS,
|
1635 | OFFSCREENCANVAS_CLASS,
|
1636 | CONTEXT2D_CLASS,
|
1637 | BITMAP_CLASS,
|
1638 | IMAGE_CLASS,
|
1639 | VIDEO_CLASS
|
1640 | ])
|
1641 |
|
1642 |
|
1643 |
|
1644 | var TYPE_SIZES = []
|
1645 | TYPE_SIZES[GL_UNSIGNED_BYTE$4] = 1
|
1646 | TYPE_SIZES[GL_FLOAT$3] = 4
|
1647 | TYPE_SIZES[GL_HALF_FLOAT_OES] = 2
|
1648 |
|
1649 | TYPE_SIZES[GL_UNSIGNED_SHORT$2] = 2
|
1650 | TYPE_SIZES[GL_UNSIGNED_INT$2] = 4
|
1651 |
|
1652 | var FORMAT_SIZES_SPECIAL = []
|
1653 | FORMAT_SIZES_SPECIAL[GL_RGBA4] = 2
|
1654 | FORMAT_SIZES_SPECIAL[GL_RGB5_A1] = 2
|
1655 | FORMAT_SIZES_SPECIAL[GL_RGB565] = 2
|
1656 | FORMAT_SIZES_SPECIAL[GL_DEPTH_STENCIL] = 4
|
1657 |
|
1658 | FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGB_S3TC_DXT1_EXT] = 0.5
|
1659 | FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGBA_S3TC_DXT1_EXT] = 0.5
|
1660 | FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGBA_S3TC_DXT3_EXT] = 1
|
1661 | FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGBA_S3TC_DXT5_EXT] = 1
|
1662 |
|
1663 | FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGB_ATC_WEBGL] = 0.5
|
1664 | FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGBA_ATC_EXPLICIT_ALPHA_WEBGL] = 1
|
1665 | FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGBA_ATC_INTERPOLATED_ALPHA_WEBGL] = 1
|
1666 |
|
1667 | FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG] = 0.5
|
1668 | FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG] = 0.25
|
1669 | FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG] = 0.5
|
1670 | FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG] = 0.25
|
1671 |
|
1672 | FORMAT_SIZES_SPECIAL[GL_COMPRESSED_RGB_ETC1_WEBGL] = 0.5
|
1673 |
|
1674 | function isNumericArray (arr) {
|
1675 | return (
|
1676 | Array.isArray(arr) &&
|
1677 | (arr.length === 0 ||
|
1678 | typeof arr[0] === 'number'))
|
1679 | }
|
1680 |
|
1681 | function isRectArray (arr) {
|
1682 | if (!Array.isArray(arr)) {
|
1683 | return false
|
1684 | }
|
1685 | var width = arr.length
|
1686 | if (width === 0 || !isArrayLike(arr[0])) {
|
1687 | return false
|
1688 | }
|
1689 | return true
|
1690 | }
|
1691 |
|
1692 | function classString (x) {
|
1693 | return Object.prototype.toString.call(x)
|
1694 | }
|
1695 |
|
1696 | function isCanvasElement (object) {
|
1697 | return classString(object) === CANVAS_CLASS
|
1698 | }
|
1699 |
|
1700 | function isOffscreenCanvas (object) {
|
1701 | return classString(object) === OFFSCREENCANVAS_CLASS
|
1702 | }
|
1703 |
|
1704 | function isContext2D (object) {
|
1705 | return classString(object) === CONTEXT2D_CLASS
|
1706 | }
|
1707 |
|
1708 | function isBitmap (object) {
|
1709 | return classString(object) === BITMAP_CLASS
|
1710 | }
|
1711 |
|
1712 | function isImageElement (object) {
|
1713 | return classString(object) === IMAGE_CLASS
|
1714 | }
|
1715 |
|
1716 | function isVideoElement (object) {
|
1717 | return classString(object) === VIDEO_CLASS
|
1718 | }
|
1719 |
|
1720 | function isPixelData (object) {
|
1721 | if (!object) {
|
1722 | return false
|
1723 | }
|
1724 | var className = classString(object)
|
1725 | if (PIXEL_CLASSES.indexOf(className) >= 0) {
|
1726 | return true
|
1727 | }
|
1728 | return (
|
1729 | isNumericArray(object) ||
|
1730 | isRectArray(object) ||
|
1731 | isNDArrayLike(object))
|
1732 | }
|
1733 |
|
1734 | function typedArrayCode$1 (data) {
|
1735 | return arrayTypes[Object.prototype.toString.call(data)] | 0
|
1736 | }
|
1737 |
|
1738 | function convertData (result, data) {
|
1739 | var n = data.length
|
1740 | switch (result.type) {
|
1741 | case GL_UNSIGNED_BYTE$4:
|
1742 | case GL_UNSIGNED_SHORT$2:
|
1743 | case GL_UNSIGNED_INT$2:
|
1744 | case GL_FLOAT$3:
|
1745 | var converted = pool.allocType(result.type, n)
|
1746 | converted.set(data)
|
1747 | result.data = converted
|
1748 | break
|
1749 |
|
1750 | case GL_HALF_FLOAT_OES:
|
1751 | result.data = convertToHalfFloat(data)
|
1752 | break
|
1753 |
|
1754 | default:
|
1755 |
|
1756 | }
|
1757 | }
|
1758 |
|
1759 | function preConvert (image, n) {
|
1760 | return pool.allocType(
|
1761 | image.type === GL_HALF_FLOAT_OES
|
1762 | ? GL_FLOAT$3
|
1763 | : image.type, n)
|
1764 | }
|
1765 |
|
1766 | function postConvert (image, data) {
|
1767 | if (image.type === GL_HALF_FLOAT_OES) {
|
1768 | image.data = convertToHalfFloat(data)
|
1769 | pool.freeType(data)
|
1770 | } else {
|
1771 | image.data = data
|
1772 | }
|
1773 | }
|
1774 |
|
1775 | function transposeData (image, array, strideX, strideY, strideC, offset) {
|
1776 | var w = image.width
|
1777 | var h = image.height
|
1778 | var c = image.channels
|
1779 | var n = w * h * c
|
1780 | var data = preConvert(image, n)
|
1781 |
|
1782 | var p = 0
|
1783 | for (var i = 0; i < h; ++i) {
|
1784 | for (var j = 0; j < w; ++j) {
|
1785 | for (var k = 0; k < c; ++k) {
|
1786 | data[p++] = array[strideX * j + strideY * i + strideC * k + offset]
|
1787 | }
|
1788 | }
|
1789 | }
|
1790 |
|
1791 | postConvert(image, data)
|
1792 | }
|
1793 |
|
1794 | function getTextureSize (format, type, width, height, isMipmap, isCube) {
|
1795 | var s
|
1796 | if (typeof FORMAT_SIZES_SPECIAL[format] !== 'undefined') {
|
1797 |
|
1798 | s = FORMAT_SIZES_SPECIAL[format]
|
1799 | } else {
|
1800 | s = FORMAT_CHANNELS[format] * TYPE_SIZES[type]
|
1801 | }
|
1802 |
|
1803 | if (isCube) {
|
1804 | s *= 6
|
1805 | }
|
1806 |
|
1807 | if (isMipmap) {
|
1808 |
|
1809 | var total = 0
|
1810 |
|
1811 | var w = width
|
1812 | while (w >= 1) {
|
1813 |
|
1814 |
|
1815 | total += s * w * w
|
1816 | w /= 2
|
1817 | }
|
1818 | return total
|
1819 | } else {
|
1820 | return s * width * height
|
1821 | }
|
1822 | }
|
1823 |
|
1824 | function createTextureSet (
|
1825 | gl, extensions, limits, reglPoll, contextState, stats, config) {
|
1826 |
|
1827 |
|
1828 |
|
1829 | var mipmapHint = {
|
1830 | "don't care": GL_DONT_CARE,
|
1831 | 'dont care': GL_DONT_CARE,
|
1832 | 'nice': GL_NICEST,
|
1833 | 'fast': GL_FASTEST
|
1834 | }
|
1835 |
|
1836 | var wrapModes = {
|
1837 | 'repeat': GL_REPEAT,
|
1838 | 'clamp': GL_CLAMP_TO_EDGE,
|
1839 | 'mirror': GL_MIRRORED_REPEAT
|
1840 | }
|
1841 |
|
1842 | var magFilters = {
|
1843 | 'nearest': GL_NEAREST,
|
1844 | 'linear': GL_LINEAR
|
1845 | }
|
1846 |
|
1847 | var minFilters = extend({
|
1848 | 'mipmap': GL_LINEAR_MIPMAP_LINEAR,
|
1849 | 'nearest mipmap nearest': GL_NEAREST_MIPMAP_NEAREST,
|
1850 | 'linear mipmap nearest': GL_LINEAR_MIPMAP_NEAREST,
|
1851 | 'nearest mipmap linear': GL_NEAREST_MIPMAP_LINEAR,
|
1852 | 'linear mipmap linear': GL_LINEAR_MIPMAP_LINEAR
|
1853 | }, magFilters)
|
1854 |
|
1855 | var colorSpace = {
|
1856 | 'none': 0,
|
1857 | 'browser': GL_BROWSER_DEFAULT_WEBGL
|
1858 | }
|
1859 |
|
1860 | var textureTypes = {
|
1861 | 'uint8': GL_UNSIGNED_BYTE$4,
|
1862 | 'rgba4': GL_UNSIGNED_SHORT_4_4_4_4,
|
1863 | 'rgb565': GL_UNSIGNED_SHORT_5_6_5,
|
1864 | 'rgb5 a1': GL_UNSIGNED_SHORT_5_5_5_1
|
1865 | }
|
1866 |
|
1867 | var textureFormats = {
|
1868 | 'alpha': GL_ALPHA,
|
1869 | 'luminance': GL_LUMINANCE,
|
1870 | 'luminance alpha': GL_LUMINANCE_ALPHA,
|
1871 | 'rgb': GL_RGB,
|
1872 | 'rgba': GL_RGBA$1,
|
1873 | 'rgba4': GL_RGBA4,
|
1874 | 'rgb5 a1': GL_RGB5_A1,
|
1875 | 'rgb565': GL_RGB565
|
1876 | }
|
1877 |
|
1878 | var compressedTextureFormats = {}
|
1879 |
|
1880 | if (extensions.ext_srgb) {
|
1881 | textureFormats.srgb = GL_SRGB_EXT
|
1882 | textureFormats.srgba = GL_SRGB_ALPHA_EXT
|
1883 | }
|
1884 |
|
1885 | if (extensions.oes_texture_float) {
|
1886 | textureTypes.float32 = textureTypes.float = GL_FLOAT$3
|
1887 | }
|
1888 |
|
1889 | if (extensions.oes_texture_half_float) {
|
1890 | textureTypes['float16'] = textureTypes['half float'] = GL_HALF_FLOAT_OES
|
1891 | }
|
1892 |
|
1893 | if (extensions.webgl_depth_texture) {
|
1894 | extend(textureFormats, {
|
1895 | 'depth': GL_DEPTH_COMPONENT,
|
1896 | 'depth stencil': GL_DEPTH_STENCIL
|
1897 | })
|
1898 |
|
1899 | extend(textureTypes, {
|
1900 | 'uint16': GL_UNSIGNED_SHORT$2,
|
1901 | 'uint32': GL_UNSIGNED_INT$2,
|
1902 | 'depth stencil': GL_UNSIGNED_INT_24_8_WEBGL
|
1903 | })
|
1904 | }
|
1905 |
|
1906 | if (extensions.webgl_compressed_texture_s3tc) {
|
1907 | extend(compressedTextureFormats, {
|
1908 | 'rgb s3tc dxt1': GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
|
1909 | 'rgba s3tc dxt1': GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
|
1910 | 'rgba s3tc dxt3': GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,
|
1911 | 'rgba s3tc dxt5': GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
|
1912 | })
|
1913 | }
|
1914 |
|
1915 | if (extensions.webgl_compressed_texture_atc) {
|
1916 | extend(compressedTextureFormats, {
|
1917 | 'rgb atc': GL_COMPRESSED_RGB_ATC_WEBGL,
|
1918 | 'rgba atc explicit alpha': GL_COMPRESSED_RGBA_ATC_EXPLICIT_ALPHA_WEBGL,
|
1919 | 'rgba atc interpolated alpha': GL_COMPRESSED_RGBA_ATC_INTERPOLATED_ALPHA_WEBGL
|
1920 | })
|
1921 | }
|
1922 |
|
1923 | if (extensions.webgl_compressed_texture_pvrtc) {
|
1924 | extend(compressedTextureFormats, {
|
1925 | 'rgb pvrtc 4bppv1': GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG,
|
1926 | 'rgb pvrtc 2bppv1': GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG,
|
1927 | 'rgba pvrtc 4bppv1': GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG,
|
1928 | 'rgba pvrtc 2bppv1': GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG
|
1929 | })
|
1930 | }
|
1931 |
|
1932 | if (extensions.webgl_compressed_texture_etc1) {
|
1933 | compressedTextureFormats['rgb etc1'] = GL_COMPRESSED_RGB_ETC1_WEBGL
|
1934 | }
|
1935 |
|
1936 |
|
1937 | var supportedCompressedFormats = Array.prototype.slice.call(
|
1938 | gl.getParameter(GL_COMPRESSED_TEXTURE_FORMATS))
|
1939 | Object.keys(compressedTextureFormats).forEach(function (name) {
|
1940 | var format = compressedTextureFormats[name]
|
1941 | if (supportedCompressedFormats.indexOf(format) >= 0) {
|
1942 | textureFormats[name] = format
|
1943 | }
|
1944 | })
|
1945 |
|
1946 | var supportedFormats = Object.keys(textureFormats)
|
1947 | limits.textureFormats = supportedFormats
|
1948 |
|
1949 |
|
1950 |
|
1951 | var textureFormatsInvert = []
|
1952 | Object.keys(textureFormats).forEach(function (key) {
|
1953 | var val = textureFormats[key]
|
1954 | textureFormatsInvert[val] = key
|
1955 | })
|
1956 |
|
1957 |
|
1958 |
|
1959 | var textureTypesInvert = []
|
1960 | Object.keys(textureTypes).forEach(function (key) {
|
1961 | var val = textureTypes[key]
|
1962 | textureTypesInvert[val] = key
|
1963 | })
|
1964 |
|
1965 | var magFiltersInvert = []
|
1966 | Object.keys(magFilters).forEach(function (key) {
|
1967 | var val = magFilters[key]
|
1968 | magFiltersInvert[val] = key
|
1969 | })
|
1970 |
|
1971 | var minFiltersInvert = []
|
1972 | Object.keys(minFilters).forEach(function (key) {
|
1973 | var val = minFilters[key]
|
1974 | minFiltersInvert[val] = key
|
1975 | })
|
1976 |
|
1977 | var wrapModesInvert = []
|
1978 | Object.keys(wrapModes).forEach(function (key) {
|
1979 | var val = wrapModes[key]
|
1980 | wrapModesInvert[val] = key
|
1981 | })
|
1982 |
|
1983 |
|
1984 |
|
1985 | var colorFormats = supportedFormats.reduce(function (color, key) {
|
1986 | var glenum = textureFormats[key]
|
1987 | if (glenum === GL_LUMINANCE ||
|
1988 | glenum === GL_ALPHA ||
|
1989 | glenum === GL_LUMINANCE ||
|
1990 | glenum === GL_LUMINANCE_ALPHA ||
|
1991 | glenum === GL_DEPTH_COMPONENT ||
|
1992 | glenum === GL_DEPTH_STENCIL ||
|
1993 | (extensions.ext_srgb &&
|
1994 | (glenum === GL_SRGB_EXT ||
|
1995 | glenum === GL_SRGB_ALPHA_EXT))) {
|
1996 | color[glenum] = glenum
|
1997 | } else if (glenum === GL_RGB5_A1 || key.indexOf('rgba') >= 0) {
|
1998 | color[glenum] = GL_RGBA$1
|
1999 | } else {
|
2000 | color[glenum] = GL_RGB
|
2001 | }
|
2002 | return color
|
2003 | }, {})
|
2004 |
|
2005 | function TexFlags () {
|
2006 |
|
2007 | this.internalformat = GL_RGBA$1
|
2008 | this.format = GL_RGBA$1
|
2009 | this.type = GL_UNSIGNED_BYTE$4
|
2010 | this.compressed = false
|
2011 |
|
2012 |
|
2013 | this.premultiplyAlpha = false
|
2014 | this.flipY = false
|
2015 | this.unpackAlignment = 1
|
2016 | this.colorSpace = GL_BROWSER_DEFAULT_WEBGL
|
2017 |
|
2018 |
|
2019 | this.width = 0
|
2020 | this.height = 0
|
2021 | this.channels = 0
|
2022 | }
|
2023 |
|
2024 | function copyFlags (result, other) {
|
2025 | result.internalformat = other.internalformat
|
2026 | result.format = other.format
|
2027 | result.type = other.type
|
2028 | result.compressed = other.compressed
|
2029 |
|
2030 | result.premultiplyAlpha = other.premultiplyAlpha
|
2031 | result.flipY = other.flipY
|
2032 | result.unpackAlignment = other.unpackAlignment
|
2033 | result.colorSpace = other.colorSpace
|
2034 |
|
2035 | result.width = other.width
|
2036 | result.height = other.height
|
2037 | result.channels = other.channels
|
2038 | }
|
2039 |
|
2040 | function parseFlags (flags, options) {
|
2041 | if (typeof options !== 'object' || !options) {
|
2042 | return
|
2043 | }
|
2044 |
|
2045 | if ('premultiplyAlpha' in options) {
|
2046 |
|
2047 | flags.premultiplyAlpha = options.premultiplyAlpha
|
2048 | }
|
2049 |
|
2050 | if ('flipY' in options) {
|
2051 |
|
2052 | flags.flipY = options.flipY
|
2053 | }
|
2054 |
|
2055 | if ('alignment' in options) {
|
2056 |
|
2057 | flags.unpackAlignment = options.alignment
|
2058 | }
|
2059 |
|
2060 | if ('colorSpace' in options) {
|
2061 |
|
2062 | flags.colorSpace = colorSpace[options.colorSpace]
|
2063 | }
|
2064 |
|
2065 | if ('type' in options) {
|
2066 | var type = options.type
|
2067 |
|
2068 |
|
2069 |
|
2070 |
|
2071 | flags.type = textureTypes[type]
|
2072 | }
|
2073 |
|
2074 | var w = flags.width
|
2075 | var h = flags.height
|
2076 | var c = flags.channels
|
2077 | var hasChannels = false
|
2078 | if ('shape' in options) {
|
2079 |
|
2080 | w = options.shape[0]
|
2081 | h = options.shape[1]
|
2082 | if (options.shape.length === 3) {
|
2083 | c = options.shape[2]
|
2084 |
|
2085 | hasChannels = true
|
2086 | }
|
2087 |
|
2088 |
|
2089 | } else {
|
2090 | if ('radius' in options) {
|
2091 | w = h = options.radius
|
2092 |
|
2093 | }
|
2094 | if ('width' in options) {
|
2095 | w = options.width
|
2096 |
|
2097 | }
|
2098 | if ('height' in options) {
|
2099 | h = options.height
|
2100 |
|
2101 | }
|
2102 | if ('channels' in options) {
|
2103 | c = options.channels
|
2104 |
|
2105 | hasChannels = true
|
2106 | }
|
2107 | }
|
2108 | flags.width = w | 0
|
2109 | flags.height = h | 0
|
2110 | flags.channels = c | 0
|
2111 |
|
2112 | var hasFormat = false
|
2113 | if ('format' in options) {
|
2114 | var formatStr = options.format
|
2115 |
|
2116 |
|
2117 | var internalformat = flags.internalformat = textureFormats[formatStr]
|
2118 | flags.format = colorFormats[internalformat]
|
2119 | if (formatStr in textureTypes) {
|
2120 | if (!('type' in options)) {
|
2121 | flags.type = textureTypes[formatStr]
|
2122 | }
|
2123 | }
|
2124 | if (formatStr in compressedTextureFormats) {
|
2125 | flags.compressed = true
|
2126 | }
|
2127 | hasFormat = true
|
2128 | }
|
2129 |
|
2130 |
|
2131 | if (!hasChannels && hasFormat) {
|
2132 | flags.channels = FORMAT_CHANNELS[flags.format]
|
2133 | } else if (hasChannels && !hasFormat) {
|
2134 | if (flags.channels !== CHANNELS_FORMAT[flags.format]) {
|
2135 | flags.format = flags.internalformat = CHANNELS_FORMAT[flags.channels]
|
2136 | }
|
2137 | } else if (hasFormat && hasChannels) {
|
2138 |
|
2139 | }
|
2140 | }
|
2141 |
|
2142 | function setFlags (flags) {
|
2143 | gl.pixelStorei(GL_UNPACK_FLIP_Y_WEBGL, flags.flipY)
|
2144 | gl.pixelStorei(GL_UNPACK_PREMULTIPLY_ALPHA_WEBGL, flags.premultiplyAlpha)
|
2145 | gl.pixelStorei(GL_UNPACK_COLORSPACE_CONVERSION_WEBGL, flags.colorSpace)
|
2146 | gl.pixelStorei(GL_UNPACK_ALIGNMENT, flags.unpackAlignment)
|
2147 | }
|
2148 |
|
2149 |
|
2150 |
|
2151 |
|
2152 | function TexImage () {
|
2153 | TexFlags.call(this)
|
2154 |
|
2155 | this.xOffset = 0
|
2156 | this.yOffset = 0
|
2157 |
|
2158 |
|
2159 | this.data = null
|
2160 | this.needsFree = false
|
2161 |
|
2162 |
|
2163 | this.element = null
|
2164 |
|
2165 |
|
2166 | this.needsCopy = false
|
2167 | }
|
2168 |
|
2169 | function parseImage (image, options) {
|
2170 | var data = null
|
2171 | if (isPixelData(options)) {
|
2172 | data = options
|
2173 | } else if (options) {
|
2174 |
|
2175 | parseFlags(image, options)
|
2176 | if ('x' in options) {
|
2177 | image.xOffset = options.x | 0
|
2178 | }
|
2179 | if ('y' in options) {
|
2180 | image.yOffset = options.y | 0
|
2181 | }
|
2182 | if (isPixelData(options.data)) {
|
2183 | data = options.data
|
2184 | }
|
2185 | }
|
2186 |
|
2187 |
|
2188 |
|
2189 | if (options.copy) {
|
2190 |
|
2191 | var viewW = contextState.viewportWidth
|
2192 | var viewH = contextState.viewportHeight
|
2193 | image.width = image.width || (viewW - image.xOffset)
|
2194 | image.height = image.height || (viewH - image.yOffset)
|
2195 | image.needsCopy = true
|
2196 |
|
2197 | } else if (!data) {
|
2198 | image.width = image.width || 1
|
2199 | image.height = image.height || 1
|
2200 | image.channels = image.channels || 4
|
2201 | } else if (isTypedArray(data)) {
|
2202 | image.channels = image.channels || 4
|
2203 | image.data = data
|
2204 | if (!('type' in options) && image.type === GL_UNSIGNED_BYTE$4) {
|
2205 | image.type = typedArrayCode$1(data)
|
2206 | }
|
2207 | } else if (isNumericArray(data)) {
|
2208 | image.channels = image.channels || 4
|
2209 | convertData(image, data)
|
2210 | image.alignment = 1
|
2211 | image.needsFree = true
|
2212 | } else if (isNDArrayLike(data)) {
|
2213 | var array = data.data
|
2214 | if (!Array.isArray(array) && image.type === GL_UNSIGNED_BYTE$4) {
|
2215 | image.type = typedArrayCode$1(array)
|
2216 | }
|
2217 | var shape = data.shape
|
2218 | var stride = data.stride
|
2219 | var shapeX, shapeY, shapeC, strideX, strideY, strideC
|
2220 | if (shape.length === 3) {
|
2221 | shapeC = shape[2]
|
2222 | strideC = stride[2]
|
2223 | } else {
|
2224 |
|
2225 | shapeC = 1
|
2226 | strideC = 1
|
2227 | }
|
2228 | shapeX = shape[0]
|
2229 | shapeY = shape[1]
|
2230 | strideX = stride[0]
|
2231 | strideY = stride[1]
|
2232 | image.alignment = 1
|
2233 | image.width = shapeX
|
2234 | image.height = shapeY
|
2235 | image.channels = shapeC
|
2236 | image.format = image.internalformat = CHANNELS_FORMAT[shapeC]
|
2237 | image.needsFree = true
|
2238 | transposeData(image, array, strideX, strideY, strideC, data.offset)
|
2239 | } else if (isCanvasElement(data) || isOffscreenCanvas(data) || isContext2D(data)) {
|
2240 | if (isCanvasElement(data) || isOffscreenCanvas(data)) {
|
2241 | image.element = data
|
2242 | } else {
|
2243 | image.element = data.canvas
|
2244 | }
|
2245 | image.width = image.element.width
|
2246 | image.height = image.element.height
|
2247 | image.channels = 4
|
2248 | } else if (isBitmap(data)) {
|
2249 | image.element = data
|
2250 | image.width = data.width
|
2251 | image.height = data.height
|
2252 | image.channels = 4
|
2253 | } else if (isImageElement(data)) {
|
2254 | image.element = data
|
2255 | image.width = data.naturalWidth
|
2256 | image.height = data.naturalHeight
|
2257 | image.channels = 4
|
2258 | } else if (isVideoElement(data)) {
|
2259 | image.element = data
|
2260 | image.width = data.videoWidth
|
2261 | image.height = data.videoHeight
|
2262 | image.channels = 4
|
2263 | } else if (isRectArray(data)) {
|
2264 | var w = image.width || data[0].length
|
2265 | var h = image.height || data.length
|
2266 | var c = image.channels
|
2267 | if (isArrayLike(data[0][0])) {
|
2268 | c = c || data[0][0].length
|
2269 | } else {
|
2270 | c = c || 1
|
2271 | }
|
2272 | var arrayShape = flattenUtils.shape(data)
|
2273 | var n = 1
|
2274 | for (var dd = 0; dd < arrayShape.length; ++dd) {
|
2275 | n *= arrayShape[dd]
|
2276 | }
|
2277 | var allocData = preConvert(image, n)
|
2278 | flattenUtils.flatten(data, arrayShape, '', allocData)
|
2279 | postConvert(image, allocData)
|
2280 | image.alignment = 1
|
2281 | image.width = w
|
2282 | image.height = h
|
2283 | image.channels = c
|
2284 | image.format = image.internalformat = CHANNELS_FORMAT[c]
|
2285 | image.needsFree = true
|
2286 | }
|
2287 |
|
2288 | if (image.type === GL_FLOAT$3) {
|
2289 |
|
2290 | } else if (image.type === GL_HALF_FLOAT_OES) {
|
2291 |
|
2292 | }
|
2293 |
|
2294 |
|
2295 | }
|
2296 |
|
2297 | function setImage (info, target, miplevel) {
|
2298 | var element = info.element
|
2299 | var data = info.data
|
2300 | var internalformat = info.internalformat
|
2301 | var format = info.format
|
2302 | var type = info.type
|
2303 | var width = info.width
|
2304 | var height = info.height
|
2305 |
|
2306 | setFlags(info)
|
2307 |
|
2308 | if (element) {
|
2309 | gl.texImage2D(target, miplevel, format, format, type, element)
|
2310 | } else if (info.compressed) {
|
2311 | gl.compressedTexImage2D(target, miplevel, internalformat, width, height, 0, data)
|
2312 | } else if (info.needsCopy) {
|
2313 | reglPoll()
|
2314 | gl.copyTexImage2D(
|
2315 | target, miplevel, format, info.xOffset, info.yOffset, width, height, 0)
|
2316 | } else {
|
2317 | gl.texImage2D(target, miplevel, format, width, height, 0, format, type, data || null)
|
2318 | }
|
2319 | }
|
2320 |
|
2321 | function setSubImage (info, target, x, y, miplevel) {
|
2322 | var element = info.element
|
2323 | var data = info.data
|
2324 | var internalformat = info.internalformat
|
2325 | var format = info.format
|
2326 | var type = info.type
|
2327 | var width = info.width
|
2328 | var height = info.height
|
2329 |
|
2330 | setFlags(info)
|
2331 |
|
2332 | if (element) {
|
2333 | gl.texSubImage2D(
|
2334 | target, miplevel, x, y, format, type, element)
|
2335 | } else if (info.compressed) {
|
2336 | gl.compressedTexSubImage2D(
|
2337 | target, miplevel, x, y, internalformat, width, height, data)
|
2338 | } else if (info.needsCopy) {
|
2339 | reglPoll()
|
2340 | gl.copyTexSubImage2D(
|
2341 | target, miplevel, x, y, info.xOffset, info.yOffset, width, height)
|
2342 | } else {
|
2343 | gl.texSubImage2D(
|
2344 | target, miplevel, x, y, width, height, format, type, data)
|
2345 | }
|
2346 | }
|
2347 |
|
2348 |
|
2349 | var imagePool = []
|
2350 |
|
2351 | function allocImage () {
|
2352 | return imagePool.pop() || new TexImage()
|
2353 | }
|
2354 |
|
2355 | function freeImage (image) {
|
2356 | if (image.needsFree) {
|
2357 | pool.freeType(image.data)
|
2358 | }
|
2359 | TexImage.call(image)
|
2360 | imagePool.push(image)
|
2361 | }
|
2362 |
|
2363 |
|
2364 |
|
2365 |
|
2366 | function MipMap () {
|
2367 | TexFlags.call(this)
|
2368 |
|
2369 | this.genMipmaps = false
|
2370 | this.mipmapHint = GL_DONT_CARE
|
2371 | this.mipmask = 0
|
2372 | this.images = Array(16)
|
2373 | }
|
2374 |
|
2375 | function parseMipMapFromShape (mipmap, width, height) {
|
2376 | var img = mipmap.images[0] = allocImage()
|
2377 | mipmap.mipmask = 1
|
2378 | img.width = mipmap.width = width
|
2379 | img.height = mipmap.height = height
|
2380 | img.channels = mipmap.channels = 4
|
2381 | }
|
2382 |
|
2383 | function parseMipMapFromObject (mipmap, options) {
|
2384 | var imgData = null
|
2385 | if (isPixelData(options)) {
|
2386 | imgData = mipmap.images[0] = allocImage()
|
2387 | copyFlags(imgData, mipmap)
|
2388 | parseImage(imgData, options)
|
2389 | mipmap.mipmask = 1
|
2390 | } else {
|
2391 | parseFlags(mipmap, options)
|
2392 | if (Array.isArray(options.mipmap)) {
|
2393 | var mipData = options.mipmap
|
2394 | for (var i = 0; i < mipData.length; ++i) {
|
2395 | imgData = mipmap.images[i] = allocImage()
|
2396 | copyFlags(imgData, mipmap)
|
2397 | imgData.width >>= i
|
2398 | imgData.height >>= i
|
2399 | parseImage(imgData, mipData[i])
|
2400 | mipmap.mipmask |= (1 << i)
|
2401 | }
|
2402 | } else {
|
2403 | imgData = mipmap.images[0] = allocImage()
|
2404 | copyFlags(imgData, mipmap)
|
2405 | parseImage(imgData, options)
|
2406 | mipmap.mipmask = 1
|
2407 | }
|
2408 | }
|
2409 | copyFlags(mipmap, mipmap.images[0])
|
2410 |
|
2411 |
|
2412 |
|
2413 |
|
2414 |
|
2415 |
|
2416 |
|
2417 |
|
2418 |
|
2419 |
|
2420 | if (
|
2421 | mipmap.compressed &&
|
2422 | (
|
2423 | mipmap.internalformat === GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
|
2424 | mipmap.internalformat === GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ||
|
2425 | mipmap.internalformat === GL_COMPRESSED_RGBA_S3TC_DXT3_EXT ||
|
2426 | mipmap.internalformat === GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
|
2427 | )
|
2428 | ) {
|
2429 |
|
2430 | }
|
2431 | }
|
2432 |
|
2433 | function setMipMap (mipmap, target) {
|
2434 | var images = mipmap.images
|
2435 | for (var i = 0; i < images.length; ++i) {
|
2436 | if (!images[i]) {
|
2437 | return
|
2438 | }
|
2439 | setImage(images[i], target, i)
|
2440 | }
|
2441 | }
|
2442 |
|
2443 | var mipPool = []
|
2444 |
|
2445 | function allocMipMap () {
|
2446 | var result = mipPool.pop() || new MipMap()
|
2447 | TexFlags.call(result)
|
2448 | result.mipmask = 0
|
2449 | for (var i = 0; i < 16; ++i) {
|
2450 | result.images[i] = null
|
2451 | }
|
2452 | return result
|
2453 | }
|
2454 |
|
2455 | function freeMipMap (mipmap) {
|
2456 | var images = mipmap.images
|
2457 | for (var i = 0; i < images.length; ++i) {
|
2458 | if (images[i]) {
|
2459 | freeImage(images[i])
|
2460 | }
|
2461 | images[i] = null
|
2462 | }
|
2463 | mipPool.push(mipmap)
|
2464 | }
|
2465 |
|
2466 |
|
2467 |
|
2468 |
|
2469 | function TexInfo () {
|
2470 | this.minFilter = GL_NEAREST
|
2471 | this.magFilter = GL_NEAREST
|
2472 |
|
2473 | this.wrapS = GL_CLAMP_TO_EDGE
|
2474 | this.wrapT = GL_CLAMP_TO_EDGE
|
2475 |
|
2476 | this.anisotropic = 1
|
2477 |
|
2478 | this.genMipmaps = false
|
2479 | this.mipmapHint = GL_DONT_CARE
|
2480 | }
|
2481 |
|
2482 | function parseTexInfo (info, options) {
|
2483 | if ('min' in options) {
|
2484 | var minFilter = options.min
|
2485 |
|
2486 | info.minFilter = minFilters[minFilter]
|
2487 | if (MIPMAP_FILTERS.indexOf(info.minFilter) >= 0 && !('faces' in options)) {
|
2488 | info.genMipmaps = true
|
2489 | }
|
2490 | }
|
2491 |
|
2492 | if ('mag' in options) {
|
2493 | var magFilter = options.mag
|
2494 |
|
2495 | info.magFilter = magFilters[magFilter]
|
2496 | }
|
2497 |
|
2498 | var wrapS = info.wrapS
|
2499 | var wrapT = info.wrapT
|
2500 | if ('wrap' in options) {
|
2501 | var wrap = options.wrap
|
2502 | if (typeof wrap === 'string') {
|
2503 |
|
2504 | wrapS = wrapT = wrapModes[wrap]
|
2505 | } else if (Array.isArray(wrap)) {
|
2506 |
|
2507 |
|
2508 | wrapS = wrapModes[wrap[0]]
|
2509 | wrapT = wrapModes[wrap[1]]
|
2510 | }
|
2511 | } else {
|
2512 | if ('wrapS' in options) {
|
2513 | var optWrapS = options.wrapS
|
2514 |
|
2515 | wrapS = wrapModes[optWrapS]
|
2516 | }
|
2517 | if ('wrapT' in options) {
|
2518 | var optWrapT = options.wrapT
|
2519 |
|
2520 | wrapT = wrapModes[optWrapT]
|
2521 | }
|
2522 | }
|
2523 | info.wrapS = wrapS
|
2524 | info.wrapT = wrapT
|
2525 |
|
2526 | if ('anisotropic' in options) {
|
2527 | var anisotropic = options.anisotropic
|
2528 |
|
2529 | info.anisotropic = options.anisotropic
|
2530 | }
|
2531 |
|
2532 | if ('mipmap' in options) {
|
2533 | var hasMipMap = false
|
2534 | switch (typeof options.mipmap) {
|
2535 | case 'string':
|
2536 |
|
2537 | info.mipmapHint = mipmapHint[options.mipmap]
|
2538 | info.genMipmaps = true
|
2539 | hasMipMap = true
|
2540 | break
|
2541 |
|
2542 | case 'boolean':
|
2543 | hasMipMap = info.genMipmaps = options.mipmap
|
2544 | break
|
2545 |
|
2546 | case 'object':
|
2547 |
|
2548 | info.genMipmaps = false
|
2549 | hasMipMap = true
|
2550 | break
|
2551 |
|
2552 | default:
|
2553 |
|
2554 | }
|
2555 | if (hasMipMap && !('min' in options)) {
|
2556 | info.minFilter = GL_NEAREST_MIPMAP_NEAREST
|
2557 | }
|
2558 | }
|
2559 | }
|
2560 |
|
2561 | function setTexInfo (info, target) {
|
2562 | gl.texParameteri(target, GL_TEXTURE_MIN_FILTER, info.minFilter)
|
2563 | gl.texParameteri(target, GL_TEXTURE_MAG_FILTER, info.magFilter)
|
2564 | gl.texParameteri(target, GL_TEXTURE_WRAP_S, info.wrapS)
|
2565 | gl.texParameteri(target, GL_TEXTURE_WRAP_T, info.wrapT)
|
2566 | if (extensions.ext_texture_filter_anisotropic) {
|
2567 | gl.texParameteri(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, info.anisotropic)
|
2568 | }
|
2569 | if (info.genMipmaps) {
|
2570 | gl.hint(GL_GENERATE_MIPMAP_HINT, info.mipmapHint)
|
2571 | gl.generateMipmap(target)
|
2572 | }
|
2573 | }
|
2574 |
|
2575 |
|
2576 |
|
2577 |
|
2578 | var textureCount = 0
|
2579 | var textureSet = {}
|
2580 | var numTexUnits = limits.maxTextureUnits
|
2581 | var textureUnits = Array(numTexUnits).map(function () {
|
2582 | return null
|
2583 | })
|
2584 |
|
2585 | function REGLTexture (target) {
|
2586 | TexFlags.call(this)
|
2587 | this.mipmask = 0
|
2588 | this.internalformat = GL_RGBA$1
|
2589 |
|
2590 | this.id = textureCount++
|
2591 |
|
2592 | this.refCount = 1
|
2593 |
|
2594 | this.target = target
|
2595 | this.texture = gl.createTexture()
|
2596 |
|
2597 | this.unit = -1
|
2598 | this.bindCount = 0
|
2599 |
|
2600 | this.texInfo = new TexInfo()
|
2601 |
|
2602 | if (config.profile) {
|
2603 | this.stats = { size: 0 }
|
2604 | }
|
2605 | }
|
2606 |
|
2607 | function tempBind (texture) {
|
2608 | gl.activeTexture(GL_TEXTURE0$1)
|
2609 | gl.bindTexture(texture.target, texture.texture)
|
2610 | }
|
2611 |
|
2612 | function tempRestore () {
|
2613 | var prev = textureUnits[0]
|
2614 | if (prev) {
|
2615 | gl.bindTexture(prev.target, prev.texture)
|
2616 | } else {
|
2617 | gl.bindTexture(GL_TEXTURE_2D$1, null)
|
2618 | }
|
2619 | }
|
2620 |
|
2621 | function destroy (texture) {
|
2622 | var handle = texture.texture
|
2623 |
|
2624 | var unit = texture.unit
|
2625 | var target = texture.target
|
2626 | if (unit >= 0) {
|
2627 | gl.activeTexture(GL_TEXTURE0$1 + unit)
|
2628 | gl.bindTexture(target, null)
|
2629 | textureUnits[unit] = null
|
2630 | }
|
2631 | gl.deleteTexture(handle)
|
2632 | texture.texture = null
|
2633 | texture.params = null
|
2634 | texture.pixels = null
|
2635 | texture.refCount = 0
|
2636 | delete textureSet[texture.id]
|
2637 | stats.textureCount--
|
2638 | }
|
2639 |
|
2640 | extend(REGLTexture.prototype, {
|
2641 | bind: function () {
|
2642 | var texture = this
|
2643 | texture.bindCount += 1
|
2644 | var unit = texture.unit
|
2645 | if (unit < 0) {
|
2646 | for (var i = 0; i < numTexUnits; ++i) {
|
2647 | var other = textureUnits[i]
|
2648 | if (other) {
|
2649 | if (other.bindCount > 0) {
|
2650 | continue
|
2651 | }
|
2652 | other.unit = -1
|
2653 | }
|
2654 | textureUnits[i] = texture
|
2655 | unit = i
|
2656 | break
|
2657 | }
|
2658 | if (unit >= numTexUnits) {
|
2659 |
|
2660 | }
|
2661 | if (config.profile && stats.maxTextureUnits < (unit + 1)) {
|
2662 | stats.maxTextureUnits = unit + 1
|
2663 | }
|
2664 | texture.unit = unit
|
2665 | gl.activeTexture(GL_TEXTURE0$1 + unit)
|
2666 | gl.bindTexture(texture.target, texture.texture)
|
2667 | }
|
2668 | return unit
|
2669 | },
|
2670 |
|
2671 | unbind: function () {
|
2672 | this.bindCount -= 1
|
2673 | },
|
2674 |
|
2675 | decRef: function () {
|
2676 | if (--this.refCount <= 0) {
|
2677 | destroy(this)
|
2678 | }
|
2679 | }
|
2680 | })
|
2681 |
|
2682 | function createTexture2D (a, b) {
|
2683 | var texture = new REGLTexture(GL_TEXTURE_2D$1)
|
2684 | textureSet[texture.id] = texture
|
2685 | stats.textureCount++
|
2686 |
|
2687 | function reglTexture2D (a, b) {
|
2688 | var texInfo = texture.texInfo
|
2689 | TexInfo.call(texInfo)
|
2690 | var mipData = allocMipMap()
|
2691 |
|
2692 | if (typeof a === 'number') {
|
2693 | if (typeof b === 'number') {
|
2694 | parseMipMapFromShape(mipData, a | 0, b | 0)
|
2695 | } else {
|
2696 | parseMipMapFromShape(mipData, a | 0, a | 0)
|
2697 | }
|
2698 | } else if (a) {
|
2699 |
|
2700 | parseTexInfo(texInfo, a)
|
2701 | parseMipMapFromObject(mipData, a)
|
2702 | } else {
|
2703 |
|
2704 | parseMipMapFromShape(mipData, 1, 1)
|
2705 | }
|
2706 |
|
2707 | if (texInfo.genMipmaps) {
|
2708 | mipData.mipmask = (mipData.width << 1) - 1
|
2709 | }
|
2710 | texture.mipmask = mipData.mipmask
|
2711 |
|
2712 | copyFlags(texture, mipData)
|
2713 |
|
2714 |
|
2715 | texture.internalformat = mipData.internalformat
|
2716 |
|
2717 | reglTexture2D.width = mipData.width
|
2718 | reglTexture2D.height = mipData.height
|
2719 |
|
2720 | tempBind(texture)
|
2721 | setMipMap(mipData, GL_TEXTURE_2D$1)
|
2722 | setTexInfo(texInfo, GL_TEXTURE_2D$1)
|
2723 | tempRestore()
|
2724 |
|
2725 | freeMipMap(mipData)
|
2726 |
|
2727 | if (config.profile) {
|
2728 | texture.stats.size = getTextureSize(
|
2729 | texture.internalformat,
|
2730 | texture.type,
|
2731 | mipData.width,
|
2732 | mipData.height,
|
2733 | texInfo.genMipmaps,
|
2734 | false)
|
2735 | }
|
2736 | reglTexture2D.format = textureFormatsInvert[texture.internalformat]
|
2737 | reglTexture2D.type = textureTypesInvert[texture.type]
|
2738 |
|
2739 | reglTexture2D.mag = magFiltersInvert[texInfo.magFilter]
|
2740 | reglTexture2D.min = minFiltersInvert[texInfo.minFilter]
|
2741 |
|
2742 | reglTexture2D.wrapS = wrapModesInvert[texInfo.wrapS]
|
2743 | reglTexture2D.wrapT = wrapModesInvert[texInfo.wrapT]
|
2744 |
|
2745 | return reglTexture2D
|
2746 | }
|
2747 |
|
2748 | function subimage (image, x_, y_, level_) {
|
2749 |
|
2750 |
|
2751 | var x = x_ | 0
|
2752 | var y = y_ | 0
|
2753 | var level = level_ | 0
|
2754 |
|
2755 | var imageData = allocImage()
|
2756 | copyFlags(imageData, texture)
|
2757 | imageData.width = 0
|
2758 | imageData.height = 0
|
2759 | parseImage(imageData, image)
|
2760 | imageData.width = imageData.width || ((texture.width >> level) - x)
|
2761 | imageData.height = imageData.height || ((texture.height >> level) - y)
|
2762 |
|
2763 |
|
2764 |
|
2765 |
|
2766 |
|
2767 |
|
2768 | tempBind(texture)
|
2769 | setSubImage(imageData, GL_TEXTURE_2D$1, x, y, level)
|
2770 | tempRestore()
|
2771 |
|
2772 | freeImage(imageData)
|
2773 |
|
2774 | return reglTexture2D
|
2775 | }
|
2776 |
|
2777 | function resize (w_, h_) {
|
2778 | var w = w_ | 0
|
2779 | var h = (h_ | 0) || w
|
2780 | if (w === texture.width && h === texture.height) {
|
2781 | return reglTexture2D
|
2782 | }
|
2783 |
|
2784 | reglTexture2D.width = texture.width = w
|
2785 | reglTexture2D.height = texture.height = h
|
2786 |
|
2787 | tempBind(texture)
|
2788 |
|
2789 | for (var i = 0; texture.mipmask >> i; ++i) {
|
2790 | var _w = w >> i
|
2791 | var _h = h >> i
|
2792 | if (!_w || !_h) break
|
2793 | gl.texImage2D(
|
2794 | GL_TEXTURE_2D$1,
|
2795 | i,
|
2796 | texture.format,
|
2797 | _w,
|
2798 | _h,
|
2799 | 0,
|
2800 | texture.format,
|
2801 | texture.type,
|
2802 | null)
|
2803 | }
|
2804 | tempRestore()
|
2805 |
|
2806 |
|
2807 | if (config.profile) {
|
2808 | texture.stats.size = getTextureSize(
|
2809 | texture.internalformat,
|
2810 | texture.type,
|
2811 | w,
|
2812 | h,
|
2813 | false,
|
2814 | false)
|
2815 | }
|
2816 |
|
2817 | return reglTexture2D
|
2818 | }
|
2819 |
|
2820 | reglTexture2D(a, b)
|
2821 |
|
2822 | reglTexture2D.subimage = subimage
|
2823 | reglTexture2D.resize = resize
|
2824 | reglTexture2D._reglType = 'texture2d'
|
2825 | reglTexture2D._texture = texture
|
2826 | if (config.profile) {
|
2827 | reglTexture2D.stats = texture.stats
|
2828 | }
|
2829 | reglTexture2D.destroy = function () {
|
2830 | texture.decRef()
|
2831 | }
|
2832 |
|
2833 | return reglTexture2D
|
2834 | }
|
2835 |
|
2836 | function createTextureCube (a0, a1, a2, a3, a4, a5) {
|
2837 | var texture = new REGLTexture(GL_TEXTURE_CUBE_MAP$1)
|
2838 | textureSet[texture.id] = texture
|
2839 | stats.cubeCount++
|
2840 |
|
2841 | var faces = new Array(6)
|
2842 |
|
2843 | function reglTextureCube (a0, a1, a2, a3, a4, a5) {
|
2844 | var i
|
2845 | var texInfo = texture.texInfo
|
2846 | TexInfo.call(texInfo)
|
2847 | for (i = 0; i < 6; ++i) {
|
2848 | faces[i] = allocMipMap()
|
2849 | }
|
2850 |
|
2851 | if (typeof a0 === 'number' || !a0) {
|
2852 | var s = (a0 | 0) || 1
|
2853 | for (i = 0; i < 6; ++i) {
|
2854 | parseMipMapFromShape(faces[i], s, s)
|
2855 | }
|
2856 | } else if (typeof a0 === 'object') {
|
2857 | if (a1) {
|
2858 | parseMipMapFromObject(faces[0], a0)
|
2859 | parseMipMapFromObject(faces[1], a1)
|
2860 | parseMipMapFromObject(faces[2], a2)
|
2861 | parseMipMapFromObject(faces[3], a3)
|
2862 | parseMipMapFromObject(faces[4], a4)
|
2863 | parseMipMapFromObject(faces[5], a5)
|
2864 | } else {
|
2865 | parseTexInfo(texInfo, a0)
|
2866 | parseFlags(texture, a0)
|
2867 | if ('faces' in a0) {
|
2868 | var faceInput = a0.faces
|
2869 |
|
2870 | for (i = 0; i < 6; ++i) {
|
2871 |
|
2872 | copyFlags(faces[i], texture)
|
2873 | parseMipMapFromObject(faces[i], faceInput[i])
|
2874 | }
|
2875 | } else {
|
2876 | for (i = 0; i < 6; ++i) {
|
2877 | parseMipMapFromObject(faces[i], a0)
|
2878 | }
|
2879 | }
|
2880 | }
|
2881 | } else {
|
2882 |
|
2883 | }
|
2884 |
|
2885 | copyFlags(texture, faces[0])
|
2886 |
|
2887 | if (!limits.npotTextureCube) {
|
2888 |
|
2889 | }
|
2890 |
|
2891 | if (texInfo.genMipmaps) {
|
2892 | texture.mipmask = (faces[0].width << 1) - 1
|
2893 | } else {
|
2894 | texture.mipmask = faces[0].mipmask
|
2895 | }
|
2896 |
|
2897 |
|
2898 | texture.internalformat = faces[0].internalformat
|
2899 |
|
2900 | reglTextureCube.width = faces[0].width
|
2901 | reglTextureCube.height = faces[0].height
|
2902 |
|
2903 | tempBind(texture)
|
2904 | for (i = 0; i < 6; ++i) {
|
2905 | setMipMap(faces[i], GL_TEXTURE_CUBE_MAP_POSITIVE_X$1 + i)
|
2906 | }
|
2907 | setTexInfo(texInfo, GL_TEXTURE_CUBE_MAP$1)
|
2908 | tempRestore()
|
2909 |
|
2910 | if (config.profile) {
|
2911 | texture.stats.size = getTextureSize(
|
2912 | texture.internalformat,
|
2913 | texture.type,
|
2914 | reglTextureCube.width,
|
2915 | reglTextureCube.height,
|
2916 | texInfo.genMipmaps,
|
2917 | true)
|
2918 | }
|
2919 |
|
2920 | reglTextureCube.format = textureFormatsInvert[texture.internalformat]
|
2921 | reglTextureCube.type = textureTypesInvert[texture.type]
|
2922 |
|
2923 | reglTextureCube.mag = magFiltersInvert[texInfo.magFilter]
|
2924 | reglTextureCube.min = minFiltersInvert[texInfo.minFilter]
|
2925 |
|
2926 | reglTextureCube.wrapS = wrapModesInvert[texInfo.wrapS]
|
2927 | reglTextureCube.wrapT = wrapModesInvert[texInfo.wrapT]
|
2928 |
|
2929 | for (i = 0; i < 6; ++i) {
|
2930 | freeMipMap(faces[i])
|
2931 | }
|
2932 |
|
2933 | return reglTextureCube
|
2934 | }
|
2935 |
|
2936 | function subimage (face, image, x_, y_, level_) {
|
2937 |
|
2938 |
|
2939 |
|
2940 | var x = x_ | 0
|
2941 | var y = y_ | 0
|
2942 | var level = level_ | 0
|
2943 |
|
2944 | var imageData = allocImage()
|
2945 | copyFlags(imageData, texture)
|
2946 | imageData.width = 0
|
2947 | imageData.height = 0
|
2948 | parseImage(imageData, image)
|
2949 | imageData.width = imageData.width || ((texture.width >> level) - x)
|
2950 | imageData.height = imageData.height || ((texture.height >> level) - y)
|
2951 |
|
2952 |
|
2953 |
|
2954 |
|
2955 |
|
2956 |
|
2957 | tempBind(texture)
|
2958 | setSubImage(imageData, GL_TEXTURE_CUBE_MAP_POSITIVE_X$1 + face, x, y, level)
|
2959 | tempRestore()
|
2960 |
|
2961 | freeImage(imageData)
|
2962 |
|
2963 | return reglTextureCube
|
2964 | }
|
2965 |
|
2966 | function resize (radius_) {
|
2967 | var radius = radius_ | 0
|
2968 | if (radius === texture.width) {
|
2969 | return
|
2970 | }
|
2971 |
|
2972 | reglTextureCube.width = texture.width = radius
|
2973 | reglTextureCube.height = texture.height = radius
|
2974 |
|
2975 | tempBind(texture)
|
2976 | for (var i = 0; i < 6; ++i) {
|
2977 | for (var j = 0; texture.mipmask >> j; ++j) {
|
2978 | gl.texImage2D(
|
2979 | GL_TEXTURE_CUBE_MAP_POSITIVE_X$1 + i,
|
2980 | j,
|
2981 | texture.format,
|
2982 | radius >> j,
|
2983 | radius >> j,
|
2984 | 0,
|
2985 | texture.format,
|
2986 | texture.type,
|
2987 | null)
|
2988 | }
|
2989 | }
|
2990 | tempRestore()
|
2991 |
|
2992 | if (config.profile) {
|
2993 | texture.stats.size = getTextureSize(
|
2994 | texture.internalformat,
|
2995 | texture.type,
|
2996 | reglTextureCube.width,
|
2997 | reglTextureCube.height,
|
2998 | false,
|
2999 | true)
|
3000 | }
|
3001 |
|
3002 | return reglTextureCube
|
3003 | }
|
3004 |
|
3005 | reglTextureCube(a0, a1, a2, a3, a4, a5)
|
3006 |
|
3007 | reglTextureCube.subimage = subimage
|
3008 | reglTextureCube.resize = resize
|
3009 | reglTextureCube._reglType = 'textureCube'
|
3010 | reglTextureCube._texture = texture
|
3011 | if (config.profile) {
|
3012 | reglTextureCube.stats = texture.stats
|
3013 | }
|
3014 | reglTextureCube.destroy = function () {
|
3015 | texture.decRef()
|
3016 | }
|
3017 |
|
3018 | return reglTextureCube
|
3019 | }
|
3020 |
|
3021 |
|
3022 | function destroyTextures () {
|
3023 | for (var i = 0; i < numTexUnits; ++i) {
|
3024 | gl.activeTexture(GL_TEXTURE0$1 + i)
|
3025 | gl.bindTexture(GL_TEXTURE_2D$1, null)
|
3026 | textureUnits[i] = null
|
3027 | }
|
3028 | values(textureSet).forEach(destroy)
|
3029 |
|
3030 | stats.cubeCount = 0
|
3031 | stats.textureCount = 0
|
3032 | }
|
3033 |
|
3034 | if (config.profile) {
|
3035 | stats.getTotalTextureSize = function () {
|
3036 | var total = 0
|
3037 | Object.keys(textureSet).forEach(function (key) {
|
3038 | total += textureSet[key].stats.size
|
3039 | })
|
3040 | return total
|
3041 | }
|
3042 | }
|
3043 |
|
3044 | function restoreTextures () {
|
3045 | for (var i = 0; i < numTexUnits; ++i) {
|
3046 | var tex = textureUnits[i]
|
3047 | if (tex) {
|
3048 | tex.bindCount = 0
|
3049 | tex.unit = -1
|
3050 | textureUnits[i] = null
|
3051 | }
|
3052 | }
|
3053 |
|
3054 | values(textureSet).forEach(function (texture) {
|
3055 | texture.texture = gl.createTexture()
|
3056 | gl.bindTexture(texture.target, texture.texture)
|
3057 | for (var i = 0; i < 32; ++i) {
|
3058 | if ((texture.mipmask & (1 << i)) === 0) {
|
3059 | continue
|
3060 | }
|
3061 | if (texture.target === GL_TEXTURE_2D$1) {
|
3062 | gl.texImage2D(GL_TEXTURE_2D$1,
|
3063 | i,
|
3064 | texture.internalformat,
|
3065 | texture.width >> i,
|
3066 | texture.height >> i,
|
3067 | 0,
|
3068 | texture.internalformat,
|
3069 | texture.type,
|
3070 | null)
|
3071 | } else {
|
3072 | for (var j = 0; j < 6; ++j) {
|
3073 | gl.texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X$1 + j,
|
3074 | i,
|
3075 | texture.internalformat,
|
3076 | texture.width >> i,
|
3077 | texture.height >> i,
|
3078 | 0,
|
3079 | texture.internalformat,
|
3080 | texture.type,
|
3081 | null)
|
3082 | }
|
3083 | }
|
3084 | }
|
3085 | setTexInfo(texture.texInfo, texture.target)
|
3086 | })
|
3087 | }
|
3088 |
|
3089 | return {
|
3090 | create2D: createTexture2D,
|
3091 | createCube: createTextureCube,
|
3092 | clear: destroyTextures,
|
3093 | getTexture: function (wrapper) {
|
3094 | return null
|
3095 | },
|
3096 | restore: restoreTextures
|
3097 | }
|
3098 | }
|
3099 |
|
3100 | var GL_RENDERBUFFER = 0x8D41
|
3101 |
|
3102 | var GL_RGBA4$1 = 0x8056
|
3103 | var GL_RGB5_A1$1 = 0x8057
|
3104 | var GL_RGB565$1 = 0x8D62
|
3105 | var GL_DEPTH_COMPONENT16 = 0x81A5
|
3106 | var GL_STENCIL_INDEX8 = 0x8D48
|
3107 | var GL_DEPTH_STENCIL$1 = 0x84F9
|
3108 |
|
3109 | var GL_SRGB8_ALPHA8_EXT = 0x8C43
|
3110 |
|
3111 | var GL_RGBA32F_EXT = 0x8814
|
3112 |
|
3113 | var GL_RGBA16F_EXT = 0x881A
|
3114 | var GL_RGB16F_EXT = 0x881B
|
3115 |
|
3116 | var FORMAT_SIZES = []
|
3117 |
|
3118 | FORMAT_SIZES[GL_RGBA4$1] = 2
|
3119 | FORMAT_SIZES[GL_RGB5_A1$1] = 2
|
3120 | FORMAT_SIZES[GL_RGB565$1] = 2
|
3121 |
|
3122 | FORMAT_SIZES[GL_DEPTH_COMPONENT16] = 2
|
3123 | FORMAT_SIZES[GL_STENCIL_INDEX8] = 1
|
3124 | FORMAT_SIZES[GL_DEPTH_STENCIL$1] = 4
|
3125 |
|
3126 | FORMAT_SIZES[GL_SRGB8_ALPHA8_EXT] = 4
|
3127 | FORMAT_SIZES[GL_RGBA32F_EXT] = 16
|
3128 | FORMAT_SIZES[GL_RGBA16F_EXT] = 8
|
3129 | FORMAT_SIZES[GL_RGB16F_EXT] = 6
|
3130 |
|
3131 | function getRenderbufferSize (format, width, height) {
|
3132 | return FORMAT_SIZES[format] * width * height
|
3133 | }
|
3134 |
|
3135 | var wrapRenderbuffers = function (gl, extensions, limits, stats, config) {
|
3136 | var formatTypes = {
|
3137 | 'rgba4': GL_RGBA4$1,
|
3138 | 'rgb565': GL_RGB565$1,
|
3139 | 'rgb5 a1': GL_RGB5_A1$1,
|
3140 | 'depth': GL_DEPTH_COMPONENT16,
|
3141 | 'stencil': GL_STENCIL_INDEX8,
|
3142 | 'depth stencil': GL_DEPTH_STENCIL$1
|
3143 | }
|
3144 |
|
3145 | if (extensions.ext_srgb) {
|
3146 | formatTypes['srgba'] = GL_SRGB8_ALPHA8_EXT
|
3147 | }
|
3148 |
|
3149 | if (extensions.ext_color_buffer_half_float) {
|
3150 | formatTypes['rgba16f'] = GL_RGBA16F_EXT
|
3151 | formatTypes['rgb16f'] = GL_RGB16F_EXT
|
3152 | }
|
3153 |
|
3154 | if (extensions.webgl_color_buffer_float) {
|
3155 | formatTypes['rgba32f'] = GL_RGBA32F_EXT
|
3156 | }
|
3157 |
|
3158 | var formatTypesInvert = []
|
3159 | Object.keys(formatTypes).forEach(function (key) {
|
3160 | var val = formatTypes[key]
|
3161 | formatTypesInvert[val] = key
|
3162 | })
|
3163 |
|
3164 | var renderbufferCount = 0
|
3165 | var renderbufferSet = {}
|
3166 |
|
3167 | function REGLRenderbuffer (renderbuffer) {
|
3168 | this.id = renderbufferCount++
|
3169 | this.refCount = 1
|
3170 |
|
3171 | this.renderbuffer = renderbuffer
|
3172 |
|
3173 | this.format = GL_RGBA4$1
|
3174 | this.width = 0
|
3175 | this.height = 0
|
3176 |
|
3177 | if (config.profile) {
|
3178 | this.stats = { size: 0 }
|
3179 | }
|
3180 | }
|
3181 |
|
3182 | REGLRenderbuffer.prototype.decRef = function () {
|
3183 | if (--this.refCount <= 0) {
|
3184 | destroy(this)
|
3185 | }
|
3186 | }
|
3187 |
|
3188 | function destroy (rb) {
|
3189 | var handle = rb.renderbuffer
|
3190 |
|
3191 | gl.bindRenderbuffer(GL_RENDERBUFFER, null)
|
3192 | gl.deleteRenderbuffer(handle)
|
3193 | rb.renderbuffer = null
|
3194 | rb.refCount = 0
|
3195 | delete renderbufferSet[rb.id]
|
3196 | stats.renderbufferCount--
|
3197 | }
|
3198 |
|
3199 | function createRenderbuffer (a, b) {
|
3200 | var renderbuffer = new REGLRenderbuffer(gl.createRenderbuffer())
|
3201 | renderbufferSet[renderbuffer.id] = renderbuffer
|
3202 | stats.renderbufferCount++
|
3203 |
|
3204 | function reglRenderbuffer (a, b) {
|
3205 | var w = 0
|
3206 | var h = 0
|
3207 | var format = GL_RGBA4$1
|
3208 |
|
3209 | if (typeof a === 'object' && a) {
|
3210 | var options = a
|
3211 | if ('shape' in options) {
|
3212 | var shape = options.shape
|
3213 |
|
3214 | w = shape[0] | 0
|
3215 | h = shape[1] | 0
|
3216 | } else {
|
3217 | if ('radius' in options) {
|
3218 | w = h = options.radius | 0
|
3219 | }
|
3220 | if ('width' in options) {
|
3221 | w = options.width | 0
|
3222 | }
|
3223 | if ('height' in options) {
|
3224 | h = options.height | 0
|
3225 | }
|
3226 | }
|
3227 | if ('format' in options) {
|
3228 |
|
3229 | format = formatTypes[options.format]
|
3230 | }
|
3231 | } else if (typeof a === 'number') {
|
3232 | w = a | 0
|
3233 | if (typeof b === 'number') {
|
3234 | h = b | 0
|
3235 | } else {
|
3236 | h = w
|
3237 | }
|
3238 | } else if (!a) {
|
3239 | w = h = 1
|
3240 | } else {
|
3241 |
|
3242 | }
|
3243 |
|
3244 |
|
3245 |
|
3246 |
|
3247 | if (w === renderbuffer.width &&
|
3248 | h === renderbuffer.height &&
|
3249 | format === renderbuffer.format) {
|
3250 | return
|
3251 | }
|
3252 |
|
3253 | reglRenderbuffer.width = renderbuffer.width = w
|
3254 | reglRenderbuffer.height = renderbuffer.height = h
|
3255 | renderbuffer.format = format
|
3256 |
|
3257 | gl.bindRenderbuffer(GL_RENDERBUFFER, renderbuffer.renderbuffer)
|
3258 | gl.renderbufferStorage(GL_RENDERBUFFER, format, w, h)
|
3259 |
|
3260 |
|
3261 |
|
3262 | if (config.profile) {
|
3263 | renderbuffer.stats.size = getRenderbufferSize(renderbuffer.format, renderbuffer.width, renderbuffer.height)
|
3264 | }
|
3265 | reglRenderbuffer.format = formatTypesInvert[renderbuffer.format]
|
3266 |
|
3267 | return reglRenderbuffer
|
3268 | }
|
3269 |
|
3270 | function resize (w_, h_) {
|
3271 | var w = w_ | 0
|
3272 | var h = (h_ | 0) || w
|
3273 |
|
3274 | if (w === renderbuffer.width && h === renderbuffer.height) {
|
3275 | return reglRenderbuffer
|
3276 | }
|
3277 |
|
3278 |
|
3279 |
|
3280 |
|
3281 | reglRenderbuffer.width = renderbuffer.width = w
|
3282 | reglRenderbuffer.height = renderbuffer.height = h
|
3283 |
|
3284 | gl.bindRenderbuffer(GL_RENDERBUFFER, renderbuffer.renderbuffer)
|
3285 | gl.renderbufferStorage(GL_RENDERBUFFER, renderbuffer.format, w, h)
|
3286 |
|
3287 |
|
3288 |
|
3289 |
|
3290 | if (config.profile) {
|
3291 | renderbuffer.stats.size = getRenderbufferSize(
|
3292 | renderbuffer.format, renderbuffer.width, renderbuffer.height)
|
3293 | }
|
3294 |
|
3295 | return reglRenderbuffer
|
3296 | }
|
3297 |
|
3298 | reglRenderbuffer(a, b)
|
3299 |
|
3300 | reglRenderbuffer.resize = resize
|
3301 | reglRenderbuffer._reglType = 'renderbuffer'
|
3302 | reglRenderbuffer._renderbuffer = renderbuffer
|
3303 | if (config.profile) {
|
3304 | reglRenderbuffer.stats = renderbuffer.stats
|
3305 | }
|
3306 | reglRenderbuffer.destroy = function () {
|
3307 | renderbuffer.decRef()
|
3308 | }
|
3309 |
|
3310 | return reglRenderbuffer
|
3311 | }
|
3312 |
|
3313 | if (config.profile) {
|
3314 | stats.getTotalRenderbufferSize = function () {
|
3315 | var total = 0
|
3316 | Object.keys(renderbufferSet).forEach(function (key) {
|
3317 | total += renderbufferSet[key].stats.size
|
3318 | })
|
3319 | return total
|
3320 | }
|
3321 | }
|
3322 |
|
3323 | function restoreRenderbuffers () {
|
3324 | values(renderbufferSet).forEach(function (rb) {
|
3325 | rb.renderbuffer = gl.createRenderbuffer()
|
3326 | gl.bindRenderbuffer(GL_RENDERBUFFER, rb.renderbuffer)
|
3327 | gl.renderbufferStorage(GL_RENDERBUFFER, rb.format, rb.width, rb.height)
|
3328 | })
|
3329 | gl.bindRenderbuffer(GL_RENDERBUFFER, null)
|
3330 | }
|
3331 |
|
3332 | return {
|
3333 | create: createRenderbuffer,
|
3334 | clear: function () {
|
3335 | values(renderbufferSet).forEach(destroy)
|
3336 | },
|
3337 | restore: restoreRenderbuffers
|
3338 | }
|
3339 | }
|
3340 |
|
3341 |
|
3342 | var GL_FRAMEBUFFER$1 = 0x8D40
|
3343 | var GL_RENDERBUFFER$1 = 0x8D41
|
3344 |
|
3345 | var GL_TEXTURE_2D$2 = 0x0DE1
|
3346 | var GL_TEXTURE_CUBE_MAP_POSITIVE_X$2 = 0x8515
|
3347 |
|
3348 | var GL_COLOR_ATTACHMENT0$1 = 0x8CE0
|
3349 | var GL_DEPTH_ATTACHMENT = 0x8D00
|
3350 | var GL_STENCIL_ATTACHMENT = 0x8D20
|
3351 | var GL_DEPTH_STENCIL_ATTACHMENT = 0x821A
|
3352 |
|
3353 | var GL_FRAMEBUFFER_COMPLETE$1 = 0x8CD5
|
3354 | var GL_HALF_FLOAT_OES$1 = 0x8D61
|
3355 | var GL_UNSIGNED_BYTE$5 = 0x1401
|
3356 | var GL_FLOAT$4 = 0x1406
|
3357 |
|
3358 | var GL_RGB$1 = 0x1907
|
3359 | var GL_RGBA$2 = 0x1908
|
3360 |
|
3361 |
|
3362 |
|
3363 | var textureFormatChannels = []
|
3364 | textureFormatChannels[GL_RGBA$2] = 4
|
3365 | textureFormatChannels[GL_RGB$1] = 3
|
3366 |
|
3367 |
|
3368 |
|
3369 | var textureTypeSizes = []
|
3370 | textureTypeSizes[GL_UNSIGNED_BYTE$5] = 1
|
3371 | textureTypeSizes[GL_FLOAT$4] = 4
|
3372 | textureTypeSizes[GL_HALF_FLOAT_OES$1] = 2
|
3373 |
|
3374 | function wrapFBOState (
|
3375 | gl,
|
3376 | extensions,
|
3377 | limits,
|
3378 | textureState,
|
3379 | renderbufferState,
|
3380 | stats) {
|
3381 | var framebufferState = {
|
3382 | cur: null,
|
3383 | next: null,
|
3384 | dirty: false,
|
3385 | setFBO: null
|
3386 | }
|
3387 |
|
3388 | var colorTextureFormats = ['rgba']
|
3389 | var colorRenderbufferFormats = ['rgba4', 'rgb565', 'rgb5 a1']
|
3390 |
|
3391 | if (extensions.ext_srgb) {
|
3392 | colorRenderbufferFormats.push('srgba')
|
3393 | }
|
3394 |
|
3395 | if (extensions.ext_color_buffer_half_float) {
|
3396 | colorRenderbufferFormats.push('rgba16f', 'rgb16f')
|
3397 | }
|
3398 |
|
3399 | if (extensions.webgl_color_buffer_float) {
|
3400 | colorRenderbufferFormats.push('rgba32f')
|
3401 | }
|
3402 |
|
3403 | var colorTypes = ['uint8']
|
3404 | if (extensions.oes_texture_half_float) {
|
3405 | colorTypes.push('half float', 'float16')
|
3406 | }
|
3407 | if (extensions.oes_texture_float) {
|
3408 | colorTypes.push('float', 'float32')
|
3409 | }
|
3410 |
|
3411 | function FramebufferAttachment (target, texture, renderbuffer) {
|
3412 | this.target = target
|
3413 | this.texture = texture
|
3414 | this.renderbuffer = renderbuffer
|
3415 |
|
3416 | var w = 0
|
3417 | var h = 0
|
3418 | if (texture) {
|
3419 | w = texture.width
|
3420 | h = texture.height
|
3421 | } else if (renderbuffer) {
|
3422 | w = renderbuffer.width
|
3423 | h = renderbuffer.height
|
3424 | }
|
3425 | this.width = w
|
3426 | this.height = h
|
3427 | }
|
3428 |
|
3429 | function decRef (attachment) {
|
3430 | if (attachment) {
|
3431 | if (attachment.texture) {
|
3432 | attachment.texture._texture.decRef()
|
3433 | }
|
3434 | if (attachment.renderbuffer) {
|
3435 | attachment.renderbuffer._renderbuffer.decRef()
|
3436 | }
|
3437 | }
|
3438 | }
|
3439 |
|
3440 | function incRefAndCheckShape (attachment, width, height) {
|
3441 | if (!attachment) {
|
3442 | return
|
3443 | }
|
3444 | if (attachment.texture) {
|
3445 | var texture = attachment.texture._texture
|
3446 | var tw = Math.max(1, texture.width)
|
3447 | var th = Math.max(1, texture.height)
|
3448 |
|
3449 | texture.refCount += 1
|
3450 | } else {
|
3451 | var renderbuffer = attachment.renderbuffer._renderbuffer
|
3452 |
|
3453 | renderbuffer.refCount += 1
|
3454 | }
|
3455 | }
|
3456 |
|
3457 | function attach (location, attachment) {
|
3458 | if (attachment) {
|
3459 | if (attachment.texture) {
|
3460 | gl.framebufferTexture2D(
|
3461 | GL_FRAMEBUFFER$1,
|
3462 | location,
|
3463 | attachment.target,
|
3464 | attachment.texture._texture.texture,
|
3465 | 0)
|
3466 | } else {
|
3467 | gl.framebufferRenderbuffer(
|
3468 | GL_FRAMEBUFFER$1,
|
3469 | location,
|
3470 | GL_RENDERBUFFER$1,
|
3471 | attachment.renderbuffer._renderbuffer.renderbuffer)
|
3472 | }
|
3473 | }
|
3474 | }
|
3475 |
|
3476 | function parseAttachment (attachment) {
|
3477 | var target = GL_TEXTURE_2D$2
|
3478 | var texture = null
|
3479 | var renderbuffer = null
|
3480 |
|
3481 | var data = attachment
|
3482 | if (typeof attachment === 'object') {
|
3483 | data = attachment.data
|
3484 | if ('target' in attachment) {
|
3485 | target = attachment.target | 0
|
3486 | }
|
3487 | }
|
3488 |
|
3489 |
|
3490 |
|
3491 | var type = data._reglType
|
3492 | if (type === 'texture2d') {
|
3493 | texture = data
|
3494 |
|
3495 | } else if (type === 'textureCube') {
|
3496 | texture = data
|
3497 |
|
3498 | } else if (type === 'renderbuffer') {
|
3499 | renderbuffer = data
|
3500 | target = GL_RENDERBUFFER$1
|
3501 | } else {
|
3502 |
|
3503 | }
|
3504 |
|
3505 | return new FramebufferAttachment(target, texture, renderbuffer)
|
3506 | }
|
3507 |
|
3508 | function allocAttachment (
|
3509 | width,
|
3510 | height,
|
3511 | isTexture,
|
3512 | format,
|
3513 | type) {
|
3514 | if (isTexture) {
|
3515 | var texture = textureState.create2D({
|
3516 | width: width,
|
3517 | height: height,
|
3518 | format: format,
|
3519 | type: type
|
3520 | })
|
3521 | texture._texture.refCount = 0
|
3522 | return new FramebufferAttachment(GL_TEXTURE_2D$2, texture, null)
|
3523 | } else {
|
3524 | var rb = renderbufferState.create({
|
3525 | width: width,
|
3526 | height: height,
|
3527 | format: format
|
3528 | })
|
3529 | rb._renderbuffer.refCount = 0
|
3530 | return new FramebufferAttachment(GL_RENDERBUFFER$1, null, rb)
|
3531 | }
|
3532 | }
|
3533 |
|
3534 | function unwrapAttachment (attachment) {
|
3535 | return attachment && (attachment.texture || attachment.renderbuffer)
|
3536 | }
|
3537 |
|
3538 | function resizeAttachment (attachment, w, h) {
|
3539 | if (attachment) {
|
3540 | if (attachment.texture) {
|
3541 | attachment.texture.resize(w, h)
|
3542 | } else if (attachment.renderbuffer) {
|
3543 | attachment.renderbuffer.resize(w, h)
|
3544 | }
|
3545 | attachment.width = w
|
3546 | attachment.height = h
|
3547 | }
|
3548 | }
|
3549 |
|
3550 | var framebufferCount = 0
|
3551 | var framebufferSet = {}
|
3552 |
|
3553 | function REGLFramebuffer () {
|
3554 | this.id = framebufferCount++
|
3555 | framebufferSet[this.id] = this
|
3556 |
|
3557 | this.framebuffer = gl.createFramebuffer()
|
3558 | this.width = 0
|
3559 | this.height = 0
|
3560 |
|
3561 | this.colorAttachments = []
|
3562 | this.depthAttachment = null
|
3563 | this.stencilAttachment = null
|
3564 | this.depthStencilAttachment = null
|
3565 | }
|
3566 |
|
3567 | function decFBORefs (framebuffer) {
|
3568 | framebuffer.colorAttachments.forEach(decRef)
|
3569 | decRef(framebuffer.depthAttachment)
|
3570 | decRef(framebuffer.stencilAttachment)
|
3571 | decRef(framebuffer.depthStencilAttachment)
|
3572 | }
|
3573 |
|
3574 | function destroy (framebuffer) {
|
3575 | var handle = framebuffer.framebuffer
|
3576 |
|
3577 | gl.deleteFramebuffer(handle)
|
3578 | framebuffer.framebuffer = null
|
3579 | stats.framebufferCount--
|
3580 | delete framebufferSet[framebuffer.id]
|
3581 | }
|
3582 |
|
3583 | function updateFramebuffer (framebuffer) {
|
3584 | var i
|
3585 |
|
3586 | gl.bindFramebuffer(GL_FRAMEBUFFER$1, framebuffer.framebuffer)
|
3587 | var colorAttachments = framebuffer.colorAttachments
|
3588 | for (i = 0; i < colorAttachments.length; ++i) {
|
3589 | attach(GL_COLOR_ATTACHMENT0$1 + i, colorAttachments[i])
|
3590 | }
|
3591 | for (i = colorAttachments.length; i < limits.maxColorAttachments; ++i) {
|
3592 | gl.framebufferTexture2D(
|
3593 | GL_FRAMEBUFFER$1,
|
3594 | GL_COLOR_ATTACHMENT0$1 + i,
|
3595 | GL_TEXTURE_2D$2,
|
3596 | null,
|
3597 | 0)
|
3598 | }
|
3599 |
|
3600 | gl.framebufferTexture2D(
|
3601 | GL_FRAMEBUFFER$1,
|
3602 | GL_DEPTH_STENCIL_ATTACHMENT,
|
3603 | GL_TEXTURE_2D$2,
|
3604 | null,
|
3605 | 0)
|
3606 | gl.framebufferTexture2D(
|
3607 | GL_FRAMEBUFFER$1,
|
3608 | GL_DEPTH_ATTACHMENT,
|
3609 | GL_TEXTURE_2D$2,
|
3610 | null,
|
3611 | 0)
|
3612 | gl.framebufferTexture2D(
|
3613 | GL_FRAMEBUFFER$1,
|
3614 | GL_STENCIL_ATTACHMENT,
|
3615 | GL_TEXTURE_2D$2,
|
3616 | null,
|
3617 | 0)
|
3618 |
|
3619 | attach(GL_DEPTH_ATTACHMENT, framebuffer.depthAttachment)
|
3620 | attach(GL_STENCIL_ATTACHMENT, framebuffer.stencilAttachment)
|
3621 | attach(GL_DEPTH_STENCIL_ATTACHMENT, framebuffer.depthStencilAttachment)
|
3622 |
|
3623 |
|
3624 | var status = gl.checkFramebufferStatus(GL_FRAMEBUFFER$1)
|
3625 | if (!gl.isContextLost() && status !== GL_FRAMEBUFFER_COMPLETE$1) {
|
3626 |
|
3627 | }
|
3628 |
|
3629 | gl.bindFramebuffer(GL_FRAMEBUFFER$1, framebufferState.next ? framebufferState.next.framebuffer : null)
|
3630 | framebufferState.cur = framebufferState.next
|
3631 |
|
3632 |
|
3633 |
|
3634 | gl.getError()
|
3635 | }
|
3636 |
|
3637 | function createFBO (a0, a1) {
|
3638 | var framebuffer = new REGLFramebuffer()
|
3639 | stats.framebufferCount++
|
3640 |
|
3641 | function reglFramebuffer (a, b) {
|
3642 | var i
|
3643 |
|
3644 |
|
3645 |
|
3646 | var width = 0
|
3647 | var height = 0
|
3648 |
|
3649 | var needsDepth = true
|
3650 | var needsStencil = true
|
3651 |
|
3652 | var colorBuffer = null
|
3653 | var colorTexture = true
|
3654 | var colorFormat = 'rgba'
|
3655 | var colorType = 'uint8'
|
3656 | var colorCount = 1
|
3657 |
|
3658 | var depthBuffer = null
|
3659 | var stencilBuffer = null
|
3660 | var depthStencilBuffer = null
|
3661 | var depthStencilTexture = false
|
3662 |
|
3663 | if (typeof a === 'number') {
|
3664 | width = a | 0
|
3665 | height = (b | 0) || width
|
3666 | } else if (!a) {
|
3667 | width = height = 1
|
3668 | } else {
|
3669 |
|
3670 | var options = a
|
3671 |
|
3672 | if ('shape' in options) {
|
3673 | var shape = options.shape
|
3674 |
|
3675 | width = shape[0]
|
3676 | height = shape[1]
|
3677 | } else {
|
3678 | if ('radius' in options) {
|
3679 | width = height = options.radius
|
3680 | }
|
3681 | if ('width' in options) {
|
3682 | width = options.width
|
3683 | }
|
3684 | if ('height' in options) {
|
3685 | height = options.height
|
3686 | }
|
3687 | }
|
3688 |
|
3689 | if ('color' in options ||
|
3690 | 'colors' in options) {
|
3691 | colorBuffer =
|
3692 | options.color ||
|
3693 | options.colors
|
3694 | if (Array.isArray(colorBuffer)) {
|
3695 |
|
3696 | }
|
3697 | }
|
3698 |
|
3699 | if (!colorBuffer) {
|
3700 | if ('colorCount' in options) {
|
3701 | colorCount = options.colorCount | 0
|
3702 |
|
3703 | }
|
3704 |
|
3705 | if ('colorTexture' in options) {
|
3706 | colorTexture = !!options.colorTexture
|
3707 | colorFormat = 'rgba4'
|
3708 | }
|
3709 |
|
3710 | if ('colorType' in options) {
|
3711 | colorType = options.colorType
|
3712 | if (!colorTexture) {
|
3713 | if (colorType === 'half float' || colorType === 'float16') {
|
3714 |
|
3715 | colorFormat = 'rgba16f'
|
3716 | } else if (colorType === 'float' || colorType === 'float32') {
|
3717 |
|
3718 | colorFormat = 'rgba32f'
|
3719 | }
|
3720 | } else {
|
3721 |
|
3722 |
|
3723 | }
|
3724 |
|
3725 | }
|
3726 |
|
3727 | if ('colorFormat' in options) {
|
3728 | colorFormat = options.colorFormat
|
3729 | if (colorTextureFormats.indexOf(colorFormat) >= 0) {
|
3730 | colorTexture = true
|
3731 | } else if (colorRenderbufferFormats.indexOf(colorFormat) >= 0) {
|
3732 | colorTexture = false
|
3733 | } else {
|
3734 | if (colorTexture) {
|
3735 |
|
3736 | } else {
|
3737 |
|
3738 | }
|
3739 | }
|
3740 | }
|
3741 | }
|
3742 |
|
3743 | if ('depthTexture' in options || 'depthStencilTexture' in options) {
|
3744 | depthStencilTexture = !!(options.depthTexture ||
|
3745 | options.depthStencilTexture)
|
3746 |
|
3747 | }
|
3748 |
|
3749 | if ('depth' in options) {
|
3750 | if (typeof options.depth === 'boolean') {
|
3751 | needsDepth = options.depth
|
3752 | } else {
|
3753 | depthBuffer = options.depth
|
3754 | needsStencil = false
|
3755 | }
|
3756 | }
|
3757 |
|
3758 | if ('stencil' in options) {
|
3759 | if (typeof options.stencil === 'boolean') {
|
3760 | needsStencil = options.stencil
|
3761 | } else {
|
3762 | stencilBuffer = options.stencil
|
3763 | needsDepth = false
|
3764 | }
|
3765 | }
|
3766 |
|
3767 | if ('depthStencil' in options) {
|
3768 | if (typeof options.depthStencil === 'boolean') {
|
3769 | needsDepth = needsStencil = options.depthStencil
|
3770 | } else {
|
3771 | depthStencilBuffer = options.depthStencil
|
3772 | needsDepth = false
|
3773 | needsStencil = false
|
3774 | }
|
3775 | }
|
3776 | }
|
3777 |
|
3778 |
|
3779 | var colorAttachments = null
|
3780 | var depthAttachment = null
|
3781 | var stencilAttachment = null
|
3782 | var depthStencilAttachment = null
|
3783 |
|
3784 |
|
3785 | if (Array.isArray(colorBuffer)) {
|
3786 | colorAttachments = colorBuffer.map(parseAttachment)
|
3787 | } else if (colorBuffer) {
|
3788 | colorAttachments = [parseAttachment(colorBuffer)]
|
3789 | } else {
|
3790 | colorAttachments = new Array(colorCount)
|
3791 | for (i = 0; i < colorCount; ++i) {
|
3792 | colorAttachments[i] = allocAttachment(
|
3793 | width,
|
3794 | height,
|
3795 | colorTexture,
|
3796 | colorFormat,
|
3797 | colorType)
|
3798 | }
|
3799 | }
|
3800 |
|
3801 |
|
3802 |
|
3803 |
|
3804 | width = width || colorAttachments[0].width
|
3805 | height = height || colorAttachments[0].height
|
3806 |
|
3807 | if (depthBuffer) {
|
3808 | depthAttachment = parseAttachment(depthBuffer)
|
3809 | } else if (needsDepth && !needsStencil) {
|
3810 | depthAttachment = allocAttachment(
|
3811 | width,
|
3812 | height,
|
3813 | depthStencilTexture,
|
3814 | 'depth',
|
3815 | 'uint32')
|
3816 | }
|
3817 |
|
3818 | if (stencilBuffer) {
|
3819 | stencilAttachment = parseAttachment(stencilBuffer)
|
3820 | } else if (needsStencil && !needsDepth) {
|
3821 | stencilAttachment = allocAttachment(
|
3822 | width,
|
3823 | height,
|
3824 | false,
|
3825 | 'stencil',
|
3826 | 'uint8')
|
3827 | }
|
3828 |
|
3829 | if (depthStencilBuffer) {
|
3830 | depthStencilAttachment = parseAttachment(depthStencilBuffer)
|
3831 | } else if (!depthBuffer && !stencilBuffer && needsStencil && needsDepth) {
|
3832 | depthStencilAttachment = allocAttachment(
|
3833 | width,
|
3834 | height,
|
3835 | depthStencilTexture,
|
3836 | 'depth stencil',
|
3837 | 'depth stencil')
|
3838 | }
|
3839 |
|
3840 |
|
3841 |
|
3842 | var commonColorAttachmentSize = null
|
3843 |
|
3844 | for (i = 0; i < colorAttachments.length; ++i) {
|
3845 | incRefAndCheckShape(colorAttachments[i], width, height)
|
3846 |
|
3847 |
|
3848 | if (colorAttachments[i] && colorAttachments[i].texture) {
|
3849 | var colorAttachmentSize =
|
3850 | textureFormatChannels[colorAttachments[i].texture._texture.format] *
|
3851 | textureTypeSizes[colorAttachments[i].texture._texture.type]
|
3852 |
|
3853 | if (commonColorAttachmentSize === null) {
|
3854 | commonColorAttachmentSize = colorAttachmentSize
|
3855 | } else {
|
3856 |
|
3857 |
|
3858 |
|
3859 |
|
3860 | }
|
3861 | }
|
3862 | }
|
3863 | incRefAndCheckShape(depthAttachment, width, height)
|
3864 |
|
3865 | incRefAndCheckShape(stencilAttachment, width, height)
|
3866 |
|
3867 | incRefAndCheckShape(depthStencilAttachment, width, height)
|
3868 |
|
3869 |
|
3870 |
|
3871 | decFBORefs(framebuffer)
|
3872 |
|
3873 | framebuffer.width = width
|
3874 | framebuffer.height = height
|
3875 |
|
3876 | framebuffer.colorAttachments = colorAttachments
|
3877 | framebuffer.depthAttachment = depthAttachment
|
3878 | framebuffer.stencilAttachment = stencilAttachment
|
3879 | framebuffer.depthStencilAttachment = depthStencilAttachment
|
3880 |
|
3881 | reglFramebuffer.color = colorAttachments.map(unwrapAttachment)
|
3882 | reglFramebuffer.depth = unwrapAttachment(depthAttachment)
|
3883 | reglFramebuffer.stencil = unwrapAttachment(stencilAttachment)
|
3884 | reglFramebuffer.depthStencil = unwrapAttachment(depthStencilAttachment)
|
3885 |
|
3886 | reglFramebuffer.width = framebuffer.width
|
3887 | reglFramebuffer.height = framebuffer.height
|
3888 |
|
3889 | updateFramebuffer(framebuffer)
|
3890 |
|
3891 | return reglFramebuffer
|
3892 | }
|
3893 |
|
3894 | function resize (w_, h_) {
|
3895 |
|
3896 |
|
3897 | var w = Math.max(w_ | 0, 1)
|
3898 | var h = Math.max((h_ | 0) || w, 1)
|
3899 | if (w === framebuffer.width && h === framebuffer.height) {
|
3900 | return reglFramebuffer
|
3901 | }
|
3902 |
|
3903 |
|
3904 | var colorAttachments = framebuffer.colorAttachments
|
3905 | for (var i = 0; i < colorAttachments.length; ++i) {
|
3906 | resizeAttachment(colorAttachments[i], w, h)
|
3907 | }
|
3908 | resizeAttachment(framebuffer.depthAttachment, w, h)
|
3909 | resizeAttachment(framebuffer.stencilAttachment, w, h)
|
3910 | resizeAttachment(framebuffer.depthStencilAttachment, w, h)
|
3911 |
|
3912 | framebuffer.width = reglFramebuffer.width = w
|
3913 | framebuffer.height = reglFramebuffer.height = h
|
3914 |
|
3915 | updateFramebuffer(framebuffer)
|
3916 |
|
3917 | return reglFramebuffer
|
3918 | }
|
3919 |
|
3920 | reglFramebuffer(a0, a1)
|
3921 |
|
3922 | return extend(reglFramebuffer, {
|
3923 | resize: resize,
|
3924 | _reglType: 'framebuffer',
|
3925 | _framebuffer: framebuffer,
|
3926 | destroy: function () {
|
3927 | destroy(framebuffer)
|
3928 | decFBORefs(framebuffer)
|
3929 | },
|
3930 | use: function (block) {
|
3931 | framebufferState.setFBO({
|
3932 | framebuffer: reglFramebuffer
|
3933 | }, block)
|
3934 | }
|
3935 | })
|
3936 | }
|
3937 |
|
3938 | function createCubeFBO (options) {
|
3939 | var faces = Array(6)
|
3940 |
|
3941 | function reglFramebufferCube (a) {
|
3942 | var i
|
3943 |
|
3944 |
|
3945 |
|
3946 | var params = {
|
3947 | color: null
|
3948 | }
|
3949 |
|
3950 | var radius = 0
|
3951 |
|
3952 | var colorBuffer = null
|
3953 | var colorFormat = 'rgba'
|
3954 | var colorType = 'uint8'
|
3955 | var colorCount = 1
|
3956 |
|
3957 | if (typeof a === 'number') {
|
3958 | radius = a | 0
|
3959 | } else if (!a) {
|
3960 | radius = 1
|
3961 | } else {
|
3962 |
|
3963 | var options = a
|
3964 |
|
3965 | if ('shape' in options) {
|
3966 | var shape = options.shape
|
3967 |
|
3968 |
|
3969 | radius = shape[0]
|
3970 | } else {
|
3971 | if ('radius' in options) {
|
3972 | radius = options.radius | 0
|
3973 | }
|
3974 | if ('width' in options) {
|
3975 | radius = options.width | 0
|
3976 | if ('height' in options) {
|
3977 |
|
3978 | }
|
3979 | } else if ('height' in options) {
|
3980 | radius = options.height | 0
|
3981 | }
|
3982 | }
|
3983 |
|
3984 | if ('color' in options ||
|
3985 | 'colors' in options) {
|
3986 | colorBuffer =
|
3987 | options.color ||
|
3988 | options.colors
|
3989 | if (Array.isArray(colorBuffer)) {
|
3990 |
|
3991 | }
|
3992 | }
|
3993 |
|
3994 | if (!colorBuffer) {
|
3995 | if ('colorCount' in options) {
|
3996 | colorCount = options.colorCount | 0
|
3997 |
|
3998 | }
|
3999 |
|
4000 | if ('colorType' in options) {
|
4001 |
|
4002 | colorType = options.colorType
|
4003 | }
|
4004 |
|
4005 | if ('colorFormat' in options) {
|
4006 | colorFormat = options.colorFormat
|
4007 |
|
4008 | }
|
4009 | }
|
4010 |
|
4011 | if ('depth' in options) {
|
4012 | params.depth = options.depth
|
4013 | }
|
4014 |
|
4015 | if ('stencil' in options) {
|
4016 | params.stencil = options.stencil
|
4017 | }
|
4018 |
|
4019 | if ('depthStencil' in options) {
|
4020 | params.depthStencil = options.depthStencil
|
4021 | }
|
4022 | }
|
4023 |
|
4024 | var colorCubes
|
4025 | if (colorBuffer) {
|
4026 | if (Array.isArray(colorBuffer)) {
|
4027 | colorCubes = []
|
4028 | for (i = 0; i < colorBuffer.length; ++i) {
|
4029 | colorCubes[i] = colorBuffer[i]
|
4030 | }
|
4031 | } else {
|
4032 | colorCubes = [ colorBuffer ]
|
4033 | }
|
4034 | } else {
|
4035 | colorCubes = Array(colorCount)
|
4036 | var cubeMapParams = {
|
4037 | radius: radius,
|
4038 | format: colorFormat,
|
4039 | type: colorType
|
4040 | }
|
4041 | for (i = 0; i < colorCount; ++i) {
|
4042 | colorCubes[i] = textureState.createCube(cubeMapParams)
|
4043 | }
|
4044 | }
|
4045 |
|
4046 |
|
4047 | params.color = Array(colorCubes.length)
|
4048 | for (i = 0; i < colorCubes.length; ++i) {
|
4049 | var cube = colorCubes[i]
|
4050 |
|
4051 | radius = radius || cube.width
|
4052 |
|
4053 | params.color[i] = {
|
4054 | target: GL_TEXTURE_CUBE_MAP_POSITIVE_X$2,
|
4055 | data: colorCubes[i]
|
4056 | }
|
4057 | }
|
4058 |
|
4059 | for (i = 0; i < 6; ++i) {
|
4060 | for (var j = 0; j < colorCubes.length; ++j) {
|
4061 | params.color[j].target = GL_TEXTURE_CUBE_MAP_POSITIVE_X$2 + i
|
4062 | }
|
4063 |
|
4064 | if (i > 0) {
|
4065 | params.depth = faces[0].depth
|
4066 | params.stencil = faces[0].stencil
|
4067 | params.depthStencil = faces[0].depthStencil
|
4068 | }
|
4069 | if (faces[i]) {
|
4070 | (faces[i])(params)
|
4071 | } else {
|
4072 | faces[i] = createFBO(params)
|
4073 | }
|
4074 | }
|
4075 |
|
4076 | return extend(reglFramebufferCube, {
|
4077 | width: radius,
|
4078 | height: radius,
|
4079 | color: colorCubes
|
4080 | })
|
4081 | }
|
4082 |
|
4083 | function resize (radius_) {
|
4084 | var i
|
4085 | var radius = radius_ | 0
|
4086 |
|
4087 |
|
4088 | if (radius === reglFramebufferCube.width) {
|
4089 | return reglFramebufferCube
|
4090 | }
|
4091 |
|
4092 | var colors = reglFramebufferCube.color
|
4093 | for (i = 0; i < colors.length; ++i) {
|
4094 | colors[i].resize(radius)
|
4095 | }
|
4096 |
|
4097 | for (i = 0; i < 6; ++i) {
|
4098 | faces[i].resize(radius)
|
4099 | }
|
4100 |
|
4101 | reglFramebufferCube.width = reglFramebufferCube.height = radius
|
4102 |
|
4103 | return reglFramebufferCube
|
4104 | }
|
4105 |
|
4106 | reglFramebufferCube(options)
|
4107 |
|
4108 | return extend(reglFramebufferCube, {
|
4109 | faces: faces,
|
4110 | resize: resize,
|
4111 | _reglType: 'framebufferCube',
|
4112 | destroy: function () {
|
4113 | faces.forEach(function (f) {
|
4114 | f.destroy()
|
4115 | })
|
4116 | }
|
4117 | })
|
4118 | }
|
4119 |
|
4120 | function restoreFramebuffers () {
|
4121 | framebufferState.cur = null
|
4122 | framebufferState.next = null
|
4123 | framebufferState.dirty = true
|
4124 | values(framebufferSet).forEach(function (fb) {
|
4125 | fb.framebuffer = gl.createFramebuffer()
|
4126 | updateFramebuffer(fb)
|
4127 | })
|
4128 | }
|
4129 |
|
4130 | return extend(framebufferState, {
|
4131 | getFramebuffer: function (object) {
|
4132 | if (typeof object === 'function' && object._reglType === 'framebuffer') {
|
4133 | var fbo = object._framebuffer
|
4134 | if (fbo instanceof REGLFramebuffer) {
|
4135 | return fbo
|
4136 | }
|
4137 | }
|
4138 | return null
|
4139 | },
|
4140 | create: createFBO,
|
4141 | createCube: createCubeFBO,
|
4142 | clear: function () {
|
4143 | values(framebufferSet).forEach(destroy)
|
4144 | },
|
4145 | restore: restoreFramebuffers
|
4146 | })
|
4147 | }
|
4148 |
|
4149 | var GL_FLOAT$5 = 5126
|
4150 | var GL_ARRAY_BUFFER$1 = 34962
|
4151 |
|
4152 | function AttributeRecord () {
|
4153 | this.state = 0
|
4154 |
|
4155 | this.x = 0.0
|
4156 | this.y = 0.0
|
4157 | this.z = 0.0
|
4158 | this.w = 0.0
|
4159 |
|
4160 | this.buffer = null
|
4161 | this.size = 0
|
4162 | this.normalized = false
|
4163 | this.type = GL_FLOAT$5
|
4164 | this.offset = 0
|
4165 | this.stride = 0
|
4166 | this.divisor = 0
|
4167 | }
|
4168 |
|
4169 | function wrapAttributeState (
|
4170 | gl,
|
4171 | extensions,
|
4172 | limits,
|
4173 | stats,
|
4174 | bufferState) {
|
4175 | var NUM_ATTRIBUTES = limits.maxAttributes
|
4176 | var attributeBindings = new Array(NUM_ATTRIBUTES)
|
4177 | for (var i = 0; i < NUM_ATTRIBUTES; ++i) {
|
4178 | attributeBindings[i] = new AttributeRecord()
|
4179 | }
|
4180 | var vaoCount = 0
|
4181 | var vaoSet = {}
|
4182 |
|
4183 | var state = {
|
4184 | Record: AttributeRecord,
|
4185 | scope: {},
|
4186 | state: attributeBindings,
|
4187 | currentVAO: null,
|
4188 | targetVAO: null,
|
4189 | restore: extVAO() ? restoreVAO : function () {},
|
4190 | createVAO: createVAO,
|
4191 | getVAO: getVAO,
|
4192 | destroyBuffer: destroyBuffer,
|
4193 | setVAO: extVAO() ? setVAOEXT : setVAOEmulated,
|
4194 | clear: extVAO() ? destroyVAOEXT : function () {}
|
4195 | }
|
4196 |
|
4197 | function destroyBuffer (buffer) {
|
4198 | for (var i = 0; i < attributeBindings.length; ++i) {
|
4199 | var record = attributeBindings[i]
|
4200 | if (record.buffer === buffer) {
|
4201 | gl.disableVertexAttribArray(i)
|
4202 | record.buffer = null
|
4203 | }
|
4204 | }
|
4205 | }
|
4206 |
|
4207 | function extVAO () {
|
4208 | return extensions.oes_vertex_array_object
|
4209 | }
|
4210 |
|
4211 | function extInstanced () {
|
4212 | return extensions.angle_instanced_arrays
|
4213 | }
|
4214 |
|
4215 | function getVAO (vao) {
|
4216 | if (typeof vao === 'function' && vao._vao) {
|
4217 | return vao._vao
|
4218 | }
|
4219 | return null
|
4220 | }
|
4221 |
|
4222 | function setVAOEXT (vao) {
|
4223 | if (vao === state.currentVAO) {
|
4224 | return
|
4225 | }
|
4226 | var ext = extVAO()
|
4227 | if (vao) {
|
4228 | ext.bindVertexArrayOES(vao.vao)
|
4229 | } else {
|
4230 | ext.bindVertexArrayOES(null)
|
4231 | }
|
4232 | state.currentVAO = vao
|
4233 | }
|
4234 |
|
4235 | function setVAOEmulated (vao) {
|
4236 | if (vao === state.currentVAO) {
|
4237 | return
|
4238 | }
|
4239 | if (vao) {
|
4240 | vao.bindAttrs()
|
4241 | } else {
|
4242 | var exti = extInstanced()
|
4243 | for (let i = 0; i < attributeBindings.length; ++i) {
|
4244 | var binding = attributeBindings[i]
|
4245 | if (binding.buffer) {
|
4246 | gl.enableVertexAttribArray(i)
|
4247 | gl.vertexAttribPointer(i, binding.size, binding.type, binding.normalized, binding.stride, binding.offfset)
|
4248 | if (exti) {
|
4249 | exti.vertexAttribDivisorANGLE(i, binding.divisor)
|
4250 | }
|
4251 | } else {
|
4252 | gl.disableVertexAttribArray(i)
|
4253 | gl.vertexAttrib4f(i, binding.x, binding.y, binding.z, binding.w)
|
4254 | }
|
4255 | }
|
4256 | }
|
4257 | state.currentVAO = vao
|
4258 | }
|
4259 |
|
4260 | function destroyVAOEXT (vao) {
|
4261 | values(vaoSet).forEach((vao) => {
|
4262 | vao.destroy()
|
4263 | })
|
4264 | }
|
4265 |
|
4266 | function REGLVAO () {
|
4267 | this.id = ++vaoCount
|
4268 | this.attributes = []
|
4269 | var extension = extVAO()
|
4270 | if (extension) {
|
4271 | this.vao = extension.createVertexArrayOES()
|
4272 | } else {
|
4273 | this.vao = null
|
4274 | }
|
4275 | vaoSet[this.id] = this
|
4276 | this.buffers = []
|
4277 | }
|
4278 |
|
4279 | REGLVAO.prototype.bindAttrs = function () {
|
4280 | var exti = extInstanced()
|
4281 | var attributes = this.attributes
|
4282 | for (var i = 0; i < attributes.length; ++i) {
|
4283 | var attr = attributes[i]
|
4284 | if (attr.buffer) {
|
4285 | gl.enableVertexAttribArray(i)
|
4286 | gl.bindBuffer(GL_ARRAY_BUFFER$1, attr.buffer.buffer)
|
4287 | gl.vertexAttribPointer(i, attr.size, attr.type, attr.normalized, attr.stride, attr.offset)
|
4288 | if (exti) {
|
4289 | exti.vertexAttribDivisorANGLE(i, attr.divisor)
|
4290 | }
|
4291 | } else {
|
4292 | gl.disableVertexAttribArray(i)
|
4293 | gl.vertexAttrib4f(i, attr.x, attr.y, attr.z, attr.w)
|
4294 | }
|
4295 | }
|
4296 | for (var j = attributes.length; j < NUM_ATTRIBUTES; ++j) {
|
4297 | gl.disableVertexAttribArray(j)
|
4298 | }
|
4299 | }
|
4300 |
|
4301 | REGLVAO.prototype.refresh = function () {
|
4302 | var ext = extVAO()
|
4303 | if (ext) {
|
4304 | ext.bindVertexArrayOES(this.vao)
|
4305 | this.bindAttrs()
|
4306 | state.currentVAO = this
|
4307 | }
|
4308 | }
|
4309 |
|
4310 | REGLVAO.prototype.destroy = function () {
|
4311 | if (this.vao) {
|
4312 | var extension = extVAO()
|
4313 | if (this === state.currentVAO) {
|
4314 | state.currentVAO = null
|
4315 | extension.bindVertexArrayOES(null)
|
4316 | }
|
4317 | extension.deleteVertexArrayOES(this.vao)
|
4318 | this.vao = null
|
4319 | }
|
4320 | if (vaoSet[this.id]) {
|
4321 | delete vaoSet[this.id]
|
4322 | stats.vaoCount -= 1
|
4323 | }
|
4324 | }
|
4325 |
|
4326 | function restoreVAO () {
|
4327 | var ext = extVAO()
|
4328 | if (ext) {
|
4329 | values(vaoSet).forEach(function (vao) {
|
4330 | vao.refresh()
|
4331 | })
|
4332 | }
|
4333 | }
|
4334 |
|
4335 | function createVAO (_attr) {
|
4336 | var vao = new REGLVAO()
|
4337 | stats.vaoCount += 1
|
4338 |
|
4339 | function updateVAO (attributes) {
|
4340 |
|
4341 |
|
4342 |
|
4343 |
|
4344 | for (var j = 0; j < vao.buffers.length; ++j) {
|
4345 | vao.buffers[j].destroy()
|
4346 | }
|
4347 | vao.buffers.length = 0
|
4348 |
|
4349 | var nattributes = vao.attributes
|
4350 | nattributes.length = attributes.length
|
4351 | for (var i = 0; i < attributes.length; ++i) {
|
4352 | var spec = attributes[i]
|
4353 | var rec = nattributes[i] = new AttributeRecord()
|
4354 | if (Array.isArray(spec) || isTypedArray(spec) || isNDArrayLike(spec)) {
|
4355 | var buf = bufferState.create(spec, GL_ARRAY_BUFFER$1, false, true)
|
4356 | rec.buffer = bufferState.getBuffer(buf)
|
4357 | rec.size = rec.buffer.dimension | 0
|
4358 | rec.normalized = false
|
4359 | rec.type = rec.buffer.dtype
|
4360 | rec.offset = 0
|
4361 | rec.stride = 0
|
4362 | rec.divisor = 0
|
4363 | rec.state = 1
|
4364 | vao.buffers.push(buf)
|
4365 | } else if (bufferState.getBuffer(spec)) {
|
4366 | rec.buffer = bufferState.getBuffer(spec)
|
4367 | rec.size = rec.buffer.dimension | 0
|
4368 | rec.normalized = false
|
4369 | rec.type = rec.buffer.dtype
|
4370 | rec.offset = 0
|
4371 | rec.stride = 0
|
4372 | rec.divisor = 0
|
4373 | rec.state = 1
|
4374 | } else if (bufferState.getBuffer(spec.buffer)) {
|
4375 | rec.buffer = bufferState.getBuffer(spec.buffer)
|
4376 | rec.size = ((+spec.size) || rec.buffer.dimension) | 0
|
4377 | rec.normalized = !!spec.normalized || false
|
4378 | if ('type' in spec) {
|
4379 |
|
4380 | rec.type = glTypes[spec.type]
|
4381 | } else {
|
4382 | rec.type = rec.buffer.dtype
|
4383 | }
|
4384 | rec.offset = (spec.offset || 0) | 0
|
4385 | rec.stride = (spec.stride || 0) | 0
|
4386 | rec.divisor = (spec.divisor || 0) | 0
|
4387 | rec.state = 1
|
4388 |
|
4389 |
|
4390 |
|
4391 |
|
4392 |
|
4393 |
|
4394 | } else if ('x' in spec) {
|
4395 |
|
4396 | rec.x = +spec.x || 0
|
4397 | rec.y = +spec.y || 0
|
4398 | rec.z = +spec.z || 0
|
4399 | rec.w = +spec.w || 0
|
4400 | rec.state = 2
|
4401 | } else {
|
4402 |
|
4403 | }
|
4404 | }
|
4405 |
|
4406 | vao.refresh()
|
4407 | return updateVAO
|
4408 | }
|
4409 |
|
4410 | updateVAO.destroy = function () {
|
4411 | vao.destroy()
|
4412 | }
|
4413 |
|
4414 | updateVAO._vao = vao
|
4415 | updateVAO._reglType = 'vao'
|
4416 |
|
4417 | return updateVAO(_attr)
|
4418 | }
|
4419 |
|
4420 | return state
|
4421 | }
|
4422 |
|
4423 | var GL_FRAGMENT_SHADER = 35632
|
4424 | var GL_VERTEX_SHADER = 35633
|
4425 |
|
4426 | var GL_ACTIVE_UNIFORMS = 0x8B86
|
4427 | var GL_ACTIVE_ATTRIBUTES = 0x8B89
|
4428 |
|
4429 | function wrapShaderState (gl, stringStore, stats, config) {
|
4430 |
|
4431 |
|
4432 |
|
4433 | var fragShaders = {}
|
4434 | var vertShaders = {}
|
4435 |
|
4436 | function ActiveInfo (name, id, location, info) {
|
4437 | this.name = name
|
4438 | this.id = id
|
4439 | this.location = location
|
4440 | this.info = info
|
4441 | }
|
4442 |
|
4443 | function insertActiveInfo (list, info) {
|
4444 | for (var i = 0; i < list.length; ++i) {
|
4445 | if (list[i].id === info.id) {
|
4446 | list[i].location = info.location
|
4447 | return
|
4448 | }
|
4449 | }
|
4450 | list.push(info)
|
4451 | }
|
4452 |
|
4453 | function getShader (type, id, command) {
|
4454 | var cache = type === GL_FRAGMENT_SHADER ? fragShaders : vertShaders
|
4455 | var shader = cache[id]
|
4456 |
|
4457 | if (!shader) {
|
4458 | var source = stringStore.str(id)
|
4459 | shader = gl.createShader(type)
|
4460 | gl.shaderSource(shader, source)
|
4461 | gl.compileShader(shader)
|
4462 |
|
4463 | cache[id] = shader
|
4464 | }
|
4465 |
|
4466 | return shader
|
4467 | }
|
4468 |
|
4469 |
|
4470 |
|
4471 |
|
4472 | var programCache = {}
|
4473 | var programList = []
|
4474 |
|
4475 | var PROGRAM_COUNTER = 0
|
4476 |
|
4477 | function REGLProgram (fragId, vertId) {
|
4478 | this.id = PROGRAM_COUNTER++
|
4479 | this.fragId = fragId
|
4480 | this.vertId = vertId
|
4481 | this.program = null
|
4482 | this.uniforms = []
|
4483 | this.attributes = []
|
4484 |
|
4485 | if (config.profile) {
|
4486 | this.stats = {
|
4487 | uniformsCount: 0,
|
4488 | attributesCount: 0
|
4489 | }
|
4490 | }
|
4491 | }
|
4492 |
|
4493 | function linkProgram (desc, command, attributeLocations) {
|
4494 | var i, info
|
4495 |
|
4496 |
|
4497 |
|
4498 |
|
4499 | var fragShader = getShader(GL_FRAGMENT_SHADER, desc.fragId)
|
4500 | var vertShader = getShader(GL_VERTEX_SHADER, desc.vertId)
|
4501 |
|
4502 | var program = desc.program = gl.createProgram()
|
4503 | gl.attachShader(program, fragShader)
|
4504 | gl.attachShader(program, vertShader)
|
4505 | if (attributeLocations) {
|
4506 | for (let i = 0; i < attributeLocations.length; ++i) {
|
4507 | var binding = attributeLocations[i]
|
4508 | gl.bindAttribLocation(program, binding[0], binding[1])
|
4509 | }
|
4510 | }
|
4511 |
|
4512 | gl.linkProgram(program)
|
4513 |
|
4514 |
|
4515 |
|
4516 |
|
4517 |
|
4518 | var numUniforms = gl.getProgramParameter(program, GL_ACTIVE_UNIFORMS)
|
4519 | if (config.profile) {
|
4520 | desc.stats.uniformsCount = numUniforms
|
4521 | }
|
4522 | var uniforms = desc.uniforms
|
4523 | for (i = 0; i < numUniforms; ++i) {
|
4524 | info = gl.getActiveUniform(program, i)
|
4525 | if (info) {
|
4526 | if (info.size > 1) {
|
4527 | for (var j = 0; j < info.size; ++j) {
|
4528 | var name = info.name.replace('[0]', '[' + j + ']')
|
4529 | insertActiveInfo(uniforms, new ActiveInfo(
|
4530 | name,
|
4531 | stringStore.id(name),
|
4532 | gl.getUniformLocation(program, name),
|
4533 | info))
|
4534 | }
|
4535 | } else {
|
4536 | insertActiveInfo(uniforms, new ActiveInfo(
|
4537 | info.name,
|
4538 | stringStore.id(info.name),
|
4539 | gl.getUniformLocation(program, info.name),
|
4540 | info))
|
4541 | }
|
4542 | }
|
4543 | }
|
4544 |
|
4545 |
|
4546 |
|
4547 |
|
4548 | var numAttributes = gl.getProgramParameter(program, GL_ACTIVE_ATTRIBUTES)
|
4549 | if (config.profile) {
|
4550 | desc.stats.attributesCount = numAttributes
|
4551 | }
|
4552 |
|
4553 | var attributes = desc.attributes
|
4554 | for (i = 0; i < numAttributes; ++i) {
|
4555 | info = gl.getActiveAttrib(program, i)
|
4556 | if (info) {
|
4557 | insertActiveInfo(attributes, new ActiveInfo(
|
4558 | info.name,
|
4559 | stringStore.id(info.name),
|
4560 | gl.getAttribLocation(program, info.name),
|
4561 | info))
|
4562 | }
|
4563 | }
|
4564 | }
|
4565 |
|
4566 | if (config.profile) {
|
4567 | stats.getMaxUniformsCount = function () {
|
4568 | var m = 0
|
4569 | programList.forEach(function (desc) {
|
4570 | if (desc.stats.uniformsCount > m) {
|
4571 | m = desc.stats.uniformsCount
|
4572 | }
|
4573 | })
|
4574 | return m
|
4575 | }
|
4576 |
|
4577 | stats.getMaxAttributesCount = function () {
|
4578 | var m = 0
|
4579 | programList.forEach(function (desc) {
|
4580 | if (desc.stats.attributesCount > m) {
|
4581 | m = desc.stats.attributesCount
|
4582 | }
|
4583 | })
|
4584 | return m
|
4585 | }
|
4586 | }
|
4587 |
|
4588 | function restoreShaders () {
|
4589 | fragShaders = {}
|
4590 | vertShaders = {}
|
4591 | for (var i = 0; i < programList.length; ++i) {
|
4592 | linkProgram(programList[i], null, programList[i].attributes.map(function (info) {
|
4593 | return [info.location, info.name]
|
4594 | }))
|
4595 | }
|
4596 | }
|
4597 |
|
4598 | return {
|
4599 | clear: function () {
|
4600 | var deleteShader = gl.deleteShader.bind(gl)
|
4601 | values(fragShaders).forEach(deleteShader)
|
4602 | fragShaders = {}
|
4603 | values(vertShaders).forEach(deleteShader)
|
4604 | vertShaders = {}
|
4605 |
|
4606 | programList.forEach(function (desc) {
|
4607 | gl.deleteProgram(desc.program)
|
4608 | })
|
4609 | programList.length = 0
|
4610 | programCache = {}
|
4611 |
|
4612 | stats.shaderCount = 0
|
4613 | },
|
4614 |
|
4615 | program: function (vertId, fragId, command, attribLocations) {
|
4616 |
|
4617 |
|
4618 |
|
4619 | var cache = programCache[fragId]
|
4620 | if (!cache) {
|
4621 | cache = programCache[fragId] = {}
|
4622 | }
|
4623 | var prevProgram = cache[vertId]
|
4624 | if (prevProgram && !attribLocations) {
|
4625 | return prevProgram
|
4626 | }
|
4627 | var program = new REGLProgram(fragId, vertId)
|
4628 | stats.shaderCount++
|
4629 | linkProgram(program, command, attribLocations)
|
4630 | if (!prevProgram) {
|
4631 | cache[vertId] = program
|
4632 | }
|
4633 | programList.push(program)
|
4634 | return program
|
4635 | },
|
4636 |
|
4637 | restore: restoreShaders,
|
4638 |
|
4639 | shader: getShader,
|
4640 |
|
4641 | frag: -1,
|
4642 | vert: -1
|
4643 | }
|
4644 | }
|
4645 |
|
4646 | var GL_RGBA$3 = 6408
|
4647 | var GL_UNSIGNED_BYTE$6 = 5121
|
4648 | var GL_PACK_ALIGNMENT = 0x0D05
|
4649 | var GL_FLOAT$6 = 0x1406
|
4650 |
|
4651 | function wrapReadPixels (
|
4652 | gl,
|
4653 | framebufferState,
|
4654 | reglPoll,
|
4655 | context,
|
4656 | glAttributes,
|
4657 | extensions,
|
4658 | limits) {
|
4659 | function readPixelsImpl (input) {
|
4660 | var type
|
4661 | if (framebufferState.next === null) {
|
4662 |
|
4663 | type = GL_UNSIGNED_BYTE$6
|
4664 | } else {
|
4665 |
|
4666 | type = framebufferState.next.colorAttachments[0].texture._texture.type
|
4667 |
|
4668 | if (extensions.oes_texture_float) {
|
4669 |
|
4670 |
|
4671 | if (type === GL_FLOAT$6) {
|
4672 |
|
4673 | }
|
4674 | } else {
|
4675 |
|
4676 | }
|
4677 | }
|
4678 |
|
4679 | var x = 0
|
4680 | var y = 0
|
4681 | var width = context.framebufferWidth
|
4682 | var height = context.framebufferHeight
|
4683 | var data = null
|
4684 |
|
4685 | if (isTypedArray(input)) {
|
4686 | data = input
|
4687 | } else if (input) {
|
4688 |
|
4689 | x = input.x | 0
|
4690 | y = input.y | 0
|
4691 |
|
4692 |
|
4693 | width = (input.width || (context.framebufferWidth - x)) | 0
|
4694 | height = (input.height || (context.framebufferHeight - y)) | 0
|
4695 | data = input.data || null
|
4696 | }
|
4697 |
|
4698 |
|
4699 | if (data) {
|
4700 | if (type === GL_UNSIGNED_BYTE$6) {
|
4701 |
|
4702 | } else if (type === GL_FLOAT$6) {
|
4703 |
|
4704 | }
|
4705 | }
|
4706 |
|
4707 |
|
4708 |
|
4709 |
|
4710 |
|
4711 | reglPoll()
|
4712 |
|
4713 |
|
4714 | var size = width * height * 4
|
4715 |
|
4716 |
|
4717 | if (!data) {
|
4718 | if (type === GL_UNSIGNED_BYTE$6) {
|
4719 | data = new Uint8Array(size)
|
4720 | } else if (type === GL_FLOAT$6) {
|
4721 | data = data || new Float32Array(size)
|
4722 | }
|
4723 | }
|
4724 |
|
4725 |
|
4726 |
|
4727 |
|
4728 |
|
4729 |
|
4730 | gl.pixelStorei(GL_PACK_ALIGNMENT, 4)
|
4731 | gl.readPixels(x, y, width, height, GL_RGBA$3,
|
4732 | type,
|
4733 | data)
|
4734 |
|
4735 | return data
|
4736 | }
|
4737 |
|
4738 | function readPixelsFBO (options) {
|
4739 | var result
|
4740 | framebufferState.setFBO({
|
4741 | framebuffer: options.framebuffer
|
4742 | }, function () {
|
4743 | result = readPixelsImpl(options)
|
4744 | })
|
4745 | return result
|
4746 | }
|
4747 |
|
4748 | function readPixels (options) {
|
4749 | if (!options || !('framebuffer' in options)) {
|
4750 | return readPixelsImpl(options)
|
4751 | } else {
|
4752 | return readPixelsFBO(options)
|
4753 | }
|
4754 | }
|
4755 |
|
4756 | return readPixels
|
4757 | }
|
4758 |
|
4759 | function slice (x) {
|
4760 | return Array.prototype.slice.call(x)
|
4761 | }
|
4762 |
|
4763 | function join (x) {
|
4764 | return slice(x).join('')
|
4765 | }
|
4766 |
|
4767 | function createEnvironment () {
|
4768 |
|
4769 | var varCounter = 0
|
4770 |
|
4771 |
|
4772 |
|
4773 |
|
4774 | var linkedNames = []
|
4775 | var linkedValues = []
|
4776 | function link (value) {
|
4777 | for (var i = 0; i < linkedValues.length; ++i) {
|
4778 | if (linkedValues[i] === value) {
|
4779 | return linkedNames[i]
|
4780 | }
|
4781 | }
|
4782 |
|
4783 | var name = 'g' + (varCounter++)
|
4784 | linkedNames.push(name)
|
4785 | linkedValues.push(value)
|
4786 | return name
|
4787 | }
|
4788 |
|
4789 |
|
4790 | function block () {
|
4791 | var code = []
|
4792 | function push () {
|
4793 | code.push.apply(code, slice(arguments))
|
4794 | }
|
4795 |
|
4796 | var vars = []
|
4797 | function def () {
|
4798 | var name = 'v' + (varCounter++)
|
4799 | vars.push(name)
|
4800 |
|
4801 | if (arguments.length > 0) {
|
4802 | code.push(name, '=')
|
4803 | code.push.apply(code, slice(arguments))
|
4804 | code.push(';')
|
4805 | }
|
4806 |
|
4807 | return name
|
4808 | }
|
4809 |
|
4810 | return extend(push, {
|
4811 | def: def,
|
4812 | toString: function () {
|
4813 | return join([
|
4814 | (vars.length > 0 ? 'var ' + vars.join(',') + ';' : ''),
|
4815 | join(code)
|
4816 | ])
|
4817 | }
|
4818 | })
|
4819 | }
|
4820 |
|
4821 | function scope () {
|
4822 | var entry = block()
|
4823 | var exit = block()
|
4824 |
|
4825 | var entryToString = entry.toString
|
4826 | var exitToString = exit.toString
|
4827 |
|
4828 | function save (object, prop) {
|
4829 | exit(object, prop, '=', entry.def(object, prop), ';')
|
4830 | }
|
4831 |
|
4832 | return extend(function () {
|
4833 | entry.apply(entry, slice(arguments))
|
4834 | }, {
|
4835 | def: entry.def,
|
4836 | entry: entry,
|
4837 | exit: exit,
|
4838 | save: save,
|
4839 | set: function (object, prop, value) {
|
4840 | save(object, prop)
|
4841 | entry(object, prop, '=', value, ';')
|
4842 | },
|
4843 | toString: function () {
|
4844 | return entryToString() + exitToString()
|
4845 | }
|
4846 | })
|
4847 | }
|
4848 |
|
4849 | function conditional () {
|
4850 | var pred = join(arguments)
|
4851 | var thenBlock = scope()
|
4852 | var elseBlock = scope()
|
4853 |
|
4854 | var thenToString = thenBlock.toString
|
4855 | var elseToString = elseBlock.toString
|
4856 |
|
4857 | return extend(thenBlock, {
|
4858 | then: function () {
|
4859 | thenBlock.apply(thenBlock, slice(arguments))
|
4860 | return this
|
4861 | },
|
4862 | else: function () {
|
4863 | elseBlock.apply(elseBlock, slice(arguments))
|
4864 | return this
|
4865 | },
|
4866 | toString: function () {
|
4867 | var elseClause = elseToString()
|
4868 | if (elseClause) {
|
4869 | elseClause = 'else{' + elseClause + '}'
|
4870 | }
|
4871 | return join([
|
4872 | 'if(', pred, '){',
|
4873 | thenToString(),
|
4874 | '}', elseClause
|
4875 | ])
|
4876 | }
|
4877 | })
|
4878 | }
|
4879 |
|
4880 |
|
4881 | var globalBlock = block()
|
4882 | var procedures = {}
|
4883 | function proc (name, count) {
|
4884 | var args = []
|
4885 | function arg () {
|
4886 | var name = 'a' + args.length
|
4887 | args.push(name)
|
4888 | return name
|
4889 | }
|
4890 |
|
4891 | count = count || 0
|
4892 | for (var i = 0; i < count; ++i) {
|
4893 | arg()
|
4894 | }
|
4895 |
|
4896 | var body = scope()
|
4897 | var bodyToString = body.toString
|
4898 |
|
4899 | var result = procedures[name] = extend(body, {
|
4900 | arg: arg,
|
4901 | toString: function () {
|
4902 | return join([
|
4903 | 'function(', args.join(), '){',
|
4904 | bodyToString(),
|
4905 | '}'
|
4906 | ])
|
4907 | }
|
4908 | })
|
4909 |
|
4910 | return result
|
4911 | }
|
4912 |
|
4913 | function compile () {
|
4914 | var code = ['"use strict";',
|
4915 | globalBlock,
|
4916 | 'return {']
|
4917 | Object.keys(procedures).forEach(function (name) {
|
4918 | code.push('"', name, '":', procedures[name].toString(), ',')
|
4919 | })
|
4920 | code.push('}')
|
4921 | var src = join(code)
|
4922 | .replace(/;/g, ';\n')
|
4923 | .replace(/}/g, '}\n')
|
4924 | .replace(/{/g, '{\n')
|
4925 | var proc = Function.apply(null, linkedNames.concat(src))
|
4926 | return proc.apply(null, linkedValues)
|
4927 | }
|
4928 |
|
4929 | return {
|
4930 | global: globalBlock,
|
4931 | link: link,
|
4932 | block: block,
|
4933 | proc: proc,
|
4934 | scope: scope,
|
4935 | cond: conditional,
|
4936 | compile: compile
|
4937 | }
|
4938 | }
|
4939 |
|
4940 |
|
4941 | var CUTE_COMPONENTS = 'xyzw'.split('')
|
4942 |
|
4943 | var GL_UNSIGNED_BYTE$7 = 5121
|
4944 |
|
4945 | var ATTRIB_STATE_POINTER = 1
|
4946 | var ATTRIB_STATE_CONSTANT = 2
|
4947 |
|
4948 | var DYN_FUNC$1 = 0
|
4949 | var DYN_PROP$1 = 1
|
4950 | var DYN_CONTEXT$1 = 2
|
4951 | var DYN_STATE$1 = 3
|
4952 | var DYN_THUNK = 4
|
4953 |
|
4954 | var S_DITHER = 'dither'
|
4955 | var S_BLEND_ENABLE = 'blend.enable'
|
4956 | var S_BLEND_COLOR = 'blend.color'
|
4957 | var S_BLEND_EQUATION = 'blend.equation'
|
4958 | var S_BLEND_FUNC = 'blend.func'
|
4959 | var S_DEPTH_ENABLE = 'depth.enable'
|
4960 | var S_DEPTH_FUNC = 'depth.func'
|
4961 | var S_DEPTH_RANGE = 'depth.range'
|
4962 | var S_DEPTH_MASK = 'depth.mask'
|
4963 | var S_COLOR_MASK = 'colorMask'
|
4964 | var S_CULL_ENABLE = 'cull.enable'
|
4965 | var S_CULL_FACE = 'cull.face'
|
4966 | var S_FRONT_FACE = 'frontFace'
|
4967 | var S_LINE_WIDTH = 'lineWidth'
|
4968 | var S_POLYGON_OFFSET_ENABLE = 'polygonOffset.enable'
|
4969 | var S_POLYGON_OFFSET_OFFSET = 'polygonOffset.offset'
|
4970 | var S_SAMPLE_ALPHA = 'sample.alpha'
|
4971 | var S_SAMPLE_ENABLE = 'sample.enable'
|
4972 | var S_SAMPLE_COVERAGE = 'sample.coverage'
|
4973 | var S_STENCIL_ENABLE = 'stencil.enable'
|
4974 | var S_STENCIL_MASK = 'stencil.mask'
|
4975 | var S_STENCIL_FUNC = 'stencil.func'
|
4976 | var S_STENCIL_OPFRONT = 'stencil.opFront'
|
4977 | var S_STENCIL_OPBACK = 'stencil.opBack'
|
4978 | var S_SCISSOR_ENABLE = 'scissor.enable'
|
4979 | var S_SCISSOR_BOX = 'scissor.box'
|
4980 | var S_VIEWPORT = 'viewport'
|
4981 |
|
4982 | var S_PROFILE = 'profile'
|
4983 |
|
4984 | var S_FRAMEBUFFER = 'framebuffer'
|
4985 | var S_VERT = 'vert'
|
4986 | var S_FRAG = 'frag'
|
4987 | var S_ELEMENTS = 'elements'
|
4988 | var S_PRIMITIVE = 'primitive'
|
4989 | var S_COUNT = 'count'
|
4990 | var S_OFFSET = 'offset'
|
4991 | var S_INSTANCES = 'instances'
|
4992 | var S_VAO = 'vao'
|
4993 |
|
4994 | var SUFFIX_WIDTH = 'Width'
|
4995 | var SUFFIX_HEIGHT = 'Height'
|
4996 |
|
4997 | var S_FRAMEBUFFER_WIDTH = S_FRAMEBUFFER + SUFFIX_WIDTH
|
4998 | var S_FRAMEBUFFER_HEIGHT = S_FRAMEBUFFER + SUFFIX_HEIGHT
|
4999 | var S_VIEWPORT_WIDTH = S_VIEWPORT + SUFFIX_WIDTH
|
5000 | var S_VIEWPORT_HEIGHT = S_VIEWPORT + SUFFIX_HEIGHT
|
5001 | var S_DRAWINGBUFFER = 'drawingBuffer'
|
5002 | var S_DRAWINGBUFFER_WIDTH = S_DRAWINGBUFFER + SUFFIX_WIDTH
|
5003 | var S_DRAWINGBUFFER_HEIGHT = S_DRAWINGBUFFER + SUFFIX_HEIGHT
|
5004 |
|
5005 | var NESTED_OPTIONS = [
|
5006 | S_BLEND_FUNC,
|
5007 | S_BLEND_EQUATION,
|
5008 | S_STENCIL_FUNC,
|
5009 | S_STENCIL_OPFRONT,
|
5010 | S_STENCIL_OPBACK,
|
5011 | S_SAMPLE_COVERAGE,
|
5012 | S_VIEWPORT,
|
5013 | S_SCISSOR_BOX,
|
5014 | S_POLYGON_OFFSET_OFFSET
|
5015 | ]
|
5016 |
|
5017 | var GL_ARRAY_BUFFER$2 = 34962
|
5018 | var GL_ELEMENT_ARRAY_BUFFER$1 = 34963
|
5019 |
|
5020 | var GL_CULL_FACE = 0x0B44
|
5021 | var GL_BLEND = 0x0BE2
|
5022 | var GL_DITHER = 0x0BD0
|
5023 | var GL_STENCIL_TEST = 0x0B90
|
5024 | var GL_DEPTH_TEST = 0x0B71
|
5025 | var GL_SCISSOR_TEST = 0x0C11
|
5026 | var GL_POLYGON_OFFSET_FILL = 0x8037
|
5027 | var GL_SAMPLE_ALPHA_TO_COVERAGE = 0x809E
|
5028 | var GL_SAMPLE_COVERAGE = 0x80A0
|
5029 |
|
5030 | var GL_FLOAT$7 = 5126
|
5031 | var GL_FLOAT_VEC2 = 35664
|
5032 | var GL_FLOAT_VEC3 = 35665
|
5033 | var GL_FLOAT_VEC4 = 35666
|
5034 | var GL_INT$2 = 5124
|
5035 | var GL_INT_VEC2 = 35667
|
5036 | var GL_INT_VEC3 = 35668
|
5037 | var GL_INT_VEC4 = 35669
|
5038 | var GL_BOOL = 35670
|
5039 | var GL_BOOL_VEC2 = 35671
|
5040 | var GL_BOOL_VEC3 = 35672
|
5041 | var GL_BOOL_VEC4 = 35673
|
5042 | var GL_FLOAT_MAT2 = 35674
|
5043 | var GL_FLOAT_MAT3 = 35675
|
5044 | var GL_FLOAT_MAT4 = 35676
|
5045 | var GL_SAMPLER_2D = 35678
|
5046 | var GL_SAMPLER_CUBE = 35680
|
5047 |
|
5048 | var GL_TRIANGLES$1 = 4
|
5049 |
|
5050 | var GL_FRONT = 1028
|
5051 | var GL_BACK = 1029
|
5052 | var GL_CW = 0x0900
|
5053 | var GL_CCW = 0x0901
|
5054 | var GL_MIN_EXT = 0x8007
|
5055 | var GL_MAX_EXT = 0x8008
|
5056 | var GL_ALWAYS = 519
|
5057 | var GL_KEEP = 7680
|
5058 | var GL_ZERO = 0
|
5059 | var GL_ONE = 1
|
5060 | var GL_FUNC_ADD = 0x8006
|
5061 | var GL_LESS = 513
|
5062 |
|
5063 | var GL_FRAMEBUFFER$2 = 0x8D40
|
5064 | var GL_COLOR_ATTACHMENT0$2 = 0x8CE0
|
5065 |
|
5066 | var blendFuncs = {
|
5067 | '0': 0,
|
5068 | '1': 1,
|
5069 | 'zero': 0,
|
5070 | 'one': 1,
|
5071 | 'src color': 768,
|
5072 | 'one minus src color': 769,
|
5073 | 'src alpha': 770,
|
5074 | 'one minus src alpha': 771,
|
5075 | 'dst color': 774,
|
5076 | 'one minus dst color': 775,
|
5077 | 'dst alpha': 772,
|
5078 | 'one minus dst alpha': 773,
|
5079 | 'constant color': 32769,
|
5080 | 'one minus constant color': 32770,
|
5081 | 'constant alpha': 32771,
|
5082 | 'one minus constant alpha': 32772,
|
5083 | 'src alpha saturate': 776
|
5084 | }
|
5085 |
|
5086 | var compareFuncs = {
|
5087 | 'never': 512,
|
5088 | 'less': 513,
|
5089 | '<': 513,
|
5090 | 'equal': 514,
|
5091 | '=': 514,
|
5092 | '==': 514,
|
5093 | '===': 514,
|
5094 | 'lequal': 515,
|
5095 | '<=': 515,
|
5096 | 'greater': 516,
|
5097 | '>': 516,
|
5098 | 'notequal': 517,
|
5099 | '!=': 517,
|
5100 | '!==': 517,
|
5101 | 'gequal': 518,
|
5102 | '>=': 518,
|
5103 | 'always': 519
|
5104 | }
|
5105 |
|
5106 | var stencilOps = {
|
5107 | '0': 0,
|
5108 | 'zero': 0,
|
5109 | 'keep': 7680,
|
5110 | 'replace': 7681,
|
5111 | 'increment': 7682,
|
5112 | 'decrement': 7683,
|
5113 | 'increment wrap': 34055,
|
5114 | 'decrement wrap': 34056,
|
5115 | 'invert': 5386
|
5116 | }
|
5117 |
|
5118 | var orientationType = {
|
5119 | 'cw': GL_CW,
|
5120 | 'ccw': GL_CCW
|
5121 | }
|
5122 |
|
5123 | function isBufferArgs (x) {
|
5124 | return Array.isArray(x) ||
|
5125 | isTypedArray(x) ||
|
5126 | isNDArrayLike(x)
|
5127 | }
|
5128 |
|
5129 |
|
5130 | function sortState (state) {
|
5131 | return state.sort(function (a, b) {
|
5132 | if (a === S_VIEWPORT) {
|
5133 | return -1
|
5134 | } else if (b === S_VIEWPORT) {
|
5135 | return 1
|
5136 | }
|
5137 | return (a < b) ? -1 : 1
|
5138 | })
|
5139 | }
|
5140 |
|
5141 | function Declaration (thisDep, contextDep, propDep, append) {
|
5142 | this.thisDep = thisDep
|
5143 | this.contextDep = contextDep
|
5144 | this.propDep = propDep
|
5145 | this.append = append
|
5146 | }
|
5147 |
|
5148 | function isStatic (decl) {
|
5149 | return decl && !(decl.thisDep || decl.contextDep || decl.propDep)
|
5150 | }
|
5151 |
|
5152 | function createStaticDecl (append) {
|
5153 | return new Declaration(false, false, false, append)
|
5154 | }
|
5155 |
|
5156 | function createDynamicDecl (dyn, append) {
|
5157 | var type = dyn.type
|
5158 | if (type === DYN_FUNC$1) {
|
5159 | var numArgs = dyn.data.length
|
5160 | return new Declaration(
|
5161 | true,
|
5162 | numArgs >= 1,
|
5163 | numArgs >= 2,
|
5164 | append)
|
5165 | } else if (type === DYN_THUNK) {
|
5166 | var data = dyn.data
|
5167 | return new Declaration(
|
5168 | data.thisDep,
|
5169 | data.contextDep,
|
5170 | data.propDep,
|
5171 | append)
|
5172 | } else {
|
5173 | return new Declaration(
|
5174 | type === DYN_STATE$1,
|
5175 | type === DYN_CONTEXT$1,
|
5176 | type === DYN_PROP$1,
|
5177 | append)
|
5178 | }
|
5179 | }
|
5180 |
|
5181 | var SCOPE_DECL = new Declaration(false, false, false, function () {})
|
5182 |
|
5183 | function reglCore (
|
5184 | gl,
|
5185 | stringStore,
|
5186 | extensions,
|
5187 | limits,
|
5188 | bufferState,
|
5189 | elementState,
|
5190 | textureState,
|
5191 | framebufferState,
|
5192 | uniformState,
|
5193 | attributeState,
|
5194 | shaderState,
|
5195 | drawState,
|
5196 | contextState,
|
5197 | timer,
|
5198 | config) {
|
5199 | var AttributeRecord = attributeState.Record
|
5200 |
|
5201 | var blendEquations = {
|
5202 | 'add': 32774,
|
5203 | 'subtract': 32778,
|
5204 | 'reverse subtract': 32779
|
5205 | }
|
5206 | if (extensions.ext_blend_minmax) {
|
5207 | blendEquations.min = GL_MIN_EXT
|
5208 | blendEquations.max = GL_MAX_EXT
|
5209 | }
|
5210 |
|
5211 | var extInstancing = extensions.angle_instanced_arrays
|
5212 | var extDrawBuffers = extensions.webgl_draw_buffers
|
5213 |
|
5214 |
|
5215 |
|
5216 |
|
5217 |
|
5218 |
|
5219 | var currentState = {
|
5220 | dirty: true,
|
5221 | profile: config.profile
|
5222 | }
|
5223 | var nextState = {}
|
5224 | var GL_STATE_NAMES = []
|
5225 | var GL_FLAGS = {}
|
5226 | var GL_VARIABLES = {}
|
5227 |
|
5228 | function propName (name) {
|
5229 | return name.replace('.', '_')
|
5230 | }
|
5231 |
|
5232 | function stateFlag (sname, cap, init) {
|
5233 | var name = propName(sname)
|
5234 | GL_STATE_NAMES.push(sname)
|
5235 | nextState[name] = currentState[name] = !!init
|
5236 | GL_FLAGS[name] = cap
|
5237 | }
|
5238 |
|
5239 | function stateVariable (sname, func, init) {
|
5240 | var name = propName(sname)
|
5241 | GL_STATE_NAMES.push(sname)
|
5242 | if (Array.isArray(init)) {
|
5243 | currentState[name] = init.slice()
|
5244 | nextState[name] = init.slice()
|
5245 | } else {
|
5246 | currentState[name] = nextState[name] = init
|
5247 | }
|
5248 | GL_VARIABLES[name] = func
|
5249 | }
|
5250 |
|
5251 |
|
5252 | stateFlag(S_DITHER, GL_DITHER)
|
5253 |
|
5254 |
|
5255 | stateFlag(S_BLEND_ENABLE, GL_BLEND)
|
5256 | stateVariable(S_BLEND_COLOR, 'blendColor', [0, 0, 0, 0])
|
5257 | stateVariable(S_BLEND_EQUATION, 'blendEquationSeparate',
|
5258 | [GL_FUNC_ADD, GL_FUNC_ADD])
|
5259 | stateVariable(S_BLEND_FUNC, 'blendFuncSeparate',
|
5260 | [GL_ONE, GL_ZERO, GL_ONE, GL_ZERO])
|
5261 |
|
5262 |
|
5263 | stateFlag(S_DEPTH_ENABLE, GL_DEPTH_TEST, true)
|
5264 | stateVariable(S_DEPTH_FUNC, 'depthFunc', GL_LESS)
|
5265 | stateVariable(S_DEPTH_RANGE, 'depthRange', [0, 1])
|
5266 | stateVariable(S_DEPTH_MASK, 'depthMask', true)
|
5267 |
|
5268 |
|
5269 | stateVariable(S_COLOR_MASK, S_COLOR_MASK, [true, true, true, true])
|
5270 |
|
5271 |
|
5272 | stateFlag(S_CULL_ENABLE, GL_CULL_FACE)
|
5273 | stateVariable(S_CULL_FACE, 'cullFace', GL_BACK)
|
5274 |
|
5275 |
|
5276 | stateVariable(S_FRONT_FACE, S_FRONT_FACE, GL_CCW)
|
5277 |
|
5278 |
|
5279 | stateVariable(S_LINE_WIDTH, S_LINE_WIDTH, 1)
|
5280 |
|
5281 |
|
5282 | stateFlag(S_POLYGON_OFFSET_ENABLE, GL_POLYGON_OFFSET_FILL)
|
5283 | stateVariable(S_POLYGON_OFFSET_OFFSET, 'polygonOffset', [0, 0])
|
5284 |
|
5285 |
|
5286 | stateFlag(S_SAMPLE_ALPHA, GL_SAMPLE_ALPHA_TO_COVERAGE)
|
5287 | stateFlag(S_SAMPLE_ENABLE, GL_SAMPLE_COVERAGE)
|
5288 | stateVariable(S_SAMPLE_COVERAGE, 'sampleCoverage', [1, false])
|
5289 |
|
5290 |
|
5291 | stateFlag(S_STENCIL_ENABLE, GL_STENCIL_TEST)
|
5292 | stateVariable(S_STENCIL_MASK, 'stencilMask', -1)
|
5293 | stateVariable(S_STENCIL_FUNC, 'stencilFunc', [GL_ALWAYS, 0, -1])
|
5294 | stateVariable(S_STENCIL_OPFRONT, 'stencilOpSeparate',
|
5295 | [GL_FRONT, GL_KEEP, GL_KEEP, GL_KEEP])
|
5296 | stateVariable(S_STENCIL_OPBACK, 'stencilOpSeparate',
|
5297 | [GL_BACK, GL_KEEP, GL_KEEP, GL_KEEP])
|
5298 |
|
5299 |
|
5300 | stateFlag(S_SCISSOR_ENABLE, GL_SCISSOR_TEST)
|
5301 | stateVariable(S_SCISSOR_BOX, 'scissor',
|
5302 | [0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight])
|
5303 |
|
5304 |
|
5305 | stateVariable(S_VIEWPORT, S_VIEWPORT,
|
5306 | [0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight])
|
5307 |
|
5308 |
|
5309 |
|
5310 |
|
5311 |
|
5312 |
|
5313 | var sharedState = {
|
5314 | gl: gl,
|
5315 | context: contextState,
|
5316 | strings: stringStore,
|
5317 | next: nextState,
|
5318 | current: currentState,
|
5319 | draw: drawState,
|
5320 | elements: elementState,
|
5321 | buffer: bufferState,
|
5322 | shader: shaderState,
|
5323 | attributes: attributeState.state,
|
5324 | vao: attributeState,
|
5325 | uniforms: uniformState,
|
5326 | framebuffer: framebufferState,
|
5327 | extensions: extensions,
|
5328 |
|
5329 | timer: timer,
|
5330 | isBufferArgs: isBufferArgs
|
5331 | }
|
5332 |
|
5333 | var sharedConstants = {
|
5334 | primTypes: primTypes,
|
5335 | compareFuncs: compareFuncs,
|
5336 | blendFuncs: blendFuncs,
|
5337 | blendEquations: blendEquations,
|
5338 | stencilOps: stencilOps,
|
5339 | glTypes: glTypes,
|
5340 | orientationType: orientationType
|
5341 | }
|
5342 |
|
5343 |
|
5344 |
|
5345 | if (extDrawBuffers) {
|
5346 | sharedConstants.backBuffer = [GL_BACK]
|
5347 | sharedConstants.drawBuffer = loop(limits.maxDrawbuffers, function (i) {
|
5348 | if (i === 0) {
|
5349 | return [0]
|
5350 | }
|
5351 | return loop(i, function (j) {
|
5352 | return GL_COLOR_ATTACHMENT0$2 + j
|
5353 | })
|
5354 | })
|
5355 | }
|
5356 |
|
5357 | var drawCallCounter = 0
|
5358 | function createREGLEnvironment () {
|
5359 | var env = createEnvironment()
|
5360 | var link = env.link
|
5361 | var global = env.global
|
5362 | env.id = drawCallCounter++
|
5363 |
|
5364 | env.batchId = '0'
|
5365 |
|
5366 |
|
5367 | var SHARED = link(sharedState)
|
5368 | var shared = env.shared = {
|
5369 | props: 'a0'
|
5370 | }
|
5371 | Object.keys(sharedState).forEach(function (prop) {
|
5372 | shared[prop] = global.def(SHARED, '.', prop)
|
5373 | })
|
5374 |
|
5375 |
|
5376 |
|
5377 |
|
5378 |
|
5379 | var nextVars = env.next = {}
|
5380 | var currentVars = env.current = {}
|
5381 | Object.keys(GL_VARIABLES).forEach(function (variable) {
|
5382 | if (Array.isArray(currentState[variable])) {
|
5383 | nextVars[variable] = global.def(shared.next, '.', variable)
|
5384 | currentVars[variable] = global.def(shared.current, '.', variable)
|
5385 | }
|
5386 | })
|
5387 |
|
5388 |
|
5389 | var constants = env.constants = {}
|
5390 | Object.keys(sharedConstants).forEach(function (name) {
|
5391 | constants[name] = global.def(JSON.stringify(sharedConstants[name]))
|
5392 | })
|
5393 |
|
5394 |
|
5395 | env.invoke = function (block, x) {
|
5396 | switch (x.type) {
|
5397 | case DYN_FUNC$1:
|
5398 | var argList = [
|
5399 | 'this',
|
5400 | shared.context,
|
5401 | shared.props,
|
5402 | env.batchId
|
5403 | ]
|
5404 | return block.def(
|
5405 | link(x.data), '.call(',
|
5406 | argList.slice(0, Math.max(x.data.length + 1, 4)),
|
5407 | ')')
|
5408 | case DYN_PROP$1:
|
5409 | return block.def(shared.props, x.data)
|
5410 | case DYN_CONTEXT$1:
|
5411 | return block.def(shared.context, x.data)
|
5412 | case DYN_STATE$1:
|
5413 | return block.def('this', x.data)
|
5414 | case DYN_THUNK:
|
5415 | x.data.append(env, block)
|
5416 | return x.data.ref
|
5417 | }
|
5418 | }
|
5419 |
|
5420 | env.attribCache = {}
|
5421 |
|
5422 | var scopeAttribs = {}
|
5423 | env.scopeAttrib = function (name) {
|
5424 | var id = stringStore.id(name)
|
5425 | if (id in scopeAttribs) {
|
5426 | return scopeAttribs[id]
|
5427 | }
|
5428 | var binding = attributeState.scope[id]
|
5429 | if (!binding) {
|
5430 | binding = attributeState.scope[id] = new AttributeRecord()
|
5431 | }
|
5432 | var result = scopeAttribs[id] = link(binding)
|
5433 | return result
|
5434 | }
|
5435 |
|
5436 | return env
|
5437 | }
|
5438 |
|
5439 |
|
5440 |
|
5441 |
|
5442 |
|
5443 |
|
5444 | function parseProfile (options) {
|
5445 | var staticOptions = options.static
|
5446 | var dynamicOptions = options.dynamic
|
5447 |
|
5448 | var profileEnable
|
5449 | if (S_PROFILE in staticOptions) {
|
5450 | var value = !!staticOptions[S_PROFILE]
|
5451 | profileEnable = createStaticDecl(function (env, scope) {
|
5452 | return value
|
5453 | })
|
5454 | profileEnable.enable = value
|
5455 | } else if (S_PROFILE in dynamicOptions) {
|
5456 | var dyn = dynamicOptions[S_PROFILE]
|
5457 | profileEnable = createDynamicDecl(dyn, function (env, scope) {
|
5458 | return env.invoke(scope, dyn)
|
5459 | })
|
5460 | }
|
5461 |
|
5462 | return profileEnable
|
5463 | }
|
5464 |
|
5465 | function parseFramebuffer (options, env) {
|
5466 | var staticOptions = options.static
|
5467 | var dynamicOptions = options.dynamic
|
5468 |
|
5469 | if (S_FRAMEBUFFER in staticOptions) {
|
5470 | var framebuffer = staticOptions[S_FRAMEBUFFER]
|
5471 | if (framebuffer) {
|
5472 | framebuffer = framebufferState.getFramebuffer(framebuffer)
|
5473 |
|
5474 | return createStaticDecl(function (env, block) {
|
5475 | var FRAMEBUFFER = env.link(framebuffer)
|
5476 | var shared = env.shared
|
5477 | block.set(
|
5478 | shared.framebuffer,
|
5479 | '.next',
|
5480 | FRAMEBUFFER)
|
5481 | var CONTEXT = shared.context
|
5482 | block.set(
|
5483 | CONTEXT,
|
5484 | '.' + S_FRAMEBUFFER_WIDTH,
|
5485 | FRAMEBUFFER + '.width')
|
5486 | block.set(
|
5487 | CONTEXT,
|
5488 | '.' + S_FRAMEBUFFER_HEIGHT,
|
5489 | FRAMEBUFFER + '.height')
|
5490 | return FRAMEBUFFER
|
5491 | })
|
5492 | } else {
|
5493 | return createStaticDecl(function (env, scope) {
|
5494 | var shared = env.shared
|
5495 | scope.set(
|
5496 | shared.framebuffer,
|
5497 | '.next',
|
5498 | 'null')
|
5499 | var CONTEXT = shared.context
|
5500 | scope.set(
|
5501 | CONTEXT,
|
5502 | '.' + S_FRAMEBUFFER_WIDTH,
|
5503 | CONTEXT + '.' + S_DRAWINGBUFFER_WIDTH)
|
5504 | scope.set(
|
5505 | CONTEXT,
|
5506 | '.' + S_FRAMEBUFFER_HEIGHT,
|
5507 | CONTEXT + '.' + S_DRAWINGBUFFER_HEIGHT)
|
5508 | return 'null'
|
5509 | })
|
5510 | }
|
5511 | } else if (S_FRAMEBUFFER in dynamicOptions) {
|
5512 | var dyn = dynamicOptions[S_FRAMEBUFFER]
|
5513 | return createDynamicDecl(dyn, function (env, scope) {
|
5514 | var FRAMEBUFFER_FUNC = env.invoke(scope, dyn)
|
5515 | var shared = env.shared
|
5516 | var FRAMEBUFFER_STATE = shared.framebuffer
|
5517 | var FRAMEBUFFER = scope.def(
|
5518 | FRAMEBUFFER_STATE, '.getFramebuffer(', FRAMEBUFFER_FUNC, ')')
|
5519 |
|
5520 |
|
5521 |
|
5522 | scope.set(
|
5523 | FRAMEBUFFER_STATE,
|
5524 | '.next',
|
5525 | FRAMEBUFFER)
|
5526 | var CONTEXT = shared.context
|
5527 | scope.set(
|
5528 | CONTEXT,
|
5529 | '.' + S_FRAMEBUFFER_WIDTH,
|
5530 | FRAMEBUFFER + '?' + FRAMEBUFFER + '.width:' +
|
5531 | CONTEXT + '.' + S_DRAWINGBUFFER_WIDTH)
|
5532 | scope.set(
|
5533 | CONTEXT,
|
5534 | '.' + S_FRAMEBUFFER_HEIGHT,
|
5535 | FRAMEBUFFER +
|
5536 | '?' + FRAMEBUFFER + '.height:' +
|
5537 | CONTEXT + '.' + S_DRAWINGBUFFER_HEIGHT)
|
5538 | return FRAMEBUFFER
|
5539 | })
|
5540 | } else {
|
5541 | return null
|
5542 | }
|
5543 | }
|
5544 |
|
5545 | function parseViewportScissor (options, framebuffer, env) {
|
5546 | var staticOptions = options.static
|
5547 | var dynamicOptions = options.dynamic
|
5548 |
|
5549 | function parseBox (param) {
|
5550 | if (param in staticOptions) {
|
5551 | var box = staticOptions[param]
|
5552 |
|
5553 |
|
5554 | var isStatic = true
|
5555 | var x = box.x | 0
|
5556 | var y = box.y | 0
|
5557 | var w, h
|
5558 | if ('width' in box) {
|
5559 | w = box.width | 0
|
5560 |
|
5561 | } else {
|
5562 | isStatic = false
|
5563 | }
|
5564 | if ('height' in box) {
|
5565 | h = box.height | 0
|
5566 |
|
5567 | } else {
|
5568 | isStatic = false
|
5569 | }
|
5570 |
|
5571 | return new Declaration(
|
5572 | !isStatic && framebuffer && framebuffer.thisDep,
|
5573 | !isStatic && framebuffer && framebuffer.contextDep,
|
5574 | !isStatic && framebuffer && framebuffer.propDep,
|
5575 | function (env, scope) {
|
5576 | var CONTEXT = env.shared.context
|
5577 | var BOX_W = w
|
5578 | if (!('width' in box)) {
|
5579 | BOX_W = scope.def(CONTEXT, '.', S_FRAMEBUFFER_WIDTH, '-', x)
|
5580 | }
|
5581 | var BOX_H = h
|
5582 | if (!('height' in box)) {
|
5583 | BOX_H = scope.def(CONTEXT, '.', S_FRAMEBUFFER_HEIGHT, '-', y)
|
5584 | }
|
5585 | return [x, y, BOX_W, BOX_H]
|
5586 | })
|
5587 | } else if (param in dynamicOptions) {
|
5588 | var dynBox = dynamicOptions[param]
|
5589 | var result = createDynamicDecl(dynBox, function (env, scope) {
|
5590 | var BOX = env.invoke(scope, dynBox)
|
5591 |
|
5592 |
|
5593 |
|
5594 | var CONTEXT = env.shared.context
|
5595 | var BOX_X = scope.def(BOX, '.x|0')
|
5596 | var BOX_Y = scope.def(BOX, '.y|0')
|
5597 | var BOX_W = scope.def(
|
5598 | '"width" in ', BOX, '?', BOX, '.width|0:',
|
5599 | '(', CONTEXT, '.', S_FRAMEBUFFER_WIDTH, '-', BOX_X, ')')
|
5600 | var BOX_H = scope.def(
|
5601 | '"height" in ', BOX, '?', BOX, '.height|0:',
|
5602 | '(', CONTEXT, '.', S_FRAMEBUFFER_HEIGHT, '-', BOX_Y, ')')
|
5603 |
|
5604 |
|
5605 |
|
5606 | return [BOX_X, BOX_Y, BOX_W, BOX_H]
|
5607 | })
|
5608 | if (framebuffer) {
|
5609 | result.thisDep = result.thisDep || framebuffer.thisDep
|
5610 | result.contextDep = result.contextDep || framebuffer.contextDep
|
5611 | result.propDep = result.propDep || framebuffer.propDep
|
5612 | }
|
5613 | return result
|
5614 | } else if (framebuffer) {
|
5615 | return new Declaration(
|
5616 | framebuffer.thisDep,
|
5617 | framebuffer.contextDep,
|
5618 | framebuffer.propDep,
|
5619 | function (env, scope) {
|
5620 | var CONTEXT = env.shared.context
|
5621 | return [
|
5622 | 0, 0,
|
5623 | scope.def(CONTEXT, '.', S_FRAMEBUFFER_WIDTH),
|
5624 | scope.def(CONTEXT, '.', S_FRAMEBUFFER_HEIGHT)]
|
5625 | })
|
5626 | } else {
|
5627 | return null
|
5628 | }
|
5629 | }
|
5630 |
|
5631 | var viewport = parseBox(S_VIEWPORT)
|
5632 |
|
5633 | if (viewport) {
|
5634 | var prevViewport = viewport
|
5635 | viewport = new Declaration(
|
5636 | viewport.thisDep,
|
5637 | viewport.contextDep,
|
5638 | viewport.propDep,
|
5639 | function (env, scope) {
|
5640 | var VIEWPORT = prevViewport.append(env, scope)
|
5641 | var CONTEXT = env.shared.context
|
5642 | scope.set(
|
5643 | CONTEXT,
|
5644 | '.' + S_VIEWPORT_WIDTH,
|
5645 | VIEWPORT[2])
|
5646 | scope.set(
|
5647 | CONTEXT,
|
5648 | '.' + S_VIEWPORT_HEIGHT,
|
5649 | VIEWPORT[3])
|
5650 | return VIEWPORT
|
5651 | })
|
5652 | }
|
5653 |
|
5654 | return {
|
5655 | viewport: viewport,
|
5656 | scissor_box: parseBox(S_SCISSOR_BOX)
|
5657 | }
|
5658 | }
|
5659 |
|
5660 | function parseAttribLocations (options, attributes) {
|
5661 | var staticOptions = options.static
|
5662 | var staticProgram =
|
5663 | typeof staticOptions[S_FRAG] === 'string' &&
|
5664 | typeof staticOptions[S_VERT] === 'string'
|
5665 | if (staticProgram) {
|
5666 | if (Object.keys(attributes.dynamic).length > 0) {
|
5667 | return null
|
5668 | }
|
5669 | var staticAttributes = attributes.static
|
5670 | var sAttributes = Object.keys(staticAttributes)
|
5671 | if (sAttributes.length > 0 && typeof staticAttributes[sAttributes[0]] === 'number') {
|
5672 | var bindings = []
|
5673 | for (var i = 0; i < sAttributes.length; ++i) {
|
5674 |
|
5675 | bindings.push([staticAttributes[sAttributes[i]] | 0, sAttributes[i]])
|
5676 | }
|
5677 | return bindings
|
5678 | }
|
5679 | }
|
5680 | return null
|
5681 | }
|
5682 |
|
5683 | function parseProgram (options, env, attribLocations) {
|
5684 | var staticOptions = options.static
|
5685 | var dynamicOptions = options.dynamic
|
5686 |
|
5687 | function parseShader (name) {
|
5688 | if (name in staticOptions) {
|
5689 | var id = stringStore.id(staticOptions[name])
|
5690 |
|
5691 | var result = createStaticDecl(function () {
|
5692 | return id
|
5693 | })
|
5694 | result.id = id
|
5695 | return result
|
5696 | } else if (name in dynamicOptions) {
|
5697 | var dyn = dynamicOptions[name]
|
5698 | return createDynamicDecl(dyn, function (env, scope) {
|
5699 | var str = env.invoke(scope, dyn)
|
5700 | var id = scope.def(env.shared.strings, '.id(', str, ')')
|
5701 |
|
5702 | return id
|
5703 | })
|
5704 | }
|
5705 | return null
|
5706 | }
|
5707 |
|
5708 | var frag = parseShader(S_FRAG)
|
5709 | var vert = parseShader(S_VERT)
|
5710 |
|
5711 | var program = null
|
5712 | var progVar
|
5713 | if (isStatic(frag) && isStatic(vert)) {
|
5714 | program = shaderState.program(vert.id, frag.id, null, attribLocations)
|
5715 | progVar = createStaticDecl(function (env, scope) {
|
5716 | return env.link(program)
|
5717 | })
|
5718 | } else {
|
5719 | progVar = new Declaration(
|
5720 | (frag && frag.thisDep) || (vert && vert.thisDep),
|
5721 | (frag && frag.contextDep) || (vert && vert.contextDep),
|
5722 | (frag && frag.propDep) || (vert && vert.propDep),
|
5723 | function (env, scope) {
|
5724 | var SHADER_STATE = env.shared.shader
|
5725 | var fragId
|
5726 | if (frag) {
|
5727 | fragId = frag.append(env, scope)
|
5728 | } else {
|
5729 | fragId = scope.def(SHADER_STATE, '.', S_FRAG)
|
5730 | }
|
5731 | var vertId
|
5732 | if (vert) {
|
5733 | vertId = vert.append(env, scope)
|
5734 | } else {
|
5735 | vertId = scope.def(SHADER_STATE, '.', S_VERT)
|
5736 | }
|
5737 | var progDef = SHADER_STATE + '.program(' + vertId + ',' + fragId
|
5738 |
|
5739 | return scope.def(progDef + ')')
|
5740 | })
|
5741 | }
|
5742 |
|
5743 | return {
|
5744 | frag: frag,
|
5745 | vert: vert,
|
5746 | progVar: progVar,
|
5747 | program: program
|
5748 | }
|
5749 | }
|
5750 |
|
5751 | function parseDraw (options, env) {
|
5752 | var staticOptions = options.static
|
5753 | var dynamicOptions = options.dynamic
|
5754 |
|
5755 | function parseElements () {
|
5756 | if (S_ELEMENTS in staticOptions) {
|
5757 | var elements = staticOptions[S_ELEMENTS]
|
5758 | if (isBufferArgs(elements)) {
|
5759 | elements = elementState.getElements(elementState.create(elements, true))
|
5760 | } else if (elements) {
|
5761 | elements = elementState.getElements(elements)
|
5762 |
|
5763 | }
|
5764 | var result = createStaticDecl(function (env, scope) {
|
5765 | if (elements) {
|
5766 | var result = env.link(elements)
|
5767 | env.ELEMENTS = result
|
5768 | return result
|
5769 | }
|
5770 | env.ELEMENTS = null
|
5771 | return null
|
5772 | })
|
5773 | result.value = elements
|
5774 | return result
|
5775 | } else if (S_ELEMENTS in dynamicOptions) {
|
5776 | var dyn = dynamicOptions[S_ELEMENTS]
|
5777 | return createDynamicDecl(dyn, function (env, scope) {
|
5778 | var shared = env.shared
|
5779 |
|
5780 | var IS_BUFFER_ARGS = shared.isBufferArgs
|
5781 | var ELEMENT_STATE = shared.elements
|
5782 |
|
5783 | var elementDefn = env.invoke(scope, dyn)
|
5784 | var elements = scope.def('null')
|
5785 | var elementStream = scope.def(IS_BUFFER_ARGS, '(', elementDefn, ')')
|
5786 |
|
5787 | var ifte = env.cond(elementStream)
|
5788 | .then(elements, '=', ELEMENT_STATE, '.createStream(', elementDefn, ');')
|
5789 | .else(elements, '=', ELEMENT_STATE, '.getElements(', elementDefn, ');')
|
5790 |
|
5791 |
|
5792 |
|
5793 | scope.entry(ifte)
|
5794 | scope.exit(
|
5795 | env.cond(elementStream)
|
5796 | .then(ELEMENT_STATE, '.destroyStream(', elements, ');'))
|
5797 |
|
5798 | env.ELEMENTS = elements
|
5799 |
|
5800 | return elements
|
5801 | })
|
5802 | }
|
5803 |
|
5804 | return null
|
5805 | }
|
5806 |
|
5807 | var elements = parseElements()
|
5808 |
|
5809 | function parsePrimitive () {
|
5810 | if (S_PRIMITIVE in staticOptions) {
|
5811 | var primitive = staticOptions[S_PRIMITIVE]
|
5812 |
|
5813 | return createStaticDecl(function (env, scope) {
|
5814 | return primTypes[primitive]
|
5815 | })
|
5816 | } else if (S_PRIMITIVE in dynamicOptions) {
|
5817 | var dynPrimitive = dynamicOptions[S_PRIMITIVE]
|
5818 | return createDynamicDecl(dynPrimitive, function (env, scope) {
|
5819 | var PRIM_TYPES = env.constants.primTypes
|
5820 | var prim = env.invoke(scope, dynPrimitive)
|
5821 |
|
5822 | return scope.def(PRIM_TYPES, '[', prim, ']')
|
5823 | })
|
5824 | } else if (elements) {
|
5825 | if (isStatic(elements)) {
|
5826 | if (elements.value) {
|
5827 | return createStaticDecl(function (env, scope) {
|
5828 | return scope.def(env.ELEMENTS, '.primType')
|
5829 | })
|
5830 | } else {
|
5831 | return createStaticDecl(function () {
|
5832 | return GL_TRIANGLES$1
|
5833 | })
|
5834 | }
|
5835 | } else {
|
5836 | return new Declaration(
|
5837 | elements.thisDep,
|
5838 | elements.contextDep,
|
5839 | elements.propDep,
|
5840 | function (env, scope) {
|
5841 | var elements = env.ELEMENTS
|
5842 | return scope.def(elements, '?', elements, '.primType:', GL_TRIANGLES$1)
|
5843 | })
|
5844 | }
|
5845 | }
|
5846 | return null
|
5847 | }
|
5848 |
|
5849 | function parseParam (param, isOffset) {
|
5850 | if (param in staticOptions) {
|
5851 | var value = staticOptions[param] | 0
|
5852 |
|
5853 | return createStaticDecl(function (env, scope) {
|
5854 | if (isOffset) {
|
5855 | env.OFFSET = value
|
5856 | }
|
5857 | return value
|
5858 | })
|
5859 | } else if (param in dynamicOptions) {
|
5860 | var dynValue = dynamicOptions[param]
|
5861 | return createDynamicDecl(dynValue, function (env, scope) {
|
5862 | var result = env.invoke(scope, dynValue)
|
5863 | if (isOffset) {
|
5864 | env.OFFSET = result
|
5865 |
|
5866 | }
|
5867 | return result
|
5868 | })
|
5869 | } else if (isOffset && elements) {
|
5870 | return createStaticDecl(function (env, scope) {
|
5871 | env.OFFSET = '0'
|
5872 | return 0
|
5873 | })
|
5874 | }
|
5875 | return null
|
5876 | }
|
5877 |
|
5878 | var OFFSET = parseParam(S_OFFSET, true)
|
5879 |
|
5880 | function parseVertCount () {
|
5881 | if (S_COUNT in staticOptions) {
|
5882 | var count = staticOptions[S_COUNT] | 0
|
5883 |
|
5884 | return createStaticDecl(function () {
|
5885 | return count
|
5886 | })
|
5887 | } else if (S_COUNT in dynamicOptions) {
|
5888 | var dynCount = dynamicOptions[S_COUNT]
|
5889 | return createDynamicDecl(dynCount, function (env, scope) {
|
5890 | var result = env.invoke(scope, dynCount)
|
5891 |
|
5892 | return result
|
5893 | })
|
5894 | } else if (elements) {
|
5895 | if (isStatic(elements)) {
|
5896 | if (elements) {
|
5897 | if (OFFSET) {
|
5898 | return new Declaration(
|
5899 | OFFSET.thisDep,
|
5900 | OFFSET.contextDep,
|
5901 | OFFSET.propDep,
|
5902 | function (env, scope) {
|
5903 | var result = scope.def(
|
5904 | env.ELEMENTS, '.vertCount-', env.OFFSET)
|
5905 |
|
5906 |
|
5907 |
|
5908 | return result
|
5909 | })
|
5910 | } else {
|
5911 | return createStaticDecl(function (env, scope) {
|
5912 | return scope.def(env.ELEMENTS, '.vertCount')
|
5913 | })
|
5914 | }
|
5915 | } else {
|
5916 | var result = createStaticDecl(function () {
|
5917 | return -1
|
5918 | })
|
5919 |
|
5920 | return result
|
5921 | }
|
5922 | } else {
|
5923 | var variable = new Declaration(
|
5924 | elements.thisDep || OFFSET.thisDep,
|
5925 | elements.contextDep || OFFSET.contextDep,
|
5926 | elements.propDep || OFFSET.propDep,
|
5927 | function (env, scope) {
|
5928 | var elements = env.ELEMENTS
|
5929 | if (env.OFFSET) {
|
5930 | return scope.def(elements, '?', elements, '.vertCount-',
|
5931 | env.OFFSET, ':-1')
|
5932 | }
|
5933 | return scope.def(elements, '?', elements, '.vertCount:-1')
|
5934 | })
|
5935 |
|
5936 | return variable
|
5937 | }
|
5938 | }
|
5939 | return null
|
5940 | }
|
5941 |
|
5942 | return {
|
5943 | elements: elements,
|
5944 | primitive: parsePrimitive(),
|
5945 | count: parseVertCount(),
|
5946 | instances: parseParam(S_INSTANCES, false),
|
5947 | offset: OFFSET
|
5948 | }
|
5949 | }
|
5950 |
|
5951 | function parseGLState (options, env) {
|
5952 | var staticOptions = options.static
|
5953 | var dynamicOptions = options.dynamic
|
5954 |
|
5955 | var STATE = {}
|
5956 |
|
5957 | GL_STATE_NAMES.forEach(function (prop) {
|
5958 | var param = propName(prop)
|
5959 |
|
5960 | function parseParam (parseStatic, parseDynamic) {
|
5961 | if (prop in staticOptions) {
|
5962 | var value = parseStatic(staticOptions[prop])
|
5963 | STATE[param] = createStaticDecl(function () {
|
5964 | return value
|
5965 | })
|
5966 | } else if (prop in dynamicOptions) {
|
5967 | var dyn = dynamicOptions[prop]
|
5968 | STATE[param] = createDynamicDecl(dyn, function (env, scope) {
|
5969 | return parseDynamic(env, scope, env.invoke(scope, dyn))
|
5970 | })
|
5971 | }
|
5972 | }
|
5973 |
|
5974 | switch (prop) {
|
5975 | case S_CULL_ENABLE:
|
5976 | case S_BLEND_ENABLE:
|
5977 | case S_DITHER:
|
5978 | case S_STENCIL_ENABLE:
|
5979 | case S_DEPTH_ENABLE:
|
5980 | case S_SCISSOR_ENABLE:
|
5981 | case S_POLYGON_OFFSET_ENABLE:
|
5982 | case S_SAMPLE_ALPHA:
|
5983 | case S_SAMPLE_ENABLE:
|
5984 | case S_DEPTH_MASK:
|
5985 | return parseParam(
|
5986 | function (value) {
|
5987 |
|
5988 | return value
|
5989 | },
|
5990 | function (env, scope, value) {
|
5991 |
|
5992 | return value
|
5993 | })
|
5994 |
|
5995 | case S_DEPTH_FUNC:
|
5996 | return parseParam(
|
5997 | function (value) {
|
5998 |
|
5999 | return compareFuncs[value]
|
6000 | },
|
6001 | function (env, scope, value) {
|
6002 | var COMPARE_FUNCS = env.constants.compareFuncs
|
6003 |
|
6004 | return scope.def(COMPARE_FUNCS, '[', value, ']')
|
6005 | })
|
6006 |
|
6007 | case S_DEPTH_RANGE:
|
6008 | return parseParam(
|
6009 | function (value) {
|
6010 |
|
6011 | return value
|
6012 | },
|
6013 | function (env, scope, value) {
|
6014 |
|
6015 |
|
6016 | var Z_NEAR = scope.def('+', value, '[0]')
|
6017 | var Z_FAR = scope.def('+', value, '[1]')
|
6018 | return [Z_NEAR, Z_FAR]
|
6019 | })
|
6020 |
|
6021 | case S_BLEND_FUNC:
|
6022 | return parseParam(
|
6023 | function (value) {
|
6024 |
|
6025 | var srcRGB = ('srcRGB' in value ? value.srcRGB : value.src)
|
6026 | var srcAlpha = ('srcAlpha' in value ? value.srcAlpha : value.src)
|
6027 | var dstRGB = ('dstRGB' in value ? value.dstRGB : value.dst)
|
6028 | var dstAlpha = ('dstAlpha' in value ? value.dstAlpha : value.dst)
|
6029 |
|
6030 |
|
6031 |
|
6032 |
|
6033 |
|
6034 |
|
6035 |
|
6036 | return [
|
6037 | blendFuncs[srcRGB],
|
6038 | blendFuncs[dstRGB],
|
6039 | blendFuncs[srcAlpha],
|
6040 | blendFuncs[dstAlpha]
|
6041 | ]
|
6042 | },
|
6043 | function (env, scope, value) {
|
6044 | var BLEND_FUNCS = env.constants.blendFuncs
|
6045 |
|
6046 |
|
6047 |
|
6048 | function read (prefix, suffix) {
|
6049 | var func = scope.def(
|
6050 | '"', prefix, suffix, '" in ', value,
|
6051 | '?', value, '.', prefix, suffix,
|
6052 | ':', value, '.', prefix)
|
6053 |
|
6054 |
|
6055 |
|
6056 | return func
|
6057 | }
|
6058 |
|
6059 | var srcRGB = read('src', 'RGB')
|
6060 | var dstRGB = read('dst', 'RGB')
|
6061 |
|
6062 |
|
6063 |
|
6064 | var SRC_RGB = scope.def(BLEND_FUNCS, '[', srcRGB, ']')
|
6065 | var SRC_ALPHA = scope.def(BLEND_FUNCS, '[', read('src', 'Alpha'), ']')
|
6066 | var DST_RGB = scope.def(BLEND_FUNCS, '[', dstRGB, ']')
|
6067 | var DST_ALPHA = scope.def(BLEND_FUNCS, '[', read('dst', 'Alpha'), ']')
|
6068 |
|
6069 | return [SRC_RGB, DST_RGB, SRC_ALPHA, DST_ALPHA]
|
6070 | })
|
6071 |
|
6072 | case S_BLEND_EQUATION:
|
6073 | return parseParam(
|
6074 | function (value) {
|
6075 | if (typeof value === 'string') {
|
6076 |
|
6077 | return [
|
6078 | blendEquations[value],
|
6079 | blendEquations[value]
|
6080 | ]
|
6081 | } else if (typeof value === 'object') {
|
6082 |
|
6083 |
|
6084 | return [
|
6085 | blendEquations[value.rgb],
|
6086 | blendEquations[value.alpha]
|
6087 | ]
|
6088 | } else {
|
6089 |
|
6090 | }
|
6091 | },
|
6092 | function (env, scope, value) {
|
6093 | var BLEND_EQUATIONS = env.constants.blendEquations
|
6094 |
|
6095 | var RGB = scope.def()
|
6096 | var ALPHA = scope.def()
|
6097 |
|
6098 | var ifte = env.cond('typeof ', value, '==="string"')
|
6099 |
|
6100 |
|
6101 |
|
6102 | ifte.then(
|
6103 | RGB, '=', ALPHA, '=', BLEND_EQUATIONS, '[', value, '];')
|
6104 | ifte.else(
|
6105 | RGB, '=', BLEND_EQUATIONS, '[', value, '.rgb];',
|
6106 | ALPHA, '=', BLEND_EQUATIONS, '[', value, '.alpha];')
|
6107 |
|
6108 | scope(ifte)
|
6109 |
|
6110 | return [RGB, ALPHA]
|
6111 | })
|
6112 |
|
6113 | case S_BLEND_COLOR:
|
6114 | return parseParam(
|
6115 | function (value) {
|
6116 |
|
6117 | return loop(4, function (i) {
|
6118 | return +value[i]
|
6119 | })
|
6120 | },
|
6121 | function (env, scope, value) {
|
6122 |
|
6123 | return loop(4, function (i) {
|
6124 | return scope.def('+', value, '[', i, ']')
|
6125 | })
|
6126 | })
|
6127 |
|
6128 | case S_STENCIL_MASK:
|
6129 | return parseParam(
|
6130 | function (value) {
|
6131 |
|
6132 | return value | 0
|
6133 | },
|
6134 | function (env, scope, value) {
|
6135 |
|
6136 | return scope.def(value, '|0')
|
6137 | })
|
6138 |
|
6139 | case S_STENCIL_FUNC:
|
6140 | return parseParam(
|
6141 | function (value) {
|
6142 |
|
6143 | var cmp = value.cmp || 'keep'
|
6144 | var ref = value.ref || 0
|
6145 | var mask = 'mask' in value ? value.mask : -1
|
6146 |
|
6147 |
|
6148 |
|
6149 | return [
|
6150 | compareFuncs[cmp],
|
6151 | ref,
|
6152 | mask
|
6153 | ]
|
6154 | },
|
6155 | function (env, scope, value) {
|
6156 | var COMPARE_FUNCS = env.constants.compareFuncs
|
6157 |
|
6158 | var cmp = scope.def(
|
6159 | '"cmp" in ', value,
|
6160 | '?', COMPARE_FUNCS, '[', value, '.cmp]',
|
6161 | ':', GL_KEEP)
|
6162 | var ref = scope.def(value, '.ref|0')
|
6163 | var mask = scope.def(
|
6164 | '"mask" in ', value,
|
6165 | '?', value, '.mask|0:-1')
|
6166 | return [cmp, ref, mask]
|
6167 | })
|
6168 |
|
6169 | case S_STENCIL_OPFRONT:
|
6170 | case S_STENCIL_OPBACK:
|
6171 | return parseParam(
|
6172 | function (value) {
|
6173 |
|
6174 | var fail = value.fail || 'keep'
|
6175 | var zfail = value.zfail || 'keep'
|
6176 | var zpass = value.zpass || 'keep'
|
6177 |
|
6178 |
|
6179 |
|
6180 | return [
|
6181 | prop === S_STENCIL_OPBACK ? GL_BACK : GL_FRONT,
|
6182 | stencilOps[fail],
|
6183 | stencilOps[zfail],
|
6184 | stencilOps[zpass]
|
6185 | ]
|
6186 | },
|
6187 | function (env, scope, value) {
|
6188 | var STENCIL_OPS = env.constants.stencilOps
|
6189 |
|
6190 |
|
6191 |
|
6192 | function read (name) {
|
6193 |
|
6194 |
|
6195 | return scope.def(
|
6196 | '"', name, '" in ', value,
|
6197 | '?', STENCIL_OPS, '[', value, '.', name, ']:',
|
6198 | GL_KEEP)
|
6199 | }
|
6200 |
|
6201 | return [
|
6202 | prop === S_STENCIL_OPBACK ? GL_BACK : GL_FRONT,
|
6203 | read('fail'),
|
6204 | read('zfail'),
|
6205 | read('zpass')
|
6206 | ]
|
6207 | })
|
6208 |
|
6209 | case S_POLYGON_OFFSET_OFFSET:
|
6210 | return parseParam(
|
6211 | function (value) {
|
6212 |
|
6213 | var factor = value.factor | 0
|
6214 | var units = value.units | 0
|
6215 |
|
6216 |
|
6217 | return [factor, units]
|
6218 | },
|
6219 | function (env, scope, value) {
|
6220 |
|
6221 |
|
6222 | var FACTOR = scope.def(value, '.factor|0')
|
6223 | var UNITS = scope.def(value, '.units|0')
|
6224 |
|
6225 | return [FACTOR, UNITS]
|
6226 | })
|
6227 |
|
6228 | case S_CULL_FACE:
|
6229 | return parseParam(
|
6230 | function (value) {
|
6231 | var face = 0
|
6232 | if (value === 'front') {
|
6233 | face = GL_FRONT
|
6234 | } else if (value === 'back') {
|
6235 | face = GL_BACK
|
6236 | }
|
6237 |
|
6238 | return face
|
6239 | },
|
6240 | function (env, scope, value) {
|
6241 |
|
6242 | return scope.def(value, '==="front"?', GL_FRONT, ':', GL_BACK)
|
6243 | })
|
6244 |
|
6245 | case S_LINE_WIDTH:
|
6246 | return parseParam(
|
6247 | function (value) {
|
6248 |
|
6249 | return value
|
6250 | },
|
6251 | function (env, scope, value) {
|
6252 |
|
6253 |
|
6254 | return value
|
6255 | })
|
6256 |
|
6257 | case S_FRONT_FACE:
|
6258 | return parseParam(
|
6259 | function (value) {
|
6260 |
|
6261 | return orientationType[value]
|
6262 | },
|
6263 | function (env, scope, value) {
|
6264 |
|
6265 | return scope.def(value + '==="cw"?' + GL_CW + ':' + GL_CCW)
|
6266 | })
|
6267 |
|
6268 | case S_COLOR_MASK:
|
6269 | return parseParam(
|
6270 | function (value) {
|
6271 |
|
6272 | return value.map(function (v) { return !!v })
|
6273 | },
|
6274 | function (env, scope, value) {
|
6275 |
|
6276 | return loop(4, function (i) {
|
6277 | return '!!' + value + '[' + i + ']'
|
6278 | })
|
6279 | })
|
6280 |
|
6281 | case S_SAMPLE_COVERAGE:
|
6282 | return parseParam(
|
6283 | function (value) {
|
6284 |
|
6285 | var sampleValue = 'value' in value ? value.value : 1
|
6286 | var sampleInvert = !!value.invert
|
6287 |
|
6288 | return [sampleValue, sampleInvert]
|
6289 | },
|
6290 | function (env, scope, value) {
|
6291 |
|
6292 | var VALUE = scope.def(
|
6293 | '"value" in ', value, '?+', value, '.value:1')
|
6294 | var INVERT = scope.def('!!', value, '.invert')
|
6295 | return [VALUE, INVERT]
|
6296 | })
|
6297 | }
|
6298 | })
|
6299 |
|
6300 | return STATE
|
6301 | }
|
6302 |
|
6303 | function parseUniforms (uniforms, env) {
|
6304 | var staticUniforms = uniforms.static
|
6305 | var dynamicUniforms = uniforms.dynamic
|
6306 |
|
6307 | var UNIFORMS = {}
|
6308 |
|
6309 | Object.keys(staticUniforms).forEach(function (name) {
|
6310 | var value = staticUniforms[name]
|
6311 | var result
|
6312 | if (typeof value === 'number' ||
|
6313 | typeof value === 'boolean') {
|
6314 | result = createStaticDecl(function () {
|
6315 | return value
|
6316 | })
|
6317 | } else if (typeof value === 'function') {
|
6318 | var reglType = value._reglType
|
6319 | if (reglType === 'texture2d' ||
|
6320 | reglType === 'textureCube') {
|
6321 | result = createStaticDecl(function (env) {
|
6322 | return env.link(value)
|
6323 | })
|
6324 | } else if (reglType === 'framebuffer' ||
|
6325 | reglType === 'framebufferCube') {
|
6326 |
|
6327 | result = createStaticDecl(function (env) {
|
6328 | return env.link(value.color[0])
|
6329 | })
|
6330 | } else {
|
6331 |
|
6332 | }
|
6333 | } else if (isArrayLike(value)) {
|
6334 | result = createStaticDecl(function (env) {
|
6335 | var ITEM = env.global.def('[',
|
6336 | loop(value.length, function (i) {
|
6337 |
|
6338 | return value[i]
|
6339 | }), ']')
|
6340 | return ITEM
|
6341 | })
|
6342 | } else {
|
6343 |
|
6344 | }
|
6345 | result.value = value
|
6346 | UNIFORMS[name] = result
|
6347 | })
|
6348 |
|
6349 | Object.keys(dynamicUniforms).forEach(function (key) {
|
6350 | var dyn = dynamicUniforms[key]
|
6351 | UNIFORMS[key] = createDynamicDecl(dyn, function (env, scope) {
|
6352 | return env.invoke(scope, dyn)
|
6353 | })
|
6354 | })
|
6355 |
|
6356 | return UNIFORMS
|
6357 | }
|
6358 |
|
6359 | function parseAttributes (attributes, env) {
|
6360 | var staticAttributes = attributes.static
|
6361 | var dynamicAttributes = attributes.dynamic
|
6362 |
|
6363 | var attributeDefs = {}
|
6364 |
|
6365 | Object.keys(staticAttributes).forEach(function (attribute) {
|
6366 | var value = staticAttributes[attribute]
|
6367 | var id = stringStore.id(attribute)
|
6368 |
|
6369 | var record = new AttributeRecord()
|
6370 | if (isBufferArgs(value)) {
|
6371 | record.state = ATTRIB_STATE_POINTER
|
6372 | record.buffer = bufferState.getBuffer(
|
6373 | bufferState.create(value, GL_ARRAY_BUFFER$2, false, true))
|
6374 | record.type = 0
|
6375 | } else {
|
6376 | var buffer = bufferState.getBuffer(value)
|
6377 | if (buffer) {
|
6378 | record.state = ATTRIB_STATE_POINTER
|
6379 | record.buffer = buffer
|
6380 | record.type = 0
|
6381 | } else {
|
6382 |
|
6383 | if ('constant' in value) {
|
6384 | var constant = value.constant
|
6385 | record.buffer = 'null'
|
6386 | record.state = ATTRIB_STATE_CONSTANT
|
6387 | if (typeof constant === 'number') {
|
6388 | record.x = constant
|
6389 | } else {
|
6390 |
|
6391 | CUTE_COMPONENTS.forEach(function (c, i) {
|
6392 | if (i < constant.length) {
|
6393 | record[c] = constant[i]
|
6394 | }
|
6395 | })
|
6396 | }
|
6397 | } else {
|
6398 | if (isBufferArgs(value.buffer)) {
|
6399 | buffer = bufferState.getBuffer(
|
6400 | bufferState.create(value.buffer, GL_ARRAY_BUFFER$2, false, true))
|
6401 | } else {
|
6402 | buffer = bufferState.getBuffer(value.buffer)
|
6403 | }
|
6404 |
|
6405 |
|
6406 | var offset = value.offset | 0
|
6407 |
|
6408 |
|
6409 | var stride = value.stride | 0
|
6410 |
|
6411 |
|
6412 | var size = value.size | 0
|
6413 |
|
6414 |
|
6415 | var normalized = !!value.normalized
|
6416 |
|
6417 | var type = 0
|
6418 | if ('type' in value) {
|
6419 |
|
6420 | type = glTypes[value.type]
|
6421 | }
|
6422 |
|
6423 | var divisor = value.divisor | 0
|
6424 | if ('divisor' in value) {
|
6425 |
|
6426 |
|
6427 | }
|
6428 |
|
6429 |
|
6430 |
|
6431 | record.buffer = buffer
|
6432 | record.state = ATTRIB_STATE_POINTER
|
6433 | record.size = size
|
6434 | record.normalized = normalized
|
6435 | record.type = type || buffer.dtype
|
6436 | record.offset = offset
|
6437 | record.stride = stride
|
6438 | record.divisor = divisor
|
6439 | }
|
6440 | }
|
6441 | }
|
6442 |
|
6443 | attributeDefs[attribute] = createStaticDecl(function (env, scope) {
|
6444 | var cache = env.attribCache
|
6445 | if (id in cache) {
|
6446 | return cache[id]
|
6447 | }
|
6448 | var result = {
|
6449 | isStream: false
|
6450 | }
|
6451 | Object.keys(record).forEach(function (key) {
|
6452 | result[key] = record[key]
|
6453 | })
|
6454 | if (record.buffer) {
|
6455 | result.buffer = env.link(record.buffer)
|
6456 | result.type = result.type || (result.buffer + '.dtype')
|
6457 | }
|
6458 | cache[id] = result
|
6459 | return result
|
6460 | })
|
6461 | })
|
6462 |
|
6463 | Object.keys(dynamicAttributes).forEach(function (attribute) {
|
6464 | var dyn = dynamicAttributes[attribute]
|
6465 |
|
6466 | function appendAttributeCode (env, block) {
|
6467 | var VALUE = env.invoke(block, dyn)
|
6468 |
|
6469 | var shared = env.shared
|
6470 | var constants = env.constants
|
6471 |
|
6472 | var IS_BUFFER_ARGS = shared.isBufferArgs
|
6473 | var BUFFER_STATE = shared.buffer
|
6474 |
|
6475 |
|
6476 |
|
6477 |
|
6478 |
|
6479 | var result = {
|
6480 | isStream: block.def(false)
|
6481 | }
|
6482 | var defaultRecord = new AttributeRecord()
|
6483 | defaultRecord.state = ATTRIB_STATE_POINTER
|
6484 | Object.keys(defaultRecord).forEach(function (key) {
|
6485 | result[key] = block.def('' + defaultRecord[key])
|
6486 | })
|
6487 |
|
6488 | var BUFFER = result.buffer
|
6489 | var TYPE = result.type
|
6490 | block(
|
6491 | 'if(', IS_BUFFER_ARGS, '(', VALUE, ')){',
|
6492 | result.isStream, '=true;',
|
6493 | BUFFER, '=', BUFFER_STATE, '.createStream(', GL_ARRAY_BUFFER$2, ',', VALUE, ');',
|
6494 | TYPE, '=', BUFFER, '.dtype;',
|
6495 | '}else{',
|
6496 | BUFFER, '=', BUFFER_STATE, '.getBuffer(', VALUE, ');',
|
6497 | 'if(', BUFFER, '){',
|
6498 | TYPE, '=', BUFFER, '.dtype;',
|
6499 | '}else if("constant" in ', VALUE, '){',
|
6500 | result.state, '=', ATTRIB_STATE_CONSTANT, ';',
|
6501 | 'if(typeof ' + VALUE + '.constant === "number"){',
|
6502 | result[CUTE_COMPONENTS[0]], '=', VALUE, '.constant;',
|
6503 | CUTE_COMPONENTS.slice(1).map(function (n) {
|
6504 | return result[n]
|
6505 | }).join('='), '=0;',
|
6506 | '}else{',
|
6507 | CUTE_COMPONENTS.map(function (name, i) {
|
6508 | return (
|
6509 | result[name] + '=' + VALUE + '.constant.length>' + i +
|
6510 | '?' + VALUE + '.constant[' + i + ']:0;'
|
6511 | )
|
6512 | }).join(''),
|
6513 | '}}else{',
|
6514 | 'if(', IS_BUFFER_ARGS, '(', VALUE, '.buffer)){',
|
6515 | BUFFER, '=', BUFFER_STATE, '.createStream(', GL_ARRAY_BUFFER$2, ',', VALUE, '.buffer);',
|
6516 | '}else{',
|
6517 | BUFFER, '=', BUFFER_STATE, '.getBuffer(', VALUE, '.buffer);',
|
6518 | '}',
|
6519 | TYPE, '="type" in ', VALUE, '?',
|
6520 | constants.glTypes, '[', VALUE, '.type]:', BUFFER, '.dtype;',
|
6521 | result.normalized, '=!!', VALUE, '.normalized;')
|
6522 | function emitReadRecord (name) {
|
6523 | block(result[name], '=', VALUE, '.', name, '|0;')
|
6524 | }
|
6525 | emitReadRecord('size')
|
6526 | emitReadRecord('offset')
|
6527 | emitReadRecord('stride')
|
6528 | emitReadRecord('divisor')
|
6529 |
|
6530 | block('}}')
|
6531 |
|
6532 | block.exit(
|
6533 | 'if(', result.isStream, '){',
|
6534 | BUFFER_STATE, '.destroyStream(', BUFFER, ');',
|
6535 | '}')
|
6536 |
|
6537 | return result
|
6538 | }
|
6539 |
|
6540 | attributeDefs[attribute] = createDynamicDecl(dyn, appendAttributeCode)
|
6541 | })
|
6542 |
|
6543 | return attributeDefs
|
6544 | }
|
6545 |
|
6546 | function parseVAO (options, env) {
|
6547 | var staticOptions = options.static
|
6548 | var dynamicOptions = options.dynamic
|
6549 | if (S_VAO in staticOptions) {
|
6550 | var vao = staticOptions[S_VAO]
|
6551 | if (vao !== null && attributeState.getVAO(vao) === null) {
|
6552 | vao = attributeState.createVAO(vao)
|
6553 | }
|
6554 | return createStaticDecl(function (env) {
|
6555 | return env.link(attributeState.getVAO(vao))
|
6556 | })
|
6557 | } else if (S_VAO in dynamicOptions) {
|
6558 | var dyn = dynamicOptions[S_VAO]
|
6559 | return createDynamicDecl(dyn, function (env, scope) {
|
6560 | var vaoRef = env.invoke(scope, dyn)
|
6561 | return scope.def(env.shared.vao + '.getVAO(' + vaoRef + ')')
|
6562 | })
|
6563 | }
|
6564 | return null
|
6565 | }
|
6566 |
|
6567 | function parseContext (context) {
|
6568 | var staticContext = context.static
|
6569 | var dynamicContext = context.dynamic
|
6570 | var result = {}
|
6571 |
|
6572 | Object.keys(staticContext).forEach(function (name) {
|
6573 | var value = staticContext[name]
|
6574 | result[name] = createStaticDecl(function (env, scope) {
|
6575 | if (typeof value === 'number' || typeof value === 'boolean') {
|
6576 | return '' + value
|
6577 | } else {
|
6578 | return env.link(value)
|
6579 | }
|
6580 | })
|
6581 | })
|
6582 |
|
6583 | Object.keys(dynamicContext).forEach(function (name) {
|
6584 | var dyn = dynamicContext[name]
|
6585 | result[name] = createDynamicDecl(dyn, function (env, scope) {
|
6586 | return env.invoke(scope, dyn)
|
6587 | })
|
6588 | })
|
6589 |
|
6590 | return result
|
6591 | }
|
6592 |
|
6593 | function parseArguments (options, attributes, uniforms, context, env) {
|
6594 | var staticOptions = options.static
|
6595 | var dynamicOptions = options.dynamic
|
6596 |
|
6597 |
|
6598 |
|
6599 | var attribLocations = parseAttribLocations(options, attributes)
|
6600 |
|
6601 | var framebuffer = parseFramebuffer(options, env)
|
6602 | var viewportAndScissor = parseViewportScissor(options, framebuffer, env)
|
6603 | var draw = parseDraw(options, env)
|
6604 | var state = parseGLState(options, env)
|
6605 | var shader = parseProgram(options, env, attribLocations)
|
6606 |
|
6607 | function copyBox (name) {
|
6608 | var defn = viewportAndScissor[name]
|
6609 | if (defn) {
|
6610 | state[name] = defn
|
6611 | }
|
6612 | }
|
6613 | copyBox(S_VIEWPORT)
|
6614 | copyBox(propName(S_SCISSOR_BOX))
|
6615 |
|
6616 | var dirty = Object.keys(state).length > 0
|
6617 |
|
6618 | var result = {
|
6619 | framebuffer: framebuffer,
|
6620 | draw: draw,
|
6621 | shader: shader,
|
6622 | state: state,
|
6623 | dirty: dirty,
|
6624 | scopeVAO: null,
|
6625 | drawVAO: null,
|
6626 | useVAO: false,
|
6627 | attributes: {}
|
6628 | }
|
6629 |
|
6630 | result.profile = parseProfile(options, env)
|
6631 | result.uniforms = parseUniforms(uniforms, env)
|
6632 | result.drawVAO = result.scopeVAO = parseVAO(options, env)
|
6633 |
|
6634 | if (!result.drawVAO && shader.program && !attribLocations && extensions.angle_instanced_arrays) {
|
6635 | var useVAO = true
|
6636 | var staticBindings = shader.program.attributes.map(function (attr) {
|
6637 | var binding = attributes.static[attr]
|
6638 | useVAO = useVAO && !!binding
|
6639 | return binding
|
6640 | })
|
6641 | if (useVAO && staticBindings.length > 0) {
|
6642 | var vao = attributeState.getVAO(attributeState.createVAO(staticBindings))
|
6643 | result.drawVAO = new Declaration(null, null, null, function (env, scope) {
|
6644 | return env.link(vao)
|
6645 | })
|
6646 | result.useVAO = true
|
6647 | }
|
6648 | }
|
6649 | if (attribLocations) {
|
6650 | result.useVAO = true
|
6651 | } else {
|
6652 | result.attributes = parseAttributes(attributes, env)
|
6653 | }
|
6654 | result.context = parseContext(context, env)
|
6655 | return result
|
6656 | }
|
6657 |
|
6658 |
|
6659 |
|
6660 |
|
6661 |
|
6662 |
|
6663 | function emitContext (env, scope, context) {
|
6664 | var shared = env.shared
|
6665 | var CONTEXT = shared.context
|
6666 |
|
6667 | var contextEnter = env.scope()
|
6668 |
|
6669 | Object.keys(context).forEach(function (name) {
|
6670 | scope.save(CONTEXT, '.' + name)
|
6671 | var defn = context[name]
|
6672 | contextEnter(CONTEXT, '.', name, '=', defn.append(env, scope), ';')
|
6673 | })
|
6674 |
|
6675 | scope(contextEnter)
|
6676 | }
|
6677 |
|
6678 |
|
6679 |
|
6680 |
|
6681 |
|
6682 |
|
6683 | function emitPollFramebuffer (env, scope, framebuffer, skipCheck) {
|
6684 | var shared = env.shared
|
6685 |
|
6686 | var GL = shared.gl
|
6687 | var FRAMEBUFFER_STATE = shared.framebuffer
|
6688 | var EXT_DRAW_BUFFERS
|
6689 | if (extDrawBuffers) {
|
6690 | EXT_DRAW_BUFFERS = scope.def(shared.extensions, '.webgl_draw_buffers')
|
6691 | }
|
6692 |
|
6693 | var constants = env.constants
|
6694 |
|
6695 | var DRAW_BUFFERS = constants.drawBuffer
|
6696 | var BACK_BUFFER = constants.backBuffer
|
6697 |
|
6698 | var NEXT
|
6699 | if (framebuffer) {
|
6700 | NEXT = framebuffer.append(env, scope)
|
6701 | } else {
|
6702 | NEXT = scope.def(FRAMEBUFFER_STATE, '.next')
|
6703 | }
|
6704 |
|
6705 | if (!skipCheck) {
|
6706 | scope('if(', NEXT, '!==', FRAMEBUFFER_STATE, '.cur){')
|
6707 | }
|
6708 | scope(
|
6709 | 'if(', NEXT, '){',
|
6710 | GL, '.bindFramebuffer(', GL_FRAMEBUFFER$2, ',', NEXT, '.framebuffer);')
|
6711 | if (extDrawBuffers) {
|
6712 | scope(EXT_DRAW_BUFFERS, '.drawBuffersWEBGL(',
|
6713 | DRAW_BUFFERS, '[', NEXT, '.colorAttachments.length]);')
|
6714 | }
|
6715 | scope('}else{',
|
6716 | GL, '.bindFramebuffer(', GL_FRAMEBUFFER$2, ',null);')
|
6717 | if (extDrawBuffers) {
|
6718 | scope(EXT_DRAW_BUFFERS, '.drawBuffersWEBGL(', BACK_BUFFER, ');')
|
6719 | }
|
6720 | scope(
|
6721 | '}',
|
6722 | FRAMEBUFFER_STATE, '.cur=', NEXT, ';')
|
6723 | if (!skipCheck) {
|
6724 | scope('}')
|
6725 | }
|
6726 | }
|
6727 |
|
6728 | function emitPollState (env, scope, args) {
|
6729 | var shared = env.shared
|
6730 |
|
6731 | var GL = shared.gl
|
6732 |
|
6733 | var CURRENT_VARS = env.current
|
6734 | var NEXT_VARS = env.next
|
6735 | var CURRENT_STATE = shared.current
|
6736 | var NEXT_STATE = shared.next
|
6737 |
|
6738 | var block = env.cond(CURRENT_STATE, '.dirty')
|
6739 |
|
6740 | GL_STATE_NAMES.forEach(function (prop) {
|
6741 | var param = propName(prop)
|
6742 | if (param in args.state) {
|
6743 | return
|
6744 | }
|
6745 |
|
6746 | var NEXT, CURRENT
|
6747 | if (param in NEXT_VARS) {
|
6748 | NEXT = NEXT_VARS[param]
|
6749 | CURRENT = CURRENT_VARS[param]
|
6750 | var parts = loop(currentState[param].length, function (i) {
|
6751 | return block.def(NEXT, '[', i, ']')
|
6752 | })
|
6753 | block(env.cond(parts.map(function (p, i) {
|
6754 | return p + '!==' + CURRENT + '[' + i + ']'
|
6755 | }).join('||'))
|
6756 | .then(
|
6757 | GL, '.', GL_VARIABLES[param], '(', parts, ');',
|
6758 | parts.map(function (p, i) {
|
6759 | return CURRENT + '[' + i + ']=' + p
|
6760 | }).join(';'), ';'))
|
6761 | } else {
|
6762 | NEXT = block.def(NEXT_STATE, '.', param)
|
6763 | var ifte = env.cond(NEXT, '!==', CURRENT_STATE, '.', param)
|
6764 | block(ifte)
|
6765 | if (param in GL_FLAGS) {
|
6766 | ifte(
|
6767 | env.cond(NEXT)
|
6768 | .then(GL, '.enable(', GL_FLAGS[param], ');')
|
6769 | .else(GL, '.disable(', GL_FLAGS[param], ');'),
|
6770 | CURRENT_STATE, '.', param, '=', NEXT, ';')
|
6771 | } else {
|
6772 | ifte(
|
6773 | GL, '.', GL_VARIABLES[param], '(', NEXT, ');',
|
6774 | CURRENT_STATE, '.', param, '=', NEXT, ';')
|
6775 | }
|
6776 | }
|
6777 | })
|
6778 | if (Object.keys(args.state).length === 0) {
|
6779 | block(CURRENT_STATE, '.dirty=false;')
|
6780 | }
|
6781 | scope(block)
|
6782 | }
|
6783 |
|
6784 | function emitSetOptions (env, scope, options, filter) {
|
6785 | var shared = env.shared
|
6786 | var CURRENT_VARS = env.current
|
6787 | var CURRENT_STATE = shared.current
|
6788 | var GL = shared.gl
|
6789 | sortState(Object.keys(options)).forEach(function (param) {
|
6790 | var defn = options[param]
|
6791 | if (filter && !filter(defn)) {
|
6792 | return
|
6793 | }
|
6794 | var variable = defn.append(env, scope)
|
6795 | if (GL_FLAGS[param]) {
|
6796 | var flag = GL_FLAGS[param]
|
6797 | if (isStatic(defn)) {
|
6798 | if (variable) {
|
6799 | scope(GL, '.enable(', flag, ');')
|
6800 | } else {
|
6801 | scope(GL, '.disable(', flag, ');')
|
6802 | }
|
6803 | } else {
|
6804 | scope(env.cond(variable)
|
6805 | .then(GL, '.enable(', flag, ');')
|
6806 | .else(GL, '.disable(', flag, ');'))
|
6807 | }
|
6808 | scope(CURRENT_STATE, '.', param, '=', variable, ';')
|
6809 | } else if (isArrayLike(variable)) {
|
6810 | var CURRENT = CURRENT_VARS[param]
|
6811 | scope(
|
6812 | GL, '.', GL_VARIABLES[param], '(', variable, ');',
|
6813 | variable.map(function (v, i) {
|
6814 | return CURRENT + '[' + i + ']=' + v
|
6815 | }).join(';'), ';')
|
6816 | } else {
|
6817 | scope(
|
6818 | GL, '.', GL_VARIABLES[param], '(', variable, ');',
|
6819 | CURRENT_STATE, '.', param, '=', variable, ';')
|
6820 | }
|
6821 | })
|
6822 | }
|
6823 |
|
6824 | function injectExtensions (env, scope) {
|
6825 | if (extInstancing) {
|
6826 | env.instancing = scope.def(
|
6827 | env.shared.extensions, '.angle_instanced_arrays')
|
6828 | }
|
6829 | }
|
6830 |
|
6831 | function emitProfile (env, scope, args, useScope, incrementCounter) {
|
6832 | var shared = env.shared
|
6833 | var STATS = env.stats
|
6834 | var CURRENT_STATE = shared.current
|
6835 | var TIMER = shared.timer
|
6836 | var profileArg = args.profile
|
6837 |
|
6838 | function perfCounter () {
|
6839 | if (typeof performance === 'undefined') {
|
6840 | return 'Date.now()'
|
6841 | } else {
|
6842 | return 'performance.now()'
|
6843 | }
|
6844 | }
|
6845 |
|
6846 | var CPU_START, QUERY_COUNTER
|
6847 | function emitProfileStart (block) {
|
6848 | CPU_START = scope.def()
|
6849 | block(CPU_START, '=', perfCounter(), ';')
|
6850 | if (typeof incrementCounter === 'string') {
|
6851 | block(STATS, '.count+=', incrementCounter, ';')
|
6852 | } else {
|
6853 | block(STATS, '.count++;')
|
6854 | }
|
6855 | if (timer) {
|
6856 | if (useScope) {
|
6857 | QUERY_COUNTER = scope.def()
|
6858 | block(QUERY_COUNTER, '=', TIMER, '.getNumPendingQueries();')
|
6859 | } else {
|
6860 | block(TIMER, '.beginQuery(', STATS, ');')
|
6861 | }
|
6862 | }
|
6863 | }
|
6864 |
|
6865 | function emitProfileEnd (block) {
|
6866 | block(STATS, '.cpuTime+=', perfCounter(), '-', CPU_START, ';')
|
6867 | if (timer) {
|
6868 | if (useScope) {
|
6869 | block(TIMER, '.pushScopeStats(',
|
6870 | QUERY_COUNTER, ',',
|
6871 | TIMER, '.getNumPendingQueries(),',
|
6872 | STATS, ');')
|
6873 | } else {
|
6874 | block(TIMER, '.endQuery();')
|
6875 | }
|
6876 | }
|
6877 | }
|
6878 |
|
6879 | function scopeProfile (value) {
|
6880 | var prev = scope.def(CURRENT_STATE, '.profile')
|
6881 | scope(CURRENT_STATE, '.profile=', value, ';')
|
6882 | scope.exit(CURRENT_STATE, '.profile=', prev, ';')
|
6883 | }
|
6884 |
|
6885 | var USE_PROFILE
|
6886 | if (profileArg) {
|
6887 | if (isStatic(profileArg)) {
|
6888 | if (profileArg.enable) {
|
6889 | emitProfileStart(scope)
|
6890 | emitProfileEnd(scope.exit)
|
6891 | scopeProfile('true')
|
6892 | } else {
|
6893 | scopeProfile('false')
|
6894 | }
|
6895 | return
|
6896 | }
|
6897 | USE_PROFILE = profileArg.append(env, scope)
|
6898 | scopeProfile(USE_PROFILE)
|
6899 | } else {
|
6900 | USE_PROFILE = scope.def(CURRENT_STATE, '.profile')
|
6901 | }
|
6902 |
|
6903 | var start = env.block()
|
6904 | emitProfileStart(start)
|
6905 | scope('if(', USE_PROFILE, '){', start, '}')
|
6906 | var end = env.block()
|
6907 | emitProfileEnd(end)
|
6908 | scope.exit('if(', USE_PROFILE, '){', end, '}')
|
6909 | }
|
6910 |
|
6911 | function emitAttributes (env, scope, args, attributes, filter) {
|
6912 | var shared = env.shared
|
6913 |
|
6914 | function typeLength (x) {
|
6915 | switch (x) {
|
6916 | case GL_FLOAT_VEC2:
|
6917 | case GL_INT_VEC2:
|
6918 | case GL_BOOL_VEC2:
|
6919 | return 2
|
6920 | case GL_FLOAT_VEC3:
|
6921 | case GL_INT_VEC3:
|
6922 | case GL_BOOL_VEC3:
|
6923 | return 3
|
6924 | case GL_FLOAT_VEC4:
|
6925 | case GL_INT_VEC4:
|
6926 | case GL_BOOL_VEC4:
|
6927 | return 4
|
6928 | default:
|
6929 | return 1
|
6930 | }
|
6931 | }
|
6932 |
|
6933 | function emitBindAttribute (ATTRIBUTE, size, record) {
|
6934 | var GL = shared.gl
|
6935 |
|
6936 | var LOCATION = scope.def(ATTRIBUTE, '.location')
|
6937 | var BINDING = scope.def(shared.attributes, '[', LOCATION, ']')
|
6938 |
|
6939 | var STATE = record.state
|
6940 | var BUFFER = record.buffer
|
6941 | var CONST_COMPONENTS = [
|
6942 | record.x,
|
6943 | record.y,
|
6944 | record.z,
|
6945 | record.w
|
6946 | ]
|
6947 |
|
6948 | var COMMON_KEYS = [
|
6949 | 'buffer',
|
6950 | 'normalized',
|
6951 | 'offset',
|
6952 | 'stride'
|
6953 | ]
|
6954 |
|
6955 | function emitBuffer () {
|
6956 | scope(
|
6957 | 'if(!', BINDING, '.buffer){',
|
6958 | GL, '.enableVertexAttribArray(', LOCATION, ');}')
|
6959 |
|
6960 | var TYPE = record.type
|
6961 | var SIZE
|
6962 | if (!record.size) {
|
6963 | SIZE = size
|
6964 | } else {
|
6965 | SIZE = scope.def(record.size, '||', size)
|
6966 | }
|
6967 |
|
6968 | scope('if(',
|
6969 | BINDING, '.type!==', TYPE, '||',
|
6970 | BINDING, '.size!==', SIZE, '||',
|
6971 | COMMON_KEYS.map(function (key) {
|
6972 | return BINDING + '.' + key + '!==' + record[key]
|
6973 | }).join('||'),
|
6974 | '){',
|
6975 | GL, '.bindBuffer(', GL_ARRAY_BUFFER$2, ',', BUFFER, '.buffer);',
|
6976 | GL, '.vertexAttribPointer(', [
|
6977 | LOCATION,
|
6978 | SIZE,
|
6979 | TYPE,
|
6980 | record.normalized,
|
6981 | record.stride,
|
6982 | record.offset
|
6983 | ], ');',
|
6984 | BINDING, '.type=', TYPE, ';',
|
6985 | BINDING, '.size=', SIZE, ';',
|
6986 | COMMON_KEYS.map(function (key) {
|
6987 | return BINDING + '.' + key + '=' + record[key] + ';'
|
6988 | }).join(''),
|
6989 | '}')
|
6990 |
|
6991 | if (extInstancing) {
|
6992 | var DIVISOR = record.divisor
|
6993 | scope(
|
6994 | 'if(', BINDING, '.divisor!==', DIVISOR, '){',
|
6995 | env.instancing, '.vertexAttribDivisorANGLE(', [LOCATION, DIVISOR], ');',
|
6996 | BINDING, '.divisor=', DIVISOR, ';}')
|
6997 | }
|
6998 | }
|
6999 |
|
7000 | function emitConstant () {
|
7001 | scope(
|
7002 | 'if(', BINDING, '.buffer){',
|
7003 | GL, '.disableVertexAttribArray(', LOCATION, ');',
|
7004 | BINDING, '.buffer=null;',
|
7005 | '}if(', CUTE_COMPONENTS.map(function (c, i) {
|
7006 | return BINDING + '.' + c + '!==' + CONST_COMPONENTS[i]
|
7007 | }).join('||'), '){',
|
7008 | GL, '.vertexAttrib4f(', LOCATION, ',', CONST_COMPONENTS, ');',
|
7009 | CUTE_COMPONENTS.map(function (c, i) {
|
7010 | return BINDING + '.' + c + '=' + CONST_COMPONENTS[i] + ';'
|
7011 | }).join(''),
|
7012 | '}')
|
7013 | }
|
7014 |
|
7015 | if (STATE === ATTRIB_STATE_POINTER) {
|
7016 | emitBuffer()
|
7017 | } else if (STATE === ATTRIB_STATE_CONSTANT) {
|
7018 | emitConstant()
|
7019 | } else {
|
7020 | scope('if(', STATE, '===', ATTRIB_STATE_POINTER, '){')
|
7021 | emitBuffer()
|
7022 | scope('}else{')
|
7023 | emitConstant()
|
7024 | scope('}')
|
7025 | }
|
7026 | }
|
7027 |
|
7028 | attributes.forEach(function (attribute) {
|
7029 | var name = attribute.name
|
7030 | var arg = args.attributes[name]
|
7031 | var record
|
7032 | if (arg) {
|
7033 | if (!filter(arg)) {
|
7034 | return
|
7035 | }
|
7036 | record = arg.append(env, scope)
|
7037 | } else {
|
7038 | if (!filter(SCOPE_DECL)) {
|
7039 | return
|
7040 | }
|
7041 | var scopeAttrib = env.scopeAttrib(name)
|
7042 |
|
7043 | record = {}
|
7044 | Object.keys(new AttributeRecord()).forEach(function (key) {
|
7045 | record[key] = scope.def(scopeAttrib, '.', key)
|
7046 | })
|
7047 | }
|
7048 | emitBindAttribute(
|
7049 | env.link(attribute), typeLength(attribute.info.type), record)
|
7050 | })
|
7051 | }
|
7052 |
|
7053 | function emitUniforms (env, scope, args, uniforms, filter) {
|
7054 | var shared = env.shared
|
7055 | var GL = shared.gl
|
7056 |
|
7057 | var infix
|
7058 | for (var i = 0; i < uniforms.length; ++i) {
|
7059 | var uniform = uniforms[i]
|
7060 | var name = uniform.name
|
7061 | var type = uniform.info.type
|
7062 | var arg = args.uniforms[name]
|
7063 | var UNIFORM = env.link(uniform)
|
7064 | var LOCATION = UNIFORM + '.location'
|
7065 |
|
7066 | var VALUE
|
7067 | if (arg) {
|
7068 | if (!filter(arg)) {
|
7069 | continue
|
7070 | }
|
7071 | if (isStatic(arg)) {
|
7072 | var value = arg.value
|
7073 |
|
7074 | if (type === GL_SAMPLER_2D || type === GL_SAMPLER_CUBE) {
|
7075 |
|
7076 | var TEX_VALUE = env.link(value._texture || value.color[0]._texture)
|
7077 | scope(GL, '.uniform1i(', LOCATION, ',', TEX_VALUE + '.bind());')
|
7078 | scope.exit(TEX_VALUE, '.unbind();')
|
7079 | } else if (
|
7080 | type === GL_FLOAT_MAT2 ||
|
7081 | type === GL_FLOAT_MAT3 ||
|
7082 | type === GL_FLOAT_MAT4) {
|
7083 |
|
7084 | var MAT_VALUE = env.global.def('new Float32Array([' +
|
7085 | Array.prototype.slice.call(value) + '])')
|
7086 | var dim = 2
|
7087 | if (type === GL_FLOAT_MAT3) {
|
7088 | dim = 3
|
7089 | } else if (type === GL_FLOAT_MAT4) {
|
7090 | dim = 4
|
7091 | }
|
7092 | scope(
|
7093 | GL, '.uniformMatrix', dim, 'fv(',
|
7094 | LOCATION, ',false,', MAT_VALUE, ');')
|
7095 | } else {
|
7096 | switch (type) {
|
7097 | case GL_FLOAT$7:
|
7098 |
|
7099 | infix = '1f'
|
7100 | break
|
7101 | case GL_FLOAT_VEC2:
|
7102 |
|
7103 | infix = '2f'
|
7104 | break
|
7105 | case GL_FLOAT_VEC3:
|
7106 |
|
7107 | infix = '3f'
|
7108 | break
|
7109 | case GL_FLOAT_VEC4:
|
7110 |
|
7111 | infix = '4f'
|
7112 | break
|
7113 | case GL_BOOL:
|
7114 |
|
7115 | infix = '1i'
|
7116 | break
|
7117 | case GL_INT$2:
|
7118 |
|
7119 | infix = '1i'
|
7120 | break
|
7121 | case GL_BOOL_VEC2:
|
7122 |
|
7123 | infix = '2i'
|
7124 | break
|
7125 | case GL_INT_VEC2:
|
7126 |
|
7127 | infix = '2i'
|
7128 | break
|
7129 | case GL_BOOL_VEC3:
|
7130 |
|
7131 | infix = '3i'
|
7132 | break
|
7133 | case GL_INT_VEC3:
|
7134 |
|
7135 | infix = '3i'
|
7136 | break
|
7137 | case GL_BOOL_VEC4:
|
7138 |
|
7139 | infix = '4i'
|
7140 | break
|
7141 | case GL_INT_VEC4:
|
7142 |
|
7143 | infix = '4i'
|
7144 | break
|
7145 | }
|
7146 | scope(GL, '.uniform', infix, '(', LOCATION, ',',
|
7147 | isArrayLike(value) ? Array.prototype.slice.call(value) : value,
|
7148 | ');')
|
7149 | }
|
7150 | continue
|
7151 | } else {
|
7152 | VALUE = arg.append(env, scope)
|
7153 | }
|
7154 | } else {
|
7155 | if (!filter(SCOPE_DECL)) {
|
7156 | continue
|
7157 | }
|
7158 | VALUE = scope.def(shared.uniforms, '[', stringStore.id(name), ']')
|
7159 | }
|
7160 |
|
7161 | if (type === GL_SAMPLER_2D) {
|
7162 | scope(
|
7163 | 'if(', VALUE, '&&', VALUE, '._reglType==="framebuffer"){',
|
7164 | VALUE, '=', VALUE, '.color[0];',
|
7165 | '}')
|
7166 | } else if (type === GL_SAMPLER_CUBE) {
|
7167 | scope(
|
7168 | 'if(', VALUE, '&&', VALUE, '._reglType==="framebufferCube"){',
|
7169 | VALUE, '=', VALUE, '.color[0];',
|
7170 | '}')
|
7171 | }
|
7172 |
|
7173 |
|
7174 |
|
7175 |
|
7176 | var unroll = 1
|
7177 | switch (type) {
|
7178 | case GL_SAMPLER_2D:
|
7179 | case GL_SAMPLER_CUBE:
|
7180 | var TEX = scope.def(VALUE, '._texture')
|
7181 | scope(GL, '.uniform1i(', LOCATION, ',', TEX, '.bind());')
|
7182 | scope.exit(TEX, '.unbind();')
|
7183 | continue
|
7184 |
|
7185 | case GL_INT$2:
|
7186 | case GL_BOOL:
|
7187 | infix = '1i'
|
7188 | break
|
7189 |
|
7190 | case GL_INT_VEC2:
|
7191 | case GL_BOOL_VEC2:
|
7192 | infix = '2i'
|
7193 | unroll = 2
|
7194 | break
|
7195 |
|
7196 | case GL_INT_VEC3:
|
7197 | case GL_BOOL_VEC3:
|
7198 | infix = '3i'
|
7199 | unroll = 3
|
7200 | break
|
7201 |
|
7202 | case GL_INT_VEC4:
|
7203 | case GL_BOOL_VEC4:
|
7204 | infix = '4i'
|
7205 | unroll = 4
|
7206 | break
|
7207 |
|
7208 | case GL_FLOAT$7:
|
7209 | infix = '1f'
|
7210 | break
|
7211 |
|
7212 | case GL_FLOAT_VEC2:
|
7213 | infix = '2f'
|
7214 | unroll = 2
|
7215 | break
|
7216 |
|
7217 | case GL_FLOAT_VEC3:
|
7218 | infix = '3f'
|
7219 | unroll = 3
|
7220 | break
|
7221 |
|
7222 | case GL_FLOAT_VEC4:
|
7223 | infix = '4f'
|
7224 | unroll = 4
|
7225 | break
|
7226 |
|
7227 | case GL_FLOAT_MAT2:
|
7228 | infix = 'Matrix2fv'
|
7229 | break
|
7230 |
|
7231 | case GL_FLOAT_MAT3:
|
7232 | infix = 'Matrix3fv'
|
7233 | break
|
7234 |
|
7235 | case GL_FLOAT_MAT4:
|
7236 | infix = 'Matrix4fv'
|
7237 | break
|
7238 | }
|
7239 |
|
7240 | scope(GL, '.uniform', infix, '(', LOCATION, ',')
|
7241 | if (infix.charAt(0) === 'M') {
|
7242 | var matSize = Math.pow(type - GL_FLOAT_MAT2 + 2, 2)
|
7243 | var STORAGE = env.global.def('new Float32Array(', matSize, ')')
|
7244 | scope(
|
7245 | 'false,(Array.isArray(', VALUE, ')||', VALUE, ' instanceof Float32Array)?', VALUE, ':(',
|
7246 | loop(matSize, function (i) {
|
7247 | return STORAGE + '[' + i + ']=' + VALUE + '[' + i + ']'
|
7248 | }), ',', STORAGE, ')')
|
7249 | } else if (unroll > 1) {
|
7250 | scope(loop(unroll, function (i) {
|
7251 | return VALUE + '[' + i + ']'
|
7252 | }))
|
7253 | } else {
|
7254 | scope(VALUE)
|
7255 | }
|
7256 | scope(');')
|
7257 | }
|
7258 | }
|
7259 |
|
7260 | function emitDraw (env, outer, inner, args) {
|
7261 | var shared = env.shared
|
7262 | var GL = shared.gl
|
7263 | var DRAW_STATE = shared.draw
|
7264 |
|
7265 | var drawOptions = args.draw
|
7266 |
|
7267 | function emitElements () {
|
7268 | var defn = drawOptions.elements
|
7269 | var ELEMENTS
|
7270 | var scope = outer
|
7271 | if (defn) {
|
7272 | if ((defn.contextDep && args.contextDynamic) || defn.propDep) {
|
7273 | scope = inner
|
7274 | }
|
7275 | ELEMENTS = defn.append(env, scope)
|
7276 | } else {
|
7277 | ELEMENTS = scope.def(DRAW_STATE, '.', S_ELEMENTS)
|
7278 | }
|
7279 | if (ELEMENTS) {
|
7280 | scope(
|
7281 | 'if(' + ELEMENTS + ')' +
|
7282 | GL + '.bindBuffer(' + GL_ELEMENT_ARRAY_BUFFER$1 + ',' + ELEMENTS + '.buffer.buffer);')
|
7283 | }
|
7284 | return ELEMENTS
|
7285 | }
|
7286 |
|
7287 | function emitCount () {
|
7288 | var defn = drawOptions.count
|
7289 | var COUNT
|
7290 | var scope = outer
|
7291 | if (defn) {
|
7292 | if ((defn.contextDep && args.contextDynamic) || defn.propDep) {
|
7293 | scope = inner
|
7294 | }
|
7295 | COUNT = defn.append(env, scope)
|
7296 |
|
7297 | } else {
|
7298 | COUNT = scope.def(DRAW_STATE, '.', S_COUNT)
|
7299 |
|
7300 | }
|
7301 | return COUNT
|
7302 | }
|
7303 |
|
7304 | var ELEMENTS = emitElements()
|
7305 | function emitValue (name) {
|
7306 | var defn = drawOptions[name]
|
7307 | if (defn) {
|
7308 | if ((defn.contextDep && args.contextDynamic) || defn.propDep) {
|
7309 | return defn.append(env, inner)
|
7310 | } else {
|
7311 | return defn.append(env, outer)
|
7312 | }
|
7313 | } else {
|
7314 | return outer.def(DRAW_STATE, '.', name)
|
7315 | }
|
7316 | }
|
7317 |
|
7318 | var PRIMITIVE = emitValue(S_PRIMITIVE)
|
7319 | var OFFSET = emitValue(S_OFFSET)
|
7320 |
|
7321 | var COUNT = emitCount()
|
7322 | if (typeof COUNT === 'number') {
|
7323 | if (COUNT === 0) {
|
7324 | return
|
7325 | }
|
7326 | } else {
|
7327 | inner('if(', COUNT, '){')
|
7328 | inner.exit('}')
|
7329 | }
|
7330 |
|
7331 | var INSTANCES, EXT_INSTANCING
|
7332 | if (extInstancing) {
|
7333 | INSTANCES = emitValue(S_INSTANCES)
|
7334 | EXT_INSTANCING = env.instancing
|
7335 | }
|
7336 |
|
7337 | var ELEMENT_TYPE = ELEMENTS + '.type'
|
7338 |
|
7339 | var elementsStatic = drawOptions.elements && isStatic(drawOptions.elements)
|
7340 |
|
7341 | function emitInstancing () {
|
7342 | function drawElements () {
|
7343 | inner(EXT_INSTANCING, '.drawElementsInstancedANGLE(', [
|
7344 | PRIMITIVE,
|
7345 | COUNT,
|
7346 | ELEMENT_TYPE,
|
7347 | OFFSET + '<<((' + ELEMENT_TYPE + '-' + GL_UNSIGNED_BYTE$7 + ')>>1)',
|
7348 | INSTANCES
|
7349 | ], ');')
|
7350 | }
|
7351 |
|
7352 | function drawArrays () {
|
7353 | inner(EXT_INSTANCING, '.drawArraysInstancedANGLE(',
|
7354 | [PRIMITIVE, OFFSET, COUNT, INSTANCES], ');')
|
7355 | }
|
7356 |
|
7357 | if (ELEMENTS) {
|
7358 | if (!elementsStatic) {
|
7359 | inner('if(', ELEMENTS, '){')
|
7360 | drawElements()
|
7361 | inner('}else{')
|
7362 | drawArrays()
|
7363 | inner('}')
|
7364 | } else {
|
7365 | drawElements()
|
7366 | }
|
7367 | } else {
|
7368 | drawArrays()
|
7369 | }
|
7370 | }
|
7371 |
|
7372 | function emitRegular () {
|
7373 | function drawElements () {
|
7374 | inner(GL + '.drawElements(' + [
|
7375 | PRIMITIVE,
|
7376 | COUNT,
|
7377 | ELEMENT_TYPE,
|
7378 | OFFSET + '<<((' + ELEMENT_TYPE + '-' + GL_UNSIGNED_BYTE$7 + ')>>1)'
|
7379 | ] + ');')
|
7380 | }
|
7381 |
|
7382 | function drawArrays () {
|
7383 | inner(GL + '.drawArrays(' + [PRIMITIVE, OFFSET, COUNT] + ');')
|
7384 | }
|
7385 |
|
7386 | if (ELEMENTS) {
|
7387 | if (!elementsStatic) {
|
7388 | inner('if(', ELEMENTS, '){')
|
7389 | drawElements()
|
7390 | inner('}else{')
|
7391 | drawArrays()
|
7392 | inner('}')
|
7393 | } else {
|
7394 | drawElements()
|
7395 | }
|
7396 | } else {
|
7397 | drawArrays()
|
7398 | }
|
7399 | }
|
7400 |
|
7401 | if (extInstancing && (typeof INSTANCES !== 'number' || INSTANCES >= 0)) {
|
7402 | if (typeof INSTANCES === 'string') {
|
7403 | inner('if(', INSTANCES, '>0){')
|
7404 | emitInstancing()
|
7405 | inner('}else if(', INSTANCES, '<0){')
|
7406 | emitRegular()
|
7407 | inner('}')
|
7408 | } else {
|
7409 | emitInstancing()
|
7410 | }
|
7411 | } else {
|
7412 | emitRegular()
|
7413 | }
|
7414 | }
|
7415 |
|
7416 | function createBody (emitBody, parentEnv, args, program, count) {
|
7417 | var env = createREGLEnvironment()
|
7418 | var scope = env.proc('body', count)
|
7419 |
|
7420 | if (extInstancing) {
|
7421 | env.instancing = scope.def(
|
7422 | env.shared.extensions, '.angle_instanced_arrays')
|
7423 | }
|
7424 | emitBody(env, scope, args, program)
|
7425 | return env.compile().body
|
7426 | }
|
7427 |
|
7428 |
|
7429 |
|
7430 |
|
7431 |
|
7432 |
|
7433 | function emitDrawBody (env, draw, args, program) {
|
7434 | injectExtensions(env, draw)
|
7435 | if (args.useVAO) {
|
7436 | if (args.drawVAO) {
|
7437 | draw(env.shared.vao, '.setVAO(', args.drawVAO.append(env, draw), ');')
|
7438 | } else {
|
7439 | draw(env.shared.vao, '.setVAO(', env.shared.vao, '.targetVAO);')
|
7440 | }
|
7441 | } else {
|
7442 | draw(env.shared.vao, '.setVAO(null);')
|
7443 | emitAttributes(env, draw, args, program.attributes, function () {
|
7444 | return true
|
7445 | })
|
7446 | }
|
7447 | emitUniforms(env, draw, args, program.uniforms, function () {
|
7448 | return true
|
7449 | })
|
7450 | emitDraw(env, draw, draw, args)
|
7451 | }
|
7452 |
|
7453 | function emitDrawProc (env, args) {
|
7454 | var draw = env.proc('draw', 1)
|
7455 |
|
7456 | injectExtensions(env, draw)
|
7457 |
|
7458 | emitContext(env, draw, args.context)
|
7459 | emitPollFramebuffer(env, draw, args.framebuffer)
|
7460 |
|
7461 | emitPollState(env, draw, args)
|
7462 | emitSetOptions(env, draw, args.state)
|
7463 |
|
7464 | emitProfile(env, draw, args, false, true)
|
7465 |
|
7466 | var program = args.shader.progVar.append(env, draw)
|
7467 | draw(env.shared.gl, '.useProgram(', program, '.program);')
|
7468 |
|
7469 | if (args.shader.program) {
|
7470 | emitDrawBody(env, draw, args, args.shader.program)
|
7471 | } else {
|
7472 | draw(env.shared.vao, '.setVAO(null);')
|
7473 | var drawCache = env.global.def('{}')
|
7474 | var PROG_ID = draw.def(program, '.id')
|
7475 | var CACHED_PROC = draw.def(drawCache, '[', PROG_ID, ']')
|
7476 | draw(
|
7477 | env.cond(CACHED_PROC)
|
7478 | .then(CACHED_PROC, '.call(this,a0);')
|
7479 | .else(
|
7480 | CACHED_PROC, '=', drawCache, '[', PROG_ID, ']=',
|
7481 | env.link(function (program) {
|
7482 | return createBody(emitDrawBody, env, args, program, 1)
|
7483 | }), '(', program, ');',
|
7484 | CACHED_PROC, '.call(this,a0);'))
|
7485 | }
|
7486 |
|
7487 | if (Object.keys(args.state).length > 0) {
|
7488 | draw(env.shared.current, '.dirty=true;')
|
7489 | }
|
7490 | }
|
7491 |
|
7492 |
|
7493 |
|
7494 |
|
7495 |
|
7496 |
|
7497 |
|
7498 | function emitBatchDynamicShaderBody (env, scope, args, program) {
|
7499 | env.batchId = 'a1'
|
7500 |
|
7501 | injectExtensions(env, scope)
|
7502 |
|
7503 | function all () {
|
7504 | return true
|
7505 | }
|
7506 |
|
7507 | emitAttributes(env, scope, args, program.attributes, all)
|
7508 | emitUniforms(env, scope, args, program.uniforms, all)
|
7509 | emitDraw(env, scope, scope, args)
|
7510 | }
|
7511 |
|
7512 | function emitBatchBody (env, scope, args, program) {
|
7513 | injectExtensions(env, scope)
|
7514 |
|
7515 | var contextDynamic = args.contextDep
|
7516 |
|
7517 | var BATCH_ID = scope.def()
|
7518 | var PROP_LIST = 'a0'
|
7519 | var NUM_PROPS = 'a1'
|
7520 | var PROPS = scope.def()
|
7521 | env.shared.props = PROPS
|
7522 | env.batchId = BATCH_ID
|
7523 |
|
7524 | var outer = env.scope()
|
7525 | var inner = env.scope()
|
7526 |
|
7527 | scope(
|
7528 | outer.entry,
|
7529 | 'for(', BATCH_ID, '=0;', BATCH_ID, '<', NUM_PROPS, ';++', BATCH_ID, '){',
|
7530 | PROPS, '=', PROP_LIST, '[', BATCH_ID, '];',
|
7531 | inner,
|
7532 | '}',
|
7533 | outer.exit)
|
7534 |
|
7535 | function isInnerDefn (defn) {
|
7536 | return ((defn.contextDep && contextDynamic) || defn.propDep)
|
7537 | }
|
7538 |
|
7539 | function isOuterDefn (defn) {
|
7540 | return !isInnerDefn(defn)
|
7541 | }
|
7542 |
|
7543 | if (args.needsContext) {
|
7544 | emitContext(env, inner, args.context)
|
7545 | }
|
7546 | if (args.needsFramebuffer) {
|
7547 | emitPollFramebuffer(env, inner, args.framebuffer)
|
7548 | }
|
7549 | emitSetOptions(env, inner, args.state, isInnerDefn)
|
7550 |
|
7551 | if (args.profile && isInnerDefn(args.profile)) {
|
7552 | emitProfile(env, inner, args, false, true)
|
7553 | }
|
7554 |
|
7555 | if (!program) {
|
7556 | var progCache = env.global.def('{}')
|
7557 | var PROGRAM = args.shader.progVar.append(env, inner)
|
7558 | var PROG_ID = inner.def(PROGRAM, '.id')
|
7559 | var CACHED_PROC = inner.def(progCache, '[', PROG_ID, ']')
|
7560 | inner(
|
7561 | env.shared.gl, '.useProgram(', PROGRAM, '.program);',
|
7562 | 'if(!', CACHED_PROC, '){',
|
7563 | CACHED_PROC, '=', progCache, '[', PROG_ID, ']=',
|
7564 | env.link(function (program) {
|
7565 | return createBody(
|
7566 | emitBatchDynamicShaderBody, env, args, program, 2)
|
7567 | }), '(', PROGRAM, ');}',
|
7568 | CACHED_PROC, '.call(this,a0[', BATCH_ID, '],', BATCH_ID, ');')
|
7569 | } else {
|
7570 | if (args.useVAO) {
|
7571 | if (args.drawVAO) {
|
7572 | if (isInnerDefn(args.drawVAO)) {
|
7573 |
|
7574 | inner(env.shared.vao, '.setVAO(', args.drawVAO.append(env, inner), ');')
|
7575 | } else {
|
7576 |
|
7577 | outer(env.shared.vao, '.setVAO(', args.drawVAO.append(env, outer), ');')
|
7578 | }
|
7579 | } else {
|
7580 |
|
7581 | outer(env.shared.vao, '.setVAO(', env.shared.vao, '.targetVAO);')
|
7582 | }
|
7583 | } else {
|
7584 | outer(env.shared.vao, '.setVAO(null);')
|
7585 | emitAttributes(env, outer, args, program.attributes, isOuterDefn)
|
7586 | emitAttributes(env, inner, args, program.attributes, isInnerDefn)
|
7587 | }
|
7588 | emitUniforms(env, outer, args, program.uniforms, isOuterDefn)
|
7589 | emitUniforms(env, inner, args, program.uniforms, isInnerDefn)
|
7590 | emitDraw(env, outer, inner, args)
|
7591 | }
|
7592 | }
|
7593 |
|
7594 | function emitBatchProc (env, args) {
|
7595 | var batch = env.proc('batch', 2)
|
7596 | env.batchId = '0'
|
7597 |
|
7598 | injectExtensions(env, batch)
|
7599 |
|
7600 |
|
7601 | var contextDynamic = false
|
7602 | var needsContext = true
|
7603 | Object.keys(args.context).forEach(function (name) {
|
7604 | contextDynamic = contextDynamic || args.context[name].propDep
|
7605 | })
|
7606 | if (!contextDynamic) {
|
7607 | emitContext(env, batch, args.context)
|
7608 | needsContext = false
|
7609 | }
|
7610 |
|
7611 |
|
7612 | var framebuffer = args.framebuffer
|
7613 | var needsFramebuffer = false
|
7614 | if (framebuffer) {
|
7615 | if (framebuffer.propDep) {
|
7616 | contextDynamic = needsFramebuffer = true
|
7617 | } else if (framebuffer.contextDep && contextDynamic) {
|
7618 | needsFramebuffer = true
|
7619 | }
|
7620 | if (!needsFramebuffer) {
|
7621 | emitPollFramebuffer(env, batch, framebuffer)
|
7622 | }
|
7623 | } else {
|
7624 | emitPollFramebuffer(env, batch, null)
|
7625 | }
|
7626 |
|
7627 |
|
7628 | if (args.state.viewport && args.state.viewport.propDep) {
|
7629 | contextDynamic = true
|
7630 | }
|
7631 |
|
7632 | function isInnerDefn (defn) {
|
7633 | return (defn.contextDep && contextDynamic) || defn.propDep
|
7634 | }
|
7635 |
|
7636 |
|
7637 | emitPollState(env, batch, args)
|
7638 | emitSetOptions(env, batch, args.state, function (defn) {
|
7639 | return !isInnerDefn(defn)
|
7640 | })
|
7641 |
|
7642 | if (!args.profile || !isInnerDefn(args.profile)) {
|
7643 | emitProfile(env, batch, args, false, 'a1')
|
7644 | }
|
7645 |
|
7646 |
|
7647 | args.contextDep = contextDynamic
|
7648 | args.needsContext = needsContext
|
7649 | args.needsFramebuffer = needsFramebuffer
|
7650 |
|
7651 |
|
7652 | var progDefn = args.shader.progVar
|
7653 | if ((progDefn.contextDep && contextDynamic) || progDefn.propDep) {
|
7654 | emitBatchBody(
|
7655 | env,
|
7656 | batch,
|
7657 | args,
|
7658 | null)
|
7659 | } else {
|
7660 | var PROGRAM = progDefn.append(env, batch)
|
7661 | batch(env.shared.gl, '.useProgram(', PROGRAM, '.program);')
|
7662 | if (args.shader.program) {
|
7663 | emitBatchBody(
|
7664 | env,
|
7665 | batch,
|
7666 | args,
|
7667 | args.shader.program)
|
7668 | } else {
|
7669 | batch(env.shared.vao, '.setVAO(null);')
|
7670 | var batchCache = env.global.def('{}')
|
7671 | var PROG_ID = batch.def(PROGRAM, '.id')
|
7672 | var CACHED_PROC = batch.def(batchCache, '[', PROG_ID, ']')
|
7673 | batch(
|
7674 | env.cond(CACHED_PROC)
|
7675 | .then(CACHED_PROC, '.call(this,a0,a1);')
|
7676 | .else(
|
7677 | CACHED_PROC, '=', batchCache, '[', PROG_ID, ']=',
|
7678 | env.link(function (program) {
|
7679 | return createBody(emitBatchBody, env, args, program, 2)
|
7680 | }), '(', PROGRAM, ');',
|
7681 | CACHED_PROC, '.call(this,a0,a1);'))
|
7682 | }
|
7683 | }
|
7684 |
|
7685 | if (Object.keys(args.state).length > 0) {
|
7686 | batch(env.shared.current, '.dirty=true;')
|
7687 | }
|
7688 | }
|
7689 |
|
7690 |
|
7691 |
|
7692 |
|
7693 |
|
7694 |
|
7695 | function emitScopeProc (env, args) {
|
7696 | var scope = env.proc('scope', 3)
|
7697 | env.batchId = 'a2'
|
7698 |
|
7699 | var shared = env.shared
|
7700 | var CURRENT_STATE = shared.current
|
7701 |
|
7702 | emitContext(env, scope, args.context)
|
7703 |
|
7704 | if (args.framebuffer) {
|
7705 | args.framebuffer.append(env, scope)
|
7706 | }
|
7707 |
|
7708 | sortState(Object.keys(args.state)).forEach(function (name) {
|
7709 | var defn = args.state[name]
|
7710 | var value = defn.append(env, scope)
|
7711 | if (isArrayLike(value)) {
|
7712 | value.forEach(function (v, i) {
|
7713 | scope.set(env.next[name], '[' + i + ']', v)
|
7714 | })
|
7715 | } else {
|
7716 | scope.set(shared.next, '.' + name, value)
|
7717 | }
|
7718 | })
|
7719 |
|
7720 | emitProfile(env, scope, args, true, true)
|
7721 |
|
7722 | ;[S_ELEMENTS, S_OFFSET, S_COUNT, S_INSTANCES, S_PRIMITIVE].forEach(
|
7723 | function (opt) {
|
7724 | var variable = args.draw[opt]
|
7725 | if (!variable) {
|
7726 | return
|
7727 | }
|
7728 | scope.set(shared.draw, '.' + opt, '' + variable.append(env, scope))
|
7729 | })
|
7730 |
|
7731 | Object.keys(args.uniforms).forEach(function (opt) {
|
7732 | scope.set(
|
7733 | shared.uniforms,
|
7734 | '[' + stringStore.id(opt) + ']',
|
7735 | args.uniforms[opt].append(env, scope))
|
7736 | })
|
7737 |
|
7738 | Object.keys(args.attributes).forEach(function (name) {
|
7739 | var record = args.attributes[name].append(env, scope)
|
7740 | var scopeAttrib = env.scopeAttrib(name)
|
7741 | Object.keys(new AttributeRecord()).forEach(function (prop) {
|
7742 | scope.set(scopeAttrib, '.' + prop, record[prop])
|
7743 | })
|
7744 | })
|
7745 |
|
7746 | if (args.scopeVAO) {
|
7747 | scope.set(shared.vao, '.targetVAO', args.scopeVAO.append(env, scope))
|
7748 | }
|
7749 |
|
7750 | function saveShader (name) {
|
7751 | var shader = args.shader[name]
|
7752 | if (shader) {
|
7753 | scope.set(shared.shader, '.' + name, shader.append(env, scope))
|
7754 | }
|
7755 | }
|
7756 | saveShader(S_VERT)
|
7757 | saveShader(S_FRAG)
|
7758 |
|
7759 | if (Object.keys(args.state).length > 0) {
|
7760 | scope(CURRENT_STATE, '.dirty=true;')
|
7761 | scope.exit(CURRENT_STATE, '.dirty=true;')
|
7762 | }
|
7763 |
|
7764 | scope('a1(', env.shared.context, ',a0,', env.batchId, ');')
|
7765 | }
|
7766 |
|
7767 | function isDynamicObject (object) {
|
7768 | if (typeof object !== 'object' || isArrayLike(object)) {
|
7769 | return
|
7770 | }
|
7771 | var props = Object.keys(object)
|
7772 | for (var i = 0; i < props.length; ++i) {
|
7773 | if (dynamic.isDynamic(object[props[i]])) {
|
7774 | return true
|
7775 | }
|
7776 | }
|
7777 | return false
|
7778 | }
|
7779 |
|
7780 | function splatObject (env, options, name) {
|
7781 | var object = options.static[name]
|
7782 | if (!object || !isDynamicObject(object)) {
|
7783 | return
|
7784 | }
|
7785 |
|
7786 | var globals = env.global
|
7787 | var keys = Object.keys(object)
|
7788 | var thisDep = false
|
7789 | var contextDep = false
|
7790 | var propDep = false
|
7791 | var objectRef = env.global.def('{}')
|
7792 | keys.forEach(function (key) {
|
7793 | var value = object[key]
|
7794 | if (dynamic.isDynamic(value)) {
|
7795 | if (typeof value === 'function') {
|
7796 | value = object[key] = dynamic.unbox(value)
|
7797 | }
|
7798 | var deps = createDynamicDecl(value, null)
|
7799 | thisDep = thisDep || deps.thisDep
|
7800 | propDep = propDep || deps.propDep
|
7801 | contextDep = contextDep || deps.contextDep
|
7802 | } else {
|
7803 | globals(objectRef, '.', key, '=')
|
7804 | switch (typeof value) {
|
7805 | case 'number':
|
7806 | globals(value)
|
7807 | break
|
7808 | case 'string':
|
7809 | globals('"', value, '"')
|
7810 | break
|
7811 | case 'object':
|
7812 | if (Array.isArray(value)) {
|
7813 | globals('[', value.join(), ']')
|
7814 | }
|
7815 | break
|
7816 | default:
|
7817 | globals(env.link(value))
|
7818 | break
|
7819 | }
|
7820 | globals(';')
|
7821 | }
|
7822 | })
|
7823 |
|
7824 | function appendBlock (env, block) {
|
7825 | keys.forEach(function (key) {
|
7826 | var value = object[key]
|
7827 | if (!dynamic.isDynamic(value)) {
|
7828 | return
|
7829 | }
|
7830 | var ref = env.invoke(block, value)
|
7831 | block(objectRef, '.', key, '=', ref, ';')
|
7832 | })
|
7833 | }
|
7834 |
|
7835 | options.dynamic[name] = new dynamic.DynamicVariable(DYN_THUNK, {
|
7836 | thisDep: thisDep,
|
7837 | contextDep: contextDep,
|
7838 | propDep: propDep,
|
7839 | ref: objectRef,
|
7840 | append: appendBlock
|
7841 | })
|
7842 | delete options.static[name]
|
7843 | }
|
7844 |
|
7845 |
|
7846 |
|
7847 |
|
7848 |
|
7849 |
|
7850 | function compileCommand (options, attributes, uniforms, context, stats) {
|
7851 | var env = createREGLEnvironment()
|
7852 |
|
7853 |
|
7854 | env.stats = env.link(stats)
|
7855 |
|
7856 |
|
7857 | Object.keys(attributes.static).forEach(function (key) {
|
7858 | splatObject(env, attributes, key)
|
7859 | })
|
7860 | NESTED_OPTIONS.forEach(function (name) {
|
7861 | splatObject(env, options, name)
|
7862 | })
|
7863 |
|
7864 | var args = parseArguments(options, attributes, uniforms, context, env)
|
7865 |
|
7866 | emitDrawProc(env, args)
|
7867 | emitScopeProc(env, args)
|
7868 | emitBatchProc(env, args)
|
7869 |
|
7870 | return env.compile()
|
7871 | }
|
7872 |
|
7873 |
|
7874 |
|
7875 |
|
7876 |
|
7877 |
|
7878 | return {
|
7879 | next: nextState,
|
7880 | current: currentState,
|
7881 | procs: (function () {
|
7882 | var env = createREGLEnvironment()
|
7883 | var poll = env.proc('poll')
|
7884 | var refresh = env.proc('refresh')
|
7885 | var common = env.block()
|
7886 | poll(common)
|
7887 | refresh(common)
|
7888 |
|
7889 | var shared = env.shared
|
7890 | var GL = shared.gl
|
7891 | var NEXT_STATE = shared.next
|
7892 | var CURRENT_STATE = shared.current
|
7893 |
|
7894 | common(CURRENT_STATE, '.dirty=false;')
|
7895 |
|
7896 | emitPollFramebuffer(env, poll)
|
7897 | emitPollFramebuffer(env, refresh, null, true)
|
7898 |
|
7899 |
|
7900 | var INSTANCING
|
7901 | if (extInstancing) {
|
7902 | INSTANCING = env.link(extInstancing)
|
7903 | }
|
7904 |
|
7905 |
|
7906 | if (extensions.oes_vertex_array_object) {
|
7907 | refresh(env.link(extensions.oes_vertex_array_object), '.bindVertexArrayOES(null);')
|
7908 | }
|
7909 | for (var i = 0; i < limits.maxAttributes; ++i) {
|
7910 | var BINDING = refresh.def(shared.attributes, '[', i, ']')
|
7911 | var ifte = env.cond(BINDING, '.buffer')
|
7912 | ifte.then(
|
7913 | GL, '.enableVertexAttribArray(', i, ');',
|
7914 | GL, '.bindBuffer(',
|
7915 | GL_ARRAY_BUFFER$2, ',',
|
7916 | BINDING, '.buffer.buffer);',
|
7917 | GL, '.vertexAttribPointer(',
|
7918 | i, ',',
|
7919 | BINDING, '.size,',
|
7920 | BINDING, '.type,',
|
7921 | BINDING, '.normalized,',
|
7922 | BINDING, '.stride,',
|
7923 | BINDING, '.offset);'
|
7924 | ).else(
|
7925 | GL, '.disableVertexAttribArray(', i, ');',
|
7926 | GL, '.vertexAttrib4f(',
|
7927 | i, ',',
|
7928 | BINDING, '.x,',
|
7929 | BINDING, '.y,',
|
7930 | BINDING, '.z,',
|
7931 | BINDING, '.w);',
|
7932 | BINDING, '.buffer=null;')
|
7933 | refresh(ifte)
|
7934 | if (extInstancing) {
|
7935 | refresh(
|
7936 | INSTANCING, '.vertexAttribDivisorANGLE(',
|
7937 | i, ',',
|
7938 | BINDING, '.divisor);')
|
7939 | }
|
7940 | }
|
7941 | refresh(
|
7942 | env.shared.vao, '.currentVAO=null;',
|
7943 | env.shared.vao, '.setVAO(', env.shared.vao, '.targetVAO);')
|
7944 |
|
7945 | Object.keys(GL_FLAGS).forEach(function (flag) {
|
7946 | var cap = GL_FLAGS[flag]
|
7947 | var NEXT = common.def(NEXT_STATE, '.', flag)
|
7948 | var block = env.block()
|
7949 | block('if(', NEXT, '){',
|
7950 | GL, '.enable(', cap, ')}else{',
|
7951 | GL, '.disable(', cap, ')}',
|
7952 | CURRENT_STATE, '.', flag, '=', NEXT, ';')
|
7953 | refresh(block)
|
7954 | poll(
|
7955 | 'if(', NEXT, '!==', CURRENT_STATE, '.', flag, '){',
|
7956 | block,
|
7957 | '}')
|
7958 | })
|
7959 |
|
7960 | Object.keys(GL_VARIABLES).forEach(function (name) {
|
7961 | var func = GL_VARIABLES[name]
|
7962 | var init = currentState[name]
|
7963 | var NEXT, CURRENT
|
7964 | var block = env.block()
|
7965 | block(GL, '.', func, '(')
|
7966 | if (isArrayLike(init)) {
|
7967 | var n = init.length
|
7968 | NEXT = env.global.def(NEXT_STATE, '.', name)
|
7969 | CURRENT = env.global.def(CURRENT_STATE, '.', name)
|
7970 | block(
|
7971 | loop(n, function (i) {
|
7972 | return NEXT + '[' + i + ']'
|
7973 | }), ');',
|
7974 | loop(n, function (i) {
|
7975 | return CURRENT + '[' + i + ']=' + NEXT + '[' + i + '];'
|
7976 | }).join(''))
|
7977 | poll(
|
7978 | 'if(', loop(n, function (i) {
|
7979 | return NEXT + '[' + i + ']!==' + CURRENT + '[' + i + ']'
|
7980 | }).join('||'), '){',
|
7981 | block,
|
7982 | '}')
|
7983 | } else {
|
7984 | NEXT = common.def(NEXT_STATE, '.', name)
|
7985 | CURRENT = common.def(CURRENT_STATE, '.', name)
|
7986 | block(
|
7987 | NEXT, ');',
|
7988 | CURRENT_STATE, '.', name, '=', NEXT, ';')
|
7989 | poll(
|
7990 | 'if(', NEXT, '!==', CURRENT, '){',
|
7991 | block,
|
7992 | '}')
|
7993 | }
|
7994 | refresh(block)
|
7995 | })
|
7996 |
|
7997 | return env.compile()
|
7998 | })(),
|
7999 | compile: compileCommand
|
8000 | }
|
8001 | }
|
8002 |
|
8003 | function stats () {
|
8004 | return {
|
8005 | vaoCount: 0,
|
8006 | bufferCount: 0,
|
8007 | elementsCount: 0,
|
8008 | framebufferCount: 0,
|
8009 | shaderCount: 0,
|
8010 | textureCount: 0,
|
8011 | cubeCount: 0,
|
8012 | renderbufferCount: 0,
|
8013 | maxTextureUnits: 0
|
8014 | }
|
8015 | }
|
8016 |
|
8017 | var GL_QUERY_RESULT_EXT = 0x8866
|
8018 | var GL_QUERY_RESULT_AVAILABLE_EXT = 0x8867
|
8019 | var GL_TIME_ELAPSED_EXT = 0x88BF
|
8020 |
|
8021 | var createTimer = function (gl, extensions) {
|
8022 | if (!extensions.ext_disjoint_timer_query) {
|
8023 | return null
|
8024 | }
|
8025 |
|
8026 |
|
8027 | var queryPool = []
|
8028 | function allocQuery () {
|
8029 | return queryPool.pop() || extensions.ext_disjoint_timer_query.createQueryEXT()
|
8030 | }
|
8031 | function freeQuery (query) {
|
8032 | queryPool.push(query)
|
8033 | }
|
8034 |
|
8035 |
|
8036 | var pendingQueries = []
|
8037 | function beginQuery (stats) {
|
8038 | var query = allocQuery()
|
8039 | extensions.ext_disjoint_timer_query.beginQueryEXT(GL_TIME_ELAPSED_EXT, query)
|
8040 | pendingQueries.push(query)
|
8041 | pushScopeStats(pendingQueries.length - 1, pendingQueries.length, stats)
|
8042 | }
|
8043 |
|
8044 | function endQuery () {
|
8045 | extensions.ext_disjoint_timer_query.endQueryEXT(GL_TIME_ELAPSED_EXT)
|
8046 | }
|
8047 |
|
8048 |
|
8049 |
|
8050 |
|
8051 | function PendingStats () {
|
8052 | this.startQueryIndex = -1
|
8053 | this.endQueryIndex = -1
|
8054 | this.sum = 0
|
8055 | this.stats = null
|
8056 | }
|
8057 | var pendingStatsPool = []
|
8058 | function allocPendingStats () {
|
8059 | return pendingStatsPool.pop() || new PendingStats()
|
8060 | }
|
8061 | function freePendingStats (pendingStats) {
|
8062 | pendingStatsPool.push(pendingStats)
|
8063 | }
|
8064 |
|
8065 |
|
8066 | var pendingStats = []
|
8067 | function pushScopeStats (start, end, stats) {
|
8068 | var ps = allocPendingStats()
|
8069 | ps.startQueryIndex = start
|
8070 | ps.endQueryIndex = end
|
8071 | ps.sum = 0
|
8072 | ps.stats = stats
|
8073 | pendingStats.push(ps)
|
8074 | }
|
8075 |
|
8076 |
|
8077 |
|
8078 | var timeSum = []
|
8079 | var queryPtr = []
|
8080 | function update () {
|
8081 | var ptr, i
|
8082 |
|
8083 | var n = pendingQueries.length
|
8084 | if (n === 0) {
|
8085 | return
|
8086 | }
|
8087 |
|
8088 |
|
8089 | queryPtr.length = Math.max(queryPtr.length, n + 1)
|
8090 | timeSum.length = Math.max(timeSum.length, n + 1)
|
8091 | timeSum[0] = 0
|
8092 | queryPtr[0] = 0
|
8093 |
|
8094 |
|
8095 | var queryTime = 0
|
8096 | ptr = 0
|
8097 | for (i = 0; i < pendingQueries.length; ++i) {
|
8098 | var query = pendingQueries[i]
|
8099 | if (extensions.ext_disjoint_timer_query.getQueryObjectEXT(query, GL_QUERY_RESULT_AVAILABLE_EXT)) {
|
8100 | queryTime += extensions.ext_disjoint_timer_query.getQueryObjectEXT(query, GL_QUERY_RESULT_EXT)
|
8101 | freeQuery(query)
|
8102 | } else {
|
8103 | pendingQueries[ptr++] = query
|
8104 | }
|
8105 | timeSum[i + 1] = queryTime
|
8106 | queryPtr[i + 1] = ptr
|
8107 | }
|
8108 | pendingQueries.length = ptr
|
8109 |
|
8110 |
|
8111 | ptr = 0
|
8112 | for (i = 0; i < pendingStats.length; ++i) {
|
8113 | var stats = pendingStats[i]
|
8114 | var start = stats.startQueryIndex
|
8115 | var end = stats.endQueryIndex
|
8116 | stats.sum += timeSum[end] - timeSum[start]
|
8117 | var startPtr = queryPtr[start]
|
8118 | var endPtr = queryPtr[end]
|
8119 | if (endPtr === startPtr) {
|
8120 | stats.stats.gpuTime += stats.sum / 1e6
|
8121 | freePendingStats(stats)
|
8122 | } else {
|
8123 | stats.startQueryIndex = startPtr
|
8124 | stats.endQueryIndex = endPtr
|
8125 | pendingStats[ptr++] = stats
|
8126 | }
|
8127 | }
|
8128 | pendingStats.length = ptr
|
8129 | }
|
8130 |
|
8131 | return {
|
8132 | beginQuery: beginQuery,
|
8133 | endQuery: endQuery,
|
8134 | pushScopeStats: pushScopeStats,
|
8135 | update: update,
|
8136 | getNumPendingQueries: function () {
|
8137 | return pendingQueries.length
|
8138 | },
|
8139 | clear: function () {
|
8140 | queryPool.push.apply(queryPool, pendingQueries)
|
8141 | for (var i = 0; i < queryPool.length; i++) {
|
8142 | extensions.ext_disjoint_timer_query.deleteQueryEXT(queryPool[i])
|
8143 | }
|
8144 | pendingQueries.length = 0
|
8145 | queryPool.length = 0
|
8146 | },
|
8147 | restore: function () {
|
8148 | pendingQueries.length = 0
|
8149 | queryPool.length = 0
|
8150 | }
|
8151 | }
|
8152 | }
|
8153 |
|
8154 | var GL_COLOR_BUFFER_BIT = 16384
|
8155 | var GL_DEPTH_BUFFER_BIT = 256
|
8156 | var GL_STENCIL_BUFFER_BIT = 1024
|
8157 |
|
8158 | var GL_ARRAY_BUFFER = 34962
|
8159 |
|
8160 | var CONTEXT_LOST_EVENT = 'webglcontextlost'
|
8161 | var CONTEXT_RESTORED_EVENT = 'webglcontextrestored'
|
8162 |
|
8163 | var DYN_PROP = 1
|
8164 | var DYN_CONTEXT = 2
|
8165 | var DYN_STATE = 3
|
8166 |
|
8167 | function find (haystack, needle) {
|
8168 | for (var i = 0; i < haystack.length; ++i) {
|
8169 | if (haystack[i] === needle) {
|
8170 | return i
|
8171 | }
|
8172 | }
|
8173 | return -1
|
8174 | }
|
8175 |
|
8176 | function wrapREGL (args) {
|
8177 | var config = parseArgs(args)
|
8178 | if (!config) {
|
8179 | return null
|
8180 | }
|
8181 |
|
8182 | var gl = config.gl
|
8183 | var glAttributes = gl.getContextAttributes()
|
8184 | var contextLost = gl.isContextLost()
|
8185 |
|
8186 | var extensionState = createExtensionCache(gl, config)
|
8187 | if (!extensionState) {
|
8188 | return null
|
8189 | }
|
8190 |
|
8191 | var stringStore = createStringStore()
|
8192 | var stats$$1 = stats()
|
8193 | var extensions = extensionState.extensions
|
8194 | var timer = createTimer(gl, extensions)
|
8195 |
|
8196 | var START_TIME = clock()
|
8197 | var WIDTH = gl.drawingBufferWidth
|
8198 | var HEIGHT = gl.drawingBufferHeight
|
8199 |
|
8200 | var contextState = {
|
8201 | tick: 0,
|
8202 | time: 0,
|
8203 | viewportWidth: WIDTH,
|
8204 | viewportHeight: HEIGHT,
|
8205 | framebufferWidth: WIDTH,
|
8206 | framebufferHeight: HEIGHT,
|
8207 | drawingBufferWidth: WIDTH,
|
8208 | drawingBufferHeight: HEIGHT,
|
8209 | pixelRatio: config.pixelRatio
|
8210 | }
|
8211 | var uniformState = {}
|
8212 | var drawState = {
|
8213 | elements: null,
|
8214 | primitive: 4,
|
8215 | count: -1,
|
8216 | offset: 0,
|
8217 | instances: -1
|
8218 | }
|
8219 |
|
8220 | var limits = wrapLimits(gl, extensions)
|
8221 | var bufferState = wrapBufferState(
|
8222 | gl,
|
8223 | stats$$1,
|
8224 | config,
|
8225 | destroyBuffer)
|
8226 | var attributeState = wrapAttributeState(
|
8227 | gl,
|
8228 | extensions,
|
8229 | limits,
|
8230 | stats$$1,
|
8231 | bufferState)
|
8232 | function destroyBuffer (buffer) {
|
8233 | return attributeState.destroyBuffer(buffer)
|
8234 | }
|
8235 | var elementState = wrapElementsState(gl, extensions, bufferState, stats$$1)
|
8236 | var shaderState = wrapShaderState(gl, stringStore, stats$$1, config)
|
8237 | var textureState = createTextureSet(
|
8238 | gl,
|
8239 | extensions,
|
8240 | limits,
|
8241 | function () { core.procs.poll() },
|
8242 | contextState,
|
8243 | stats$$1,
|
8244 | config)
|
8245 | var renderbufferState = wrapRenderbuffers(gl, extensions, limits, stats$$1, config)
|
8246 | var framebufferState = wrapFBOState(
|
8247 | gl,
|
8248 | extensions,
|
8249 | limits,
|
8250 | textureState,
|
8251 | renderbufferState,
|
8252 | stats$$1)
|
8253 | var core = reglCore(
|
8254 | gl,
|
8255 | stringStore,
|
8256 | extensions,
|
8257 | limits,
|
8258 | bufferState,
|
8259 | elementState,
|
8260 | textureState,
|
8261 | framebufferState,
|
8262 | uniformState,
|
8263 | attributeState,
|
8264 | shaderState,
|
8265 | drawState,
|
8266 | contextState,
|
8267 | timer,
|
8268 | config)
|
8269 | var readPixels = wrapReadPixels(
|
8270 | gl,
|
8271 | framebufferState,
|
8272 | core.procs.poll,
|
8273 | contextState,
|
8274 | glAttributes, extensions, limits)
|
8275 |
|
8276 | var nextState = core.next
|
8277 | var canvas = gl.canvas
|
8278 |
|
8279 | var rafCallbacks = []
|
8280 | var lossCallbacks = []
|
8281 | var restoreCallbacks = []
|
8282 | var destroyCallbacks = [config.onDestroy]
|
8283 |
|
8284 | var activeRAF = null
|
8285 | function handleRAF () {
|
8286 | if (rafCallbacks.length === 0) {
|
8287 | if (timer) {
|
8288 | timer.update()
|
8289 | }
|
8290 | activeRAF = null
|
8291 | return
|
8292 | }
|
8293 |
|
8294 |
|
8295 | activeRAF = raf.next(handleRAF)
|
8296 |
|
8297 |
|
8298 | poll()
|
8299 |
|
8300 |
|
8301 | for (var i = rafCallbacks.length - 1; i >= 0; --i) {
|
8302 | var cb = rafCallbacks[i]
|
8303 | if (cb) {
|
8304 | cb(contextState, null, 0)
|
8305 | }
|
8306 | }
|
8307 |
|
8308 |
|
8309 | gl.flush()
|
8310 |
|
8311 |
|
8312 | if (timer) {
|
8313 | timer.update()
|
8314 | }
|
8315 | }
|
8316 |
|
8317 | function startRAF () {
|
8318 | if (!activeRAF && rafCallbacks.length > 0) {
|
8319 | activeRAF = raf.next(handleRAF)
|
8320 | }
|
8321 | }
|
8322 |
|
8323 | function stopRAF () {
|
8324 | if (activeRAF) {
|
8325 | raf.cancel(handleRAF)
|
8326 | activeRAF = null
|
8327 | }
|
8328 | }
|
8329 |
|
8330 | function handleContextLoss (event) {
|
8331 | event.preventDefault()
|
8332 |
|
8333 |
|
8334 | contextLost = true
|
8335 |
|
8336 |
|
8337 | stopRAF()
|
8338 |
|
8339 |
|
8340 | lossCallbacks.forEach(function (cb) {
|
8341 | cb()
|
8342 | })
|
8343 | }
|
8344 |
|
8345 | function handleContextRestored (event) {
|
8346 |
|
8347 | gl.getError()
|
8348 |
|
8349 |
|
8350 | contextLost = false
|
8351 |
|
8352 |
|
8353 | extensionState.restore()
|
8354 | shaderState.restore()
|
8355 | bufferState.restore()
|
8356 | textureState.restore()
|
8357 | renderbufferState.restore()
|
8358 | framebufferState.restore()
|
8359 | attributeState.restore()
|
8360 | if (timer) {
|
8361 | timer.restore()
|
8362 | }
|
8363 |
|
8364 |
|
8365 | core.procs.refresh()
|
8366 |
|
8367 |
|
8368 | startRAF()
|
8369 |
|
8370 |
|
8371 | restoreCallbacks.forEach(function (cb) {
|
8372 | cb()
|
8373 | })
|
8374 | }
|
8375 |
|
8376 | if (canvas) {
|
8377 | canvas.addEventListener(CONTEXT_LOST_EVENT, handleContextLoss, false)
|
8378 | canvas.addEventListener(CONTEXT_RESTORED_EVENT, handleContextRestored, false)
|
8379 | }
|
8380 |
|
8381 | function destroy () {
|
8382 | rafCallbacks.length = 0
|
8383 | stopRAF()
|
8384 |
|
8385 | if (canvas) {
|
8386 | canvas.removeEventListener(CONTEXT_LOST_EVENT, handleContextLoss)
|
8387 | canvas.removeEventListener(CONTEXT_RESTORED_EVENT, handleContextRestored)
|
8388 | }
|
8389 |
|
8390 | shaderState.clear()
|
8391 | framebufferState.clear()
|
8392 | renderbufferState.clear()
|
8393 | textureState.clear()
|
8394 | elementState.clear()
|
8395 | bufferState.clear()
|
8396 | attributeState.clear()
|
8397 |
|
8398 | if (timer) {
|
8399 | timer.clear()
|
8400 | }
|
8401 |
|
8402 | destroyCallbacks.forEach(function (cb) {
|
8403 | cb()
|
8404 | })
|
8405 | }
|
8406 |
|
8407 | function compileProcedure (options) {
|
8408 |
|
8409 |
|
8410 |
|
8411 | function flattenNestedOptions (options) {
|
8412 | var result = extend({}, options)
|
8413 | delete result.uniforms
|
8414 | delete result.attributes
|
8415 | delete result.context
|
8416 | delete result.vao
|
8417 |
|
8418 | if ('stencil' in result && result.stencil.op) {
|
8419 | result.stencil.opBack = result.stencil.opFront = result.stencil.op
|
8420 | delete result.stencil.op
|
8421 | }
|
8422 |
|
8423 | function merge (name) {
|
8424 | if (name in result) {
|
8425 | var child = result[name]
|
8426 | delete result[name]
|
8427 | Object.keys(child).forEach(function (prop) {
|
8428 | result[name + '.' + prop] = child[prop]
|
8429 | })
|
8430 | }
|
8431 | }
|
8432 | merge('blend')
|
8433 | merge('depth')
|
8434 | merge('cull')
|
8435 | merge('stencil')
|
8436 | merge('polygonOffset')
|
8437 | merge('scissor')
|
8438 | merge('sample')
|
8439 |
|
8440 | if ('vao' in options) {
|
8441 | result.vao = options.vao
|
8442 | }
|
8443 |
|
8444 | return result
|
8445 | }
|
8446 |
|
8447 | function separateDynamic (object) {
|
8448 | var staticItems = {}
|
8449 | var dynamicItems = {}
|
8450 | Object.keys(object).forEach(function (option) {
|
8451 | var value = object[option]
|
8452 | if (dynamic.isDynamic(value)) {
|
8453 | dynamicItems[option] = dynamic.unbox(value, option)
|
8454 | } else {
|
8455 | staticItems[option] = value
|
8456 | }
|
8457 | })
|
8458 | return {
|
8459 | dynamic: dynamicItems,
|
8460 | static: staticItems
|
8461 | }
|
8462 | }
|
8463 |
|
8464 |
|
8465 | var context = separateDynamic(options.context || {})
|
8466 | var uniforms = separateDynamic(options.uniforms || {})
|
8467 | var attributes = separateDynamic(options.attributes || {})
|
8468 | var opts = separateDynamic(flattenNestedOptions(options))
|
8469 |
|
8470 | var stats$$1 = {
|
8471 | gpuTime: 0.0,
|
8472 | cpuTime: 0.0,
|
8473 | count: 0
|
8474 | }
|
8475 |
|
8476 | var compiled = core.compile(opts, attributes, uniforms, context, stats$$1)
|
8477 |
|
8478 | var draw = compiled.draw
|
8479 | var batch = compiled.batch
|
8480 | var scope = compiled.scope
|
8481 |
|
8482 |
|
8483 |
|
8484 | var EMPTY_ARRAY = []
|
8485 | function reserve (count) {
|
8486 | while (EMPTY_ARRAY.length < count) {
|
8487 | EMPTY_ARRAY.push(null)
|
8488 | }
|
8489 | return EMPTY_ARRAY
|
8490 | }
|
8491 |
|
8492 | function REGLCommand (args, body) {
|
8493 | var i
|
8494 | if (contextLost) {
|
8495 |
|
8496 | }
|
8497 | if (typeof args === 'function') {
|
8498 | return scope.call(this, null, args, 0)
|
8499 | } else if (typeof body === 'function') {
|
8500 | if (typeof args === 'number') {
|
8501 | for (i = 0; i < args; ++i) {
|
8502 | scope.call(this, null, body, i)
|
8503 | }
|
8504 | } else if (Array.isArray(args)) {
|
8505 | for (i = 0; i < args.length; ++i) {
|
8506 | scope.call(this, args[i], body, i)
|
8507 | }
|
8508 | } else {
|
8509 | return scope.call(this, args, body, 0)
|
8510 | }
|
8511 | } else if (typeof args === 'number') {
|
8512 | if (args > 0) {
|
8513 | return batch.call(this, reserve(args | 0), args | 0)
|
8514 | }
|
8515 | } else if (Array.isArray(args)) {
|
8516 | if (args.length) {
|
8517 | return batch.call(this, args, args.length)
|
8518 | }
|
8519 | } else {
|
8520 | return draw.call(this, args)
|
8521 | }
|
8522 | }
|
8523 |
|
8524 | return extend(REGLCommand, {
|
8525 | stats: stats$$1
|
8526 | })
|
8527 | }
|
8528 |
|
8529 | var setFBO = framebufferState.setFBO = compileProcedure({
|
8530 | framebuffer: dynamic.define.call(null, DYN_PROP, 'framebuffer')
|
8531 | })
|
8532 |
|
8533 | function clearImpl (_, options) {
|
8534 | var clearFlags = 0
|
8535 | core.procs.poll()
|
8536 |
|
8537 | var c = options.color
|
8538 | if (c) {
|
8539 | gl.clearColor(+c[0] || 0, +c[1] || 0, +c[2] || 0, +c[3] || 0)
|
8540 | clearFlags |= GL_COLOR_BUFFER_BIT
|
8541 | }
|
8542 | if ('depth' in options) {
|
8543 | gl.clearDepth(+options.depth)
|
8544 | clearFlags |= GL_DEPTH_BUFFER_BIT
|
8545 | }
|
8546 | if ('stencil' in options) {
|
8547 | gl.clearStencil(options.stencil | 0)
|
8548 | clearFlags |= GL_STENCIL_BUFFER_BIT
|
8549 | }
|
8550 |
|
8551 |
|
8552 | gl.clear(clearFlags)
|
8553 | }
|
8554 |
|
8555 | function clear (options) {
|
8556 |
|
8557 | if ('framebuffer' in options) {
|
8558 | if (options.framebuffer &&
|
8559 | options.framebuffer_reglType === 'framebufferCube') {
|
8560 | for (var i = 0; i < 6; ++i) {
|
8561 | setFBO(extend({
|
8562 | framebuffer: options.framebuffer.faces[i]
|
8563 | }, options), clearImpl)
|
8564 | }
|
8565 | } else {
|
8566 | setFBO(options, clearImpl)
|
8567 | }
|
8568 | } else {
|
8569 | clearImpl(null, options)
|
8570 | }
|
8571 | }
|
8572 |
|
8573 | function frame (cb) {
|
8574 |
|
8575 | rafCallbacks.push(cb)
|
8576 |
|
8577 | function cancel () {
|
8578 |
|
8579 |
|
8580 |
|
8581 | var i = find(rafCallbacks, cb)
|
8582 |
|
8583 | function pendingCancel () {
|
8584 | var index = find(rafCallbacks, pendingCancel)
|
8585 | rafCallbacks[index] = rafCallbacks[rafCallbacks.length - 1]
|
8586 | rafCallbacks.length -= 1
|
8587 | if (rafCallbacks.length <= 0) {
|
8588 | stopRAF()
|
8589 | }
|
8590 | }
|
8591 | rafCallbacks[i] = pendingCancel
|
8592 | }
|
8593 |
|
8594 | startRAF()
|
8595 |
|
8596 | return {
|
8597 | cancel: cancel
|
8598 | }
|
8599 | }
|
8600 |
|
8601 |
|
8602 | function pollViewport () {
|
8603 | var viewport = nextState.viewport
|
8604 | var scissorBox = nextState.scissor_box
|
8605 | viewport[0] = viewport[1] = scissorBox[0] = scissorBox[1] = 0
|
8606 | contextState.viewportWidth =
|
8607 | contextState.framebufferWidth =
|
8608 | contextState.drawingBufferWidth =
|
8609 | viewport[2] =
|
8610 | scissorBox[2] = gl.drawingBufferWidth
|
8611 | contextState.viewportHeight =
|
8612 | contextState.framebufferHeight =
|
8613 | contextState.drawingBufferHeight =
|
8614 | viewport[3] =
|
8615 | scissorBox[3] = gl.drawingBufferHeight
|
8616 | }
|
8617 |
|
8618 | function poll () {
|
8619 | contextState.tick += 1
|
8620 | contextState.time = now()
|
8621 | pollViewport()
|
8622 | core.procs.poll()
|
8623 | }
|
8624 |
|
8625 | function refresh () {
|
8626 | pollViewport()
|
8627 | core.procs.refresh()
|
8628 | if (timer) {
|
8629 | timer.update()
|
8630 | }
|
8631 | }
|
8632 |
|
8633 | function now () {
|
8634 | return (clock() - START_TIME) / 1000.0
|
8635 | }
|
8636 |
|
8637 | refresh()
|
8638 |
|
8639 | function addListener (event, callback) {
|
8640 |
|
8641 |
|
8642 | var callbacks
|
8643 | switch (event) {
|
8644 | case 'frame':
|
8645 | return frame(callback)
|
8646 | case 'lost':
|
8647 | callbacks = lossCallbacks
|
8648 | break
|
8649 | case 'restore':
|
8650 | callbacks = restoreCallbacks
|
8651 | break
|
8652 | case 'destroy':
|
8653 | callbacks = destroyCallbacks
|
8654 | break
|
8655 | default:
|
8656 |
|
8657 | }
|
8658 |
|
8659 | callbacks.push(callback)
|
8660 | return {
|
8661 | cancel: function () {
|
8662 | for (var i = 0; i < callbacks.length; ++i) {
|
8663 | if (callbacks[i] === callback) {
|
8664 | callbacks[i] = callbacks[callbacks.length - 1]
|
8665 | callbacks.pop()
|
8666 | return
|
8667 | }
|
8668 | }
|
8669 | }
|
8670 | }
|
8671 | }
|
8672 |
|
8673 | var regl = extend(compileProcedure, {
|
8674 |
|
8675 | clear: clear,
|
8676 |
|
8677 |
|
8678 | prop: dynamic.define.bind(null, DYN_PROP),
|
8679 | context: dynamic.define.bind(null, DYN_CONTEXT),
|
8680 | this: dynamic.define.bind(null, DYN_STATE),
|
8681 |
|
8682 |
|
8683 | draw: compileProcedure({}),
|
8684 |
|
8685 |
|
8686 | buffer: function (options) {
|
8687 | return bufferState.create(options, GL_ARRAY_BUFFER, false, false)
|
8688 | },
|
8689 | elements: function (options) {
|
8690 | return elementState.create(options, false)
|
8691 | },
|
8692 | texture: textureState.create2D,
|
8693 | cube: textureState.createCube,
|
8694 | renderbuffer: renderbufferState.create,
|
8695 | framebuffer: framebufferState.create,
|
8696 | framebufferCube: framebufferState.createCube,
|
8697 | vao: attributeState.createVAO,
|
8698 |
|
8699 |
|
8700 | attributes: glAttributes,
|
8701 |
|
8702 |
|
8703 | frame: frame,
|
8704 | on: addListener,
|
8705 |
|
8706 |
|
8707 | limits: limits,
|
8708 | hasExtension: function (name) {
|
8709 | return limits.extensions.indexOf(name.toLowerCase()) >= 0
|
8710 | },
|
8711 |
|
8712 |
|
8713 | read: readPixels,
|
8714 |
|
8715 |
|
8716 | destroy: destroy,
|
8717 |
|
8718 |
|
8719 | _gl: gl,
|
8720 | _refresh: refresh,
|
8721 |
|
8722 | poll: function () {
|
8723 | poll()
|
8724 | if (timer) {
|
8725 | timer.update()
|
8726 | }
|
8727 | },
|
8728 |
|
8729 |
|
8730 | now: now,
|
8731 |
|
8732 |
|
8733 | stats: stats$$1
|
8734 | })
|
8735 |
|
8736 | config.onDone(null, regl)
|
8737 |
|
8738 | return regl
|
8739 | }
|
8740 |
|
8741 | return wrapREGL;
|
8742 |
|
8743 | })));
|