1
1
/*
2
2
| shader.js
3
3
|----------------
4
- | shader.js is copyright Patrick Rhodes Martin 2013,2017, used with permission.
4
+ | shader.js is copyright Patrick Rhodes Martin 2013,2017,2024 used with permission.
5
5
|
6
6
|-
7
7
*/
12
12
*/
13
13
const shaderlog = { } ;
14
14
let statetracker = { } ;
15
+ let shadercounter = Number . MIN_SAFE_INTEGER ;
15
16
16
17
function isArrayish ( a ) {
17
18
return (
@@ -28,6 +29,11 @@ function isArrayish(a) {
28
29
}
29
30
30
31
const ShaderPrototype = Object . create ( Object , {
32
+ _shaderId : {
33
+ value : NaN ,
34
+ writable : true
35
+ } ,
36
+
31
37
_shader : {
32
38
value : null ,
33
39
writable : true
@@ -54,16 +60,16 @@ const ShaderPrototype = Object.create(Object, {
54
60
} ,
55
61
56
62
_isUnchanged : {
57
- value : function _isUnchanged ( property , uniformid , context ) {
63
+ value : function _isUnchanged ( property , uniformid ) {
58
64
let val = property . val ;
59
- let cval = statetracker [ context ] [ uniformid ] ;
65
+ let cval = statetracker [ this . _shaderId ] [ uniformid ] ;
60
66
let i ;
61
67
let unchanged = true ;
62
68
if ( isArrayish ( val ) && isArrayish ( cval ) ) {
63
69
if ( val . length !== cval . length ) return false ;
64
70
else
65
71
for ( i = 0 ; i < val . length ; i ++ )
66
- if ( ! ( unchanged = unchanged && val [ i ] === cval [ i ] ) )
72
+ if ( ! ( unchanged = ( unchanged && val [ i ] === cval [ i ] ) ) )
67
73
break ;
68
74
69
75
return unchanged ;
@@ -242,6 +248,7 @@ const ShaderPrototype = Object.create(Object, {
242
248
"bindShader" : {
243
249
value : function bindShader ( gl ) {
244
250
gl . useProgram ( this . _shader ) ;
251
+ statetracker [ this . _shaderId ] = statetracker [ this . _shaderId ] ?? { } ;
245
252
let props = Object . keys ( this . _keys ) ;
246
253
let key = null ;
247
254
let uniform = null ;
@@ -254,7 +261,7 @@ const ShaderPrototype = Object.create(Object, {
254
261
key
255
262
) ;
256
263
uniform = this . _uniformLocations [ key ] ;
257
- if ( this . _isUnchanged ( this . _keys [ key ] , uniform , gl ) ) continue ;
264
+ if ( this . _isUnchanged ( this . _keys [ key ] , i ) ) continue ;
258
265
if ( ( uniform || null ) !== null ) {
259
266
type = this . _keys [ key ] . datatype ;
260
267
switch ( type ) {
@@ -358,7 +365,14 @@ const ShaderPrototype = Object.create(Object, {
358
365
) ;
359
366
break ;
360
367
}
361
- statetracker [ uniform ] = this . _keys [ key ] . val ;
368
+ if ( isArrayish ( this . _keys [ key ] . val ) ) {
369
+ if ( ! statetracker [ this . _shaderId ] [ uniform ] )
370
+ statetracker [ this . _shaderId ] [ uniform ] = Array . from ( this . _keys [ key ] . val ) ;
371
+ else {
372
+ for ( let i = 0 ; i < this . _keys [ key ] . val . length ; i ++ )
373
+ statetracker [ this . _shaderId ] [ uniform ] [ i ] = this . _keys [ key ] . val [ i ] ;
374
+ }
375
+ } else statetracker [ this . _shaderId ] [ uniform ] = this . _keys [ key ] . val ;
362
376
}
363
377
}
364
378
} ,
@@ -387,7 +401,6 @@ const ShaderPrototype = Object.create(Object, {
387
401
388
402
"compile" : {
389
403
value : function compile ( gl , defines , err , version ) {
390
- statetracker [ gl ] = statetracker [ gl ] ?? { } ;
391
404
this . _uniformLocations = { } ;
392
405
if ( typeof err === "undefined" || err === null ) {
393
406
err = defines ;
@@ -442,29 +455,42 @@ const ShaderPrototype = Object.create(Object, {
442
455
443
456
_compile : {
444
457
value : function _compile ( gl , source , defines , type , version ) {
445
- let shaderHeader = "" ;
458
+ let shaderHeader = "#ifndef WEB_GL\n" ;
459
+ shaderHeader += "#define WEB_GL\n" ;
460
+ shaderHeader += "#endif\n" ;
446
461
if ( version && version !== "100" ) {
447
462
shaderHeader += "#version " + version + " es\n" ;
448
463
}
449
- shaderHeader += "#ifndef WEB_GL\n" ;
450
- shaderHeader += "#define WEB_GL\n" ;
451
- shaderHeader += "#endif\n" ;
452
464
shaderHeader += "#ifdef GL_ES\n" ;
453
- shaderHeader += "precision highp float;\n" ;
454
- shaderHeader += "precision highp int;\n" ;
465
+ if ( type === gl . VERTEX_SHADER ) {
466
+ shaderHeader += "precision highp float;\n" ;
467
+ shaderHeader += "precision highp int;\n" ;
468
+ shaderHeader += "#if !defined(GL_FRAGMENT_PRECISION_HIGH) || !GL_FRAGMENT_PRECISION_HIGH\n" ;
469
+ shaderHeader += "#define MEDIUM_FRAGMENT_PRECISION\n" ;
470
+ } else if ( type === gl . FRAGMENT_SHADER ) {
471
+ shaderHeader += "#if defined(GL_FRAGMENT_PRECISION_HIGH) && GL_FRAGMENT_PRECISION_HIGH\n" ;
472
+ shaderHeader += "precision highp float;\n" ;
473
+ shaderHeader += "precision highp int;\n" ;
474
+ shaderHeader += "#else\n" ;
475
+ shaderHeader += "#define MEDIUM_FRAGMENT_PRECISION\n" ;
476
+ shaderHeader += "precision mediump float;\n" ;
477
+ shaderHeader += "precision mediump int;\n" ;
478
+ }
479
+ shaderHeader += "#endif\n" ;
455
480
shaderHeader += "#endif\n" ;
456
481
if ( defines !== null ) {
457
482
let define_names = Object . keys ( defines ) ;
458
483
for ( let i = 0 ; i < define_names . length ; i ++ ) {
459
- if ( defines [ define_names [ i ] ] === true )
484
+ if ( defines [ define_names [ i ] ] === true ) {
460
485
shaderHeader += "#define " + define_names [ i ] + "\n" ;
461
- else if ( defines [ define_names [ i ] ] !== null )
486
+ } else if ( defines [ define_names [ i ] ] !== null ) {
462
487
shaderHeader +=
463
488
"#define " +
464
489
define_names [ i ] +
465
490
" " +
466
491
defines [ define_names [ i ] ] . toString ( ) +
467
492
"\n" ;
493
+ }
468
494
}
469
495
}
470
496
@@ -492,7 +518,9 @@ const ShaderPrototype = Object.create(Object, {
492
518
} ) ;
493
519
494
520
sabre [ "Shader" ] = function Shader ( ) {
495
- return Object . create ( ShaderPrototype ) ;
521
+ let shader = Object . create ( ShaderPrototype ) ;
522
+ shader . _shaderId = shadercounter ++ ;
523
+ return shader ;
496
524
} ;
497
525
sabre [ "Shader" ] [ "resetStateEngine" ] = function resetStateEngine ( ) {
498
526
statetracker = { } ;
0 commit comments