@codexo/exojs 0.6.2 → 0.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +516 -499
- package/README.md +156 -156
- package/dist/esm/core/capabilities.d.ts +37 -0
- package/dist/esm/core/capabilities.js +96 -0
- package/dist/esm/core/capabilities.js.map +1 -0
- package/dist/esm/core/index.d.ts +1 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/rendering/webgl2/glsl/mask-compose.frag.js +1 -1
- package/dist/esm/rendering/webgl2/glsl/mask-compose.vert.js +1 -1
- package/dist/esm/rendering/webgl2/glsl/particle.frag.js +1 -1
- package/dist/esm/rendering/webgl2/glsl/primitive.frag.js +1 -1
- package/dist/esm/rendering/webgl2/glsl/primitive.vert.js +1 -1
- package/dist/esm/rendering/webgl2/glsl/sprite.frag.js +1 -1
- package/dist/esm/rendering/webgpu/WebGpuBackend.js +41 -41
- package/dist/esm/rendering/webgpu/WebGpuBackend.js.map +1 -1
- package/dist/esm/rendering/webgpu/WebGpuMaskCompositor.js +44 -44
- package/dist/esm/rendering/webgpu/WebGpuMaskCompositor.js.map +1 -1
- package/dist/esm/rendering/webgpu/WebGpuParticleRenderer.js +65 -65
- package/dist/esm/rendering/webgpu/WebGpuParticleRenderer.js.map +1 -1
- package/dist/esm/rendering/webgpu/WebGpuPrimitiveRenderer.js +25 -25
- package/dist/esm/rendering/webgpu/WebGpuPrimitiveRenderer.js.map +1 -1
- package/dist/esm/vendor/webgl-debug.js +1156 -1156
- package/dist/esm/vendor/webgl-debug.js.map +1 -1
- package/dist/exo.esm.js +1432 -1338
- package/dist/exo.esm.js.map +1 -1
- package/package.json +105 -105
package/dist/exo.esm.js
CHANGED
|
@@ -3870,1162 +3870,1162 @@ class SceneManager {
|
|
|
3870
3870
|
}
|
|
3871
3871
|
}
|
|
3872
3872
|
|
|
3873
|
-
/*
|
|
3874
|
-
** Copyright (c) 2012 The Khronos Group Inc.
|
|
3875
|
-
**
|
|
3876
|
-
** Permission is hereby granted, free of charge, to any person obtaining a
|
|
3877
|
-
** copy of this software and/or associated documentation files (the
|
|
3878
|
-
** "Materials"), to deal in the Materials without restriction, including
|
|
3879
|
-
** without limitation the rights to use, copy, modify, merge, publish,
|
|
3880
|
-
** distribute, sublicense, and/or sell copies of the Materials, and to
|
|
3881
|
-
** permit persons to whom the Materials are furnished to do so, subject to
|
|
3882
|
-
** the following conditions:
|
|
3883
|
-
**
|
|
3884
|
-
** The above copyright notice and this permission notice shall be included
|
|
3885
|
-
** in all copies or substantial portions of the Materials.
|
|
3886
|
-
**
|
|
3887
|
-
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
3888
|
-
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
3889
|
-
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
3890
|
-
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
3891
|
-
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
3892
|
-
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
3893
|
-
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
|
3894
|
-
*/
|
|
3895
|
-
|
|
3896
|
-
// Various functions for helping debug WebGL apps.
|
|
3897
|
-
|
|
3898
|
-
const WebGLDebugUtils = function() {
|
|
3899
|
-
|
|
3900
|
-
/**
|
|
3901
|
-
* Wrapped logging function.
|
|
3902
|
-
* @param {string} msg Message to log.
|
|
3903
|
-
*/
|
|
3904
|
-
var log = function(msg) {
|
|
3905
|
-
if (window.console && window.console.log) {
|
|
3906
|
-
window.console.log(msg);
|
|
3907
|
-
}
|
|
3908
|
-
};
|
|
3909
|
-
|
|
3910
|
-
/**
|
|
3911
|
-
* Wrapped error logging function.
|
|
3912
|
-
* @param {string} msg Message to log.
|
|
3913
|
-
*/
|
|
3914
|
-
var error = function(msg) {
|
|
3915
|
-
if (window.console && window.console.error) {
|
|
3916
|
-
window.console.error(msg);
|
|
3917
|
-
} else {
|
|
3918
|
-
log(msg);
|
|
3919
|
-
}
|
|
3920
|
-
};
|
|
3921
|
-
|
|
3922
|
-
|
|
3923
|
-
/**
|
|
3924
|
-
* Which arguments are enums based on the number of arguments to the function.
|
|
3925
|
-
* So
|
|
3926
|
-
* 'texImage2D': {
|
|
3927
|
-
* 9: { 0:true, 2:true, 6:true, 7:true },
|
|
3928
|
-
* 6: { 0:true, 2:true, 3:true, 4:true },
|
|
3929
|
-
* },
|
|
3930
|
-
*
|
|
3931
|
-
* means if there are 9 arguments then 6 and 7 are enums, if there are 6
|
|
3932
|
-
* arguments 3 and 4 are enums
|
|
3933
|
-
*
|
|
3934
|
-
* @type {!Object.<number, !Object.<number, string>}
|
|
3935
|
-
*/
|
|
3936
|
-
var glValidEnumContexts = {
|
|
3937
|
-
// Generic setters and getters
|
|
3938
|
-
|
|
3939
|
-
'enable': {1: { 0:true }},
|
|
3940
|
-
'disable': {1: { 0:true }},
|
|
3941
|
-
'getParameter': {1: { 0:true }},
|
|
3942
|
-
|
|
3943
|
-
// Rendering
|
|
3944
|
-
|
|
3945
|
-
'drawArrays': {3:{ 0:true }},
|
|
3946
|
-
'drawElements': {4:{ 0:true, 2:true }},
|
|
3947
|
-
|
|
3948
|
-
// Shaders
|
|
3949
|
-
|
|
3950
|
-
'createShader': {1: { 0:true }},
|
|
3951
|
-
'getShaderParameter': {2: { 1:true }},
|
|
3952
|
-
'getProgramParameter': {2: { 1:true }},
|
|
3953
|
-
'getShaderPrecisionFormat': {2: { 0: true, 1:true }},
|
|
3954
|
-
|
|
3955
|
-
// Vertex attributes
|
|
3956
|
-
|
|
3957
|
-
'getVertexAttrib': {2: { 1:true }},
|
|
3958
|
-
'vertexAttribPointer': {6: { 2:true }},
|
|
3959
|
-
|
|
3960
|
-
// Textures
|
|
3961
|
-
|
|
3962
|
-
'bindTexture': {2: { 0:true }},
|
|
3963
|
-
'activeTexture': {1: { 0:true }},
|
|
3964
|
-
'getTexParameter': {2: { 0:true, 1:true }},
|
|
3965
|
-
'texParameterf': {3: { 0:true, 1:true }},
|
|
3966
|
-
'texParameteri': {3: { 0:true, 1:true, 2:true }},
|
|
3967
|
-
// texImage2D and texSubImage2D are defined below with WebGL 2 entrypoints
|
|
3968
|
-
'copyTexImage2D': {8: { 0:true, 2:true }},
|
|
3969
|
-
'copyTexSubImage2D': {8: { 0:true }},
|
|
3970
|
-
'generateMipmap': {1: { 0:true }},
|
|
3971
|
-
// compressedTexImage2D and compressedTexSubImage2D are defined below with WebGL 2 entrypoints
|
|
3972
|
-
|
|
3973
|
-
// Buffer objects
|
|
3974
|
-
|
|
3975
|
-
'bindBuffer': {2: { 0:true }},
|
|
3976
|
-
// bufferData and bufferSubData are defined below with WebGL 2 entrypoints
|
|
3977
|
-
'getBufferParameter': {2: { 0:true, 1:true }},
|
|
3978
|
-
|
|
3979
|
-
// Renderbuffers and framebuffers
|
|
3980
|
-
|
|
3981
|
-
'pixelStorei': {2: { 0:true, 1:true }},
|
|
3982
|
-
// readPixels is defined below with WebGL 2 entrypoints
|
|
3983
|
-
'bindRenderbuffer': {2: { 0:true }},
|
|
3984
|
-
'bindFramebuffer': {2: { 0:true }},
|
|
3985
|
-
'checkFramebufferStatus': {1: { 0:true }},
|
|
3986
|
-
'framebufferRenderbuffer': {4: { 0:true, 1:true, 2:true }},
|
|
3987
|
-
'framebufferTexture2D': {5: { 0:true, 1:true, 2:true }},
|
|
3988
|
-
'getFramebufferAttachmentParameter': {3: { 0:true, 1:true, 2:true }},
|
|
3989
|
-
'getRenderbufferParameter': {2: { 0:true, 1:true }},
|
|
3990
|
-
'renderbufferStorage': {4: { 0:true, 1:true }},
|
|
3991
|
-
|
|
3992
|
-
// Frame buffer operations (clear, blend, depth test, stencil)
|
|
3993
|
-
|
|
3994
|
-
'clear': {1: { 0: { 'enumBitwiseOr': ['COLOR_BUFFER_BIT', 'DEPTH_BUFFER_BIT', 'STENCIL_BUFFER_BIT'] }}},
|
|
3995
|
-
'depthFunc': {1: { 0:true }},
|
|
3996
|
-
'blendFunc': {2: { 0:true, 1:true }},
|
|
3997
|
-
'blendFuncSeparate': {4: { 0:true, 1:true, 2:true, 3:true }},
|
|
3998
|
-
'blendEquation': {1: { 0:true }},
|
|
3999
|
-
'blendEquationSeparate': {2: { 0:true, 1:true }},
|
|
4000
|
-
'stencilFunc': {3: { 0:true }},
|
|
4001
|
-
'stencilFuncSeparate': {4: { 0:true, 1:true }},
|
|
4002
|
-
'stencilMaskSeparate': {2: { 0:true }},
|
|
4003
|
-
'stencilOp': {3: { 0:true, 1:true, 2:true }},
|
|
4004
|
-
'stencilOpSeparate': {4: { 0:true, 1:true, 2:true, 3:true }},
|
|
4005
|
-
|
|
4006
|
-
// Culling
|
|
4007
|
-
|
|
4008
|
-
'cullFace': {1: { 0:true }},
|
|
4009
|
-
'frontFace': {1: { 0:true }},
|
|
4010
|
-
|
|
4011
|
-
// ANGLE_instanced_arrays extension
|
|
4012
|
-
|
|
4013
|
-
'drawArraysInstancedANGLE': {4: { 0:true }},
|
|
4014
|
-
'drawElementsInstancedANGLE': {5: { 0:true, 2:true }},
|
|
4015
|
-
|
|
4016
|
-
// EXT_blend_minmax extension
|
|
4017
|
-
|
|
4018
|
-
'blendEquationEXT': {1: { 0:true }},
|
|
4019
|
-
|
|
4020
|
-
// WebGL 2 Buffer objects
|
|
4021
|
-
|
|
4022
|
-
'bufferData': {
|
|
4023
|
-
3: { 0:true, 2:true }, // WebGL 1
|
|
4024
|
-
4: { 0:true, 2:true }, // WebGL 2
|
|
4025
|
-
5: { 0:true, 2:true } // WebGL 2
|
|
4026
|
-
},
|
|
4027
|
-
'bufferSubData': {
|
|
4028
|
-
3: { 0:true }, // WebGL 1
|
|
4029
|
-
4: { 0:true }, // WebGL 2
|
|
4030
|
-
5: { 0:true } // WebGL 2
|
|
4031
|
-
},
|
|
4032
|
-
'copyBufferSubData': {5: { 0:true, 1:true }},
|
|
4033
|
-
'getBufferSubData': {3: { 0:true }, 4: { 0:true }, 5: { 0:true }},
|
|
4034
|
-
|
|
4035
|
-
// WebGL 2 Framebuffer objects
|
|
4036
|
-
|
|
4037
|
-
'blitFramebuffer': {10: { 8: { 'enumBitwiseOr': ['COLOR_BUFFER_BIT', 'DEPTH_BUFFER_BIT', 'STENCIL_BUFFER_BIT'] }, 9:true }},
|
|
4038
|
-
'framebufferTextureLayer': {5: { 0:true, 1:true }},
|
|
4039
|
-
'invalidateFramebuffer': {2: { 0:true }},
|
|
4040
|
-
'invalidateSubFramebuffer': {6: { 0:true }},
|
|
4041
|
-
'readBuffer': {1: { 0:true }},
|
|
4042
|
-
|
|
4043
|
-
// WebGL 2 Renderbuffer objects
|
|
4044
|
-
|
|
4045
|
-
'getInternalformatParameter': {3: { 0:true, 1:true, 2:true }},
|
|
4046
|
-
'renderbufferStorageMultisample': {5: { 0:true, 2:true }},
|
|
4047
|
-
|
|
4048
|
-
// WebGL 2 Texture objects
|
|
4049
|
-
|
|
4050
|
-
'texStorage2D': {5: { 0:true, 2:true }},
|
|
4051
|
-
'texStorage3D': {6: { 0:true, 2:true }},
|
|
4052
|
-
'texImage2D': {
|
|
4053
|
-
9: { 0:true, 2:true, 6:true, 7:true }, // WebGL 1 & 2
|
|
4054
|
-
6: { 0:true, 2:true, 3:true, 4:true }, // WebGL 1
|
|
4055
|
-
10: { 0:true, 2:true, 6:true, 7:true } // WebGL 2
|
|
4056
|
-
},
|
|
4057
|
-
'texImage3D': {
|
|
4058
|
-
10: { 0:true, 2:true, 7:true, 8:true },
|
|
4059
|
-
11: { 0:true, 2:true, 7:true, 8:true }
|
|
4060
|
-
},
|
|
4061
|
-
'texSubImage2D': {
|
|
4062
|
-
9: { 0:true, 6:true, 7:true }, // WebGL 1 & 2
|
|
4063
|
-
7: { 0:true, 4:true, 5:true }, // WebGL 1
|
|
4064
|
-
10: { 0:true, 6:true, 7:true } // WebGL 2
|
|
4065
|
-
},
|
|
4066
|
-
'texSubImage3D': {
|
|
4067
|
-
11: { 0:true, 8:true, 9:true },
|
|
4068
|
-
12: { 0:true, 8:true, 9:true }
|
|
4069
|
-
},
|
|
4070
|
-
'copyTexSubImage3D': {9: { 0:true }},
|
|
4071
|
-
'compressedTexImage2D': {
|
|
4072
|
-
7: { 0: true, 2:true }, // WebGL 1 & 2
|
|
4073
|
-
8: { 0: true, 2:true }, // WebGL 2
|
|
4074
|
-
9: { 0: true, 2:true } // WebGL 2
|
|
4075
|
-
},
|
|
4076
|
-
'compressedTexImage3D': {
|
|
4077
|
-
8: { 0: true, 2:true },
|
|
4078
|
-
9: { 0: true, 2:true },
|
|
4079
|
-
10: { 0: true, 2:true }
|
|
4080
|
-
},
|
|
4081
|
-
'compressedTexSubImage2D': {
|
|
4082
|
-
8: { 0: true, 6:true }, // WebGL 1 & 2
|
|
4083
|
-
9: { 0: true, 6:true }, // WebGL 2
|
|
4084
|
-
10: { 0: true, 6:true } // WebGL 2
|
|
4085
|
-
},
|
|
4086
|
-
'compressedTexSubImage3D': {
|
|
4087
|
-
10: { 0: true, 8:true },
|
|
4088
|
-
11: { 0: true, 8:true },
|
|
4089
|
-
12: { 0: true, 8:true }
|
|
4090
|
-
},
|
|
4091
|
-
|
|
4092
|
-
// WebGL 2 Vertex attribs
|
|
4093
|
-
|
|
4094
|
-
'vertexAttribIPointer': {5: { 2:true }},
|
|
4095
|
-
|
|
4096
|
-
// WebGL 2 Writing to the drawing buffer
|
|
4097
|
-
|
|
4098
|
-
'drawArraysInstanced': {4: { 0:true }},
|
|
4099
|
-
'drawElementsInstanced': {5: { 0:true, 2:true }},
|
|
4100
|
-
'drawRangeElements': {6: { 0:true, 4:true }},
|
|
4101
|
-
|
|
4102
|
-
// WebGL 2 Reading back pixels
|
|
4103
|
-
|
|
4104
|
-
'readPixels': {
|
|
4105
|
-
7: { 4:true, 5:true }, // WebGL 1 & 2
|
|
4106
|
-
8: { 4:true, 5:true } // WebGL 2
|
|
4107
|
-
},
|
|
4108
|
-
|
|
4109
|
-
// WebGL 2 Multiple Render Targets
|
|
4110
|
-
|
|
4111
|
-
'clearBufferfv': {3: { 0:true }, 4: { 0:true }},
|
|
4112
|
-
'clearBufferiv': {3: { 0:true }, 4: { 0:true }},
|
|
4113
|
-
'clearBufferuiv': {3: { 0:true }, 4: { 0:true }},
|
|
4114
|
-
'clearBufferfi': {4: { 0:true }},
|
|
4115
|
-
|
|
4116
|
-
// WebGL 2 Query objects
|
|
4117
|
-
|
|
4118
|
-
'beginQuery': {2: { 0:true }},
|
|
4119
|
-
'endQuery': {1: { 0:true }},
|
|
4120
|
-
'getQuery': {2: { 0:true, 1:true }},
|
|
4121
|
-
'getQueryParameter': {2: { 1:true }},
|
|
4122
|
-
|
|
4123
|
-
// WebGL 2 Sampler objects
|
|
4124
|
-
|
|
4125
|
-
'samplerParameteri': {3: { 1:true, 2:true }},
|
|
4126
|
-
'samplerParameterf': {3: { 1:true }},
|
|
4127
|
-
'getSamplerParameter': {2: { 1:true }},
|
|
4128
|
-
|
|
4129
|
-
// WebGL 2 Sync objects
|
|
4130
|
-
|
|
4131
|
-
'fenceSync': {2: { 0:true, 1: { 'enumBitwiseOr': [] } }},
|
|
4132
|
-
'clientWaitSync': {3: { 1: { 'enumBitwiseOr': ['SYNC_FLUSH_COMMANDS_BIT'] } }},
|
|
4133
|
-
'waitSync': {3: { 1: { 'enumBitwiseOr': [] } }},
|
|
4134
|
-
'getSyncParameter': {2: { 1:true }},
|
|
4135
|
-
|
|
4136
|
-
// WebGL 2 Transform Feedback
|
|
4137
|
-
|
|
4138
|
-
'bindTransformFeedback': {2: { 0:true }},
|
|
4139
|
-
'beginTransformFeedback': {1: { 0:true }},
|
|
4140
|
-
'transformFeedbackVaryings': {3: { 2:true }},
|
|
4141
|
-
|
|
4142
|
-
// WebGL2 Uniform Buffer Objects and Transform Feedback Buffers
|
|
4143
|
-
|
|
4144
|
-
'bindBufferBase': {3: { 0:true }},
|
|
4145
|
-
'bindBufferRange': {5: { 0:true }},
|
|
4146
|
-
'getIndexedParameter': {2: { 0:true }},
|
|
4147
|
-
'getActiveUniforms': {3: { 2:true }},
|
|
4148
|
-
'getActiveUniformBlockParameter': {3: { 2:true }}
|
|
4149
|
-
};
|
|
4150
|
-
|
|
4151
|
-
/**
|
|
4152
|
-
* Map of numbers to names.
|
|
4153
|
-
* @type {Object}
|
|
4154
|
-
*/
|
|
4155
|
-
var glEnums = null;
|
|
4156
|
-
|
|
4157
|
-
/**
|
|
4158
|
-
* Map of names to numbers.
|
|
4159
|
-
* @type {Object}
|
|
4160
|
-
*/
|
|
4161
|
-
var enumStringToValue = null;
|
|
4162
|
-
|
|
4163
|
-
/**
|
|
4164
|
-
* Initializes this module. Safe to call more than once.
|
|
4165
|
-
* @param {!WebGLRenderingContext} ctx A WebGL context. If
|
|
4166
|
-
* you have more than one context it doesn't matter which one
|
|
4167
|
-
* you pass in, it is only used to pull out constants.
|
|
4168
|
-
*/
|
|
4169
|
-
function init(ctx) {
|
|
4170
|
-
if (glEnums == null) {
|
|
4171
|
-
glEnums = { };
|
|
4172
|
-
enumStringToValue = { };
|
|
4173
|
-
for (var propertyName in ctx) {
|
|
4174
|
-
if (typeof ctx[propertyName] == 'number') {
|
|
4175
|
-
glEnums[ctx[propertyName]] = propertyName;
|
|
4176
|
-
enumStringToValue[propertyName] = ctx[propertyName];
|
|
4177
|
-
}
|
|
4178
|
-
}
|
|
4179
|
-
}
|
|
4180
|
-
}
|
|
4181
|
-
|
|
4182
|
-
/**
|
|
4183
|
-
* Checks the utils have been initialized.
|
|
4184
|
-
*/
|
|
4185
|
-
function checkInit() {
|
|
4186
|
-
if (glEnums == null) {
|
|
4187
|
-
throw 'WebGLDebugUtils.init(ctx) not called';
|
|
4188
|
-
}
|
|
4189
|
-
}
|
|
4190
|
-
|
|
4191
|
-
/**
|
|
4192
|
-
* Returns true or false if value matches any WebGL enum
|
|
4193
|
-
* @param {*} value Value to check if it might be an enum.
|
|
4194
|
-
* @return {boolean} True if value matches one of the WebGL defined enums
|
|
4195
|
-
*/
|
|
4196
|
-
function mightBeEnum(value) {
|
|
4197
|
-
checkInit();
|
|
4198
|
-
return (glEnums[value] !== undefined);
|
|
4199
|
-
}
|
|
4200
|
-
|
|
4201
|
-
/**
|
|
4202
|
-
* Gets an string version of an WebGL enum.
|
|
4203
|
-
*
|
|
4204
|
-
* Example:
|
|
4205
|
-
* var str = WebGLDebugUtil.glEnumToString(ctx.getError());
|
|
4206
|
-
*
|
|
4207
|
-
* @param {number} value Value to return an enum for
|
|
4208
|
-
* @return {string} The string version of the enum.
|
|
4209
|
-
*/
|
|
4210
|
-
function glEnumToString(value) {
|
|
4211
|
-
checkInit();
|
|
4212
|
-
var name = glEnums[value];
|
|
4213
|
-
return (name !== undefined) ? ("gl." + name) :
|
|
4214
|
-
("/*UNKNOWN WebGL ENUM*/ 0x" + value.toString(16) + "");
|
|
4215
|
-
}
|
|
4216
|
-
|
|
4217
|
-
/**
|
|
4218
|
-
* Returns the string version of a WebGL argument.
|
|
4219
|
-
* Attempts to convert enum arguments to strings.
|
|
4220
|
-
* @param {string} functionName the name of the WebGL function.
|
|
4221
|
-
* @param {number} numArgs the number of arguments passed to the function.
|
|
4222
|
-
* @param {number} argumentIndx the index of the argument.
|
|
4223
|
-
* @param {*} value The value of the argument.
|
|
4224
|
-
* @return {string} The value as a string.
|
|
4225
|
-
*/
|
|
4226
|
-
function glFunctionArgToString(functionName, numArgs, argumentIndex, value) {
|
|
4227
|
-
var funcInfo = glValidEnumContexts[functionName];
|
|
4228
|
-
if (funcInfo !== undefined) {
|
|
4229
|
-
var funcInfo = funcInfo[numArgs];
|
|
4230
|
-
if (funcInfo !== undefined) {
|
|
4231
|
-
if (funcInfo[argumentIndex]) {
|
|
4232
|
-
if (typeof funcInfo[argumentIndex] === 'object' &&
|
|
4233
|
-
funcInfo[argumentIndex]['enumBitwiseOr'] !== undefined) {
|
|
4234
|
-
var enums = funcInfo[argumentIndex]['enumBitwiseOr'];
|
|
4235
|
-
var orResult = 0;
|
|
4236
|
-
var orEnums = [];
|
|
4237
|
-
for (var i = 0; i < enums.length; ++i) {
|
|
4238
|
-
var enumValue = enumStringToValue[enums[i]];
|
|
4239
|
-
if ((value & enumValue) !== 0) {
|
|
4240
|
-
orResult |= enumValue;
|
|
4241
|
-
orEnums.push(glEnumToString(enumValue));
|
|
4242
|
-
}
|
|
4243
|
-
}
|
|
4244
|
-
if (orResult === value) {
|
|
4245
|
-
return orEnums.join(' | ');
|
|
4246
|
-
} else {
|
|
4247
|
-
return glEnumToString(value);
|
|
4248
|
-
}
|
|
4249
|
-
} else {
|
|
4250
|
-
return glEnumToString(value);
|
|
4251
|
-
}
|
|
4252
|
-
}
|
|
4253
|
-
}
|
|
4254
|
-
}
|
|
4255
|
-
if (value === null) {
|
|
4256
|
-
return "null";
|
|
4257
|
-
} else if (value === undefined) {
|
|
4258
|
-
return "undefined";
|
|
4259
|
-
} else {
|
|
4260
|
-
return value.toString();
|
|
4261
|
-
}
|
|
4262
|
-
}
|
|
4263
|
-
|
|
4264
|
-
/**
|
|
4265
|
-
* Converts the arguments of a WebGL function to a string.
|
|
4266
|
-
* Attempts to convert enum arguments to strings.
|
|
4267
|
-
*
|
|
4268
|
-
* @param {string} functionName the name of the WebGL function.
|
|
4269
|
-
* @param {Array<*>} args The arguments.
|
|
4270
|
-
* @return {string} The arguments as a string.
|
|
4271
|
-
*/
|
|
4272
|
-
function glFunctionArgsToString(functionName, args) {
|
|
4273
|
-
// apparently we can't do args.join(",");
|
|
4274
|
-
var argStr = "";
|
|
4275
|
-
var numArgs = args.length;
|
|
4276
|
-
for (var ii = 0; ii < numArgs; ++ii) {
|
|
4277
|
-
argStr += ((ii == 0) ? '' : ', ') +
|
|
4278
|
-
glFunctionArgToString(functionName, numArgs, ii, args[ii]);
|
|
4279
|
-
}
|
|
4280
|
-
return argStr;
|
|
4281
|
-
}
|
|
4282
|
-
|
|
4283
|
-
function makePropertyWrapper(wrapper, original, propertyName) {
|
|
4284
|
-
//log("wrap prop: " + propertyName);
|
|
4285
|
-
wrapper.__defineGetter__(propertyName, function() {
|
|
4286
|
-
return original[propertyName];
|
|
4287
|
-
});
|
|
4288
|
-
// TODO(gmane): this needs to handle properties that take more than
|
|
4289
|
-
// one value?
|
|
4290
|
-
wrapper.__defineSetter__(propertyName, function(value) {
|
|
4291
|
-
//log("set: " + propertyName);
|
|
4292
|
-
original[propertyName] = value;
|
|
4293
|
-
});
|
|
4294
|
-
}
|
|
4295
|
-
|
|
4296
|
-
/**
|
|
4297
|
-
* Given a WebGL context returns a wrapped context that calls
|
|
4298
|
-
* gl.getError after every command and calls a function if the
|
|
4299
|
-
* result is not gl.NO_ERROR.
|
|
4300
|
-
*
|
|
4301
|
-
* @param {!WebGLRenderingContext} ctx The webgl context to
|
|
4302
|
-
* wrap.
|
|
4303
|
-
* @param {!function(err, funcName, args): void} opt_onErrorFunc
|
|
4304
|
-
* The function to call when gl.getError returns an
|
|
4305
|
-
* error. If not specified the default function calls
|
|
4306
|
-
* console.log with a message.
|
|
4307
|
-
* @param {!function(funcName, args): void} opt_onFunc The
|
|
4308
|
-
* function to call when each webgl function is called.
|
|
4309
|
-
* You can use this to log all calls for example.
|
|
4310
|
-
* @param {!WebGLRenderingContext} opt_err_ctx The webgl context
|
|
4311
|
-
* to call getError on if different than ctx.
|
|
4312
|
-
*/
|
|
4313
|
-
function makeDebugContext(ctx, opt_onErrorFunc, opt_onFunc, opt_err_ctx) {
|
|
4314
|
-
opt_err_ctx = opt_err_ctx || ctx;
|
|
4315
|
-
init(ctx);
|
|
4316
|
-
opt_onErrorFunc = opt_onErrorFunc || function(err, functionName, args) {
|
|
4317
|
-
// apparently we can't do args.join(",");
|
|
4318
|
-
var argStr = "";
|
|
4319
|
-
var numArgs = args.length;
|
|
4320
|
-
for (var ii = 0; ii < numArgs; ++ii) {
|
|
4321
|
-
argStr += ((ii == 0) ? '' : ', ') +
|
|
4322
|
-
glFunctionArgToString(functionName, numArgs, ii, args[ii]);
|
|
4323
|
-
}
|
|
4324
|
-
error("WebGL error "+ glEnumToString(err) + " in "+ functionName +
|
|
4325
|
-
"(" + argStr + ")");
|
|
4326
|
-
};
|
|
4327
|
-
|
|
4328
|
-
// Holds booleans for each GL error so after we get the error ourselves
|
|
4329
|
-
// we can still return it to the client app.
|
|
4330
|
-
var glErrorShadow = { };
|
|
4331
|
-
|
|
4332
|
-
// Makes a function that calls a WebGL function and then calls getError.
|
|
4333
|
-
function makeErrorWrapper(ctx, functionName) {
|
|
4334
|
-
return function() {
|
|
4335
|
-
if (opt_onFunc) {
|
|
4336
|
-
opt_onFunc(functionName, arguments);
|
|
4337
|
-
}
|
|
4338
|
-
var result = ctx[functionName].apply(ctx, arguments);
|
|
4339
|
-
var err = opt_err_ctx.getError();
|
|
4340
|
-
if (err != 0) {
|
|
4341
|
-
glErrorShadow[err] = true;
|
|
4342
|
-
opt_onErrorFunc(err, functionName, arguments);
|
|
4343
|
-
}
|
|
4344
|
-
return result;
|
|
4345
|
-
};
|
|
4346
|
-
}
|
|
4347
|
-
|
|
4348
|
-
// Make a an object that has a copy of every property of the WebGL context
|
|
4349
|
-
// but wraps all functions.
|
|
4350
|
-
var wrapper = {};
|
|
4351
|
-
for (var propertyName in ctx) {
|
|
4352
|
-
if (typeof ctx[propertyName] == 'function') {
|
|
4353
|
-
if (propertyName != 'getExtension') {
|
|
4354
|
-
wrapper[propertyName] = makeErrorWrapper(ctx, propertyName);
|
|
4355
|
-
} else {
|
|
4356
|
-
var wrapped = makeErrorWrapper(ctx, propertyName);
|
|
4357
|
-
wrapper[propertyName] = function () {
|
|
4358
|
-
var result = wrapped.apply(ctx, arguments);
|
|
4359
|
-
if (!result) {
|
|
4360
|
-
return null;
|
|
4361
|
-
}
|
|
4362
|
-
return makeDebugContext(result, opt_onErrorFunc, opt_onFunc, opt_err_ctx);
|
|
4363
|
-
};
|
|
4364
|
-
}
|
|
4365
|
-
} else {
|
|
4366
|
-
makePropertyWrapper(wrapper, ctx, propertyName);
|
|
4367
|
-
}
|
|
4368
|
-
}
|
|
4369
|
-
|
|
4370
|
-
// Override the getError function with one that returns our saved results.
|
|
4371
|
-
wrapper.getError = function() {
|
|
4372
|
-
for (var err in glErrorShadow) {
|
|
4373
|
-
if (glErrorShadow.hasOwnProperty(err)) {
|
|
4374
|
-
if (glErrorShadow[err]) {
|
|
4375
|
-
glErrorShadow[err] = false;
|
|
4376
|
-
return err;
|
|
4377
|
-
}
|
|
4378
|
-
}
|
|
4379
|
-
}
|
|
4380
|
-
return ctx.NO_ERROR;
|
|
4381
|
-
};
|
|
4382
|
-
|
|
4383
|
-
return wrapper;
|
|
4384
|
-
}
|
|
4385
|
-
|
|
4386
|
-
function resetToInitialState(ctx) {
|
|
4387
|
-
var isWebGL2RenderingContext = !!ctx.createTransformFeedback;
|
|
4388
|
-
|
|
4389
|
-
if (isWebGL2RenderingContext) {
|
|
4390
|
-
ctx.bindVertexArray(null);
|
|
4391
|
-
}
|
|
4392
|
-
|
|
4393
|
-
var numAttribs = ctx.getParameter(ctx.MAX_VERTEX_ATTRIBS);
|
|
4394
|
-
var tmp = ctx.createBuffer();
|
|
4395
|
-
ctx.bindBuffer(ctx.ARRAY_BUFFER, tmp);
|
|
4396
|
-
for (var ii = 0; ii < numAttribs; ++ii) {
|
|
4397
|
-
ctx.disableVertexAttribArray(ii);
|
|
4398
|
-
ctx.vertexAttribPointer(ii, 4, ctx.FLOAT, false, 0, 0);
|
|
4399
|
-
ctx.vertexAttrib1f(ii, 0);
|
|
4400
|
-
if (isWebGL2RenderingContext) {
|
|
4401
|
-
ctx.vertexAttribDivisor(ii, 0);
|
|
4402
|
-
}
|
|
4403
|
-
}
|
|
4404
|
-
ctx.deleteBuffer(tmp);
|
|
4405
|
-
|
|
4406
|
-
var numTextureUnits = ctx.getParameter(ctx.MAX_TEXTURE_IMAGE_UNITS);
|
|
4407
|
-
for (var ii = 0; ii < numTextureUnits; ++ii) {
|
|
4408
|
-
ctx.activeTexture(ctx.TEXTURE0 + ii);
|
|
4409
|
-
ctx.bindTexture(ctx.TEXTURE_CUBE_MAP, null);
|
|
4410
|
-
ctx.bindTexture(ctx.TEXTURE_2D, null);
|
|
4411
|
-
if (isWebGL2RenderingContext) {
|
|
4412
|
-
ctx.bindTexture(ctx.TEXTURE_2D_ARRAY, null);
|
|
4413
|
-
ctx.bindTexture(ctx.TEXTURE_3D, null);
|
|
4414
|
-
ctx.bindSampler(ii, null);
|
|
4415
|
-
}
|
|
4416
|
-
}
|
|
4417
|
-
|
|
4418
|
-
ctx.activeTexture(ctx.TEXTURE0);
|
|
4419
|
-
ctx.useProgram(null);
|
|
4420
|
-
ctx.bindBuffer(ctx.ARRAY_BUFFER, null);
|
|
4421
|
-
ctx.bindBuffer(ctx.ELEMENT_ARRAY_BUFFER, null);
|
|
4422
|
-
ctx.bindFramebuffer(ctx.FRAMEBUFFER, null);
|
|
4423
|
-
ctx.bindRenderbuffer(ctx.RENDERBUFFER, null);
|
|
4424
|
-
ctx.disable(ctx.BLEND);
|
|
4425
|
-
ctx.disable(ctx.CULL_FACE);
|
|
4426
|
-
ctx.disable(ctx.DEPTH_TEST);
|
|
4427
|
-
ctx.disable(ctx.DITHER);
|
|
4428
|
-
ctx.disable(ctx.SCISSOR_TEST);
|
|
4429
|
-
ctx.blendColor(0, 0, 0, 0);
|
|
4430
|
-
ctx.blendEquation(ctx.FUNC_ADD);
|
|
4431
|
-
ctx.blendFunc(ctx.ONE, ctx.ZERO);
|
|
4432
|
-
ctx.clearColor(0, 0, 0, 0);
|
|
4433
|
-
ctx.clearDepth(1);
|
|
4434
|
-
ctx.clearStencil(-1);
|
|
4435
|
-
ctx.colorMask(true, true, true, true);
|
|
4436
|
-
ctx.cullFace(ctx.BACK);
|
|
4437
|
-
ctx.depthFunc(ctx.LESS);
|
|
4438
|
-
ctx.depthMask(true);
|
|
4439
|
-
ctx.depthRange(0, 1);
|
|
4440
|
-
ctx.frontFace(ctx.CCW);
|
|
4441
|
-
ctx.hint(ctx.GENERATE_MIPMAP_HINT, ctx.DONT_CARE);
|
|
4442
|
-
ctx.lineWidth(1);
|
|
4443
|
-
ctx.pixelStorei(ctx.PACK_ALIGNMENT, 4);
|
|
4444
|
-
ctx.pixelStorei(ctx.UNPACK_ALIGNMENT, 4);
|
|
4445
|
-
ctx.pixelStorei(ctx.UNPACK_FLIP_Y_WEBGL, false);
|
|
4446
|
-
ctx.pixelStorei(ctx.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
|
|
4447
|
-
// TODO: Delete this IF.
|
|
4448
|
-
if (ctx.UNPACK_COLORSPACE_CONVERSION_WEBGL) {
|
|
4449
|
-
ctx.pixelStorei(ctx.UNPACK_COLORSPACE_CONVERSION_WEBGL, ctx.BROWSER_DEFAULT_WEBGL);
|
|
4450
|
-
}
|
|
4451
|
-
ctx.polygonOffset(0, 0);
|
|
4452
|
-
ctx.sampleCoverage(1, false);
|
|
4453
|
-
ctx.scissor(0, 0, ctx.canvas.width, ctx.canvas.height);
|
|
4454
|
-
ctx.stencilFunc(ctx.ALWAYS, 0, 0xFFFFFFFF);
|
|
4455
|
-
ctx.stencilMask(0xFFFFFFFF);
|
|
4456
|
-
ctx.stencilOp(ctx.KEEP, ctx.KEEP, ctx.KEEP);
|
|
4457
|
-
ctx.viewport(0, 0, ctx.canvas.width, ctx.canvas.height);
|
|
4458
|
-
ctx.clear(ctx.COLOR_BUFFER_BIT | ctx.DEPTH_BUFFER_BIT | ctx.STENCIL_BUFFER_BIT);
|
|
4459
|
-
|
|
4460
|
-
if (isWebGL2RenderingContext) {
|
|
4461
|
-
ctx.drawBuffers([ctx.BACK]);
|
|
4462
|
-
ctx.readBuffer(ctx.BACK);
|
|
4463
|
-
ctx.bindBuffer(ctx.COPY_READ_BUFFER, null);
|
|
4464
|
-
ctx.bindBuffer(ctx.COPY_WRITE_BUFFER, null);
|
|
4465
|
-
ctx.bindBuffer(ctx.PIXEL_PACK_BUFFER, null);
|
|
4466
|
-
ctx.bindBuffer(ctx.PIXEL_UNPACK_BUFFER, null);
|
|
4467
|
-
var numTransformFeedbacks = ctx.getParameter(ctx.MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS);
|
|
4468
|
-
for (var ii = 0; ii < numTransformFeedbacks; ++ii) {
|
|
4469
|
-
ctx.bindBufferBase(ctx.TRANSFORM_FEEDBACK_BUFFER, ii, null);
|
|
4470
|
-
}
|
|
4471
|
-
var numUBOs = ctx.getParameter(ctx.MAX_UNIFORM_BUFFER_BINDINGS);
|
|
4472
|
-
for (var ii = 0; ii < numUBOs; ++ii) {
|
|
4473
|
-
ctx.bindBufferBase(ctx.UNIFORM_BUFFER, ii, null);
|
|
4474
|
-
}
|
|
4475
|
-
ctx.disable(ctx.RASTERIZER_DISCARD);
|
|
4476
|
-
ctx.pixelStorei(ctx.UNPACK_IMAGE_HEIGHT, 0);
|
|
4477
|
-
ctx.pixelStorei(ctx.UNPACK_SKIP_IMAGES, 0);
|
|
4478
|
-
ctx.pixelStorei(ctx.UNPACK_ROW_LENGTH, 0);
|
|
4479
|
-
ctx.pixelStorei(ctx.UNPACK_SKIP_ROWS, 0);
|
|
4480
|
-
ctx.pixelStorei(ctx.UNPACK_SKIP_PIXELS, 0);
|
|
4481
|
-
ctx.pixelStorei(ctx.PACK_ROW_LENGTH, 0);
|
|
4482
|
-
ctx.pixelStorei(ctx.PACK_SKIP_ROWS, 0);
|
|
4483
|
-
ctx.pixelStorei(ctx.PACK_SKIP_PIXELS, 0);
|
|
4484
|
-
ctx.hint(ctx.FRAGMENT_SHADER_DERIVATIVE_HINT, ctx.DONT_CARE);
|
|
4485
|
-
}
|
|
4486
|
-
|
|
4487
|
-
// TODO: This should NOT be needed but Firefox fails with 'hint'
|
|
4488
|
-
while(ctx.getError());
|
|
4489
|
-
}
|
|
4490
|
-
|
|
4491
|
-
function makeLostContextSimulatingCanvas(canvas) {
|
|
4492
|
-
var unwrappedContext_;
|
|
4493
|
-
var wrappedContext_;
|
|
4494
|
-
var onLost_ = [];
|
|
4495
|
-
var onRestored_ = [];
|
|
4496
|
-
var wrappedContext_ = {};
|
|
4497
|
-
var contextId_ = 1;
|
|
4498
|
-
var contextLost_ = false;
|
|
4499
|
-
var resourceDb_ = [];
|
|
4500
|
-
var numCallsToLoseContext_ = 0;
|
|
4501
|
-
var numCalls_ = 0;
|
|
4502
|
-
var canRestore_ = false;
|
|
4503
|
-
var restoreTimeout_ = 0;
|
|
4504
|
-
var isWebGL2RenderingContext;
|
|
4505
|
-
|
|
4506
|
-
// Holds booleans for each GL error so can simulate errors.
|
|
4507
|
-
var glErrorShadow_ = { };
|
|
4508
|
-
|
|
4509
|
-
canvas.getContext = function(f) {
|
|
4510
|
-
return function() {
|
|
4511
|
-
var ctx = f.apply(canvas, arguments);
|
|
4512
|
-
// Did we get a context and is it a WebGL context?
|
|
4513
|
-
if ((ctx instanceof WebGLRenderingContext) || (window.WebGL2RenderingContext && (ctx instanceof WebGL2RenderingContext))) {
|
|
4514
|
-
if (ctx != unwrappedContext_) {
|
|
4515
|
-
if (unwrappedContext_) {
|
|
4516
|
-
throw "got different context"
|
|
4517
|
-
}
|
|
4518
|
-
isWebGL2RenderingContext = window.WebGL2RenderingContext && (ctx instanceof WebGL2RenderingContext);
|
|
4519
|
-
unwrappedContext_ = ctx;
|
|
4520
|
-
wrappedContext_ = makeLostContextSimulatingContext(unwrappedContext_);
|
|
4521
|
-
}
|
|
4522
|
-
return wrappedContext_;
|
|
4523
|
-
}
|
|
4524
|
-
return ctx;
|
|
4525
|
-
}
|
|
4526
|
-
}(canvas.getContext);
|
|
4527
|
-
|
|
4528
|
-
function wrapEvent(listener) {
|
|
4529
|
-
if (typeof(listener) == "function") {
|
|
4530
|
-
return listener;
|
|
4531
|
-
} else {
|
|
4532
|
-
return function(info) {
|
|
4533
|
-
listener.handleEvent(info);
|
|
4534
|
-
}
|
|
4535
|
-
}
|
|
4536
|
-
}
|
|
4537
|
-
|
|
4538
|
-
var addOnContextLostListener = function(listener) {
|
|
4539
|
-
onLost_.push(wrapEvent(listener));
|
|
4540
|
-
};
|
|
4541
|
-
|
|
4542
|
-
var addOnContextRestoredListener = function(listener) {
|
|
4543
|
-
onRestored_.push(wrapEvent(listener));
|
|
4544
|
-
};
|
|
4545
|
-
|
|
4546
|
-
|
|
4547
|
-
function wrapAddEventListener(canvas) {
|
|
4548
|
-
var f = canvas.addEventListener;
|
|
4549
|
-
canvas.addEventListener = function(type, listener, bubble) {
|
|
4550
|
-
switch (type) {
|
|
4551
|
-
case 'webglcontextlost':
|
|
4552
|
-
addOnContextLostListener(listener);
|
|
4553
|
-
break;
|
|
4554
|
-
case 'webglcontextrestored':
|
|
4555
|
-
addOnContextRestoredListener(listener);
|
|
4556
|
-
break;
|
|
4557
|
-
default:
|
|
4558
|
-
f.apply(canvas, arguments);
|
|
4559
|
-
}
|
|
4560
|
-
};
|
|
4561
|
-
}
|
|
4562
|
-
|
|
4563
|
-
wrapAddEventListener(canvas);
|
|
4564
|
-
|
|
4565
|
-
canvas.loseContext = function() {
|
|
4566
|
-
if (!contextLost_) {
|
|
4567
|
-
contextLost_ = true;
|
|
4568
|
-
numCallsToLoseContext_ = 0;
|
|
4569
|
-
++contextId_;
|
|
4570
|
-
while (unwrappedContext_.getError());
|
|
4571
|
-
clearErrors();
|
|
4572
|
-
glErrorShadow_[unwrappedContext_.CONTEXT_LOST_WEBGL] = true;
|
|
4573
|
-
var event = makeWebGLContextEvent("context lost");
|
|
4574
|
-
var callbacks = onLost_.slice();
|
|
4575
|
-
setTimeout(function() {
|
|
4576
|
-
//log("numCallbacks:" + callbacks.length);
|
|
4577
|
-
for (var ii = 0; ii < callbacks.length; ++ii) {
|
|
4578
|
-
//log("calling callback:" + ii);
|
|
4579
|
-
callbacks[ii](event);
|
|
4580
|
-
}
|
|
4581
|
-
if (restoreTimeout_ >= 0) {
|
|
4582
|
-
setTimeout(function() {
|
|
4583
|
-
canvas.restoreContext();
|
|
4584
|
-
}, restoreTimeout_);
|
|
4585
|
-
}
|
|
4586
|
-
}, 0);
|
|
4587
|
-
}
|
|
4588
|
-
};
|
|
4589
|
-
|
|
4590
|
-
canvas.restoreContext = function() {
|
|
4591
|
-
if (contextLost_) {
|
|
4592
|
-
if (onRestored_.length) {
|
|
4593
|
-
setTimeout(function() {
|
|
4594
|
-
if (!canRestore_) {
|
|
4595
|
-
throw "can not restore. webglcontestlost listener did not call event.preventDefault";
|
|
4596
|
-
}
|
|
4597
|
-
freeResources();
|
|
4598
|
-
resetToInitialState(unwrappedContext_);
|
|
4599
|
-
contextLost_ = false;
|
|
4600
|
-
numCalls_ = 0;
|
|
4601
|
-
canRestore_ = false;
|
|
4602
|
-
var callbacks = onRestored_.slice();
|
|
4603
|
-
var event = makeWebGLContextEvent("context restored");
|
|
4604
|
-
for (var ii = 0; ii < callbacks.length; ++ii) {
|
|
4605
|
-
callbacks[ii](event);
|
|
4606
|
-
}
|
|
4607
|
-
}, 0);
|
|
4608
|
-
}
|
|
4609
|
-
}
|
|
4610
|
-
};
|
|
4611
|
-
|
|
4612
|
-
canvas.loseContextInNCalls = function(numCalls) {
|
|
4613
|
-
if (contextLost_) {
|
|
4614
|
-
throw "You can not ask a lost contet to be lost";
|
|
4615
|
-
}
|
|
4616
|
-
numCallsToLoseContext_ = numCalls_ + numCalls;
|
|
4617
|
-
};
|
|
4618
|
-
|
|
4619
|
-
canvas.getNumCalls = function() {
|
|
4620
|
-
return numCalls_;
|
|
4621
|
-
};
|
|
4622
|
-
|
|
4623
|
-
canvas.setRestoreTimeout = function(timeout) {
|
|
4624
|
-
restoreTimeout_ = timeout;
|
|
4625
|
-
};
|
|
4626
|
-
|
|
4627
|
-
function clearErrors() {
|
|
4628
|
-
var k = Object.keys(glErrorShadow_);
|
|
4629
|
-
for (var ii = 0; ii < k.length; ++ii) {
|
|
4630
|
-
delete glErrorShadow_[k[ii]];
|
|
4631
|
-
}
|
|
4632
|
-
}
|
|
4633
|
-
|
|
4634
|
-
function loseContextIfTime() {
|
|
4635
|
-
++numCalls_;
|
|
4636
|
-
if (!contextLost_) {
|
|
4637
|
-
if (numCallsToLoseContext_ == numCalls_) {
|
|
4638
|
-
canvas.loseContext();
|
|
4639
|
-
}
|
|
4640
|
-
}
|
|
4641
|
-
}
|
|
4642
|
-
|
|
4643
|
-
// Makes a function that simulates WebGL when out of context.
|
|
4644
|
-
function makeLostContextFunctionWrapper(ctx, functionName) {
|
|
4645
|
-
var f = ctx[functionName];
|
|
4646
|
-
return function() {
|
|
4647
|
-
// log("calling:" + functionName);
|
|
4648
|
-
// Only call the functions if the context is not lost.
|
|
4649
|
-
loseContextIfTime();
|
|
4650
|
-
if (!contextLost_) {
|
|
4651
|
-
//if (!checkResources(arguments)) {
|
|
4652
|
-
// glErrorShadow_[wrappedContext_.INVALID_OPERATION] = true;
|
|
4653
|
-
// return;
|
|
4654
|
-
//}
|
|
4655
|
-
var result = f.apply(ctx, arguments);
|
|
4656
|
-
return result;
|
|
4657
|
-
}
|
|
4658
|
-
};
|
|
4659
|
-
}
|
|
4660
|
-
|
|
4661
|
-
function freeResources() {
|
|
4662
|
-
for (var ii = 0; ii < resourceDb_.length; ++ii) {
|
|
4663
|
-
var resource = resourceDb_[ii];
|
|
4664
|
-
if (resource instanceof WebGLBuffer) {
|
|
4665
|
-
unwrappedContext_.deleteBuffer(resource);
|
|
4666
|
-
} else if (resource instanceof WebGLFramebuffer) {
|
|
4667
|
-
unwrappedContext_.deleteFramebuffer(resource);
|
|
4668
|
-
} else if (resource instanceof WebGLProgram) {
|
|
4669
|
-
unwrappedContext_.deleteProgram(resource);
|
|
4670
|
-
} else if (resource instanceof WebGLRenderbuffer) {
|
|
4671
|
-
unwrappedContext_.deleteRenderbuffer(resource);
|
|
4672
|
-
} else if (resource instanceof WebGLShader) {
|
|
4673
|
-
unwrappedContext_.deleteShader(resource);
|
|
4674
|
-
} else if (resource instanceof WebGLTexture) {
|
|
4675
|
-
unwrappedContext_.deleteTexture(resource);
|
|
4676
|
-
}
|
|
4677
|
-
else if (isWebGL2RenderingContext) {
|
|
4678
|
-
if (resource instanceof WebGLQuery) {
|
|
4679
|
-
unwrappedContext_.deleteQuery(resource);
|
|
4680
|
-
} else if (resource instanceof WebGLSampler) {
|
|
4681
|
-
unwrappedContext_.deleteSampler(resource);
|
|
4682
|
-
} else if (resource instanceof WebGLSync) {
|
|
4683
|
-
unwrappedContext_.deleteSync(resource);
|
|
4684
|
-
} else if (resource instanceof WebGLTransformFeedback) {
|
|
4685
|
-
unwrappedContext_.deleteTransformFeedback(resource);
|
|
4686
|
-
} else if (resource instanceof WebGLVertexArrayObject) {
|
|
4687
|
-
unwrappedContext_.deleteVertexArray(resource);
|
|
4688
|
-
}
|
|
4689
|
-
}
|
|
4690
|
-
}
|
|
4691
|
-
}
|
|
4692
|
-
|
|
4693
|
-
function makeWebGLContextEvent(statusMessage) {
|
|
4694
|
-
return {
|
|
4695
|
-
statusMessage: statusMessage,
|
|
4696
|
-
preventDefault: function() {
|
|
4697
|
-
canRestore_ = true;
|
|
4698
|
-
}
|
|
4699
|
-
};
|
|
4700
|
-
}
|
|
4701
|
-
|
|
4702
|
-
return canvas;
|
|
4703
|
-
|
|
4704
|
-
function makeLostContextSimulatingContext(ctx) {
|
|
4705
|
-
// copy all functions and properties to wrapper
|
|
4706
|
-
for (var propertyName in ctx) {
|
|
4707
|
-
if (typeof ctx[propertyName] == 'function') {
|
|
4708
|
-
wrappedContext_[propertyName] = makeLostContextFunctionWrapper(
|
|
4709
|
-
ctx, propertyName);
|
|
4710
|
-
} else {
|
|
4711
|
-
makePropertyWrapper(wrappedContext_, ctx, propertyName);
|
|
4712
|
-
}
|
|
4713
|
-
}
|
|
4714
|
-
|
|
4715
|
-
// Wrap a few functions specially.
|
|
4716
|
-
wrappedContext_.getError = function() {
|
|
4717
|
-
loseContextIfTime();
|
|
4718
|
-
if (!contextLost_) {
|
|
4719
|
-
var err;
|
|
4720
|
-
while (err = unwrappedContext_.getError()) {
|
|
4721
|
-
glErrorShadow_[err] = true;
|
|
4722
|
-
}
|
|
4723
|
-
}
|
|
4724
|
-
for (var err in glErrorShadow_) {
|
|
4725
|
-
if (glErrorShadow_[err]) {
|
|
4726
|
-
delete glErrorShadow_[err];
|
|
4727
|
-
return err;
|
|
4728
|
-
}
|
|
4729
|
-
}
|
|
4730
|
-
return wrappedContext_.NO_ERROR;
|
|
4731
|
-
};
|
|
4732
|
-
|
|
4733
|
-
var creationFunctions = [
|
|
4734
|
-
"createBuffer",
|
|
4735
|
-
"createFramebuffer",
|
|
4736
|
-
"createProgram",
|
|
4737
|
-
"createRenderbuffer",
|
|
4738
|
-
"createShader",
|
|
4739
|
-
"createTexture"
|
|
4740
|
-
];
|
|
4741
|
-
if (isWebGL2RenderingContext) {
|
|
4742
|
-
creationFunctions.push(
|
|
4743
|
-
"createQuery",
|
|
4744
|
-
"createSampler",
|
|
4745
|
-
"fenceSync",
|
|
4746
|
-
"createTransformFeedback",
|
|
4747
|
-
"createVertexArray"
|
|
4748
|
-
);
|
|
4749
|
-
}
|
|
4750
|
-
for (var ii = 0; ii < creationFunctions.length; ++ii) {
|
|
4751
|
-
var functionName = creationFunctions[ii];
|
|
4752
|
-
wrappedContext_[functionName] = function(f) {
|
|
4753
|
-
return function() {
|
|
4754
|
-
loseContextIfTime();
|
|
4755
|
-
if (contextLost_) {
|
|
4756
|
-
return null;
|
|
4757
|
-
}
|
|
4758
|
-
var obj = f.apply(ctx, arguments);
|
|
4759
|
-
obj.__webglDebugContextLostId__ = contextId_;
|
|
4760
|
-
resourceDb_.push(obj);
|
|
4761
|
-
return obj;
|
|
4762
|
-
};
|
|
4763
|
-
}(ctx[functionName]);
|
|
4764
|
-
}
|
|
4765
|
-
|
|
4766
|
-
var functionsThatShouldReturnNull = [
|
|
4767
|
-
"getActiveAttrib",
|
|
4768
|
-
"getActiveUniform",
|
|
4769
|
-
"getBufferParameter",
|
|
4770
|
-
"getContextAttributes",
|
|
4771
|
-
"getAttachedShaders",
|
|
4772
|
-
"getFramebufferAttachmentParameter",
|
|
4773
|
-
"getParameter",
|
|
4774
|
-
"getProgramParameter",
|
|
4775
|
-
"getProgramInfoLog",
|
|
4776
|
-
"getRenderbufferParameter",
|
|
4777
|
-
"getShaderParameter",
|
|
4778
|
-
"getShaderInfoLog",
|
|
4779
|
-
"getShaderSource",
|
|
4780
|
-
"getTexParameter",
|
|
4781
|
-
"getUniform",
|
|
4782
|
-
"getUniformLocation",
|
|
4783
|
-
"getVertexAttrib"
|
|
4784
|
-
];
|
|
4785
|
-
if (isWebGL2RenderingContext) {
|
|
4786
|
-
functionsThatShouldReturnNull.push(
|
|
4787
|
-
"getInternalformatParameter",
|
|
4788
|
-
"getQuery",
|
|
4789
|
-
"getQueryParameter",
|
|
4790
|
-
"getSamplerParameter",
|
|
4791
|
-
"getSyncParameter",
|
|
4792
|
-
"getTransformFeedbackVarying",
|
|
4793
|
-
"getIndexedParameter",
|
|
4794
|
-
"getUniformIndices",
|
|
4795
|
-
"getActiveUniforms",
|
|
4796
|
-
"getActiveUniformBlockParameter",
|
|
4797
|
-
"getActiveUniformBlockName"
|
|
4798
|
-
);
|
|
4799
|
-
}
|
|
4800
|
-
for (var ii = 0; ii < functionsThatShouldReturnNull.length; ++ii) {
|
|
4801
|
-
var functionName = functionsThatShouldReturnNull[ii];
|
|
4802
|
-
wrappedContext_[functionName] = function(f) {
|
|
4803
|
-
return function() {
|
|
4804
|
-
loseContextIfTime();
|
|
4805
|
-
if (contextLost_) {
|
|
4806
|
-
return null;
|
|
4807
|
-
}
|
|
4808
|
-
return f.apply(ctx, arguments);
|
|
4809
|
-
}
|
|
4810
|
-
}(wrappedContext_[functionName]);
|
|
4811
|
-
}
|
|
4812
|
-
|
|
4813
|
-
var isFunctions = [
|
|
4814
|
-
"isBuffer",
|
|
4815
|
-
"isEnabled",
|
|
4816
|
-
"isFramebuffer",
|
|
4817
|
-
"isProgram",
|
|
4818
|
-
"isRenderbuffer",
|
|
4819
|
-
"isShader",
|
|
4820
|
-
"isTexture"
|
|
4821
|
-
];
|
|
4822
|
-
if (isWebGL2RenderingContext) {
|
|
4823
|
-
isFunctions.push(
|
|
4824
|
-
"isQuery",
|
|
4825
|
-
"isSampler",
|
|
4826
|
-
"isSync",
|
|
4827
|
-
"isTransformFeedback",
|
|
4828
|
-
"isVertexArray"
|
|
4829
|
-
);
|
|
4830
|
-
}
|
|
4831
|
-
for (var ii = 0; ii < isFunctions.length; ++ii) {
|
|
4832
|
-
var functionName = isFunctions[ii];
|
|
4833
|
-
wrappedContext_[functionName] = function(f) {
|
|
4834
|
-
return function() {
|
|
4835
|
-
loseContextIfTime();
|
|
4836
|
-
if (contextLost_) {
|
|
4837
|
-
return false;
|
|
4838
|
-
}
|
|
4839
|
-
return f.apply(ctx, arguments);
|
|
4840
|
-
}
|
|
4841
|
-
}(wrappedContext_[functionName]);
|
|
4842
|
-
}
|
|
4843
|
-
|
|
4844
|
-
wrappedContext_.checkFramebufferStatus = function(f) {
|
|
4845
|
-
return function() {
|
|
4846
|
-
loseContextIfTime();
|
|
4847
|
-
if (contextLost_) {
|
|
4848
|
-
return wrappedContext_.FRAMEBUFFER_UNSUPPORTED;
|
|
4849
|
-
}
|
|
4850
|
-
return f.apply(ctx, arguments);
|
|
4851
|
-
};
|
|
4852
|
-
}(wrappedContext_.checkFramebufferStatus);
|
|
4853
|
-
|
|
4854
|
-
wrappedContext_.getAttribLocation = function(f) {
|
|
4855
|
-
return function() {
|
|
4856
|
-
loseContextIfTime();
|
|
4857
|
-
if (contextLost_) {
|
|
4858
|
-
return -1;
|
|
4859
|
-
}
|
|
4860
|
-
return f.apply(ctx, arguments);
|
|
4861
|
-
};
|
|
4862
|
-
}(wrappedContext_.getAttribLocation);
|
|
4863
|
-
|
|
4864
|
-
wrappedContext_.getVertexAttribOffset = function(f) {
|
|
4865
|
-
return function() {
|
|
4866
|
-
loseContextIfTime();
|
|
4867
|
-
if (contextLost_) {
|
|
4868
|
-
return 0;
|
|
4869
|
-
}
|
|
4870
|
-
return f.apply(ctx, arguments);
|
|
4871
|
-
};
|
|
4872
|
-
}(wrappedContext_.getVertexAttribOffset);
|
|
4873
|
-
|
|
4874
|
-
wrappedContext_.isContextLost = function() {
|
|
4875
|
-
return contextLost_;
|
|
4876
|
-
};
|
|
4877
|
-
|
|
4878
|
-
if (isWebGL2RenderingContext) {
|
|
4879
|
-
wrappedContext_.getFragDataLocation = function(f) {
|
|
4880
|
-
return function() {
|
|
4881
|
-
loseContextIfTime();
|
|
4882
|
-
if (contextLost_) {
|
|
4883
|
-
return -1;
|
|
4884
|
-
}
|
|
4885
|
-
return f.apply(ctx, arguments);
|
|
4886
|
-
};
|
|
4887
|
-
}(wrappedContext_.getFragDataLocation);
|
|
4888
|
-
|
|
4889
|
-
wrappedContext_.clientWaitSync = function(f) {
|
|
4890
|
-
return function() {
|
|
4891
|
-
loseContextIfTime();
|
|
4892
|
-
if (contextLost_) {
|
|
4893
|
-
return wrappedContext_.WAIT_FAILED;
|
|
4894
|
-
}
|
|
4895
|
-
return f.apply(ctx, arguments);
|
|
4896
|
-
};
|
|
4897
|
-
}(wrappedContext_.clientWaitSync);
|
|
4898
|
-
|
|
4899
|
-
wrappedContext_.getUniformBlockIndex = function(f) {
|
|
4900
|
-
return function() {
|
|
4901
|
-
loseContextIfTime();
|
|
4902
|
-
if (contextLost_) {
|
|
4903
|
-
return wrappedContext_.INVALID_INDEX;
|
|
4904
|
-
}
|
|
4905
|
-
return f.apply(ctx, arguments);
|
|
4906
|
-
};
|
|
4907
|
-
}(wrappedContext_.getUniformBlockIndex);
|
|
4908
|
-
}
|
|
4909
|
-
|
|
4910
|
-
return wrappedContext_;
|
|
4911
|
-
}
|
|
4912
|
-
}
|
|
4913
|
-
|
|
4914
|
-
return {
|
|
4915
|
-
/**
|
|
4916
|
-
* Initializes this module. Safe to call more than once.
|
|
4917
|
-
* @param {!WebGLRenderingContext} ctx A WebGL context. If
|
|
4918
|
-
* you have more than one context it doesn't matter which one
|
|
4919
|
-
* you pass in, it is only used to pull out constants.
|
|
4920
|
-
*/
|
|
4921
|
-
'init': init,
|
|
4922
|
-
|
|
4923
|
-
/**
|
|
4924
|
-
* Returns true or false if value matches any WebGL enum
|
|
4925
|
-
* @param {*} value Value to check if it might be an enum.
|
|
4926
|
-
* @return {boolean} True if value matches one of the WebGL defined enums
|
|
4927
|
-
*/
|
|
4928
|
-
'mightBeEnum': mightBeEnum,
|
|
4929
|
-
|
|
4930
|
-
/**
|
|
4931
|
-
* Gets an string version of an WebGL enum.
|
|
4932
|
-
*
|
|
4933
|
-
* Example:
|
|
4934
|
-
* WebGLDebugUtil.init(ctx);
|
|
4935
|
-
* var str = WebGLDebugUtil.glEnumToString(ctx.getError());
|
|
4936
|
-
*
|
|
4937
|
-
* @param {number} value Value to return an enum for
|
|
4938
|
-
* @return {string} The string version of the enum.
|
|
4939
|
-
*/
|
|
4940
|
-
'glEnumToString': glEnumToString,
|
|
4941
|
-
|
|
4942
|
-
/**
|
|
4943
|
-
* Converts the argument of a WebGL function to a string.
|
|
4944
|
-
* Attempts to convert enum arguments to strings.
|
|
4945
|
-
*
|
|
4946
|
-
* Example:
|
|
4947
|
-
* WebGLDebugUtil.init(ctx);
|
|
4948
|
-
* var str = WebGLDebugUtil.glFunctionArgToString('bindTexture', 2, 0, gl.TEXTURE_2D);
|
|
4949
|
-
*
|
|
4950
|
-
* would return 'TEXTURE_2D'
|
|
4951
|
-
*
|
|
4952
|
-
* @param {string} functionName the name of the WebGL function.
|
|
4953
|
-
* @param {number} numArgs The number of arguments
|
|
4954
|
-
* @param {number} argumentIndx the index of the argument.
|
|
4955
|
-
* @param {*} value The value of the argument.
|
|
4956
|
-
* @return {string} The value as a string.
|
|
4957
|
-
*/
|
|
4958
|
-
'glFunctionArgToString': glFunctionArgToString,
|
|
4959
|
-
|
|
4960
|
-
/**
|
|
4961
|
-
* Converts the arguments of a WebGL function to a string.
|
|
4962
|
-
* Attempts to convert enum arguments to strings.
|
|
4963
|
-
*
|
|
4964
|
-
* @param {string} functionName the name of the WebGL function.
|
|
4965
|
-
* @param {number} args The arguments.
|
|
4966
|
-
* @return {string} The arguments as a string.
|
|
4967
|
-
*/
|
|
4968
|
-
'glFunctionArgsToString': glFunctionArgsToString,
|
|
4969
|
-
|
|
4970
|
-
/**
|
|
4971
|
-
* Given a WebGL context returns a wrapped context that calls
|
|
4972
|
-
* gl.getError after every command and calls a function if the
|
|
4973
|
-
* result is not NO_ERROR.
|
|
4974
|
-
*
|
|
4975
|
-
* You can supply your own function if you want. For example, if you'd like
|
|
4976
|
-
* an exception thrown on any GL error you could do this
|
|
4977
|
-
*
|
|
4978
|
-
* function throwOnGLError(err, funcName, args) {
|
|
4979
|
-
* throw WebGLDebugUtils.glEnumToString(err) +
|
|
4980
|
-
* " was caused by call to " + funcName;
|
|
4981
|
-
* };
|
|
4982
|
-
*
|
|
4983
|
-
* ctx = WebGLDebugUtils.makeDebugContext(
|
|
4984
|
-
* canvas.getContext("webgl"), throwOnGLError);
|
|
4985
|
-
*
|
|
4986
|
-
* @param {!WebGLRenderingContext} ctx The webgl context to wrap.
|
|
4987
|
-
* @param {!function(err, funcName, args): void} opt_onErrorFunc The function
|
|
4988
|
-
* to call when gl.getError returns an error. If not specified the default
|
|
4989
|
-
* function calls console.log with a message.
|
|
4990
|
-
* @param {!function(funcName, args): void} opt_onFunc The
|
|
4991
|
-
* function to call when each webgl function is called. You
|
|
4992
|
-
* can use this to log all calls for example.
|
|
4993
|
-
*/
|
|
4994
|
-
'makeDebugContext': makeDebugContext,
|
|
4995
|
-
|
|
4996
|
-
/**
|
|
4997
|
-
* Given a canvas element returns a wrapped canvas element that will
|
|
4998
|
-
* simulate lost context. The canvas returned adds the following functions.
|
|
4999
|
-
*
|
|
5000
|
-
* loseContext:
|
|
5001
|
-
* simulates a lost context event.
|
|
5002
|
-
*
|
|
5003
|
-
* restoreContext:
|
|
5004
|
-
* simulates the context being restored.
|
|
5005
|
-
*
|
|
5006
|
-
* lostContextInNCalls:
|
|
5007
|
-
* loses the context after N gl calls.
|
|
5008
|
-
*
|
|
5009
|
-
* getNumCalls:
|
|
5010
|
-
* tells you how many gl calls there have been so far.
|
|
5011
|
-
*
|
|
5012
|
-
* setRestoreTimeout:
|
|
5013
|
-
* sets the number of milliseconds until the context is restored
|
|
5014
|
-
* after it has been lost. Defaults to 0. Pass -1 to prevent
|
|
5015
|
-
* automatic restoring.
|
|
5016
|
-
*
|
|
5017
|
-
* @param {!Canvas} canvas The canvas element to wrap.
|
|
5018
|
-
*/
|
|
5019
|
-
'makeLostContextSimulatingCanvas': makeLostContextSimulatingCanvas,
|
|
5020
|
-
|
|
5021
|
-
/**
|
|
5022
|
-
* Resets a context to the initial state.
|
|
5023
|
-
* @param {!WebGLRenderingContext} ctx The webgl context to
|
|
5024
|
-
* reset.
|
|
5025
|
-
*/
|
|
5026
|
-
'resetToInitialState': resetToInitialState
|
|
5027
|
-
};
|
|
5028
|
-
|
|
3873
|
+
/*
|
|
3874
|
+
** Copyright (c) 2012 The Khronos Group Inc.
|
|
3875
|
+
**
|
|
3876
|
+
** Permission is hereby granted, free of charge, to any person obtaining a
|
|
3877
|
+
** copy of this software and/or associated documentation files (the
|
|
3878
|
+
** "Materials"), to deal in the Materials without restriction, including
|
|
3879
|
+
** without limitation the rights to use, copy, modify, merge, publish,
|
|
3880
|
+
** distribute, sublicense, and/or sell copies of the Materials, and to
|
|
3881
|
+
** permit persons to whom the Materials are furnished to do so, subject to
|
|
3882
|
+
** the following conditions:
|
|
3883
|
+
**
|
|
3884
|
+
** The above copyright notice and this permission notice shall be included
|
|
3885
|
+
** in all copies or substantial portions of the Materials.
|
|
3886
|
+
**
|
|
3887
|
+
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
3888
|
+
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
3889
|
+
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
3890
|
+
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
3891
|
+
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
3892
|
+
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
3893
|
+
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
|
3894
|
+
*/
|
|
3895
|
+
|
|
3896
|
+
// Various functions for helping debug WebGL apps.
|
|
3897
|
+
|
|
3898
|
+
const WebGLDebugUtils = function() {
|
|
3899
|
+
|
|
3900
|
+
/**
|
|
3901
|
+
* Wrapped logging function.
|
|
3902
|
+
* @param {string} msg Message to log.
|
|
3903
|
+
*/
|
|
3904
|
+
var log = function(msg) {
|
|
3905
|
+
if (window.console && window.console.log) {
|
|
3906
|
+
window.console.log(msg);
|
|
3907
|
+
}
|
|
3908
|
+
};
|
|
3909
|
+
|
|
3910
|
+
/**
|
|
3911
|
+
* Wrapped error logging function.
|
|
3912
|
+
* @param {string} msg Message to log.
|
|
3913
|
+
*/
|
|
3914
|
+
var error = function(msg) {
|
|
3915
|
+
if (window.console && window.console.error) {
|
|
3916
|
+
window.console.error(msg);
|
|
3917
|
+
} else {
|
|
3918
|
+
log(msg);
|
|
3919
|
+
}
|
|
3920
|
+
};
|
|
3921
|
+
|
|
3922
|
+
|
|
3923
|
+
/**
|
|
3924
|
+
* Which arguments are enums based on the number of arguments to the function.
|
|
3925
|
+
* So
|
|
3926
|
+
* 'texImage2D': {
|
|
3927
|
+
* 9: { 0:true, 2:true, 6:true, 7:true },
|
|
3928
|
+
* 6: { 0:true, 2:true, 3:true, 4:true },
|
|
3929
|
+
* },
|
|
3930
|
+
*
|
|
3931
|
+
* means if there are 9 arguments then 6 and 7 are enums, if there are 6
|
|
3932
|
+
* arguments 3 and 4 are enums
|
|
3933
|
+
*
|
|
3934
|
+
* @type {!Object.<number, !Object.<number, string>}
|
|
3935
|
+
*/
|
|
3936
|
+
var glValidEnumContexts = {
|
|
3937
|
+
// Generic setters and getters
|
|
3938
|
+
|
|
3939
|
+
'enable': {1: { 0:true }},
|
|
3940
|
+
'disable': {1: { 0:true }},
|
|
3941
|
+
'getParameter': {1: { 0:true }},
|
|
3942
|
+
|
|
3943
|
+
// Rendering
|
|
3944
|
+
|
|
3945
|
+
'drawArrays': {3:{ 0:true }},
|
|
3946
|
+
'drawElements': {4:{ 0:true, 2:true }},
|
|
3947
|
+
|
|
3948
|
+
// Shaders
|
|
3949
|
+
|
|
3950
|
+
'createShader': {1: { 0:true }},
|
|
3951
|
+
'getShaderParameter': {2: { 1:true }},
|
|
3952
|
+
'getProgramParameter': {2: { 1:true }},
|
|
3953
|
+
'getShaderPrecisionFormat': {2: { 0: true, 1:true }},
|
|
3954
|
+
|
|
3955
|
+
// Vertex attributes
|
|
3956
|
+
|
|
3957
|
+
'getVertexAttrib': {2: { 1:true }},
|
|
3958
|
+
'vertexAttribPointer': {6: { 2:true }},
|
|
3959
|
+
|
|
3960
|
+
// Textures
|
|
3961
|
+
|
|
3962
|
+
'bindTexture': {2: { 0:true }},
|
|
3963
|
+
'activeTexture': {1: { 0:true }},
|
|
3964
|
+
'getTexParameter': {2: { 0:true, 1:true }},
|
|
3965
|
+
'texParameterf': {3: { 0:true, 1:true }},
|
|
3966
|
+
'texParameteri': {3: { 0:true, 1:true, 2:true }},
|
|
3967
|
+
// texImage2D and texSubImage2D are defined below with WebGL 2 entrypoints
|
|
3968
|
+
'copyTexImage2D': {8: { 0:true, 2:true }},
|
|
3969
|
+
'copyTexSubImage2D': {8: { 0:true }},
|
|
3970
|
+
'generateMipmap': {1: { 0:true }},
|
|
3971
|
+
// compressedTexImage2D and compressedTexSubImage2D are defined below with WebGL 2 entrypoints
|
|
3972
|
+
|
|
3973
|
+
// Buffer objects
|
|
3974
|
+
|
|
3975
|
+
'bindBuffer': {2: { 0:true }},
|
|
3976
|
+
// bufferData and bufferSubData are defined below with WebGL 2 entrypoints
|
|
3977
|
+
'getBufferParameter': {2: { 0:true, 1:true }},
|
|
3978
|
+
|
|
3979
|
+
// Renderbuffers and framebuffers
|
|
3980
|
+
|
|
3981
|
+
'pixelStorei': {2: { 0:true, 1:true }},
|
|
3982
|
+
// readPixels is defined below with WebGL 2 entrypoints
|
|
3983
|
+
'bindRenderbuffer': {2: { 0:true }},
|
|
3984
|
+
'bindFramebuffer': {2: { 0:true }},
|
|
3985
|
+
'checkFramebufferStatus': {1: { 0:true }},
|
|
3986
|
+
'framebufferRenderbuffer': {4: { 0:true, 1:true, 2:true }},
|
|
3987
|
+
'framebufferTexture2D': {5: { 0:true, 1:true, 2:true }},
|
|
3988
|
+
'getFramebufferAttachmentParameter': {3: { 0:true, 1:true, 2:true }},
|
|
3989
|
+
'getRenderbufferParameter': {2: { 0:true, 1:true }},
|
|
3990
|
+
'renderbufferStorage': {4: { 0:true, 1:true }},
|
|
3991
|
+
|
|
3992
|
+
// Frame buffer operations (clear, blend, depth test, stencil)
|
|
3993
|
+
|
|
3994
|
+
'clear': {1: { 0: { 'enumBitwiseOr': ['COLOR_BUFFER_BIT', 'DEPTH_BUFFER_BIT', 'STENCIL_BUFFER_BIT'] }}},
|
|
3995
|
+
'depthFunc': {1: { 0:true }},
|
|
3996
|
+
'blendFunc': {2: { 0:true, 1:true }},
|
|
3997
|
+
'blendFuncSeparate': {4: { 0:true, 1:true, 2:true, 3:true }},
|
|
3998
|
+
'blendEquation': {1: { 0:true }},
|
|
3999
|
+
'blendEquationSeparate': {2: { 0:true, 1:true }},
|
|
4000
|
+
'stencilFunc': {3: { 0:true }},
|
|
4001
|
+
'stencilFuncSeparate': {4: { 0:true, 1:true }},
|
|
4002
|
+
'stencilMaskSeparate': {2: { 0:true }},
|
|
4003
|
+
'stencilOp': {3: { 0:true, 1:true, 2:true }},
|
|
4004
|
+
'stencilOpSeparate': {4: { 0:true, 1:true, 2:true, 3:true }},
|
|
4005
|
+
|
|
4006
|
+
// Culling
|
|
4007
|
+
|
|
4008
|
+
'cullFace': {1: { 0:true }},
|
|
4009
|
+
'frontFace': {1: { 0:true }},
|
|
4010
|
+
|
|
4011
|
+
// ANGLE_instanced_arrays extension
|
|
4012
|
+
|
|
4013
|
+
'drawArraysInstancedANGLE': {4: { 0:true }},
|
|
4014
|
+
'drawElementsInstancedANGLE': {5: { 0:true, 2:true }},
|
|
4015
|
+
|
|
4016
|
+
// EXT_blend_minmax extension
|
|
4017
|
+
|
|
4018
|
+
'blendEquationEXT': {1: { 0:true }},
|
|
4019
|
+
|
|
4020
|
+
// WebGL 2 Buffer objects
|
|
4021
|
+
|
|
4022
|
+
'bufferData': {
|
|
4023
|
+
3: { 0:true, 2:true }, // WebGL 1
|
|
4024
|
+
4: { 0:true, 2:true }, // WebGL 2
|
|
4025
|
+
5: { 0:true, 2:true } // WebGL 2
|
|
4026
|
+
},
|
|
4027
|
+
'bufferSubData': {
|
|
4028
|
+
3: { 0:true }, // WebGL 1
|
|
4029
|
+
4: { 0:true }, // WebGL 2
|
|
4030
|
+
5: { 0:true } // WebGL 2
|
|
4031
|
+
},
|
|
4032
|
+
'copyBufferSubData': {5: { 0:true, 1:true }},
|
|
4033
|
+
'getBufferSubData': {3: { 0:true }, 4: { 0:true }, 5: { 0:true }},
|
|
4034
|
+
|
|
4035
|
+
// WebGL 2 Framebuffer objects
|
|
4036
|
+
|
|
4037
|
+
'blitFramebuffer': {10: { 8: { 'enumBitwiseOr': ['COLOR_BUFFER_BIT', 'DEPTH_BUFFER_BIT', 'STENCIL_BUFFER_BIT'] }, 9:true }},
|
|
4038
|
+
'framebufferTextureLayer': {5: { 0:true, 1:true }},
|
|
4039
|
+
'invalidateFramebuffer': {2: { 0:true }},
|
|
4040
|
+
'invalidateSubFramebuffer': {6: { 0:true }},
|
|
4041
|
+
'readBuffer': {1: { 0:true }},
|
|
4042
|
+
|
|
4043
|
+
// WebGL 2 Renderbuffer objects
|
|
4044
|
+
|
|
4045
|
+
'getInternalformatParameter': {3: { 0:true, 1:true, 2:true }},
|
|
4046
|
+
'renderbufferStorageMultisample': {5: { 0:true, 2:true }},
|
|
4047
|
+
|
|
4048
|
+
// WebGL 2 Texture objects
|
|
4049
|
+
|
|
4050
|
+
'texStorage2D': {5: { 0:true, 2:true }},
|
|
4051
|
+
'texStorage3D': {6: { 0:true, 2:true }},
|
|
4052
|
+
'texImage2D': {
|
|
4053
|
+
9: { 0:true, 2:true, 6:true, 7:true }, // WebGL 1 & 2
|
|
4054
|
+
6: { 0:true, 2:true, 3:true, 4:true }, // WebGL 1
|
|
4055
|
+
10: { 0:true, 2:true, 6:true, 7:true } // WebGL 2
|
|
4056
|
+
},
|
|
4057
|
+
'texImage3D': {
|
|
4058
|
+
10: { 0:true, 2:true, 7:true, 8:true },
|
|
4059
|
+
11: { 0:true, 2:true, 7:true, 8:true }
|
|
4060
|
+
},
|
|
4061
|
+
'texSubImage2D': {
|
|
4062
|
+
9: { 0:true, 6:true, 7:true }, // WebGL 1 & 2
|
|
4063
|
+
7: { 0:true, 4:true, 5:true }, // WebGL 1
|
|
4064
|
+
10: { 0:true, 6:true, 7:true } // WebGL 2
|
|
4065
|
+
},
|
|
4066
|
+
'texSubImage3D': {
|
|
4067
|
+
11: { 0:true, 8:true, 9:true },
|
|
4068
|
+
12: { 0:true, 8:true, 9:true }
|
|
4069
|
+
},
|
|
4070
|
+
'copyTexSubImage3D': {9: { 0:true }},
|
|
4071
|
+
'compressedTexImage2D': {
|
|
4072
|
+
7: { 0: true, 2:true }, // WebGL 1 & 2
|
|
4073
|
+
8: { 0: true, 2:true }, // WebGL 2
|
|
4074
|
+
9: { 0: true, 2:true } // WebGL 2
|
|
4075
|
+
},
|
|
4076
|
+
'compressedTexImage3D': {
|
|
4077
|
+
8: { 0: true, 2:true },
|
|
4078
|
+
9: { 0: true, 2:true },
|
|
4079
|
+
10: { 0: true, 2:true }
|
|
4080
|
+
},
|
|
4081
|
+
'compressedTexSubImage2D': {
|
|
4082
|
+
8: { 0: true, 6:true }, // WebGL 1 & 2
|
|
4083
|
+
9: { 0: true, 6:true }, // WebGL 2
|
|
4084
|
+
10: { 0: true, 6:true } // WebGL 2
|
|
4085
|
+
},
|
|
4086
|
+
'compressedTexSubImage3D': {
|
|
4087
|
+
10: { 0: true, 8:true },
|
|
4088
|
+
11: { 0: true, 8:true },
|
|
4089
|
+
12: { 0: true, 8:true }
|
|
4090
|
+
},
|
|
4091
|
+
|
|
4092
|
+
// WebGL 2 Vertex attribs
|
|
4093
|
+
|
|
4094
|
+
'vertexAttribIPointer': {5: { 2:true }},
|
|
4095
|
+
|
|
4096
|
+
// WebGL 2 Writing to the drawing buffer
|
|
4097
|
+
|
|
4098
|
+
'drawArraysInstanced': {4: { 0:true }},
|
|
4099
|
+
'drawElementsInstanced': {5: { 0:true, 2:true }},
|
|
4100
|
+
'drawRangeElements': {6: { 0:true, 4:true }},
|
|
4101
|
+
|
|
4102
|
+
// WebGL 2 Reading back pixels
|
|
4103
|
+
|
|
4104
|
+
'readPixels': {
|
|
4105
|
+
7: { 4:true, 5:true }, // WebGL 1 & 2
|
|
4106
|
+
8: { 4:true, 5:true } // WebGL 2
|
|
4107
|
+
},
|
|
4108
|
+
|
|
4109
|
+
// WebGL 2 Multiple Render Targets
|
|
4110
|
+
|
|
4111
|
+
'clearBufferfv': {3: { 0:true }, 4: { 0:true }},
|
|
4112
|
+
'clearBufferiv': {3: { 0:true }, 4: { 0:true }},
|
|
4113
|
+
'clearBufferuiv': {3: { 0:true }, 4: { 0:true }},
|
|
4114
|
+
'clearBufferfi': {4: { 0:true }},
|
|
4115
|
+
|
|
4116
|
+
// WebGL 2 Query objects
|
|
4117
|
+
|
|
4118
|
+
'beginQuery': {2: { 0:true }},
|
|
4119
|
+
'endQuery': {1: { 0:true }},
|
|
4120
|
+
'getQuery': {2: { 0:true, 1:true }},
|
|
4121
|
+
'getQueryParameter': {2: { 1:true }},
|
|
4122
|
+
|
|
4123
|
+
// WebGL 2 Sampler objects
|
|
4124
|
+
|
|
4125
|
+
'samplerParameteri': {3: { 1:true, 2:true }},
|
|
4126
|
+
'samplerParameterf': {3: { 1:true }},
|
|
4127
|
+
'getSamplerParameter': {2: { 1:true }},
|
|
4128
|
+
|
|
4129
|
+
// WebGL 2 Sync objects
|
|
4130
|
+
|
|
4131
|
+
'fenceSync': {2: { 0:true, 1: { 'enumBitwiseOr': [] } }},
|
|
4132
|
+
'clientWaitSync': {3: { 1: { 'enumBitwiseOr': ['SYNC_FLUSH_COMMANDS_BIT'] } }},
|
|
4133
|
+
'waitSync': {3: { 1: { 'enumBitwiseOr': [] } }},
|
|
4134
|
+
'getSyncParameter': {2: { 1:true }},
|
|
4135
|
+
|
|
4136
|
+
// WebGL 2 Transform Feedback
|
|
4137
|
+
|
|
4138
|
+
'bindTransformFeedback': {2: { 0:true }},
|
|
4139
|
+
'beginTransformFeedback': {1: { 0:true }},
|
|
4140
|
+
'transformFeedbackVaryings': {3: { 2:true }},
|
|
4141
|
+
|
|
4142
|
+
// WebGL2 Uniform Buffer Objects and Transform Feedback Buffers
|
|
4143
|
+
|
|
4144
|
+
'bindBufferBase': {3: { 0:true }},
|
|
4145
|
+
'bindBufferRange': {5: { 0:true }},
|
|
4146
|
+
'getIndexedParameter': {2: { 0:true }},
|
|
4147
|
+
'getActiveUniforms': {3: { 2:true }},
|
|
4148
|
+
'getActiveUniformBlockParameter': {3: { 2:true }}
|
|
4149
|
+
};
|
|
4150
|
+
|
|
4151
|
+
/**
|
|
4152
|
+
* Map of numbers to names.
|
|
4153
|
+
* @type {Object}
|
|
4154
|
+
*/
|
|
4155
|
+
var glEnums = null;
|
|
4156
|
+
|
|
4157
|
+
/**
|
|
4158
|
+
* Map of names to numbers.
|
|
4159
|
+
* @type {Object}
|
|
4160
|
+
*/
|
|
4161
|
+
var enumStringToValue = null;
|
|
4162
|
+
|
|
4163
|
+
/**
|
|
4164
|
+
* Initializes this module. Safe to call more than once.
|
|
4165
|
+
* @param {!WebGLRenderingContext} ctx A WebGL context. If
|
|
4166
|
+
* you have more than one context it doesn't matter which one
|
|
4167
|
+
* you pass in, it is only used to pull out constants.
|
|
4168
|
+
*/
|
|
4169
|
+
function init(ctx) {
|
|
4170
|
+
if (glEnums == null) {
|
|
4171
|
+
glEnums = { };
|
|
4172
|
+
enumStringToValue = { };
|
|
4173
|
+
for (var propertyName in ctx) {
|
|
4174
|
+
if (typeof ctx[propertyName] == 'number') {
|
|
4175
|
+
glEnums[ctx[propertyName]] = propertyName;
|
|
4176
|
+
enumStringToValue[propertyName] = ctx[propertyName];
|
|
4177
|
+
}
|
|
4178
|
+
}
|
|
4179
|
+
}
|
|
4180
|
+
}
|
|
4181
|
+
|
|
4182
|
+
/**
|
|
4183
|
+
* Checks the utils have been initialized.
|
|
4184
|
+
*/
|
|
4185
|
+
function checkInit() {
|
|
4186
|
+
if (glEnums == null) {
|
|
4187
|
+
throw 'WebGLDebugUtils.init(ctx) not called';
|
|
4188
|
+
}
|
|
4189
|
+
}
|
|
4190
|
+
|
|
4191
|
+
/**
|
|
4192
|
+
* Returns true or false if value matches any WebGL enum
|
|
4193
|
+
* @param {*} value Value to check if it might be an enum.
|
|
4194
|
+
* @return {boolean} True if value matches one of the WebGL defined enums
|
|
4195
|
+
*/
|
|
4196
|
+
function mightBeEnum(value) {
|
|
4197
|
+
checkInit();
|
|
4198
|
+
return (glEnums[value] !== undefined);
|
|
4199
|
+
}
|
|
4200
|
+
|
|
4201
|
+
/**
|
|
4202
|
+
* Gets an string version of an WebGL enum.
|
|
4203
|
+
*
|
|
4204
|
+
* Example:
|
|
4205
|
+
* var str = WebGLDebugUtil.glEnumToString(ctx.getError());
|
|
4206
|
+
*
|
|
4207
|
+
* @param {number} value Value to return an enum for
|
|
4208
|
+
* @return {string} The string version of the enum.
|
|
4209
|
+
*/
|
|
4210
|
+
function glEnumToString(value) {
|
|
4211
|
+
checkInit();
|
|
4212
|
+
var name = glEnums[value];
|
|
4213
|
+
return (name !== undefined) ? ("gl." + name) :
|
|
4214
|
+
("/*UNKNOWN WebGL ENUM*/ 0x" + value.toString(16) + "");
|
|
4215
|
+
}
|
|
4216
|
+
|
|
4217
|
+
/**
|
|
4218
|
+
* Returns the string version of a WebGL argument.
|
|
4219
|
+
* Attempts to convert enum arguments to strings.
|
|
4220
|
+
* @param {string} functionName the name of the WebGL function.
|
|
4221
|
+
* @param {number} numArgs the number of arguments passed to the function.
|
|
4222
|
+
* @param {number} argumentIndx the index of the argument.
|
|
4223
|
+
* @param {*} value The value of the argument.
|
|
4224
|
+
* @return {string} The value as a string.
|
|
4225
|
+
*/
|
|
4226
|
+
function glFunctionArgToString(functionName, numArgs, argumentIndex, value) {
|
|
4227
|
+
var funcInfo = glValidEnumContexts[functionName];
|
|
4228
|
+
if (funcInfo !== undefined) {
|
|
4229
|
+
var funcInfo = funcInfo[numArgs];
|
|
4230
|
+
if (funcInfo !== undefined) {
|
|
4231
|
+
if (funcInfo[argumentIndex]) {
|
|
4232
|
+
if (typeof funcInfo[argumentIndex] === 'object' &&
|
|
4233
|
+
funcInfo[argumentIndex]['enumBitwiseOr'] !== undefined) {
|
|
4234
|
+
var enums = funcInfo[argumentIndex]['enumBitwiseOr'];
|
|
4235
|
+
var orResult = 0;
|
|
4236
|
+
var orEnums = [];
|
|
4237
|
+
for (var i = 0; i < enums.length; ++i) {
|
|
4238
|
+
var enumValue = enumStringToValue[enums[i]];
|
|
4239
|
+
if ((value & enumValue) !== 0) {
|
|
4240
|
+
orResult |= enumValue;
|
|
4241
|
+
orEnums.push(glEnumToString(enumValue));
|
|
4242
|
+
}
|
|
4243
|
+
}
|
|
4244
|
+
if (orResult === value) {
|
|
4245
|
+
return orEnums.join(' | ');
|
|
4246
|
+
} else {
|
|
4247
|
+
return glEnumToString(value);
|
|
4248
|
+
}
|
|
4249
|
+
} else {
|
|
4250
|
+
return glEnumToString(value);
|
|
4251
|
+
}
|
|
4252
|
+
}
|
|
4253
|
+
}
|
|
4254
|
+
}
|
|
4255
|
+
if (value === null) {
|
|
4256
|
+
return "null";
|
|
4257
|
+
} else if (value === undefined) {
|
|
4258
|
+
return "undefined";
|
|
4259
|
+
} else {
|
|
4260
|
+
return value.toString();
|
|
4261
|
+
}
|
|
4262
|
+
}
|
|
4263
|
+
|
|
4264
|
+
/**
|
|
4265
|
+
* Converts the arguments of a WebGL function to a string.
|
|
4266
|
+
* Attempts to convert enum arguments to strings.
|
|
4267
|
+
*
|
|
4268
|
+
* @param {string} functionName the name of the WebGL function.
|
|
4269
|
+
* @param {Array<*>} args The arguments.
|
|
4270
|
+
* @return {string} The arguments as a string.
|
|
4271
|
+
*/
|
|
4272
|
+
function glFunctionArgsToString(functionName, args) {
|
|
4273
|
+
// apparently we can't do args.join(",");
|
|
4274
|
+
var argStr = "";
|
|
4275
|
+
var numArgs = args.length;
|
|
4276
|
+
for (var ii = 0; ii < numArgs; ++ii) {
|
|
4277
|
+
argStr += ((ii == 0) ? '' : ', ') +
|
|
4278
|
+
glFunctionArgToString(functionName, numArgs, ii, args[ii]);
|
|
4279
|
+
}
|
|
4280
|
+
return argStr;
|
|
4281
|
+
}
|
|
4282
|
+
|
|
4283
|
+
function makePropertyWrapper(wrapper, original, propertyName) {
|
|
4284
|
+
//log("wrap prop: " + propertyName);
|
|
4285
|
+
wrapper.__defineGetter__(propertyName, function() {
|
|
4286
|
+
return original[propertyName];
|
|
4287
|
+
});
|
|
4288
|
+
// TODO(gmane): this needs to handle properties that take more than
|
|
4289
|
+
// one value?
|
|
4290
|
+
wrapper.__defineSetter__(propertyName, function(value) {
|
|
4291
|
+
//log("set: " + propertyName);
|
|
4292
|
+
original[propertyName] = value;
|
|
4293
|
+
});
|
|
4294
|
+
}
|
|
4295
|
+
|
|
4296
|
+
/**
|
|
4297
|
+
* Given a WebGL context returns a wrapped context that calls
|
|
4298
|
+
* gl.getError after every command and calls a function if the
|
|
4299
|
+
* result is not gl.NO_ERROR.
|
|
4300
|
+
*
|
|
4301
|
+
* @param {!WebGLRenderingContext} ctx The webgl context to
|
|
4302
|
+
* wrap.
|
|
4303
|
+
* @param {!function(err, funcName, args): void} opt_onErrorFunc
|
|
4304
|
+
* The function to call when gl.getError returns an
|
|
4305
|
+
* error. If not specified the default function calls
|
|
4306
|
+
* console.log with a message.
|
|
4307
|
+
* @param {!function(funcName, args): void} opt_onFunc The
|
|
4308
|
+
* function to call when each webgl function is called.
|
|
4309
|
+
* You can use this to log all calls for example.
|
|
4310
|
+
* @param {!WebGLRenderingContext} opt_err_ctx The webgl context
|
|
4311
|
+
* to call getError on if different than ctx.
|
|
4312
|
+
*/
|
|
4313
|
+
function makeDebugContext(ctx, opt_onErrorFunc, opt_onFunc, opt_err_ctx) {
|
|
4314
|
+
opt_err_ctx = opt_err_ctx || ctx;
|
|
4315
|
+
init(ctx);
|
|
4316
|
+
opt_onErrorFunc = opt_onErrorFunc || function(err, functionName, args) {
|
|
4317
|
+
// apparently we can't do args.join(",");
|
|
4318
|
+
var argStr = "";
|
|
4319
|
+
var numArgs = args.length;
|
|
4320
|
+
for (var ii = 0; ii < numArgs; ++ii) {
|
|
4321
|
+
argStr += ((ii == 0) ? '' : ', ') +
|
|
4322
|
+
glFunctionArgToString(functionName, numArgs, ii, args[ii]);
|
|
4323
|
+
}
|
|
4324
|
+
error("WebGL error "+ glEnumToString(err) + " in "+ functionName +
|
|
4325
|
+
"(" + argStr + ")");
|
|
4326
|
+
};
|
|
4327
|
+
|
|
4328
|
+
// Holds booleans for each GL error so after we get the error ourselves
|
|
4329
|
+
// we can still return it to the client app.
|
|
4330
|
+
var glErrorShadow = { };
|
|
4331
|
+
|
|
4332
|
+
// Makes a function that calls a WebGL function and then calls getError.
|
|
4333
|
+
function makeErrorWrapper(ctx, functionName) {
|
|
4334
|
+
return function() {
|
|
4335
|
+
if (opt_onFunc) {
|
|
4336
|
+
opt_onFunc(functionName, arguments);
|
|
4337
|
+
}
|
|
4338
|
+
var result = ctx[functionName].apply(ctx, arguments);
|
|
4339
|
+
var err = opt_err_ctx.getError();
|
|
4340
|
+
if (err != 0) {
|
|
4341
|
+
glErrorShadow[err] = true;
|
|
4342
|
+
opt_onErrorFunc(err, functionName, arguments);
|
|
4343
|
+
}
|
|
4344
|
+
return result;
|
|
4345
|
+
};
|
|
4346
|
+
}
|
|
4347
|
+
|
|
4348
|
+
// Make a an object that has a copy of every property of the WebGL context
|
|
4349
|
+
// but wraps all functions.
|
|
4350
|
+
var wrapper = {};
|
|
4351
|
+
for (var propertyName in ctx) {
|
|
4352
|
+
if (typeof ctx[propertyName] == 'function') {
|
|
4353
|
+
if (propertyName != 'getExtension') {
|
|
4354
|
+
wrapper[propertyName] = makeErrorWrapper(ctx, propertyName);
|
|
4355
|
+
} else {
|
|
4356
|
+
var wrapped = makeErrorWrapper(ctx, propertyName);
|
|
4357
|
+
wrapper[propertyName] = function () {
|
|
4358
|
+
var result = wrapped.apply(ctx, arguments);
|
|
4359
|
+
if (!result) {
|
|
4360
|
+
return null;
|
|
4361
|
+
}
|
|
4362
|
+
return makeDebugContext(result, opt_onErrorFunc, opt_onFunc, opt_err_ctx);
|
|
4363
|
+
};
|
|
4364
|
+
}
|
|
4365
|
+
} else {
|
|
4366
|
+
makePropertyWrapper(wrapper, ctx, propertyName);
|
|
4367
|
+
}
|
|
4368
|
+
}
|
|
4369
|
+
|
|
4370
|
+
// Override the getError function with one that returns our saved results.
|
|
4371
|
+
wrapper.getError = function() {
|
|
4372
|
+
for (var err in glErrorShadow) {
|
|
4373
|
+
if (glErrorShadow.hasOwnProperty(err)) {
|
|
4374
|
+
if (glErrorShadow[err]) {
|
|
4375
|
+
glErrorShadow[err] = false;
|
|
4376
|
+
return err;
|
|
4377
|
+
}
|
|
4378
|
+
}
|
|
4379
|
+
}
|
|
4380
|
+
return ctx.NO_ERROR;
|
|
4381
|
+
};
|
|
4382
|
+
|
|
4383
|
+
return wrapper;
|
|
4384
|
+
}
|
|
4385
|
+
|
|
4386
|
+
function resetToInitialState(ctx) {
|
|
4387
|
+
var isWebGL2RenderingContext = !!ctx.createTransformFeedback;
|
|
4388
|
+
|
|
4389
|
+
if (isWebGL2RenderingContext) {
|
|
4390
|
+
ctx.bindVertexArray(null);
|
|
4391
|
+
}
|
|
4392
|
+
|
|
4393
|
+
var numAttribs = ctx.getParameter(ctx.MAX_VERTEX_ATTRIBS);
|
|
4394
|
+
var tmp = ctx.createBuffer();
|
|
4395
|
+
ctx.bindBuffer(ctx.ARRAY_BUFFER, tmp);
|
|
4396
|
+
for (var ii = 0; ii < numAttribs; ++ii) {
|
|
4397
|
+
ctx.disableVertexAttribArray(ii);
|
|
4398
|
+
ctx.vertexAttribPointer(ii, 4, ctx.FLOAT, false, 0, 0);
|
|
4399
|
+
ctx.vertexAttrib1f(ii, 0);
|
|
4400
|
+
if (isWebGL2RenderingContext) {
|
|
4401
|
+
ctx.vertexAttribDivisor(ii, 0);
|
|
4402
|
+
}
|
|
4403
|
+
}
|
|
4404
|
+
ctx.deleteBuffer(tmp);
|
|
4405
|
+
|
|
4406
|
+
var numTextureUnits = ctx.getParameter(ctx.MAX_TEXTURE_IMAGE_UNITS);
|
|
4407
|
+
for (var ii = 0; ii < numTextureUnits; ++ii) {
|
|
4408
|
+
ctx.activeTexture(ctx.TEXTURE0 + ii);
|
|
4409
|
+
ctx.bindTexture(ctx.TEXTURE_CUBE_MAP, null);
|
|
4410
|
+
ctx.bindTexture(ctx.TEXTURE_2D, null);
|
|
4411
|
+
if (isWebGL2RenderingContext) {
|
|
4412
|
+
ctx.bindTexture(ctx.TEXTURE_2D_ARRAY, null);
|
|
4413
|
+
ctx.bindTexture(ctx.TEXTURE_3D, null);
|
|
4414
|
+
ctx.bindSampler(ii, null);
|
|
4415
|
+
}
|
|
4416
|
+
}
|
|
4417
|
+
|
|
4418
|
+
ctx.activeTexture(ctx.TEXTURE0);
|
|
4419
|
+
ctx.useProgram(null);
|
|
4420
|
+
ctx.bindBuffer(ctx.ARRAY_BUFFER, null);
|
|
4421
|
+
ctx.bindBuffer(ctx.ELEMENT_ARRAY_BUFFER, null);
|
|
4422
|
+
ctx.bindFramebuffer(ctx.FRAMEBUFFER, null);
|
|
4423
|
+
ctx.bindRenderbuffer(ctx.RENDERBUFFER, null);
|
|
4424
|
+
ctx.disable(ctx.BLEND);
|
|
4425
|
+
ctx.disable(ctx.CULL_FACE);
|
|
4426
|
+
ctx.disable(ctx.DEPTH_TEST);
|
|
4427
|
+
ctx.disable(ctx.DITHER);
|
|
4428
|
+
ctx.disable(ctx.SCISSOR_TEST);
|
|
4429
|
+
ctx.blendColor(0, 0, 0, 0);
|
|
4430
|
+
ctx.blendEquation(ctx.FUNC_ADD);
|
|
4431
|
+
ctx.blendFunc(ctx.ONE, ctx.ZERO);
|
|
4432
|
+
ctx.clearColor(0, 0, 0, 0);
|
|
4433
|
+
ctx.clearDepth(1);
|
|
4434
|
+
ctx.clearStencil(-1);
|
|
4435
|
+
ctx.colorMask(true, true, true, true);
|
|
4436
|
+
ctx.cullFace(ctx.BACK);
|
|
4437
|
+
ctx.depthFunc(ctx.LESS);
|
|
4438
|
+
ctx.depthMask(true);
|
|
4439
|
+
ctx.depthRange(0, 1);
|
|
4440
|
+
ctx.frontFace(ctx.CCW);
|
|
4441
|
+
ctx.hint(ctx.GENERATE_MIPMAP_HINT, ctx.DONT_CARE);
|
|
4442
|
+
ctx.lineWidth(1);
|
|
4443
|
+
ctx.pixelStorei(ctx.PACK_ALIGNMENT, 4);
|
|
4444
|
+
ctx.pixelStorei(ctx.UNPACK_ALIGNMENT, 4);
|
|
4445
|
+
ctx.pixelStorei(ctx.UNPACK_FLIP_Y_WEBGL, false);
|
|
4446
|
+
ctx.pixelStorei(ctx.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
|
|
4447
|
+
// TODO: Delete this IF.
|
|
4448
|
+
if (ctx.UNPACK_COLORSPACE_CONVERSION_WEBGL) {
|
|
4449
|
+
ctx.pixelStorei(ctx.UNPACK_COLORSPACE_CONVERSION_WEBGL, ctx.BROWSER_DEFAULT_WEBGL);
|
|
4450
|
+
}
|
|
4451
|
+
ctx.polygonOffset(0, 0);
|
|
4452
|
+
ctx.sampleCoverage(1, false);
|
|
4453
|
+
ctx.scissor(0, 0, ctx.canvas.width, ctx.canvas.height);
|
|
4454
|
+
ctx.stencilFunc(ctx.ALWAYS, 0, 0xFFFFFFFF);
|
|
4455
|
+
ctx.stencilMask(0xFFFFFFFF);
|
|
4456
|
+
ctx.stencilOp(ctx.KEEP, ctx.KEEP, ctx.KEEP);
|
|
4457
|
+
ctx.viewport(0, 0, ctx.canvas.width, ctx.canvas.height);
|
|
4458
|
+
ctx.clear(ctx.COLOR_BUFFER_BIT | ctx.DEPTH_BUFFER_BIT | ctx.STENCIL_BUFFER_BIT);
|
|
4459
|
+
|
|
4460
|
+
if (isWebGL2RenderingContext) {
|
|
4461
|
+
ctx.drawBuffers([ctx.BACK]);
|
|
4462
|
+
ctx.readBuffer(ctx.BACK);
|
|
4463
|
+
ctx.bindBuffer(ctx.COPY_READ_BUFFER, null);
|
|
4464
|
+
ctx.bindBuffer(ctx.COPY_WRITE_BUFFER, null);
|
|
4465
|
+
ctx.bindBuffer(ctx.PIXEL_PACK_BUFFER, null);
|
|
4466
|
+
ctx.bindBuffer(ctx.PIXEL_UNPACK_BUFFER, null);
|
|
4467
|
+
var numTransformFeedbacks = ctx.getParameter(ctx.MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS);
|
|
4468
|
+
for (var ii = 0; ii < numTransformFeedbacks; ++ii) {
|
|
4469
|
+
ctx.bindBufferBase(ctx.TRANSFORM_FEEDBACK_BUFFER, ii, null);
|
|
4470
|
+
}
|
|
4471
|
+
var numUBOs = ctx.getParameter(ctx.MAX_UNIFORM_BUFFER_BINDINGS);
|
|
4472
|
+
for (var ii = 0; ii < numUBOs; ++ii) {
|
|
4473
|
+
ctx.bindBufferBase(ctx.UNIFORM_BUFFER, ii, null);
|
|
4474
|
+
}
|
|
4475
|
+
ctx.disable(ctx.RASTERIZER_DISCARD);
|
|
4476
|
+
ctx.pixelStorei(ctx.UNPACK_IMAGE_HEIGHT, 0);
|
|
4477
|
+
ctx.pixelStorei(ctx.UNPACK_SKIP_IMAGES, 0);
|
|
4478
|
+
ctx.pixelStorei(ctx.UNPACK_ROW_LENGTH, 0);
|
|
4479
|
+
ctx.pixelStorei(ctx.UNPACK_SKIP_ROWS, 0);
|
|
4480
|
+
ctx.pixelStorei(ctx.UNPACK_SKIP_PIXELS, 0);
|
|
4481
|
+
ctx.pixelStorei(ctx.PACK_ROW_LENGTH, 0);
|
|
4482
|
+
ctx.pixelStorei(ctx.PACK_SKIP_ROWS, 0);
|
|
4483
|
+
ctx.pixelStorei(ctx.PACK_SKIP_PIXELS, 0);
|
|
4484
|
+
ctx.hint(ctx.FRAGMENT_SHADER_DERIVATIVE_HINT, ctx.DONT_CARE);
|
|
4485
|
+
}
|
|
4486
|
+
|
|
4487
|
+
// TODO: This should NOT be needed but Firefox fails with 'hint'
|
|
4488
|
+
while(ctx.getError());
|
|
4489
|
+
}
|
|
4490
|
+
|
|
4491
|
+
function makeLostContextSimulatingCanvas(canvas) {
|
|
4492
|
+
var unwrappedContext_;
|
|
4493
|
+
var wrappedContext_;
|
|
4494
|
+
var onLost_ = [];
|
|
4495
|
+
var onRestored_ = [];
|
|
4496
|
+
var wrappedContext_ = {};
|
|
4497
|
+
var contextId_ = 1;
|
|
4498
|
+
var contextLost_ = false;
|
|
4499
|
+
var resourceDb_ = [];
|
|
4500
|
+
var numCallsToLoseContext_ = 0;
|
|
4501
|
+
var numCalls_ = 0;
|
|
4502
|
+
var canRestore_ = false;
|
|
4503
|
+
var restoreTimeout_ = 0;
|
|
4504
|
+
var isWebGL2RenderingContext;
|
|
4505
|
+
|
|
4506
|
+
// Holds booleans for each GL error so can simulate errors.
|
|
4507
|
+
var glErrorShadow_ = { };
|
|
4508
|
+
|
|
4509
|
+
canvas.getContext = function(f) {
|
|
4510
|
+
return function() {
|
|
4511
|
+
var ctx = f.apply(canvas, arguments);
|
|
4512
|
+
// Did we get a context and is it a WebGL context?
|
|
4513
|
+
if ((ctx instanceof WebGLRenderingContext) || (window.WebGL2RenderingContext && (ctx instanceof WebGL2RenderingContext))) {
|
|
4514
|
+
if (ctx != unwrappedContext_) {
|
|
4515
|
+
if (unwrappedContext_) {
|
|
4516
|
+
throw "got different context"
|
|
4517
|
+
}
|
|
4518
|
+
isWebGL2RenderingContext = window.WebGL2RenderingContext && (ctx instanceof WebGL2RenderingContext);
|
|
4519
|
+
unwrappedContext_ = ctx;
|
|
4520
|
+
wrappedContext_ = makeLostContextSimulatingContext(unwrappedContext_);
|
|
4521
|
+
}
|
|
4522
|
+
return wrappedContext_;
|
|
4523
|
+
}
|
|
4524
|
+
return ctx;
|
|
4525
|
+
}
|
|
4526
|
+
}(canvas.getContext);
|
|
4527
|
+
|
|
4528
|
+
function wrapEvent(listener) {
|
|
4529
|
+
if (typeof(listener) == "function") {
|
|
4530
|
+
return listener;
|
|
4531
|
+
} else {
|
|
4532
|
+
return function(info) {
|
|
4533
|
+
listener.handleEvent(info);
|
|
4534
|
+
}
|
|
4535
|
+
}
|
|
4536
|
+
}
|
|
4537
|
+
|
|
4538
|
+
var addOnContextLostListener = function(listener) {
|
|
4539
|
+
onLost_.push(wrapEvent(listener));
|
|
4540
|
+
};
|
|
4541
|
+
|
|
4542
|
+
var addOnContextRestoredListener = function(listener) {
|
|
4543
|
+
onRestored_.push(wrapEvent(listener));
|
|
4544
|
+
};
|
|
4545
|
+
|
|
4546
|
+
|
|
4547
|
+
function wrapAddEventListener(canvas) {
|
|
4548
|
+
var f = canvas.addEventListener;
|
|
4549
|
+
canvas.addEventListener = function(type, listener, bubble) {
|
|
4550
|
+
switch (type) {
|
|
4551
|
+
case 'webglcontextlost':
|
|
4552
|
+
addOnContextLostListener(listener);
|
|
4553
|
+
break;
|
|
4554
|
+
case 'webglcontextrestored':
|
|
4555
|
+
addOnContextRestoredListener(listener);
|
|
4556
|
+
break;
|
|
4557
|
+
default:
|
|
4558
|
+
f.apply(canvas, arguments);
|
|
4559
|
+
}
|
|
4560
|
+
};
|
|
4561
|
+
}
|
|
4562
|
+
|
|
4563
|
+
wrapAddEventListener(canvas);
|
|
4564
|
+
|
|
4565
|
+
canvas.loseContext = function() {
|
|
4566
|
+
if (!contextLost_) {
|
|
4567
|
+
contextLost_ = true;
|
|
4568
|
+
numCallsToLoseContext_ = 0;
|
|
4569
|
+
++contextId_;
|
|
4570
|
+
while (unwrappedContext_.getError());
|
|
4571
|
+
clearErrors();
|
|
4572
|
+
glErrorShadow_[unwrappedContext_.CONTEXT_LOST_WEBGL] = true;
|
|
4573
|
+
var event = makeWebGLContextEvent("context lost");
|
|
4574
|
+
var callbacks = onLost_.slice();
|
|
4575
|
+
setTimeout(function() {
|
|
4576
|
+
//log("numCallbacks:" + callbacks.length);
|
|
4577
|
+
for (var ii = 0; ii < callbacks.length; ++ii) {
|
|
4578
|
+
//log("calling callback:" + ii);
|
|
4579
|
+
callbacks[ii](event);
|
|
4580
|
+
}
|
|
4581
|
+
if (restoreTimeout_ >= 0) {
|
|
4582
|
+
setTimeout(function() {
|
|
4583
|
+
canvas.restoreContext();
|
|
4584
|
+
}, restoreTimeout_);
|
|
4585
|
+
}
|
|
4586
|
+
}, 0);
|
|
4587
|
+
}
|
|
4588
|
+
};
|
|
4589
|
+
|
|
4590
|
+
canvas.restoreContext = function() {
|
|
4591
|
+
if (contextLost_) {
|
|
4592
|
+
if (onRestored_.length) {
|
|
4593
|
+
setTimeout(function() {
|
|
4594
|
+
if (!canRestore_) {
|
|
4595
|
+
throw "can not restore. webglcontestlost listener did not call event.preventDefault";
|
|
4596
|
+
}
|
|
4597
|
+
freeResources();
|
|
4598
|
+
resetToInitialState(unwrappedContext_);
|
|
4599
|
+
contextLost_ = false;
|
|
4600
|
+
numCalls_ = 0;
|
|
4601
|
+
canRestore_ = false;
|
|
4602
|
+
var callbacks = onRestored_.slice();
|
|
4603
|
+
var event = makeWebGLContextEvent("context restored");
|
|
4604
|
+
for (var ii = 0; ii < callbacks.length; ++ii) {
|
|
4605
|
+
callbacks[ii](event);
|
|
4606
|
+
}
|
|
4607
|
+
}, 0);
|
|
4608
|
+
}
|
|
4609
|
+
}
|
|
4610
|
+
};
|
|
4611
|
+
|
|
4612
|
+
canvas.loseContextInNCalls = function(numCalls) {
|
|
4613
|
+
if (contextLost_) {
|
|
4614
|
+
throw "You can not ask a lost contet to be lost";
|
|
4615
|
+
}
|
|
4616
|
+
numCallsToLoseContext_ = numCalls_ + numCalls;
|
|
4617
|
+
};
|
|
4618
|
+
|
|
4619
|
+
canvas.getNumCalls = function() {
|
|
4620
|
+
return numCalls_;
|
|
4621
|
+
};
|
|
4622
|
+
|
|
4623
|
+
canvas.setRestoreTimeout = function(timeout) {
|
|
4624
|
+
restoreTimeout_ = timeout;
|
|
4625
|
+
};
|
|
4626
|
+
|
|
4627
|
+
function clearErrors() {
|
|
4628
|
+
var k = Object.keys(glErrorShadow_);
|
|
4629
|
+
for (var ii = 0; ii < k.length; ++ii) {
|
|
4630
|
+
delete glErrorShadow_[k[ii]];
|
|
4631
|
+
}
|
|
4632
|
+
}
|
|
4633
|
+
|
|
4634
|
+
function loseContextIfTime() {
|
|
4635
|
+
++numCalls_;
|
|
4636
|
+
if (!contextLost_) {
|
|
4637
|
+
if (numCallsToLoseContext_ == numCalls_) {
|
|
4638
|
+
canvas.loseContext();
|
|
4639
|
+
}
|
|
4640
|
+
}
|
|
4641
|
+
}
|
|
4642
|
+
|
|
4643
|
+
// Makes a function that simulates WebGL when out of context.
|
|
4644
|
+
function makeLostContextFunctionWrapper(ctx, functionName) {
|
|
4645
|
+
var f = ctx[functionName];
|
|
4646
|
+
return function() {
|
|
4647
|
+
// log("calling:" + functionName);
|
|
4648
|
+
// Only call the functions if the context is not lost.
|
|
4649
|
+
loseContextIfTime();
|
|
4650
|
+
if (!contextLost_) {
|
|
4651
|
+
//if (!checkResources(arguments)) {
|
|
4652
|
+
// glErrorShadow_[wrappedContext_.INVALID_OPERATION] = true;
|
|
4653
|
+
// return;
|
|
4654
|
+
//}
|
|
4655
|
+
var result = f.apply(ctx, arguments);
|
|
4656
|
+
return result;
|
|
4657
|
+
}
|
|
4658
|
+
};
|
|
4659
|
+
}
|
|
4660
|
+
|
|
4661
|
+
function freeResources() {
|
|
4662
|
+
for (var ii = 0; ii < resourceDb_.length; ++ii) {
|
|
4663
|
+
var resource = resourceDb_[ii];
|
|
4664
|
+
if (resource instanceof WebGLBuffer) {
|
|
4665
|
+
unwrappedContext_.deleteBuffer(resource);
|
|
4666
|
+
} else if (resource instanceof WebGLFramebuffer) {
|
|
4667
|
+
unwrappedContext_.deleteFramebuffer(resource);
|
|
4668
|
+
} else if (resource instanceof WebGLProgram) {
|
|
4669
|
+
unwrappedContext_.deleteProgram(resource);
|
|
4670
|
+
} else if (resource instanceof WebGLRenderbuffer) {
|
|
4671
|
+
unwrappedContext_.deleteRenderbuffer(resource);
|
|
4672
|
+
} else if (resource instanceof WebGLShader) {
|
|
4673
|
+
unwrappedContext_.deleteShader(resource);
|
|
4674
|
+
} else if (resource instanceof WebGLTexture) {
|
|
4675
|
+
unwrappedContext_.deleteTexture(resource);
|
|
4676
|
+
}
|
|
4677
|
+
else if (isWebGL2RenderingContext) {
|
|
4678
|
+
if (resource instanceof WebGLQuery) {
|
|
4679
|
+
unwrappedContext_.deleteQuery(resource);
|
|
4680
|
+
} else if (resource instanceof WebGLSampler) {
|
|
4681
|
+
unwrappedContext_.deleteSampler(resource);
|
|
4682
|
+
} else if (resource instanceof WebGLSync) {
|
|
4683
|
+
unwrappedContext_.deleteSync(resource);
|
|
4684
|
+
} else if (resource instanceof WebGLTransformFeedback) {
|
|
4685
|
+
unwrappedContext_.deleteTransformFeedback(resource);
|
|
4686
|
+
} else if (resource instanceof WebGLVertexArrayObject) {
|
|
4687
|
+
unwrappedContext_.deleteVertexArray(resource);
|
|
4688
|
+
}
|
|
4689
|
+
}
|
|
4690
|
+
}
|
|
4691
|
+
}
|
|
4692
|
+
|
|
4693
|
+
function makeWebGLContextEvent(statusMessage) {
|
|
4694
|
+
return {
|
|
4695
|
+
statusMessage: statusMessage,
|
|
4696
|
+
preventDefault: function() {
|
|
4697
|
+
canRestore_ = true;
|
|
4698
|
+
}
|
|
4699
|
+
};
|
|
4700
|
+
}
|
|
4701
|
+
|
|
4702
|
+
return canvas;
|
|
4703
|
+
|
|
4704
|
+
function makeLostContextSimulatingContext(ctx) {
|
|
4705
|
+
// copy all functions and properties to wrapper
|
|
4706
|
+
for (var propertyName in ctx) {
|
|
4707
|
+
if (typeof ctx[propertyName] == 'function') {
|
|
4708
|
+
wrappedContext_[propertyName] = makeLostContextFunctionWrapper(
|
|
4709
|
+
ctx, propertyName);
|
|
4710
|
+
} else {
|
|
4711
|
+
makePropertyWrapper(wrappedContext_, ctx, propertyName);
|
|
4712
|
+
}
|
|
4713
|
+
}
|
|
4714
|
+
|
|
4715
|
+
// Wrap a few functions specially.
|
|
4716
|
+
wrappedContext_.getError = function() {
|
|
4717
|
+
loseContextIfTime();
|
|
4718
|
+
if (!contextLost_) {
|
|
4719
|
+
var err;
|
|
4720
|
+
while (err = unwrappedContext_.getError()) {
|
|
4721
|
+
glErrorShadow_[err] = true;
|
|
4722
|
+
}
|
|
4723
|
+
}
|
|
4724
|
+
for (var err in glErrorShadow_) {
|
|
4725
|
+
if (glErrorShadow_[err]) {
|
|
4726
|
+
delete glErrorShadow_[err];
|
|
4727
|
+
return err;
|
|
4728
|
+
}
|
|
4729
|
+
}
|
|
4730
|
+
return wrappedContext_.NO_ERROR;
|
|
4731
|
+
};
|
|
4732
|
+
|
|
4733
|
+
var creationFunctions = [
|
|
4734
|
+
"createBuffer",
|
|
4735
|
+
"createFramebuffer",
|
|
4736
|
+
"createProgram",
|
|
4737
|
+
"createRenderbuffer",
|
|
4738
|
+
"createShader",
|
|
4739
|
+
"createTexture"
|
|
4740
|
+
];
|
|
4741
|
+
if (isWebGL2RenderingContext) {
|
|
4742
|
+
creationFunctions.push(
|
|
4743
|
+
"createQuery",
|
|
4744
|
+
"createSampler",
|
|
4745
|
+
"fenceSync",
|
|
4746
|
+
"createTransformFeedback",
|
|
4747
|
+
"createVertexArray"
|
|
4748
|
+
);
|
|
4749
|
+
}
|
|
4750
|
+
for (var ii = 0; ii < creationFunctions.length; ++ii) {
|
|
4751
|
+
var functionName = creationFunctions[ii];
|
|
4752
|
+
wrappedContext_[functionName] = function(f) {
|
|
4753
|
+
return function() {
|
|
4754
|
+
loseContextIfTime();
|
|
4755
|
+
if (contextLost_) {
|
|
4756
|
+
return null;
|
|
4757
|
+
}
|
|
4758
|
+
var obj = f.apply(ctx, arguments);
|
|
4759
|
+
obj.__webglDebugContextLostId__ = contextId_;
|
|
4760
|
+
resourceDb_.push(obj);
|
|
4761
|
+
return obj;
|
|
4762
|
+
};
|
|
4763
|
+
}(ctx[functionName]);
|
|
4764
|
+
}
|
|
4765
|
+
|
|
4766
|
+
var functionsThatShouldReturnNull = [
|
|
4767
|
+
"getActiveAttrib",
|
|
4768
|
+
"getActiveUniform",
|
|
4769
|
+
"getBufferParameter",
|
|
4770
|
+
"getContextAttributes",
|
|
4771
|
+
"getAttachedShaders",
|
|
4772
|
+
"getFramebufferAttachmentParameter",
|
|
4773
|
+
"getParameter",
|
|
4774
|
+
"getProgramParameter",
|
|
4775
|
+
"getProgramInfoLog",
|
|
4776
|
+
"getRenderbufferParameter",
|
|
4777
|
+
"getShaderParameter",
|
|
4778
|
+
"getShaderInfoLog",
|
|
4779
|
+
"getShaderSource",
|
|
4780
|
+
"getTexParameter",
|
|
4781
|
+
"getUniform",
|
|
4782
|
+
"getUniformLocation",
|
|
4783
|
+
"getVertexAttrib"
|
|
4784
|
+
];
|
|
4785
|
+
if (isWebGL2RenderingContext) {
|
|
4786
|
+
functionsThatShouldReturnNull.push(
|
|
4787
|
+
"getInternalformatParameter",
|
|
4788
|
+
"getQuery",
|
|
4789
|
+
"getQueryParameter",
|
|
4790
|
+
"getSamplerParameter",
|
|
4791
|
+
"getSyncParameter",
|
|
4792
|
+
"getTransformFeedbackVarying",
|
|
4793
|
+
"getIndexedParameter",
|
|
4794
|
+
"getUniformIndices",
|
|
4795
|
+
"getActiveUniforms",
|
|
4796
|
+
"getActiveUniformBlockParameter",
|
|
4797
|
+
"getActiveUniformBlockName"
|
|
4798
|
+
);
|
|
4799
|
+
}
|
|
4800
|
+
for (var ii = 0; ii < functionsThatShouldReturnNull.length; ++ii) {
|
|
4801
|
+
var functionName = functionsThatShouldReturnNull[ii];
|
|
4802
|
+
wrappedContext_[functionName] = function(f) {
|
|
4803
|
+
return function() {
|
|
4804
|
+
loseContextIfTime();
|
|
4805
|
+
if (contextLost_) {
|
|
4806
|
+
return null;
|
|
4807
|
+
}
|
|
4808
|
+
return f.apply(ctx, arguments);
|
|
4809
|
+
}
|
|
4810
|
+
}(wrappedContext_[functionName]);
|
|
4811
|
+
}
|
|
4812
|
+
|
|
4813
|
+
var isFunctions = [
|
|
4814
|
+
"isBuffer",
|
|
4815
|
+
"isEnabled",
|
|
4816
|
+
"isFramebuffer",
|
|
4817
|
+
"isProgram",
|
|
4818
|
+
"isRenderbuffer",
|
|
4819
|
+
"isShader",
|
|
4820
|
+
"isTexture"
|
|
4821
|
+
];
|
|
4822
|
+
if (isWebGL2RenderingContext) {
|
|
4823
|
+
isFunctions.push(
|
|
4824
|
+
"isQuery",
|
|
4825
|
+
"isSampler",
|
|
4826
|
+
"isSync",
|
|
4827
|
+
"isTransformFeedback",
|
|
4828
|
+
"isVertexArray"
|
|
4829
|
+
);
|
|
4830
|
+
}
|
|
4831
|
+
for (var ii = 0; ii < isFunctions.length; ++ii) {
|
|
4832
|
+
var functionName = isFunctions[ii];
|
|
4833
|
+
wrappedContext_[functionName] = function(f) {
|
|
4834
|
+
return function() {
|
|
4835
|
+
loseContextIfTime();
|
|
4836
|
+
if (contextLost_) {
|
|
4837
|
+
return false;
|
|
4838
|
+
}
|
|
4839
|
+
return f.apply(ctx, arguments);
|
|
4840
|
+
}
|
|
4841
|
+
}(wrappedContext_[functionName]);
|
|
4842
|
+
}
|
|
4843
|
+
|
|
4844
|
+
wrappedContext_.checkFramebufferStatus = function(f) {
|
|
4845
|
+
return function() {
|
|
4846
|
+
loseContextIfTime();
|
|
4847
|
+
if (contextLost_) {
|
|
4848
|
+
return wrappedContext_.FRAMEBUFFER_UNSUPPORTED;
|
|
4849
|
+
}
|
|
4850
|
+
return f.apply(ctx, arguments);
|
|
4851
|
+
};
|
|
4852
|
+
}(wrappedContext_.checkFramebufferStatus);
|
|
4853
|
+
|
|
4854
|
+
wrappedContext_.getAttribLocation = function(f) {
|
|
4855
|
+
return function() {
|
|
4856
|
+
loseContextIfTime();
|
|
4857
|
+
if (contextLost_) {
|
|
4858
|
+
return -1;
|
|
4859
|
+
}
|
|
4860
|
+
return f.apply(ctx, arguments);
|
|
4861
|
+
};
|
|
4862
|
+
}(wrappedContext_.getAttribLocation);
|
|
4863
|
+
|
|
4864
|
+
wrappedContext_.getVertexAttribOffset = function(f) {
|
|
4865
|
+
return function() {
|
|
4866
|
+
loseContextIfTime();
|
|
4867
|
+
if (contextLost_) {
|
|
4868
|
+
return 0;
|
|
4869
|
+
}
|
|
4870
|
+
return f.apply(ctx, arguments);
|
|
4871
|
+
};
|
|
4872
|
+
}(wrappedContext_.getVertexAttribOffset);
|
|
4873
|
+
|
|
4874
|
+
wrappedContext_.isContextLost = function() {
|
|
4875
|
+
return contextLost_;
|
|
4876
|
+
};
|
|
4877
|
+
|
|
4878
|
+
if (isWebGL2RenderingContext) {
|
|
4879
|
+
wrappedContext_.getFragDataLocation = function(f) {
|
|
4880
|
+
return function() {
|
|
4881
|
+
loseContextIfTime();
|
|
4882
|
+
if (contextLost_) {
|
|
4883
|
+
return -1;
|
|
4884
|
+
}
|
|
4885
|
+
return f.apply(ctx, arguments);
|
|
4886
|
+
};
|
|
4887
|
+
}(wrappedContext_.getFragDataLocation);
|
|
4888
|
+
|
|
4889
|
+
wrappedContext_.clientWaitSync = function(f) {
|
|
4890
|
+
return function() {
|
|
4891
|
+
loseContextIfTime();
|
|
4892
|
+
if (contextLost_) {
|
|
4893
|
+
return wrappedContext_.WAIT_FAILED;
|
|
4894
|
+
}
|
|
4895
|
+
return f.apply(ctx, arguments);
|
|
4896
|
+
};
|
|
4897
|
+
}(wrappedContext_.clientWaitSync);
|
|
4898
|
+
|
|
4899
|
+
wrappedContext_.getUniformBlockIndex = function(f) {
|
|
4900
|
+
return function() {
|
|
4901
|
+
loseContextIfTime();
|
|
4902
|
+
if (contextLost_) {
|
|
4903
|
+
return wrappedContext_.INVALID_INDEX;
|
|
4904
|
+
}
|
|
4905
|
+
return f.apply(ctx, arguments);
|
|
4906
|
+
};
|
|
4907
|
+
}(wrappedContext_.getUniformBlockIndex);
|
|
4908
|
+
}
|
|
4909
|
+
|
|
4910
|
+
return wrappedContext_;
|
|
4911
|
+
}
|
|
4912
|
+
}
|
|
4913
|
+
|
|
4914
|
+
return {
|
|
4915
|
+
/**
|
|
4916
|
+
* Initializes this module. Safe to call more than once.
|
|
4917
|
+
* @param {!WebGLRenderingContext} ctx A WebGL context. If
|
|
4918
|
+
* you have more than one context it doesn't matter which one
|
|
4919
|
+
* you pass in, it is only used to pull out constants.
|
|
4920
|
+
*/
|
|
4921
|
+
'init': init,
|
|
4922
|
+
|
|
4923
|
+
/**
|
|
4924
|
+
* Returns true or false if value matches any WebGL enum
|
|
4925
|
+
* @param {*} value Value to check if it might be an enum.
|
|
4926
|
+
* @return {boolean} True if value matches one of the WebGL defined enums
|
|
4927
|
+
*/
|
|
4928
|
+
'mightBeEnum': mightBeEnum,
|
|
4929
|
+
|
|
4930
|
+
/**
|
|
4931
|
+
* Gets an string version of an WebGL enum.
|
|
4932
|
+
*
|
|
4933
|
+
* Example:
|
|
4934
|
+
* WebGLDebugUtil.init(ctx);
|
|
4935
|
+
* var str = WebGLDebugUtil.glEnumToString(ctx.getError());
|
|
4936
|
+
*
|
|
4937
|
+
* @param {number} value Value to return an enum for
|
|
4938
|
+
* @return {string} The string version of the enum.
|
|
4939
|
+
*/
|
|
4940
|
+
'glEnumToString': glEnumToString,
|
|
4941
|
+
|
|
4942
|
+
/**
|
|
4943
|
+
* Converts the argument of a WebGL function to a string.
|
|
4944
|
+
* Attempts to convert enum arguments to strings.
|
|
4945
|
+
*
|
|
4946
|
+
* Example:
|
|
4947
|
+
* WebGLDebugUtil.init(ctx);
|
|
4948
|
+
* var str = WebGLDebugUtil.glFunctionArgToString('bindTexture', 2, 0, gl.TEXTURE_2D);
|
|
4949
|
+
*
|
|
4950
|
+
* would return 'TEXTURE_2D'
|
|
4951
|
+
*
|
|
4952
|
+
* @param {string} functionName the name of the WebGL function.
|
|
4953
|
+
* @param {number} numArgs The number of arguments
|
|
4954
|
+
* @param {number} argumentIndx the index of the argument.
|
|
4955
|
+
* @param {*} value The value of the argument.
|
|
4956
|
+
* @return {string} The value as a string.
|
|
4957
|
+
*/
|
|
4958
|
+
'glFunctionArgToString': glFunctionArgToString,
|
|
4959
|
+
|
|
4960
|
+
/**
|
|
4961
|
+
* Converts the arguments of a WebGL function to a string.
|
|
4962
|
+
* Attempts to convert enum arguments to strings.
|
|
4963
|
+
*
|
|
4964
|
+
* @param {string} functionName the name of the WebGL function.
|
|
4965
|
+
* @param {number} args The arguments.
|
|
4966
|
+
* @return {string} The arguments as a string.
|
|
4967
|
+
*/
|
|
4968
|
+
'glFunctionArgsToString': glFunctionArgsToString,
|
|
4969
|
+
|
|
4970
|
+
/**
|
|
4971
|
+
* Given a WebGL context returns a wrapped context that calls
|
|
4972
|
+
* gl.getError after every command and calls a function if the
|
|
4973
|
+
* result is not NO_ERROR.
|
|
4974
|
+
*
|
|
4975
|
+
* You can supply your own function if you want. For example, if you'd like
|
|
4976
|
+
* an exception thrown on any GL error you could do this
|
|
4977
|
+
*
|
|
4978
|
+
* function throwOnGLError(err, funcName, args) {
|
|
4979
|
+
* throw WebGLDebugUtils.glEnumToString(err) +
|
|
4980
|
+
* " was caused by call to " + funcName;
|
|
4981
|
+
* };
|
|
4982
|
+
*
|
|
4983
|
+
* ctx = WebGLDebugUtils.makeDebugContext(
|
|
4984
|
+
* canvas.getContext("webgl"), throwOnGLError);
|
|
4985
|
+
*
|
|
4986
|
+
* @param {!WebGLRenderingContext} ctx The webgl context to wrap.
|
|
4987
|
+
* @param {!function(err, funcName, args): void} opt_onErrorFunc The function
|
|
4988
|
+
* to call when gl.getError returns an error. If not specified the default
|
|
4989
|
+
* function calls console.log with a message.
|
|
4990
|
+
* @param {!function(funcName, args): void} opt_onFunc The
|
|
4991
|
+
* function to call when each webgl function is called. You
|
|
4992
|
+
* can use this to log all calls for example.
|
|
4993
|
+
*/
|
|
4994
|
+
'makeDebugContext': makeDebugContext,
|
|
4995
|
+
|
|
4996
|
+
/**
|
|
4997
|
+
* Given a canvas element returns a wrapped canvas element that will
|
|
4998
|
+
* simulate lost context. The canvas returned adds the following functions.
|
|
4999
|
+
*
|
|
5000
|
+
* loseContext:
|
|
5001
|
+
* simulates a lost context event.
|
|
5002
|
+
*
|
|
5003
|
+
* restoreContext:
|
|
5004
|
+
* simulates the context being restored.
|
|
5005
|
+
*
|
|
5006
|
+
* lostContextInNCalls:
|
|
5007
|
+
* loses the context after N gl calls.
|
|
5008
|
+
*
|
|
5009
|
+
* getNumCalls:
|
|
5010
|
+
* tells you how many gl calls there have been so far.
|
|
5011
|
+
*
|
|
5012
|
+
* setRestoreTimeout:
|
|
5013
|
+
* sets the number of milliseconds until the context is restored
|
|
5014
|
+
* after it has been lost. Defaults to 0. Pass -1 to prevent
|
|
5015
|
+
* automatic restoring.
|
|
5016
|
+
*
|
|
5017
|
+
* @param {!Canvas} canvas The canvas element to wrap.
|
|
5018
|
+
*/
|
|
5019
|
+
'makeLostContextSimulatingCanvas': makeLostContextSimulatingCanvas,
|
|
5020
|
+
|
|
5021
|
+
/**
|
|
5022
|
+
* Resets a context to the initial state.
|
|
5023
|
+
* @param {!WebGLRenderingContext} ctx The webgl context to
|
|
5024
|
+
* reset.
|
|
5025
|
+
*/
|
|
5026
|
+
'resetToInitialState': resetToInitialState
|
|
5027
|
+
};
|
|
5028
|
+
|
|
5029
5029
|
}();
|
|
5030
5030
|
|
|
5031
5031
|
var RenderBackendType;
|
|
@@ -5640,7 +5640,7 @@ class WebGl2VertexArrayObject {
|
|
|
5640
5640
|
|
|
5641
5641
|
var vertexSource$4 = "#version 300 es\nprecision lowp float;\nprecision lowp int;\n\n// Per-instance attributes (divisor = 1). Each Sprite contributes one entry\n// to the per-instance buffer; gl_VertexID 0..3 selects which corner of the\n// quad this invocation is computing.\nlayout(location = 0) in vec4 a_localBounds; // left, top, right, bottom (local space)\nlayout(location = 1) in vec3 a_transformAB; // a, b, x — first row of 2D affine\nlayout(location = 2) in vec3 a_transformCD; // c, d, y — second row\nlayout(location = 3) in vec4 a_uvBounds; // uMin, vMin, uMax, vMax (normalised, already flipY-swapped)\nlayout(location = 4) in vec4 a_color; // RGBA tint\nlayout(location = 5) in uint a_textureSlot;\n\nuniform mat3 u_projection;\n\nout vec2 v_texcoord;\nout vec4 v_color;\nflat out uint v_textureSlot;\n\nvoid main(void) {\n // gl_VertexID 0..3 → corner: 0=TL, 1=TR, 2=BL, 3=BR (TRIANGLE_STRIP order)\n int vid = gl_VertexID;\n int cornerX = vid & 1;\n int cornerY = (vid >> 1) & 1;\n\n // Local-space corner: pick from the bounds rectangle.\n float localX = (cornerX == 0) ? a_localBounds.x : a_localBounds.z;\n float localY = (cornerY == 0) ? a_localBounds.y : a_localBounds.w;\n\n // Apply the per-instance affine transform: world = M * (localX, localY, 1)\n float worldX = (a_transformAB.x * localX) + (a_transformAB.y * localY) + a_transformAB.z;\n float worldY = (a_transformCD.x * localX) + (a_transformCD.y * localY) + a_transformCD.z;\n\n gl_Position = vec4((u_projection * vec3(worldX, worldY, 1.0)).xy, 0.0, 1.0);\n\n // UV: pick from the bounds rectangle. The CPU pre-swaps Y bounds when\n // the texture is flipY, so the shader doesn't have to know.\n float u = (cornerX == 0) ? a_uvBounds.x : a_uvBounds.z;\n float v = (cornerY == 0) ? a_uvBounds.y : a_uvBounds.w;\n v_texcoord = vec2(u, v);\n\n v_color = vec4(a_color.rgb * a_color.a, a_color.a);\n v_textureSlot = a_textureSlot;\n}\n";
|
|
5642
5642
|
|
|
5643
|
-
var fragmentSource$4 = "#version 300 es\
|
|
5643
|
+
var fragmentSource$4 = "#version 300 es\nprecision lowp float;\nprecision lowp int;\n\n// Multi-texture sprite batching: up to 8 textures bound per draw call,\n// each fragment selects its source via a flat-interpolated slot index.\n//\n// GLSL ES 3.0 forbids non-constant array-of-sampler indexing unless the\n// expression is dynamically uniform — which a per-vertex slot is not\n// once different triangles in the same batch carry different slots. The\n// if/else chain below dispatches statically and dodges that constraint.\n\nuniform sampler2D u_texture0;\nuniform sampler2D u_texture1;\nuniform sampler2D u_texture2;\nuniform sampler2D u_texture3;\nuniform sampler2D u_texture4;\nuniform sampler2D u_texture5;\nuniform sampler2D u_texture6;\nuniform sampler2D u_texture7;\n\nin vec2 v_texcoord;\nin vec4 v_color;\nflat in uint v_textureSlot;\n\nlayout(location = 0) out vec4 fragColor;\n\nvoid main(void) {\n vec4 sampleColor;\n\n if (v_textureSlot == 0u) {\n sampleColor = texture(u_texture0, v_texcoord);\n } else if (v_textureSlot == 1u) {\n sampleColor = texture(u_texture1, v_texcoord);\n } else if (v_textureSlot == 2u) {\n sampleColor = texture(u_texture2, v_texcoord);\n } else if (v_textureSlot == 3u) {\n sampleColor = texture(u_texture3, v_texcoord);\n } else if (v_textureSlot == 4u) {\n sampleColor = texture(u_texture4, v_texcoord);\n } else if (v_textureSlot == 5u) {\n sampleColor = texture(u_texture5, v_texcoord);\n } else if (v_textureSlot == 6u) {\n sampleColor = texture(u_texture6, v_texcoord);\n } else {\n sampleColor = texture(u_texture7, v_texcoord);\n }\n\n fragColor = sampleColor * v_color;\n}\n";
|
|
5644
5644
|
|
|
5645
5645
|
/**
|
|
5646
5646
|
* Instanced sprite renderer for WebGL2.
|
|
@@ -6349,7 +6349,7 @@ class WebGl2MeshRenderer extends AbstractWebGl2Renderer {
|
|
|
6349
6349
|
|
|
6350
6350
|
var vertexSource$2 = "#version 300 es\nprecision lowp float;\nprecision lowp int;\n\n// Per-instance attributes (one entry per particle, 24 bytes total).\nlayout(location = 0) in vec2 a_translation; // particle position in system-local space\nlayout(location = 1) in vec2 a_scale; // particle scale\nlayout(location = 2) in float a_rotation; // particle rotation in degrees\nlayout(location = 3) in vec4 a_color; // RGBA tint\n\nuniform mat3 u_projection;\nuniform mat3 u_systemTransform;\nuniform vec4 u_localBounds; // left, top, right, bottom (system.vertices)\nuniform vec4 u_uvBounds; // uMin, vMin, uMax, vMax (flipY-swapped)\n\nout vec2 v_texcoord;\nout vec4 v_color;\n\nvoid main(void) {\n // Static index buffer is [0,1,2,0,2,3] (triangle-list), so gl_VertexID 0..3\n // maps to TL, TR, BR, BL via the same bit math the sprite renderer uses.\n int vid = gl_VertexID;\n int cornerX = ((vid + 1) >> 1) & 1;\n int cornerY = vid >> 1;\n\n float localX = (cornerX == 0) ? u_localBounds.x : u_localBounds.z;\n float localY = (cornerY == 0) ? u_localBounds.y : u_localBounds.w;\n\n // Per-particle scale + rotation.\n vec2 rotation = vec2(sin(radians(a_rotation)), cos(radians(a_rotation)));\n vec2 transformed = vec2(\n (localX * (a_scale.x * rotation.y)) + (localY * (a_scale.y * rotation.x)),\n (localX * (a_scale.x * -rotation.x)) + (localY * (a_scale.y * rotation.y))\n );\n\n vec3 worldPos = vec3(transformed + a_translation, 1.0);\n\n gl_Position = vec4((u_projection * u_systemTransform * worldPos).xy, 0.0, 1.0);\n\n float u = (cornerX == 0) ? u_uvBounds.x : u_uvBounds.z;\n float v = (cornerY == 0) ? u_uvBounds.y : u_uvBounds.w;\n v_texcoord = vec2(u, v);\n\n v_color = vec4(a_color.rgb * a_color.a, a_color.a);\n}\n";
|
|
6351
6351
|
|
|
6352
|
-
var fragmentSource$2 = "#version 300 es\
|
|
6352
|
+
var fragmentSource$2 = "#version 300 es\nprecision lowp float;\n\nuniform sampler2D u_texture;\n\nin vec2 v_texcoord;\nin vec4 v_color;\n\nlayout(location = 0) out vec4 fragColor;\n\nvoid main(void) {\n fragColor = texture(u_texture, v_texcoord) * v_color;\n}\n";
|
|
6353
6353
|
|
|
6354
6354
|
/**
|
|
6355
6355
|
* Instanced particle renderer for WebGL2.
|
|
@@ -6641,9 +6641,9 @@ class WebGl2ParticleRenderer extends AbstractWebGl2Renderer {
|
|
|
6641
6641
|
}
|
|
6642
6642
|
}
|
|
6643
6643
|
|
|
6644
|
-
var vertexSource$1 = "#version 300 es\
|
|
6644
|
+
var vertexSource$1 = "#version 300 es\nprecision lowp float;\n\nlayout(location = 0) in vec2 a_position;\nlayout(location = 1) in vec4 a_color;\n\nuniform mat3 u_projection;\nuniform mat3 u_translation;\n\nout vec4 v_color;\n\nvoid main(void) {\n gl_Position = vec4((u_projection * u_translation * vec3(a_position, 1.0)).xy, 0.0, 1.0);\n v_color = vec4(a_color.rgb * a_color.a, a_color.a);\n}\n";
|
|
6645
6645
|
|
|
6646
|
-
var fragmentSource$1 = "#version 300 es\
|
|
6646
|
+
var fragmentSource$1 = "#version 300 es\nprecision lowp float;\n\nlayout(location = 0) out vec4 fragColor;\n\nin vec4 v_color;\n\nvoid main(void) {\n fragColor = v_color;\n}\n";
|
|
6647
6647
|
|
|
6648
6648
|
const minBatchVertexSize = 4;
|
|
6649
6649
|
const vertexStrideBytes$4 = 12;
|
|
@@ -6856,9 +6856,9 @@ class WebGl2PrimitiveRenderer extends AbstractWebGl2Renderer {
|
|
|
6856
6856
|
}
|
|
6857
6857
|
}
|
|
6858
6858
|
|
|
6859
|
-
var vertexSource = "#version 300 es\
|
|
6859
|
+
var vertexSource = "#version 300 es\nprecision lowp float;\n\nlayout(location = 0) in vec2 a_position;\nlayout(location = 1) in vec2 a_texcoord;\n\nuniform mat3 u_projection;\n\nout vec2 v_texcoord;\n\nvoid main(void) {\n gl_Position = vec4((u_projection * vec3(a_position, 1.0)).xy, 0.0, 1.0);\n v_texcoord = a_texcoord;\n}\n";
|
|
6860
6860
|
|
|
6861
|
-
var fragmentSource = "#version 300 es\
|
|
6861
|
+
var fragmentSource = "#version 300 es\nprecision lowp float;\n\nuniform sampler2D u_content;\nuniform sampler2D u_mask;\n\nin vec2 v_texcoord;\n\nlayout(location = 0) out vec4 fragColor;\n\nvoid main(void) {\n vec4 contentColor = texture(u_content, v_texcoord);\n float maskAlpha = texture(u_mask, v_texcoord).a;\n\n fragColor = vec4(contentColor.rgb * maskAlpha, contentColor.a * maskAlpha);\n}\n";
|
|
6862
6862
|
|
|
6863
6863
|
// 4 floats per vertex: position(x, y) + texcoord(u, v).
|
|
6864
6864
|
const vertexStrideBytes$3 = 16;
|
|
@@ -8424,31 +8424,31 @@ function getWebGpuBlendState(blendMode) {
|
|
|
8424
8424
|
}
|
|
8425
8425
|
|
|
8426
8426
|
/// <reference types="@webgpu/types" />
|
|
8427
|
-
const primitiveShaderSource = `
|
|
8428
|
-
struct VertexInput {
|
|
8429
|
-
@location(0) position: vec4<f32>,
|
|
8430
|
-
@location(1) color: vec4<f32>,
|
|
8431
|
-
};
|
|
8432
|
-
|
|
8433
|
-
struct VertexOutput {
|
|
8434
|
-
@builtin(position) position: vec4<f32>,
|
|
8435
|
-
@location(0) color: vec4<f32>,
|
|
8436
|
-
};
|
|
8437
|
-
|
|
8438
|
-
@vertex
|
|
8439
|
-
fn vertexMain(input: VertexInput) -> VertexOutput {
|
|
8440
|
-
var output: VertexOutput;
|
|
8441
|
-
|
|
8442
|
-
output.position = input.position;
|
|
8443
|
-
output.color = vec4<f32>(input.color.rgb * input.color.a, input.color.a);
|
|
8444
|
-
|
|
8445
|
-
return output;
|
|
8446
|
-
}
|
|
8447
|
-
|
|
8448
|
-
@fragment
|
|
8449
|
-
fn fragmentMain(input: VertexOutput) -> @location(0) vec4<f32> {
|
|
8450
|
-
return input.color;
|
|
8451
|
-
}
|
|
8427
|
+
const primitiveShaderSource = `
|
|
8428
|
+
struct VertexInput {
|
|
8429
|
+
@location(0) position: vec4<f32>,
|
|
8430
|
+
@location(1) color: vec4<f32>,
|
|
8431
|
+
};
|
|
8432
|
+
|
|
8433
|
+
struct VertexOutput {
|
|
8434
|
+
@builtin(position) position: vec4<f32>,
|
|
8435
|
+
@location(0) color: vec4<f32>,
|
|
8436
|
+
};
|
|
8437
|
+
|
|
8438
|
+
@vertex
|
|
8439
|
+
fn vertexMain(input: VertexInput) -> VertexOutput {
|
|
8440
|
+
var output: VertexOutput;
|
|
8441
|
+
|
|
8442
|
+
output.position = input.position;
|
|
8443
|
+
output.color = vec4<f32>(input.color.rgb * input.color.a, input.color.a);
|
|
8444
|
+
|
|
8445
|
+
return output;
|
|
8446
|
+
}
|
|
8447
|
+
|
|
8448
|
+
@fragment
|
|
8449
|
+
fn fragmentMain(input: VertexOutput) -> @location(0) vec4<f32> {
|
|
8450
|
+
return input.color;
|
|
8451
|
+
}
|
|
8452
8452
|
`;
|
|
8453
8453
|
// 4 floats (pre-transformed clip-space position) + 1 u32 (color) = 20 bytes.
|
|
8454
8454
|
// The CPU applies (view * shape.globalTransform) to each vertex before writing
|
|
@@ -9884,71 +9884,71 @@ class WebGpuMeshRenderer extends AbstractWebGpuRenderer {
|
|
|
9884
9884
|
}
|
|
9885
9885
|
|
|
9886
9886
|
/// <reference types="@webgpu/types" />
|
|
9887
|
-
const particleShaderSource = `
|
|
9888
|
-
struct ProjectionUniforms {
|
|
9889
|
-
projection: mat4x4<f32>,
|
|
9890
|
-
translation: mat4x4<f32>,
|
|
9891
|
-
flags: vec4<f32>,
|
|
9892
|
-
localBounds: vec4<f32>, // quadMin.xy, quadSize.xy
|
|
9893
|
-
uvBounds: vec4<f32>, // uvMin.xy, uvMax.xy
|
|
9894
|
-
};
|
|
9895
|
-
|
|
9896
|
-
@group(0) @binding(0)
|
|
9897
|
-
var<uniform> uniforms: ProjectionUniforms;
|
|
9898
|
-
|
|
9899
|
-
@group(1) @binding(0)
|
|
9900
|
-
var particleTexture: texture_2d<f32>;
|
|
9901
|
-
|
|
9902
|
-
@group(1) @binding(1)
|
|
9903
|
-
var particleSampler: sampler;
|
|
9904
|
-
|
|
9905
|
-
// Per-instance attributes (one entry per particle, 24 bytes total).
|
|
9906
|
-
struct VertexInput {
|
|
9907
|
-
@location(0) unitPosition: vec2<f32>, // per-vertex (static unit quad)
|
|
9908
|
-
@location(1) translation: vec2<f32>,
|
|
9909
|
-
@location(2) scale: vec2<f32>,
|
|
9910
|
-
@location(3) rotation: f32,
|
|
9911
|
-
@location(4) color: vec4<f32>,
|
|
9912
|
-
};
|
|
9913
|
-
|
|
9914
|
-
struct VertexOutput {
|
|
9915
|
-
@builtin(position) position: vec4<f32>,
|
|
9916
|
-
@location(0) texcoord: vec2<f32>,
|
|
9917
|
-
@location(1) color: vec4<f32>,
|
|
9918
|
-
};
|
|
9919
|
-
|
|
9920
|
-
@vertex
|
|
9921
|
-
fn vertexMain(input: VertexInput) -> VertexOutput {
|
|
9922
|
-
let quadMin = uniforms.localBounds.xy;
|
|
9923
|
-
let quadSize = uniforms.localBounds.zw;
|
|
9924
|
-
let uvMin = uniforms.uvBounds.xy;
|
|
9925
|
-
let uvMax = uniforms.uvBounds.zw;
|
|
9926
|
-
|
|
9927
|
-
let localPosition = quadMin + (input.unitPosition * quadSize);
|
|
9928
|
-
let radians = radians(input.rotation);
|
|
9929
|
-
let sinValue = sin(radians);
|
|
9930
|
-
let cosValue = cos(radians);
|
|
9931
|
-
let rotated = vec2<f32>(
|
|
9932
|
-
(localPosition.x * (input.scale.x * cosValue)) + (localPosition.y * (input.scale.y * sinValue)) + input.translation.x,
|
|
9933
|
-
(localPosition.x * (input.scale.x * -sinValue)) + (localPosition.y * (input.scale.y * cosValue)) + input.translation.y
|
|
9934
|
-
);
|
|
9935
|
-
|
|
9936
|
-
var output: VertexOutput;
|
|
9937
|
-
|
|
9938
|
-
output.position = uniforms.projection * uniforms.translation * vec4<f32>(rotated, 0.0, 1.0);
|
|
9939
|
-
output.texcoord = uvMin + ((uvMax - uvMin) * input.unitPosition);
|
|
9940
|
-
output.color = vec4(input.color.rgb * input.color.a, input.color.a);
|
|
9941
|
-
|
|
9942
|
-
return output;
|
|
9943
|
-
}
|
|
9944
|
-
|
|
9945
|
-
@fragment
|
|
9946
|
-
fn fragmentMain(input: VertexOutput) -> @location(0) vec4<f32> {
|
|
9947
|
-
let sample = textureSample(particleTexture, particleSampler, input.texcoord);
|
|
9948
|
-
let premultipliedSample = select(sample, vec4(sample.rgb * sample.a, sample.a), uniforms.flags.x > 0.5);
|
|
9949
|
-
|
|
9950
|
-
return premultipliedSample * input.color;
|
|
9951
|
-
}
|
|
9887
|
+
const particleShaderSource = `
|
|
9888
|
+
struct ProjectionUniforms {
|
|
9889
|
+
projection: mat4x4<f32>,
|
|
9890
|
+
translation: mat4x4<f32>,
|
|
9891
|
+
flags: vec4<f32>,
|
|
9892
|
+
localBounds: vec4<f32>, // quadMin.xy, quadSize.xy
|
|
9893
|
+
uvBounds: vec4<f32>, // uvMin.xy, uvMax.xy
|
|
9894
|
+
};
|
|
9895
|
+
|
|
9896
|
+
@group(0) @binding(0)
|
|
9897
|
+
var<uniform> uniforms: ProjectionUniforms;
|
|
9898
|
+
|
|
9899
|
+
@group(1) @binding(0)
|
|
9900
|
+
var particleTexture: texture_2d<f32>;
|
|
9901
|
+
|
|
9902
|
+
@group(1) @binding(1)
|
|
9903
|
+
var particleSampler: sampler;
|
|
9904
|
+
|
|
9905
|
+
// Per-instance attributes (one entry per particle, 24 bytes total).
|
|
9906
|
+
struct VertexInput {
|
|
9907
|
+
@location(0) unitPosition: vec2<f32>, // per-vertex (static unit quad)
|
|
9908
|
+
@location(1) translation: vec2<f32>,
|
|
9909
|
+
@location(2) scale: vec2<f32>,
|
|
9910
|
+
@location(3) rotation: f32,
|
|
9911
|
+
@location(4) color: vec4<f32>,
|
|
9912
|
+
};
|
|
9913
|
+
|
|
9914
|
+
struct VertexOutput {
|
|
9915
|
+
@builtin(position) position: vec4<f32>,
|
|
9916
|
+
@location(0) texcoord: vec2<f32>,
|
|
9917
|
+
@location(1) color: vec4<f32>,
|
|
9918
|
+
};
|
|
9919
|
+
|
|
9920
|
+
@vertex
|
|
9921
|
+
fn vertexMain(input: VertexInput) -> VertexOutput {
|
|
9922
|
+
let quadMin = uniforms.localBounds.xy;
|
|
9923
|
+
let quadSize = uniforms.localBounds.zw;
|
|
9924
|
+
let uvMin = uniforms.uvBounds.xy;
|
|
9925
|
+
let uvMax = uniforms.uvBounds.zw;
|
|
9926
|
+
|
|
9927
|
+
let localPosition = quadMin + (input.unitPosition * quadSize);
|
|
9928
|
+
let radians = radians(input.rotation);
|
|
9929
|
+
let sinValue = sin(radians);
|
|
9930
|
+
let cosValue = cos(radians);
|
|
9931
|
+
let rotated = vec2<f32>(
|
|
9932
|
+
(localPosition.x * (input.scale.x * cosValue)) + (localPosition.y * (input.scale.y * sinValue)) + input.translation.x,
|
|
9933
|
+
(localPosition.x * (input.scale.x * -sinValue)) + (localPosition.y * (input.scale.y * cosValue)) + input.translation.y
|
|
9934
|
+
);
|
|
9935
|
+
|
|
9936
|
+
var output: VertexOutput;
|
|
9937
|
+
|
|
9938
|
+
output.position = uniforms.projection * uniforms.translation * vec4<f32>(rotated, 0.0, 1.0);
|
|
9939
|
+
output.texcoord = uvMin + ((uvMax - uvMin) * input.unitPosition);
|
|
9940
|
+
output.color = vec4(input.color.rgb * input.color.a, input.color.a);
|
|
9941
|
+
|
|
9942
|
+
return output;
|
|
9943
|
+
}
|
|
9944
|
+
|
|
9945
|
+
@fragment
|
|
9946
|
+
fn fragmentMain(input: VertexOutput) -> @location(0) vec4<f32> {
|
|
9947
|
+
let sample = textureSample(particleTexture, particleSampler, input.texcoord);
|
|
9948
|
+
let premultipliedSample = select(sample, vec4(sample.rgb * sample.a, sample.a), uniforms.flags.x > 0.5);
|
|
9949
|
+
|
|
9950
|
+
return premultipliedSample * input.color;
|
|
9951
|
+
}
|
|
9952
9952
|
`;
|
|
9953
9953
|
const staticVertexStrideBytes = 8;
|
|
9954
9954
|
const instanceWords = 6;
|
|
@@ -10304,50 +10304,50 @@ class WebGpuParticleRenderer extends AbstractWebGpuRenderer {
|
|
|
10304
10304
|
}
|
|
10305
10305
|
|
|
10306
10306
|
/// <reference types="@webgpu/types" />
|
|
10307
|
-
const compositorShaderSource = `
|
|
10308
|
-
struct ProjectionUniforms {
|
|
10309
|
-
matrix: mat4x4<f32>,
|
|
10310
|
-
};
|
|
10311
|
-
|
|
10312
|
-
@group(0) @binding(0)
|
|
10313
|
-
var<uniform> projection: ProjectionUniforms;
|
|
10314
|
-
|
|
10315
|
-
@group(1) @binding(0)
|
|
10316
|
-
var contentTexture: texture_2d<f32>;
|
|
10317
|
-
@group(1) @binding(1)
|
|
10318
|
-
var contentSampler: sampler;
|
|
10319
|
-
@group(1) @binding(2)
|
|
10320
|
-
var maskTexture: texture_2d<f32>;
|
|
10321
|
-
@group(1) @binding(3)
|
|
10322
|
-
var maskSampler: sampler;
|
|
10323
|
-
|
|
10324
|
-
struct VertexInput {
|
|
10325
|
-
@location(0) position: vec2<f32>,
|
|
10326
|
-
@location(1) texcoord: vec2<f32>,
|
|
10327
|
-
};
|
|
10328
|
-
|
|
10329
|
-
struct VertexOutput {
|
|
10330
|
-
@builtin(position) position: vec4<f32>,
|
|
10331
|
-
@location(0) texcoord: vec2<f32>,
|
|
10332
|
-
};
|
|
10333
|
-
|
|
10334
|
-
@vertex
|
|
10335
|
-
fn vertexMain(input: VertexInput) -> VertexOutput {
|
|
10336
|
-
var output: VertexOutput;
|
|
10337
|
-
|
|
10338
|
-
output.position = projection.matrix * vec4<f32>(input.position, 0.0, 1.0);
|
|
10339
|
-
output.texcoord = input.texcoord;
|
|
10340
|
-
|
|
10341
|
-
return output;
|
|
10342
|
-
}
|
|
10343
|
-
|
|
10344
|
-
@fragment
|
|
10345
|
-
fn fragmentMain(input: VertexOutput) -> @location(0) vec4<f32> {
|
|
10346
|
-
let contentColor = textureSample(contentTexture, contentSampler, input.texcoord);
|
|
10347
|
-
let maskAlpha = textureSample(maskTexture, maskSampler, input.texcoord).a;
|
|
10348
|
-
|
|
10349
|
-
return vec4<f32>(contentColor.rgb * maskAlpha, contentColor.a * maskAlpha);
|
|
10350
|
-
}
|
|
10307
|
+
const compositorShaderSource = `
|
|
10308
|
+
struct ProjectionUniforms {
|
|
10309
|
+
matrix: mat4x4<f32>,
|
|
10310
|
+
};
|
|
10311
|
+
|
|
10312
|
+
@group(0) @binding(0)
|
|
10313
|
+
var<uniform> projection: ProjectionUniforms;
|
|
10314
|
+
|
|
10315
|
+
@group(1) @binding(0)
|
|
10316
|
+
var contentTexture: texture_2d<f32>;
|
|
10317
|
+
@group(1) @binding(1)
|
|
10318
|
+
var contentSampler: sampler;
|
|
10319
|
+
@group(1) @binding(2)
|
|
10320
|
+
var maskTexture: texture_2d<f32>;
|
|
10321
|
+
@group(1) @binding(3)
|
|
10322
|
+
var maskSampler: sampler;
|
|
10323
|
+
|
|
10324
|
+
struct VertexInput {
|
|
10325
|
+
@location(0) position: vec2<f32>,
|
|
10326
|
+
@location(1) texcoord: vec2<f32>,
|
|
10327
|
+
};
|
|
10328
|
+
|
|
10329
|
+
struct VertexOutput {
|
|
10330
|
+
@builtin(position) position: vec4<f32>,
|
|
10331
|
+
@location(0) texcoord: vec2<f32>,
|
|
10332
|
+
};
|
|
10333
|
+
|
|
10334
|
+
@vertex
|
|
10335
|
+
fn vertexMain(input: VertexInput) -> VertexOutput {
|
|
10336
|
+
var output: VertexOutput;
|
|
10337
|
+
|
|
10338
|
+
output.position = projection.matrix * vec4<f32>(input.position, 0.0, 1.0);
|
|
10339
|
+
output.texcoord = input.texcoord;
|
|
10340
|
+
|
|
10341
|
+
return output;
|
|
10342
|
+
}
|
|
10343
|
+
|
|
10344
|
+
@fragment
|
|
10345
|
+
fn fragmentMain(input: VertexOutput) -> @location(0) vec4<f32> {
|
|
10346
|
+
let contentColor = textureSample(contentTexture, contentSampler, input.texcoord);
|
|
10347
|
+
let maskAlpha = textureSample(maskTexture, maskSampler, input.texcoord).a;
|
|
10348
|
+
|
|
10349
|
+
return vec4<f32>(contentColor.rgb * maskAlpha, contentColor.a * maskAlpha);
|
|
10350
|
+
}
|
|
10351
10351
|
`;
|
|
10352
10352
|
// 4 floats per vertex: position(x, y) + texcoord(u, v).
|
|
10353
10353
|
const vertexStrideBytes = 16;
|
|
@@ -11278,47 +11278,47 @@ class WebGpuBackend {
|
|
|
11278
11278
|
_getMipmapResources() {
|
|
11279
11279
|
if (this._mipmapShaderModule === null || this._mipmapBindGroupLayout === null || this._mipmapPipelineLayout === null || this._mipmapPipeline === null || this._mipmapSampler === null) {
|
|
11280
11280
|
this._mipmapShaderModule = this.device.createShaderModule({
|
|
11281
|
-
code: `
|
|
11282
|
-
struct VertexOutput {
|
|
11283
|
-
@builtin(position) position: vec4<f32>,
|
|
11284
|
-
@location(0) texcoord: vec2<f32>,
|
|
11285
|
-
};
|
|
11286
|
-
|
|
11287
|
-
@group(0) @binding(0)
|
|
11288
|
-
var sourceTexture: texture_2d<f32>;
|
|
11289
|
-
@group(0) @binding(1)
|
|
11290
|
-
var sourceSampler: sampler;
|
|
11291
|
-
|
|
11292
|
-
@vertex
|
|
11293
|
-
fn vertexMain(@builtin(vertex_index) vertexIndex: u32) -> VertexOutput {
|
|
11294
|
-
var positions = array<vec2<f32>, 3>(
|
|
11295
|
-
vec2<f32>(-1.0, -1.0),
|
|
11296
|
-
vec2<f32>(3.0, -1.0),
|
|
11297
|
-
vec2<f32>(-1.0, 3.0)
|
|
11298
|
-
);
|
|
11299
|
-
// Y is flipped vs the position array: NDC Y points up, but texture UV
|
|
11300
|
-
// Y points down (UV (0,0) is the top-left of the source). Matching the
|
|
11301
|
-
// two ensures that the output texture's top-left pixel samples from the
|
|
11302
|
-
// source's top-left, so every mip level has the same orientation as the
|
|
11303
|
-
// level above it. Prior to this, odd mip levels were rendered upside
|
|
11304
|
-
// down, producing visible texture flips at view-size doublings.
|
|
11305
|
-
var texcoords = array<vec2<f32>, 3>(
|
|
11306
|
-
vec2<f32>(0.0, 1.0),
|
|
11307
|
-
vec2<f32>(2.0, 1.0),
|
|
11308
|
-
vec2<f32>(0.0, -1.0)
|
|
11309
|
-
);
|
|
11310
|
-
var output: VertexOutput;
|
|
11311
|
-
|
|
11312
|
-
output.position = vec4<f32>(positions[vertexIndex], 0.0, 1.0);
|
|
11313
|
-
output.texcoord = texcoords[vertexIndex];
|
|
11314
|
-
|
|
11315
|
-
return output;
|
|
11316
|
-
}
|
|
11317
|
-
|
|
11318
|
-
@fragment
|
|
11319
|
-
fn fragmentMain(input: VertexOutput) -> @location(0) vec4<f32> {
|
|
11320
|
-
return textureSample(sourceTexture, sourceSampler, input.texcoord);
|
|
11321
|
-
}
|
|
11281
|
+
code: `
|
|
11282
|
+
struct VertexOutput {
|
|
11283
|
+
@builtin(position) position: vec4<f32>,
|
|
11284
|
+
@location(0) texcoord: vec2<f32>,
|
|
11285
|
+
};
|
|
11286
|
+
|
|
11287
|
+
@group(0) @binding(0)
|
|
11288
|
+
var sourceTexture: texture_2d<f32>;
|
|
11289
|
+
@group(0) @binding(1)
|
|
11290
|
+
var sourceSampler: sampler;
|
|
11291
|
+
|
|
11292
|
+
@vertex
|
|
11293
|
+
fn vertexMain(@builtin(vertex_index) vertexIndex: u32) -> VertexOutput {
|
|
11294
|
+
var positions = array<vec2<f32>, 3>(
|
|
11295
|
+
vec2<f32>(-1.0, -1.0),
|
|
11296
|
+
vec2<f32>(3.0, -1.0),
|
|
11297
|
+
vec2<f32>(-1.0, 3.0)
|
|
11298
|
+
);
|
|
11299
|
+
// Y is flipped vs the position array: NDC Y points up, but texture UV
|
|
11300
|
+
// Y points down (UV (0,0) is the top-left of the source). Matching the
|
|
11301
|
+
// two ensures that the output texture's top-left pixel samples from the
|
|
11302
|
+
// source's top-left, so every mip level has the same orientation as the
|
|
11303
|
+
// level above it. Prior to this, odd mip levels were rendered upside
|
|
11304
|
+
// down, producing visible texture flips at view-size doublings.
|
|
11305
|
+
var texcoords = array<vec2<f32>, 3>(
|
|
11306
|
+
vec2<f32>(0.0, 1.0),
|
|
11307
|
+
vec2<f32>(2.0, 1.0),
|
|
11308
|
+
vec2<f32>(0.0, -1.0)
|
|
11309
|
+
);
|
|
11310
|
+
var output: VertexOutput;
|
|
11311
|
+
|
|
11312
|
+
output.position = vec4<f32>(positions[vertexIndex], 0.0, 1.0);
|
|
11313
|
+
output.texcoord = texcoords[vertexIndex];
|
|
11314
|
+
|
|
11315
|
+
return output;
|
|
11316
|
+
}
|
|
11317
|
+
|
|
11318
|
+
@fragment
|
|
11319
|
+
fn fragmentMain(input: VertexOutput) -> @location(0) vec4<f32> {
|
|
11320
|
+
return textureSample(sourceTexture, sourceSampler, input.texcoord);
|
|
11321
|
+
}
|
|
11322
11322
|
`,
|
|
11323
11323
|
});
|
|
11324
11324
|
this._mipmapBindGroupLayout = this.device.createBindGroupLayout({
|
|
@@ -14798,6 +14798,100 @@ class Application {
|
|
|
14798
14798
|
}
|
|
14799
14799
|
}
|
|
14800
14800
|
|
|
14801
|
+
// Browser feature-detection probes evaluated once at module load. The
|
|
14802
|
+
// resulting `capabilities` object is a `Readonly<Record<CapabilityName,
|
|
14803
|
+
// boolean>>` and can be inspected directly or queried via `isSupported`.
|
|
14804
|
+
//
|
|
14805
|
+
// All probes are synchronous. Async questions ("can I actually acquire a
|
|
14806
|
+
// WebGPU adapter?", "can the audio decoder play this OGG file?") are
|
|
14807
|
+
// outside this module's scope — they're owned by the Application's
|
|
14808
|
+
// backend selection and the Loader respectively. `capabilities.webgpu`
|
|
14809
|
+
// returning `true` only guarantees that the browser advertises WebGPU,
|
|
14810
|
+
// not that an adapter request will succeed.
|
|
14811
|
+
const hasWindow = typeof window !== 'undefined';
|
|
14812
|
+
const hasDocument = typeof document !== 'undefined';
|
|
14813
|
+
const hasNavigator = typeof navigator !== 'undefined';
|
|
14814
|
+
const probeWebGl2 = () => {
|
|
14815
|
+
if (!hasDocument)
|
|
14816
|
+
return false;
|
|
14817
|
+
try {
|
|
14818
|
+
const canvas = document.createElement('canvas');
|
|
14819
|
+
const gl = canvas.getContext('webgl2');
|
|
14820
|
+
return gl !== null;
|
|
14821
|
+
}
|
|
14822
|
+
catch {
|
|
14823
|
+
return false;
|
|
14824
|
+
}
|
|
14825
|
+
};
|
|
14826
|
+
const probeWebGpu = () => {
|
|
14827
|
+
return hasNavigator && 'gpu' in navigator;
|
|
14828
|
+
};
|
|
14829
|
+
const probeAudio = () => {
|
|
14830
|
+
if (!hasWindow)
|
|
14831
|
+
return false;
|
|
14832
|
+
const w = window;
|
|
14833
|
+
return typeof w.AudioContext !== 'undefined' || typeof w.webkitAudioContext !== 'undefined';
|
|
14834
|
+
};
|
|
14835
|
+
const probePointer = () => {
|
|
14836
|
+
return hasWindow && 'PointerEvent' in window;
|
|
14837
|
+
};
|
|
14838
|
+
const probeTouch = () => {
|
|
14839
|
+
if (!hasWindow)
|
|
14840
|
+
return false;
|
|
14841
|
+
if ('ontouchstart' in window)
|
|
14842
|
+
return true;
|
|
14843
|
+
if (hasNavigator && typeof navigator.maxTouchPoints === 'number' && navigator.maxTouchPoints > 0)
|
|
14844
|
+
return true;
|
|
14845
|
+
return false;
|
|
14846
|
+
};
|
|
14847
|
+
const probeGamepad = () => {
|
|
14848
|
+
return hasNavigator && typeof navigator.getGamepads === 'function';
|
|
14849
|
+
};
|
|
14850
|
+
const probeKeyboard = () => {
|
|
14851
|
+
return hasWindow && 'KeyboardEvent' in window;
|
|
14852
|
+
};
|
|
14853
|
+
const probeFullscreen = () => {
|
|
14854
|
+
if (!hasDocument)
|
|
14855
|
+
return false;
|
|
14856
|
+
const el = document.documentElement;
|
|
14857
|
+
return typeof el.requestFullscreen === 'function' || typeof el.webkitRequestFullscreen === 'function';
|
|
14858
|
+
};
|
|
14859
|
+
const probeVibration = () => {
|
|
14860
|
+
return hasNavigator && typeof navigator.vibrate === 'function';
|
|
14861
|
+
};
|
|
14862
|
+
const probeOffscreenCanvas = () => {
|
|
14863
|
+
// The browser global is verbatim `OffscreenCanvas`; eslint's
|
|
14864
|
+
// strict-camelCase rule rejects the property name even though we
|
|
14865
|
+
// can't rename a web standard.
|
|
14866
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
14867
|
+
return hasWindow && typeof window.OffscreenCanvas !== 'undefined';
|
|
14868
|
+
};
|
|
14869
|
+
/**
|
|
14870
|
+
* Synchronous, one-shot feature-detection results. Computed once at
|
|
14871
|
+
* module load and frozen. Use either as a property bag (`capabilities.touch`)
|
|
14872
|
+
* or via {@link isSupported} for typed lookup.
|
|
14873
|
+
*/
|
|
14874
|
+
const capabilities = Object.freeze({
|
|
14875
|
+
webgl2: probeWebGl2(),
|
|
14876
|
+
webgpu: probeWebGpu(),
|
|
14877
|
+
audio: probeAudio(),
|
|
14878
|
+
pointer: probePointer(),
|
|
14879
|
+
touch: probeTouch(),
|
|
14880
|
+
gamepad: probeGamepad(),
|
|
14881
|
+
keyboard: probeKeyboard(),
|
|
14882
|
+
fullscreen: probeFullscreen(),
|
|
14883
|
+
vibration: probeVibration(),
|
|
14884
|
+
offscreenCanvas: probeOffscreenCanvas(),
|
|
14885
|
+
});
|
|
14886
|
+
/**
|
|
14887
|
+
* Typed lookup over {@link capabilities}. Identical to
|
|
14888
|
+
* `capabilities[name]` but the function form gives clearer call-sites
|
|
14889
|
+
* when the name is computed.
|
|
14890
|
+
*/
|
|
14891
|
+
function isSupported(name) {
|
|
14892
|
+
return capabilities[name];
|
|
14893
|
+
}
|
|
14894
|
+
|
|
14801
14895
|
class Quadtree {
|
|
14802
14896
|
static maxSceneNodes = 50;
|
|
14803
14897
|
static maxLevel = 5;
|
|
@@ -18985,5 +19079,5 @@ const createRapierPhysicsWorld = async (options = {}) => {
|
|
|
18985
19079
|
return await RapierPhysicsWorld.create(options);
|
|
18986
19080
|
};
|
|
18987
19081
|
|
|
18988
|
-
export { AbstractAssetFactory, AbstractMedia, AbstractWebGl2BatchedRenderer, AbstractWebGl2Renderer, AbstractWebGpuRenderer, AnimatedSprite, Application, ApplicationStatus, ArcadeStickGamepadMapping, AudioAnalyser, BinaryFactory, BlendModes, BlurFilter, Bounds, BufferTypes, BufferUsage, BundleLoadError, CacheFirstStrategy, CallbackRenderPass, ChannelOffset, ChannelSize, Circle, CircleGeometry, Clock, CollisionType, Color, ColorAffector, ColorFilter, Container, Drawable, DrawableShape, Ellipse, FactoryRegistry, Filter, Flags, FontFactory, ForceAffector, GameCubeGamepadMapping, Gamepad, GamepadChannel, GamepadControl, GamepadMapping, GamepadMappingFamily, GamepadPromptLayouts, GenericDualAnalogGamepadMapping, Geometry, Graphics, ImageFactory, IndexedDbDatabase, IndexedDbStore, Input, InputManager, Interval, JoyConLeftGamepadMapping, JoyConRightGamepadMapping, Json, JsonFactory, Keyboard, Line, Loader, Matrix, Mesh, Music, MusicFactory, NetworkOnlyStrategy, ObservableSize, ObservableVector, Particle, ParticleOptions, ParticleSystem, PlayStationGamepadMapping, Pointer, PointerState, PointerStateFlag, PolarVector, Polygon, Quadtree, Random, RapierPhysicsBinding, RapierPhysicsWorld, Rectangle, RenderBackendType, RenderNode, RenderTarget, RenderTargetPass, RenderTexture, RendererRegistry, RenderingPrimitives, Sampler, ScaleAffector, ScaleModes, Scene, SceneManager, SceneNode, Segment, Shader, ShaderAttribute, ShaderPrimitives, ShaderUniform, Signal, Size, Sound, SoundFactory, Sprite, SpriteFlags, Spritesheet, SteamControllerGamepadMapping, SvgAsset, SvgFactory, SwitchProGamepadMapping, Text, TextAsset, TextFactory, TextStyle, Texture, TextureFactory, Time, Timer, TorqueAffector, UniversalEmitter, Vector, Video, VideoFactory, View, ViewFlags, VoronoiRegion, VttAsset, VttFactory, WasmFactory, WebGl2Backend, WebGl2MeshRenderer, WebGl2ParticleRenderer, WebGl2PrimitiveRenderer, WebGl2RenderBuffer, WebGl2ShaderBlock, WebGl2SpriteRenderer, WebGl2VertexArrayObject, WebGpuBackend, WebGpuMeshRenderer, WebGpuParticleRenderer, WebGpuPrimitiveRenderer, WebGpuSpriteRenderer, WrapModes, XboxGamepadMapping, bezierCurveTo, buildCircle, buildEllipse, buildLine, buildPath, buildPolygon, buildRectangle, buildStar, builtInGamepadDefinitions, canvasSourceToDataUrl, clamp, createRapierPhysicsWorld, createRenderStats, createWebGl2ShaderProgram, decodeAudioData, defineAssetManifest, degreesPerRadian, degreesToRadians, determineMimeType, emptyArrayBuffer, getAudioContext, getCanvasSourceSize, getCollisionCircleCircle, getCollisionCircleRectangle, getCollisionPolygonCircle, getCollisionRectangleRectangle, getCollisionSat, getDistance, getOfflineAudioContext, getPreciseTime, getTextureSourceSize, getVoronoiRegion$1 as getVoronoiRegion, getWebGpuBlendState, hours, inRange, intersectionCircleCircle, intersectionCircleEllipse, intersectionCirclePoly, intersectionEllipseEllipse, intersectionEllipsePoly, intersectionLineCircle, intersectionLineEllipse, intersectionLineLine, intersectionLinePoly, intersectionLineRect, intersectionPointCircle, intersectionPointEllipse, intersectionPointLine, intersectionPointPoint, intersectionPointPoly, intersectionPointRect, intersectionPolyPoly, intersectionRectCircle, intersectionRectEllipse, intersectionRectPoly, intersectionRectRect, intersectionSat, isAudioContextReady, isPowerOfTwo, lerp, matchesIds, milliseconds, minutes, noop$1 as noop, normalizeIds, onAudioContextReady, parseGamepadDescriptor, quadraticCurveTo, radiansPerDegree, radiansToDegrees, rand, removeArrayItems, resetRenderStats, resolveDefinition, resolveGamepadDefinition, seconds, sign$1 as sign, stopEvent, supportsCodec, supportsEventOptions, supportsIndexedDb, supportsPointerEvents, supportsTouchEvents, supportsWebAudio, tau, trimRotation, webGl2PrimitiveArrayConstructors, webGl2PrimitiveByteSizeMapping, webGl2PrimitiveTypeNames };
|
|
19082
|
+
export { AbstractAssetFactory, AbstractMedia, AbstractWebGl2BatchedRenderer, AbstractWebGl2Renderer, AbstractWebGpuRenderer, AnimatedSprite, Application, ApplicationStatus, ArcadeStickGamepadMapping, AudioAnalyser, BinaryFactory, BlendModes, BlurFilter, Bounds, BufferTypes, BufferUsage, BundleLoadError, CacheFirstStrategy, CallbackRenderPass, ChannelOffset, ChannelSize, Circle, CircleGeometry, Clock, CollisionType, Color, ColorAffector, ColorFilter, Container, Drawable, DrawableShape, Ellipse, FactoryRegistry, Filter, Flags, FontFactory, ForceAffector, GameCubeGamepadMapping, Gamepad, GamepadChannel, GamepadControl, GamepadMapping, GamepadMappingFamily, GamepadPromptLayouts, GenericDualAnalogGamepadMapping, Geometry, Graphics, ImageFactory, IndexedDbDatabase, IndexedDbStore, Input, InputManager, Interval, JoyConLeftGamepadMapping, JoyConRightGamepadMapping, Json, JsonFactory, Keyboard, Line, Loader, Matrix, Mesh, Music, MusicFactory, NetworkOnlyStrategy, ObservableSize, ObservableVector, Particle, ParticleOptions, ParticleSystem, PlayStationGamepadMapping, Pointer, PointerState, PointerStateFlag, PolarVector, Polygon, Quadtree, Random, RapierPhysicsBinding, RapierPhysicsWorld, Rectangle, RenderBackendType, RenderNode, RenderTarget, RenderTargetPass, RenderTexture, RendererRegistry, RenderingPrimitives, Sampler, ScaleAffector, ScaleModes, Scene, SceneManager, SceneNode, Segment, Shader, ShaderAttribute, ShaderPrimitives, ShaderUniform, Signal, Size, Sound, SoundFactory, Sprite, SpriteFlags, Spritesheet, SteamControllerGamepadMapping, SvgAsset, SvgFactory, SwitchProGamepadMapping, Text, TextAsset, TextFactory, TextStyle, Texture, TextureFactory, Time, Timer, TorqueAffector, UniversalEmitter, Vector, Video, VideoFactory, View, ViewFlags, VoronoiRegion, VttAsset, VttFactory, WasmFactory, WebGl2Backend, WebGl2MeshRenderer, WebGl2ParticleRenderer, WebGl2PrimitiveRenderer, WebGl2RenderBuffer, WebGl2ShaderBlock, WebGl2SpriteRenderer, WebGl2VertexArrayObject, WebGpuBackend, WebGpuMeshRenderer, WebGpuParticleRenderer, WebGpuPrimitiveRenderer, WebGpuSpriteRenderer, WrapModes, XboxGamepadMapping, bezierCurveTo, buildCircle, buildEllipse, buildLine, buildPath, buildPolygon, buildRectangle, buildStar, builtInGamepadDefinitions, canvasSourceToDataUrl, capabilities, clamp, createRapierPhysicsWorld, createRenderStats, createWebGl2ShaderProgram, decodeAudioData, defineAssetManifest, degreesPerRadian, degreesToRadians, determineMimeType, emptyArrayBuffer, getAudioContext, getCanvasSourceSize, getCollisionCircleCircle, getCollisionCircleRectangle, getCollisionPolygonCircle, getCollisionRectangleRectangle, getCollisionSat, getDistance, getOfflineAudioContext, getPreciseTime, getTextureSourceSize, getVoronoiRegion$1 as getVoronoiRegion, getWebGpuBlendState, hours, inRange, intersectionCircleCircle, intersectionCircleEllipse, intersectionCirclePoly, intersectionEllipseEllipse, intersectionEllipsePoly, intersectionLineCircle, intersectionLineEllipse, intersectionLineLine, intersectionLinePoly, intersectionLineRect, intersectionPointCircle, intersectionPointEllipse, intersectionPointLine, intersectionPointPoint, intersectionPointPoly, intersectionPointRect, intersectionPolyPoly, intersectionRectCircle, intersectionRectEllipse, intersectionRectPoly, intersectionRectRect, intersectionSat, isAudioContextReady, isPowerOfTwo, isSupported, lerp, matchesIds, milliseconds, minutes, noop$1 as noop, normalizeIds, onAudioContextReady, parseGamepadDescriptor, quadraticCurveTo, radiansPerDegree, radiansToDegrees, rand, removeArrayItems, resetRenderStats, resolveDefinition, resolveGamepadDefinition, seconds, sign$1 as sign, stopEvent, supportsCodec, supportsEventOptions, supportsIndexedDb, supportsPointerEvents, supportsTouchEvents, supportsWebAudio, tau, trimRotation, webGl2PrimitiveArrayConstructors, webGl2PrimitiveByteSizeMapping, webGl2PrimitiveTypeNames };
|
|
18989
19083
|
//# sourceMappingURL=exo.esm.js.map
|