@geastack/native-webgl-angle 0.1.14 → 0.1.16
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/README.md +1 -1
- package/gea-native.json +1 -1
- package/geatsc-plugin-uniforms.mjs +41 -1
- package/geatsc-plugin-uploads.mjs +12 -7
- package/geatsc-plugin.mjs +159 -18
- package/native/angle_webgl_host.mm +70 -1
- package/native/resource_host.mm +128 -0
- package/package.json +3 -2
- package/src/nativeResources.ts +22 -0
- package/src/nativeWebGL.ts +20 -6
- package/src/nativeWebGLHost.ts +35 -0
package/README.md
CHANGED
|
@@ -121,7 +121,7 @@ to change them. Any present value, including an empty string, enables them.
|
|
|
121
121
|
|
|
122
122
|
### Validation
|
|
123
123
|
|
|
124
|
-
`npm run test:host-effects` checks
|
|
124
|
+
`npm run test:host-effects` checks 87 direct GL/input declarations and 15 audio
|
|
125
125
|
declarations against the compiler's host-mutation census. Their
|
|
126
126
|
`@gea-host-inert` contracts permit native state changes while excluding script
|
|
127
127
|
reference retention, script object mutation and script callbacks. The native
|
package/gea-native.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$comment": "What a GeaStack native target needs in order to build this package into an app. Paths are relative to the package root.",
|
|
3
3
|
"windows": {
|
|
4
|
-
"sources": ["native/angle_webgl_host.mm", "native/audio_host.mm", "native/win32_webgl_surface.cpp"],
|
|
4
|
+
"sources": ["native/angle_webgl_host.mm", "native/audio_host.mm", "native/resource_host.mm", "native/win32_webgl_surface.cpp"],
|
|
5
5
|
"includeDirs": ["native"],
|
|
6
6
|
"requires": {
|
|
7
7
|
"gles": {
|
|
@@ -44,7 +44,9 @@ export const nativeLightUniformClassNames = [
|
|
|
44
44
|
export const nativeUniformTypedefs = `/**
|
|
45
45
|
* Every value a shader uniform slot can hold, as ONE disjoint union: the math
|
|
46
46
|
* classes three's setters duck-type (\`v.x\`, \`v.r\`, \`v.elements\`), textures,
|
|
47
|
-
* the flat numeric arrays, and
|
|
47
|
+
* the flat numeric arrays, the vector and matrix arrays a custom
|
|
48
|
+
* \`ShaderMaterial\` declares (\`uniform vec4 u[ N ]\`, flattened by
|
|
49
|
+
* \`copyUniformElement\`), and the light-uniform arrays \`WebGLLights\` builds.
|
|
48
50
|
* A slot is therefore one native tagged union, and every consumer narrows it
|
|
49
51
|
* with \`instanceof\`/\`typeof\`/\`Array.isArray\` instead of reading a box.
|
|
50
52
|
* @typedef {number|boolean|null|undefined
|
|
@@ -57,7 +59,9 @@ export const nativeUniformTypedefs = `/**
|
|
|
57
59
|
* |import('../../math/Matrix4.js').Matrix4
|
|
58
60
|
* |import('../../textures/Texture.js').Texture
|
|
59
61
|
* |number[]|Float32Array|Int32Array|Uint32Array
|
|
62
|
+
* |Array<import('../../math/Vector2.js').Vector2>
|
|
60
63
|
* |Array<import('../../math/Vector3.js').Vector3>
|
|
64
|
+
* |Array<import('../../math/Vector4.js').Vector4>
|
|
61
65
|
* |Array<import('../../math/Matrix4.js').Matrix4>
|
|
62
66
|
* |Array<import('../../textures/Texture.js').Texture|null>
|
|
63
67
|
${nativeLightUniformClassNames.map((name) => ` * |${name}|${name}[]`).join('\n')}
|
|
@@ -345,6 +349,13 @@ export function isUniformNumberArray( value ) {
|
|
|
345
349
|
|
|
346
350
|
}
|
|
347
351
|
|
|
352
|
+
/** @param {NativeUniformValue} value @return {value is Vector2[]} */
|
|
353
|
+
function isVector2Array( value ) {
|
|
354
|
+
|
|
355
|
+
\treturn Array.isArray( value ) && value.length > 0 && value[ 0 ] instanceof Vector2;
|
|
356
|
+
|
|
357
|
+
}
|
|
358
|
+
|
|
348
359
|
/** @param {NativeUniformValue} value @return {value is Vector3[]} */
|
|
349
360
|
function isVector3Array( value ) {
|
|
350
361
|
|
|
@@ -352,6 +363,13 @@ function isVector3Array( value ) {
|
|
|
352
363
|
|
|
353
364
|
}
|
|
354
365
|
|
|
366
|
+
/** @param {NativeUniformValue} value @return {value is Vector4[]} */
|
|
367
|
+
function isVector4Array( value ) {
|
|
368
|
+
|
|
369
|
+
\treturn Array.isArray( value ) && value.length > 0 && value[ 0 ] instanceof Vector4;
|
|
370
|
+
|
|
371
|
+
}
|
|
372
|
+
|
|
355
373
|
/** @param {NativeUniformValue} value @return {value is Matrix4[]} */
|
|
356
374
|
function isMatrix4Array( value ) {
|
|
357
375
|
|
|
@@ -405,6 +423,17 @@ export function cloneUniformValue( value ) {
|
|
|
405
423
|
|
|
406
424
|
\tif ( isUniformNumberArray( value ) ) return value.slice();
|
|
407
425
|
|
|
426
|
+
\tif ( isVector2Array( value ) ) {
|
|
427
|
+
|
|
428
|
+
\t\t/** @type {Vector2[]} */
|
|
429
|
+
\t\tconst cloned = [];
|
|
430
|
+
|
|
431
|
+
\t\tfor ( let i = 0, l = value.length; i < l; i ++ ) cloned.push( value[ i ].clone() );
|
|
432
|
+
|
|
433
|
+
\t\treturn cloned;
|
|
434
|
+
|
|
435
|
+
\t}
|
|
436
|
+
|
|
408
437
|
\tif ( isVector3Array( value ) ) {
|
|
409
438
|
|
|
410
439
|
\t\t/** @type {Vector3[]} */
|
|
@@ -416,6 +445,17 @@ export function cloneUniformValue( value ) {
|
|
|
416
445
|
|
|
417
446
|
\t}
|
|
418
447
|
|
|
448
|
+
\tif ( isVector4Array( value ) ) {
|
|
449
|
+
|
|
450
|
+
\t\t/** @type {Vector4[]} */
|
|
451
|
+
\t\tconst cloned = [];
|
|
452
|
+
|
|
453
|
+
\t\tfor ( let i = 0, l = value.length; i < l; i ++ ) cloned.push( value[ i ].clone() );
|
|
454
|
+
|
|
455
|
+
\t\treturn cloned;
|
|
456
|
+
|
|
457
|
+
\t}
|
|
458
|
+
|
|
419
459
|
\tif ( isMatrix4Array( value ) ) {
|
|
420
460
|
|
|
421
461
|
\t\t/** @type {Matrix4[]} */
|
|
@@ -1,16 +1,21 @@
|
|
|
1
|
+
// A texture upload hands GL the view's own bytes, and the GL type names the view
|
|
2
|
+
// (WebGL 2 3.7.6, OES_texture_half_float): UNSIGNED_SHORT, HALF_FLOAT and the
|
|
3
|
+
// packed 16-bit types read a Uint16Array; UNSIGNED_INT and the packed 32-bit
|
|
4
|
+
// types a Uint32Array; BYTE, SHORT and INT their signed views; FLOAT a Float32Array.
|
|
5
|
+
const textureElementKind = '(type == 0x1401 ? 4 : type == 0x1400 ? 5 : type == 0x1402 ? 6 : type == 0x1404 ? 7 : ' +
|
|
6
|
+
'type == 0x1403 || type == 0x140B || type == 0x8D61 || type == 0x8033 || type == 0x8034 || type == 0x8363 ? 2 : ' +
|
|
7
|
+
'type == 0x1405 || type == 0x8368 || type == 0x8C3B || type == 0x8C3E || type == 0x84FA ? 3 : 1)'
|
|
8
|
+
|
|
1
9
|
// The host owns the physical upload format. The compiler only preserves the
|
|
2
10
|
// native carriers at these explicitly registered synchronous boundaries.
|
|
3
|
-
// Element type of the client pixels, by GL type: half floats travel as their
|
|
4
|
-
// 16-bit patterns, never widened to float32.
|
|
5
|
-
const pixelKind = '(type == 0x1403 || type == 0x140B || type == 0x8D61 ? 2 : type == 0x1405 ? 3 : type == 0x1401 ? 4 : type == 0x1400 ? 5 : type == 0x1402 ? 6 : type == 0x1404 ? 7 : 1)';
|
|
6
11
|
export const nativeUploadFunctions = [
|
|
7
12
|
['threeWebGLBufferData', 'gea_three_webgl_buffer_data_native', ['target', 'usage', 'typeCode'], 'gea_three_webgl_buffer_data_bytes', ['target', 'usage'], 'typeCode'],
|
|
8
13
|
['threeWebGLBufferSubData', 'gea_three_webgl_buffer_sub_data_native', ['target', 'offset', 'typeCode'], 'gea_three_webgl_buffer_sub_data_bytes', ['target', 'offset'], 'typeCode'],
|
|
9
14
|
['threeWebGLBufferSubDataRange', 'gea_three_webgl_buffer_sub_data_range_native', ['target', 'offset', 'typeCode'], 'gea_three_webgl_buffer_sub_data_bytes', ['target', 'offset'], 'typeCode', true],
|
|
10
|
-
['threeWebGLTexImage2D', 'gea_three_webgl_tex_image_2d_native', ['target', 'level', 'internalFormat', 'width', 'height', 'format', 'type'], 'gea_three_webgl_tex_image_2d_bytes', ['target', 'level', 'internalFormat', 'width', 'height', 'format', 'type'],
|
|
11
|
-
['threeWebGLTexImage3D', 'gea_three_webgl_tex_image_3d_native', ['target', 'level', 'internalFormat', 'width', 'height', 'depth', 'format', 'type'], 'gea_three_webgl_tex_image_3d_bytes', ['target', 'level', 'internalFormat', 'width', 'height', 'depth', 'format', 'type'],
|
|
12
|
-
['threeWebGLTexSubImage3D', 'gea_three_webgl_tex_sub_image_3d_native', ['target', 'level', 'xoffset', 'yoffset', 'zoffset', 'width', 'height', 'depth', 'format', 'type'], 'gea_three_webgl_tex_sub_image_3d_bytes', ['target', 'level', 'xoffset', 'yoffset', 'zoffset', 'width', 'height', 'depth', 'format', 'type'],
|
|
13
|
-
['threeWebGLTexSubImage2D', 'gea_three_webgl_tex_sub_image_2d_native', ['target', 'level', 'xoffset', 'yoffset', 'width', 'height', 'format', 'type'], 'gea_three_webgl_tex_sub_image_2d_bytes', ['target', 'level', 'xoffset', 'yoffset', 'width', 'height', 'format', 'type'],
|
|
15
|
+
['threeWebGLTexImage2D', 'gea_three_webgl_tex_image_2d_native', ['target', 'level', 'internalFormat', 'width', 'height', 'format', 'type'], 'gea_three_webgl_tex_image_2d_bytes', ['target', 'level', 'internalFormat', 'width', 'height', 'format', 'type'], textureElementKind],
|
|
16
|
+
['threeWebGLTexImage3D', 'gea_three_webgl_tex_image_3d_native', ['target', 'level', 'internalFormat', 'width', 'height', 'depth', 'format', 'type'], 'gea_three_webgl_tex_image_3d_bytes', ['target', 'level', 'internalFormat', 'width', 'height', 'depth', 'format', 'type'], textureElementKind],
|
|
17
|
+
['threeWebGLTexSubImage3D', 'gea_three_webgl_tex_sub_image_3d_native', ['target', 'level', 'xoffset', 'yoffset', 'zoffset', 'width', 'height', 'depth', 'format', 'type'], 'gea_three_webgl_tex_sub_image_3d_bytes', ['target', 'level', 'xoffset', 'yoffset', 'zoffset', 'width', 'height', 'depth', 'format', 'type'], textureElementKind],
|
|
18
|
+
['threeWebGLTexSubImage2D', 'gea_three_webgl_tex_sub_image_2d_native', ['target', 'level', 'xoffset', 'yoffset', 'width', 'height', 'format', 'type'], 'gea_three_webgl_tex_sub_image_2d_bytes', ['target', 'level', 'xoffset', 'yoffset', 'width', 'height', 'format', 'type'], textureElementKind],
|
|
14
19
|
].map(([name, binding, parameters, raw, rawParameters, kind, range]) => {
|
|
15
20
|
const declaration = `extern "C" void ${raw}(${rawParameters.map(p => `double ${p}`).join(', ')}, const void* bytes, double byteLength);
|
|
16
21
|
template <typename Source> inline void ${binding}(${parameters.map(p => `double ${p}`).join(', ')}, const Source& values${range ? ', double sourceOffset, double length' : ''}) {
|
package/geatsc-plugin.mjs
CHANGED
|
@@ -77,6 +77,30 @@ function nativeVoidMemberCallContract(
|
|
|
77
77
|
const hostFunctions = [
|
|
78
78
|
['threeWebGLCopyTexImage2D','gea_three_webgl_copy_tex_image_2d','void','extern "C" void gea_three_webgl_copy_tex_image_2d(double,double,double,double,double,double,double,double);'],
|
|
79
79
|
['threeWebGLCopyTexSubImage2D','gea_three_webgl_copy_tex_sub_image_2d','void','extern "C" void gea_three_webgl_copy_tex_sub_image_2d(double,double,double,double,double,double,double,double);'],
|
|
80
|
+
[
|
|
81
|
+
"threeWebGLBindBufferBase",
|
|
82
|
+
"gea_three_webgl_bind_buffer_base",
|
|
83
|
+
"void",
|
|
84
|
+
'extern "C" void gea_three_webgl_bind_buffer_base(double target, double index, double buffer);',
|
|
85
|
+
],
|
|
86
|
+
[
|
|
87
|
+
"threeWebGLBindBufferRange",
|
|
88
|
+
"gea_three_webgl_bind_buffer_range",
|
|
89
|
+
"void",
|
|
90
|
+
'extern "C" void gea_three_webgl_bind_buffer_range(double target, double index, double buffer, double offset, double size);',
|
|
91
|
+
],
|
|
92
|
+
[
|
|
93
|
+
"threeWebGLGetUniformBlockIndex",
|
|
94
|
+
"gea_three_webgl_get_uniform_block_index",
|
|
95
|
+
"double",
|
|
96
|
+
'extern "C" double gea_three_webgl_get_uniform_block_index(double program, std::string name);',
|
|
97
|
+
],
|
|
98
|
+
[
|
|
99
|
+
"threeWebGLUniformBlockBinding",
|
|
100
|
+
"gea_three_webgl_uniform_block_binding",
|
|
101
|
+
"void",
|
|
102
|
+
'extern "C" void gea_three_webgl_uniform_block_binding(double program, double blockIndex, double binding);',
|
|
103
|
+
],
|
|
80
104
|
[
|
|
81
105
|
"threeWebGLVertexAttribDivisor",
|
|
82
106
|
"gea_three_webgl_vertex_attrib_divisor",
|
|
@@ -97,6 +121,14 @@ const hostFunctions = [
|
|
|
97
121
|
],
|
|
98
122
|
...nativeUploadFunctions,
|
|
99
123
|
...nativeReadbackFunctions,
|
|
124
|
+
// Resources files (native/resource_host.mm): read whole, in place, into the caller's Uint8Array.
|
|
125
|
+
['threeResourceSize','gea_three_resource_size','double','extern "C" double gea_three_resource_size(std::string name);'],
|
|
126
|
+
['threeResourceRead','gea_three_resource_read_native','double',`
|
|
127
|
+
extern "C" double gea_three_resource_read_bytes(std::string name, void* bytes, double byteLength);
|
|
128
|
+
inline double gea_three_resource_read_native(std::string name, const gea::Ref<gea::TypedArray<std::uint8_t>>& destination) {
|
|
129
|
+
if (!destination) return -1;
|
|
130
|
+
return gea_three_resource_read_bytes(std::move(name), destination->data(), static_cast<double>(destination->size()));
|
|
131
|
+
}`],
|
|
100
132
|
['threeWebGLBlitFramebuffer','gea_three_webgl_blit_framebuffer','void','extern "C" void gea_three_webgl_blit_framebuffer(double,double,double,double,double,double,double,double,double,double);'],
|
|
101
133
|
['threeWebGLReadPixelsPack','gea_three_webgl_read_pixels_pack','void','extern "C" void gea_three_webgl_read_pixels_pack(double,double,double,double,double,double,double);'],
|
|
102
134
|
['threeWebGLFenceSync','gea_three_webgl_fence_sync','double','extern "C" double gea_three_webgl_fence_sync();'],
|
|
@@ -148,6 +180,12 @@ const hostFunctions = [
|
|
|
148
180
|
"void",
|
|
149
181
|
'extern "C" void gea_three_webgl_swap();',
|
|
150
182
|
],
|
|
183
|
+
[
|
|
184
|
+
"threeWebGLSetVsync",
|
|
185
|
+
"gea_three_webgl_set_vsync",
|
|
186
|
+
"void",
|
|
187
|
+
'extern "C" void gea_three_webgl_set_vsync(double on);',
|
|
188
|
+
],
|
|
151
189
|
[
|
|
152
190
|
"threeAngleSmokeLog",
|
|
153
191
|
"gea_three_angle_smoke_log",
|
|
@@ -222,6 +260,12 @@ const hostFunctions = [
|
|
|
222
260
|
"double",
|
|
223
261
|
'extern "C" double gea_three_webgl_get_shader_parameter(double shader, double pname);',
|
|
224
262
|
],
|
|
263
|
+
[
|
|
264
|
+
"threeWebGLGetShaderInfoLog",
|
|
265
|
+
"gea_three_webgl_get_shader_info_log",
|
|
266
|
+
"std::string",
|
|
267
|
+
'extern "C" std::string gea_three_webgl_get_shader_info_log(double shader);',
|
|
268
|
+
],
|
|
225
269
|
[
|
|
226
270
|
"threeWebGLDeleteShader",
|
|
227
271
|
"gea_three_webgl_delete_shader",
|
|
@@ -253,6 +297,12 @@ const hostFunctions = [
|
|
|
253
297
|
"double",
|
|
254
298
|
'extern "C" double gea_three_webgl_get_program_parameter(double program, double pname);',
|
|
255
299
|
],
|
|
300
|
+
[
|
|
301
|
+
"threeWebGLGetProgramInfoLog",
|
|
302
|
+
"gea_three_webgl_get_program_info_log",
|
|
303
|
+
"std::string",
|
|
304
|
+
'extern "C" std::string gea_three_webgl_get_program_info_log(double program);',
|
|
305
|
+
],
|
|
256
306
|
[
|
|
257
307
|
"threeWebGLDeleteProgram",
|
|
258
308
|
"gea_three_webgl_delete_program",
|
|
@@ -1698,6 +1748,12 @@ const nativeDataTextureOverlayUnpackAlignmentSource =
|
|
|
1698
1748
|
"\t/** @type {number} */\n\tunpackAlignment;";
|
|
1699
1749
|
const overlayToJSONParameterSource =
|
|
1700
1750
|
/(\/\*\*\n\t \* @param )\{[^\n]+\}( \[meta\]\n\t \*\/\n\ttoJSON\( meta \) \{)/g;
|
|
1751
|
+
const nativeObject3DJSONType =
|
|
1752
|
+
"{ metadata?: { version: number, type: string, generator: string }, geometries?: Array<Object>, materials?: Array<Object>, textures?: Array<Object>, images?: Array<Object>, shapes?: Array<Object>, skeletons?: Array<Object>, animations?: Array<Object>, nodes?: Array<Object>, object: Object }";
|
|
1753
|
+
const nativeBufferGeometryJSONType =
|
|
1754
|
+
"{ metadata: { version: number, type: string, generator: string }, uuid?: string, type?: string, name?: string, userData?: Object, data?: Object, instanceCount?: number, isInstancedBufferGeometry?: boolean, [key: string]: any }";
|
|
1755
|
+
const nativeFogJSONType =
|
|
1756
|
+
"{ type: string, name: string, color: number, near?: number, far?: number, density?: number }";
|
|
1701
1757
|
const rendererReceiverMethods = [
|
|
1702
1758
|
"setPixelRatio",
|
|
1703
1759
|
"setSize",
|
|
@@ -2032,6 +2088,37 @@ const transformSource = ({ fileName, text }) => {
|
|
|
2032
2088
|
object3DRaycastSource,
|
|
2033
2089
|
nativeObject3DRaycastSource,
|
|
2034
2090
|
);
|
|
2091
|
+
// `JSON.stringify` on a declared-any value keeps every class's `toJSON`
|
|
2092
|
+
// (three's own `copy()` deep-copies `userData` that way), so these bodies
|
|
2093
|
+
// compile whenever a material or texture is cloned. `@return {Object}`
|
|
2094
|
+
// states nothing, so every `super.toJSON( meta )`, `child.toJSON( meta )`
|
|
2095
|
+
// and `camera.toJSON( false )` result boxed and then had to be read back
|
|
2096
|
+
// as the record the body builds, which no conversion can do. The envelope
|
|
2097
|
+
// is the record the body builds; `object` stays `Object` because each
|
|
2098
|
+
// subclass adds its own fields to it (`data.object.fov = ...`).
|
|
2099
|
+
transformed = replaceOne(
|
|
2100
|
+
transformed,
|
|
2101
|
+
"\t * @return {Object} A JSON object representing the serialized 3D object.",
|
|
2102
|
+
`\t * @return {${nativeObject3DJSONType}} A JSON object representing the serialized 3D object.`,
|
|
2103
|
+
fileName,
|
|
2104
|
+
"Object3D.toJSON envelope",
|
|
2105
|
+
);
|
|
2106
|
+
}
|
|
2107
|
+
if (
|
|
2108
|
+
normalized.endsWith("/three/src/scenes/Fog.js") ||
|
|
2109
|
+
normalized.endsWith("/three/src/scenes/FogExp2.js")
|
|
2110
|
+
) {
|
|
2111
|
+
// `Scene.toJSON` calls `toJSON` on `?(Fog|FogExp2)`. Each body's own
|
|
2112
|
+
// literal made the two methods two function types, and the read over the
|
|
2113
|
+
// union had to convert one into the other. One record both literals fit,
|
|
2114
|
+
// spelled once, makes them one type.
|
|
2115
|
+
transformed = replaceOne(
|
|
2116
|
+
transformed,
|
|
2117
|
+
"\t * @return {Object} A JSON object representing the serialized fog",
|
|
2118
|
+
`\t * @return {${nativeFogJSONType}} A JSON object representing the serialized fog`,
|
|
2119
|
+
fileName,
|
|
2120
|
+
"Fog toJSON shared record",
|
|
2121
|
+
);
|
|
2035
2122
|
}
|
|
2036
2123
|
if (normalized.endsWith("/three/src/renderers/WebGLRenderer.js")) {
|
|
2037
2124
|
transformed =
|
|
@@ -2215,6 +2302,15 @@ class WebGLRenderer {
|
|
|
2215
2302
|
rendererCompileReturnSource,
|
|
2216
2303
|
nativeRendererCompileReturnSource,
|
|
2217
2304
|
);
|
|
2305
|
+
// `if ( targetScene === null ) targetScene = scene;` stores the Object3D
|
|
2306
|
+
// being compiled; every use after it is an Object3D use.
|
|
2307
|
+
transformed = replaceOne(
|
|
2308
|
+
transformed,
|
|
2309
|
+
`@param {?Scene} [targetScene=null] - The target scene.\n\t\t * ${nativeRendererCompileReturnSource}`,
|
|
2310
|
+
`@param {?Object3D} [targetScene=null] - The target scene.\n\t\t * ${nativeRendererCompileReturnSource}`,
|
|
2311
|
+
fileName,
|
|
2312
|
+
"WebGLRenderer compile target root",
|
|
2313
|
+
);
|
|
2218
2314
|
transformed = transformed.replace(
|
|
2219
2315
|
rendererCompileAssignmentSource,
|
|
2220
2316
|
nativeRendererCompileAssignmentSource,
|
|
@@ -3718,6 +3814,33 @@ class BufferGeometry extends EventDispatcher {`,
|
|
|
3718
3814
|
fileName,
|
|
3719
3815
|
"BufferGeometry morph-attribute table",
|
|
3720
3816
|
);
|
|
3817
|
+
// `toJSON` fills each morph entry from `const array = []`, which the
|
|
3818
|
+
// checker types `any[]` (the table's entry type) while the census lays it
|
|
3819
|
+
// out from its pushes, the union of the two attribute `toJSON` records.
|
|
3820
|
+
// Two carriers for one array, and an array cannot be converted in place.
|
|
3821
|
+
// State the element three's attribute `toJSON`s state: `Object`.
|
|
3822
|
+
transformed = replaceOne(
|
|
3823
|
+
transformed,
|
|
3824
|
+
"\t\t\tconst attributeArray = this.morphAttributes[ key ];\n\n\t\t\tconst array = [];",
|
|
3825
|
+
"\t\t\tconst attributeArray = this.morphAttributes[ key ];\n\n\t\t\t/** @type {Array<Object>} */\n\t\t\tconst array = [];",
|
|
3826
|
+
fileName,
|
|
3827
|
+
"BufferGeometry.toJSON morph entry array",
|
|
3828
|
+
);
|
|
3829
|
+
// `JSON.stringify` on a declared-any value keeps every `toJSON` (see
|
|
3830
|
+
// Object3D's envelope), so this envelope is published to dynamic code,
|
|
3831
|
+
// which may write any of its fields. Laid out from the body, its `data`
|
|
3832
|
+
// field is the record `data.data = { attributes: {} }` and the writes
|
|
3833
|
+
// after it build, and a dynamic value has no reader into that record.
|
|
3834
|
+
// State the envelope, with `data` left `Object` as Object3D's `object`
|
|
3835
|
+
// is: the body fills it key by key. The index signature is the
|
|
3836
|
+
// parameters branch, which copies each parameter in by name.
|
|
3837
|
+
transformed = replaceOne(
|
|
3838
|
+
transformed,
|
|
3839
|
+
"\t * @return {Object} A JSON object representing the serialized geometry.\n\t */\n\ttoJSON() {\n\n\t\tconst data = {",
|
|
3840
|
+
`\t * @return {${nativeBufferGeometryJSONType}} A JSON object representing the serialized geometry.\n\t */\n\ttoJSON() {\n\n\t\t/** @type {${nativeBufferGeometryJSONType}} */\n\t\tconst data = {`,
|
|
3841
|
+
fileName,
|
|
3842
|
+
"BufferGeometry.toJSON envelope",
|
|
3843
|
+
);
|
|
3721
3844
|
transformed = replaceOne(
|
|
3722
3845
|
transformed,
|
|
3723
3846
|
`\tgetAttribute( name ) {
|
|
@@ -5455,6 +5578,18 @@ function requireWebGLStateTextureImageSource( value ) {
|
|
|
5455
5578
|
fileName,
|
|
5456
5579
|
"WebGLBindingStates interleaved attribute import",
|
|
5457
5580
|
);
|
|
5581
|
+
// The binding-state fast paths below test `object instanceof InstancedMesh`; three's own
|
|
5582
|
+
// file reads `object.isInstancedMesh` and imports no InstancedMesh. An app that patches
|
|
5583
|
+
// three on disk may have added the import already.
|
|
5584
|
+
if (!transformed.includes("import { InstancedMesh } from '../../objects/InstancedMesh.js';")) {
|
|
5585
|
+
transformed = replaceOne(
|
|
5586
|
+
transformed,
|
|
5587
|
+
"import { IntType } from '../../constants.js';",
|
|
5588
|
+
"import { IntType } from '../../constants.js';\nimport { InstancedMesh } from '../../objects/InstancedMesh.js';",
|
|
5589
|
+
fileName,
|
|
5590
|
+
"WebGLBindingStates instanced mesh import",
|
|
5591
|
+
);
|
|
5592
|
+
}
|
|
5458
5593
|
transformed = replaceOne(
|
|
5459
5594
|
transformed,
|
|
5460
5595
|
"\t\t\tif ( index !== null ) {\n\n\t\t\t\tgl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, attributes.get( index ).buffer );",
|
|
@@ -5641,7 +5776,7 @@ function requireWebGLStateTextureImageSource( value ) {
|
|
|
5641
5776
|
transformed = replaceOne(
|
|
5642
5777
|
transformed,
|
|
5643
5778
|
"\tfunction get( scene, renderCallDepth ) {",
|
|
5644
|
-
"\t/** @param {import('../../
|
|
5779
|
+
"\t/** @param {import('../../core/Object3D.js').Object3D} scene @param {number} renderCallDepth */\n\tfunction get( scene, renderCallDepth ) {",
|
|
5645
5780
|
fileName,
|
|
5646
5781
|
"WebGLRenderLists lookup inputs",
|
|
5647
5782
|
);
|
|
@@ -6373,7 +6508,10 @@ function WebGLShadowMap( renderer, objects, capabilities ) {`,
|
|
|
6373
6508
|
transformed = replaceOne(
|
|
6374
6509
|
transformed,
|
|
6375
6510
|
"this.render = function ( lights, scene, camera ) {",
|
|
6376
|
-
|
|
6511
|
+
// `scene` is the root WebGLRenderer.render was handed, any Object3D;
|
|
6512
|
+
// the body only traverses it. This inline block outranks the
|
|
6513
|
+
// declaration overlay's `@param {Scene} scene` above the assignment.
|
|
6514
|
+
"this.render = /** @this {WebGLShadowMap} @param {Array<import('../../lights/Light.js').Light>} lights @param {import('../../core/Object3D.js').Object3D} scene */ function ( lights, scene, camera ) {",
|
|
6377
6515
|
fileName,
|
|
6378
6516
|
"WebGLShadowMap.render receiver",
|
|
6379
6517
|
);
|
|
@@ -6741,21 +6879,21 @@ class WebGLBackgroundPlaneMaterial extends ShaderMaterial {
|
|
|
6741
6879
|
transformed = replaceOne(
|
|
6742
6880
|
transformed,
|
|
6743
6881
|
"\tfunction getBackground( scene ) {",
|
|
6744
|
-
"\t/** @param {
|
|
6882
|
+
"\t/** @param {import('../../core/Object3D.js').Object3D} scene */\n\tfunction getBackground( scene ) {",
|
|
6745
6883
|
fileName,
|
|
6746
6884
|
"WebGLBackground background scene input",
|
|
6747
6885
|
);
|
|
6748
6886
|
transformed = replaceOne(
|
|
6749
6887
|
transformed,
|
|
6750
6888
|
"\tfunction render( scene ) {",
|
|
6751
|
-
"\t/** @param {
|
|
6889
|
+
"\t/** @param {import('../../core/Object3D.js').Object3D} scene */\n\tfunction render( scene ) {",
|
|
6752
6890
|
fileName,
|
|
6753
6891
|
"WebGLBackground scene input",
|
|
6754
6892
|
);
|
|
6755
6893
|
transformed = replaceOne(
|
|
6756
6894
|
transformed,
|
|
6757
6895
|
"\tfunction addToRenderList( renderList, scene ) {",
|
|
6758
|
-
"\t/** @param {
|
|
6896
|
+
"\t/** @param {import('../../core/Object3D.js').Object3D} scene */\n\tfunction addToRenderList( renderList, scene ) {",
|
|
6759
6897
|
fileName,
|
|
6760
6898
|
"WebGLBackground render-list scene input",
|
|
6761
6899
|
);
|
|
@@ -7092,6 +7230,15 @@ class WebGLBackgroundPlaneMaterial extends ShaderMaterial {
|
|
|
7092
7230
|
backgroundRotation: "uniformMatrix3",
|
|
7093
7231
|
uvTransform: "uniformMatrix3",
|
|
7094
7232
|
});
|
|
7233
|
+
// The renderer renders any Object3D (WebGLRenderer.render states
|
|
7234
|
+
// `@param {Object3D} scene`), so the scene inputs above state Object3D.
|
|
7235
|
+
// Only a Scene has a background: each read sits behind
|
|
7236
|
+
// `scene.isScene === true`, or behind a background only a Scene yields,
|
|
7237
|
+
// and names the Scene it reads.
|
|
7238
|
+
transformed = transformed.replaceAll(
|
|
7239
|
+
"scene.background",
|
|
7240
|
+
"/** @type {Scene} */ ( scene ).background",
|
|
7241
|
+
);
|
|
7095
7242
|
}
|
|
7096
7243
|
if (normalized.endsWith("/three/src/renderers/shaders/UniformsLib.js")) {
|
|
7097
7244
|
transformed = transformUniformsLib(transformed, fileName, replaceOne);
|
|
@@ -8511,17 +8658,6 @@ function WebGLProperties() {
|
|
|
8511
8658
|
|
|
8512
8659
|
\t}
|
|
8513
8660
|
|
|
8514
|
-
\t/**
|
|
8515
|
-
\t * @param {WebGLPropertyOwner} object
|
|
8516
|
-
\t * @param {keyof NativeWebGLPropertyBag} key
|
|
8517
|
-
\t * @param {NativeWebGLPropertyBag[keyof NativeWebGLPropertyBag]} value
|
|
8518
|
-
\t */
|
|
8519
|
-
\tfunction update( object, key, value ) {
|
|
8520
|
-
|
|
8521
|
-
\t\tget( object )[ key ] = value;
|
|
8522
|
-
|
|
8523
|
-
\t}
|
|
8524
|
-
|
|
8525
8661
|
\tfunction dispose() {
|
|
8526
8662
|
|
|
8527
8663
|
\t\tmaterials.clear();
|
|
@@ -8533,7 +8669,12 @@ function WebGLProperties() {
|
|
|
8533
8669
|
|
|
8534
8670
|
\t}
|
|
8535
8671
|
|
|
8536
|
-
\
|
|
8672
|
+
\t// Three's \`update( object, key, value )\` is left out: nothing in three
|
|
8673
|
+
\t// calls it, and its \`get( object )[ key ] = value\` stores a union of every
|
|
8674
|
+
\t// slot's type into the one slot \`key\` names. TypeScript rejects that store
|
|
8675
|
+
\t// (the target is \`never\`), and geatsc certifies no conversion from the
|
|
8676
|
+
\t// union into a single slot, so the C++ emitter refused the body.
|
|
8677
|
+
\treturn { has, get, remove, dispose };
|
|
8537
8678
|
|
|
8538
8679
|
}
|
|
8539
8680
|
|
|
@@ -9238,7 +9379,7 @@ function WebGLRenderState( extensions ) {`,
|
|
|
9238
9379
|
transformed = replaceOne(
|
|
9239
9380
|
transformed,
|
|
9240
9381
|
"\tfunction get( scene, renderCallDepth = 0 ) {",
|
|
9241
|
-
"\t/** @param {import('../../
|
|
9382
|
+
"\t/** @param {import('../../core/Object3D.js').Object3D} scene @param {number} [renderCallDepth=0] */\n\tfunction get( scene, renderCallDepth = 0 ) {",
|
|
9242
9383
|
fileName,
|
|
9243
9384
|
"WebGLRenderStates lookup inputs",
|
|
9244
9385
|
);
|
|
@@ -328,6 +328,7 @@ static constexpr GLenum GL_UNSIGNED_INT = 0x1405;
|
|
|
328
328
|
static constexpr GLenum GL_RGBA_VALUE = 0x1908;
|
|
329
329
|
static constexpr GLenum GL_VIEWPORT_VALUE = 0x0BA2;
|
|
330
330
|
static constexpr GLenum GL_FRAMEBUFFER_BINDING_VALUE = 0x8CA6;
|
|
331
|
+
static constexpr GLenum GL_INFO_LOG_LENGTH_VALUE = 0x8B84;
|
|
331
332
|
|
|
332
333
|
using PFNEGLGETPROCADDRESS = void *(*)(const char *);
|
|
333
334
|
using PFNEGLGETPLATFORMDISPLAYEXTPROC = EGLDisplay (*)(EGLenum, void *, const EGLint *);
|
|
@@ -346,6 +347,10 @@ using PFNEGLSWAPINTERVALPROC = EGLBoolean (*)(EGLDisplay, EGLint);
|
|
|
346
347
|
using PFNGLACTIVETEXTUREPROC = void (*)(GLenum);
|
|
347
348
|
using PFNGLATTACHSHADERPROC = void (*)(GLuint, GLuint);
|
|
348
349
|
using PFNGLBINDBUFFERPROC = void (*)(GLenum, GLuint);
|
|
350
|
+
using PFNGLBINDBUFFERBASEPROC = void (*)(GLenum, GLuint, GLuint);
|
|
351
|
+
using PFNGLBINDBUFFERRANGEPROC = void (*)(GLenum, GLuint, GLuint, GLintptr, GLsizeiptr);
|
|
352
|
+
using PFNGLGETUNIFORMBLOCKINDEXPROC = GLuint (*)(GLuint, const char *);
|
|
353
|
+
using PFNGLUNIFORMBLOCKBINDINGPROC = void (*)(GLuint, GLuint, GLuint);
|
|
349
354
|
using PFNGLBINDFRAMEBUFFERPROC = void (*)(GLenum, GLuint);
|
|
350
355
|
using PFNGLBINDRENDERBUFFERPROC = void (*)(GLenum, GLuint);
|
|
351
356
|
using PFNGLBINDTEXTUREPROC = void (*)(GLenum, GLuint);
|
|
@@ -402,6 +407,7 @@ using PFNGLGETINTEGERVPROC = void (*)(GLenum, GLint *);
|
|
|
402
407
|
using PFNGLGETPROGRAMIVPROC = void (*)(GLuint, GLenum, GLint *);
|
|
403
408
|
using PFNGLGETSHADERIVPROC = void (*)(GLuint, GLenum, GLint *);
|
|
404
409
|
using PFNGLGETSHADERINFOLOGPROC = void (*)(GLuint, GLsizei, GLsizei *, GLchar *);
|
|
410
|
+
using PFNGLGETPROGRAMINFOLOGPROC = void (*)(GLuint, GLsizei, GLsizei *, GLchar *);
|
|
405
411
|
using PFNGLGETSTRINGPROC = const unsigned char *(*)(GLenum);
|
|
406
412
|
using PFNGLGETUNIFORMLOCATIONPROC = GLint (*)(GLuint, const GLchar *);
|
|
407
413
|
using PFNGLLINEWIDTHPROC = void (*)(GLfloat);
|
|
@@ -493,6 +499,10 @@ struct AngleWebGLState {
|
|
|
493
499
|
PFNGLACTIVETEXTUREPROC glActiveTexture = nullptr;
|
|
494
500
|
PFNGLATTACHSHADERPROC glAttachShader = nullptr;
|
|
495
501
|
PFNGLBINDBUFFERPROC glBindBuffer = nullptr;
|
|
502
|
+
PFNGLBINDBUFFERBASEPROC glBindBufferBase = nullptr;
|
|
503
|
+
PFNGLBINDBUFFERRANGEPROC glBindBufferRange = nullptr;
|
|
504
|
+
PFNGLGETUNIFORMBLOCKINDEXPROC glGetUniformBlockIndex = nullptr;
|
|
505
|
+
PFNGLUNIFORMBLOCKBINDINGPROC glUniformBlockBinding = nullptr;
|
|
496
506
|
PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer = nullptr;
|
|
497
507
|
PFNGLBINDRENDERBUFFERPROC glBindRenderbuffer = nullptr;
|
|
498
508
|
PFNGLBINDTEXTUREPROC glBindTexture = nullptr;
|
|
@@ -549,6 +559,7 @@ struct AngleWebGLState {
|
|
|
549
559
|
PFNGLGETPROGRAMIVPROC glGetProgramiv = nullptr;
|
|
550
560
|
PFNGLGETSHADERIVPROC glGetShaderiv = nullptr;
|
|
551
561
|
PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog = nullptr;
|
|
562
|
+
PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog = nullptr;
|
|
552
563
|
PFNGLGETSTRINGPROC glGetString = nullptr;
|
|
553
564
|
PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation = nullptr;
|
|
554
565
|
PFNGLLINEWIDTHPROC glLineWidth = nullptr;
|
|
@@ -627,6 +638,10 @@ struct AngleWebGLState {
|
|
|
627
638
|
};
|
|
628
639
|
|
|
629
640
|
static AngleWebGLState gWebGL;
|
|
641
|
+
// Vertical sync as the program chose it (nativeWebGLSetVsync): 1 on, 0 off, -1 not chosen
|
|
642
|
+
// (then GEA_ANGLE_SWAP_INTERVAL, else 0; see makeCurrent).
|
|
643
|
+
static int gVsyncChoice = -1;
|
|
644
|
+
extern "C" void gea_three_webgl_set_vsync(double on) { gVsyncChoice = on != 0 ? 1 : 0; }
|
|
630
645
|
static GLenum hostReadbackError = 0;
|
|
631
646
|
static std::chrono::steady_clock::time_point gProfileSizeSync;
|
|
632
647
|
static bool gProfileSizeSyncPending = false;
|
|
@@ -942,9 +957,19 @@ static bool makeCurrent(const char *label) {
|
|
|
942
957
|
// reintroduced because the layer still syncs its own present.
|
|
943
958
|
// `GEA_ANGLE_SWAP_INTERVAL` overrides it (set `1` to restore the old
|
|
944
959
|
// double-paced behaviour) so both arms can be measured from one binary.
|
|
960
|
+
// A program's choice (nativeWebGLSetVsync) wins: off is interval 0; on is
|
|
961
|
+
// interval 1 where nothing else paces the frames (a desktop window with no
|
|
962
|
+
// display link), and the default above on Apple platforms, where the display
|
|
963
|
+
// link and the layer's own sync already do.
|
|
945
964
|
if (gWebGL.eglSwapInterval) {
|
|
946
965
|
const char *requested = std::getenv("GEA_ANGLE_SWAP_INTERVAL");
|
|
947
|
-
const EGLint
|
|
966
|
+
const EGLint fallback = requested ? static_cast<EGLint>(std::atoi(requested)) : 0;
|
|
967
|
+
#if defined(__APPLE__)
|
|
968
|
+
const EGLint paced = fallback;
|
|
969
|
+
#else
|
|
970
|
+
const EGLint paced = 1;
|
|
971
|
+
#endif
|
|
972
|
+
const EGLint interval = gVsyncChoice == 0 ? 0 : gVsyncChoice == 1 ? paced : fallback;
|
|
948
973
|
gWebGL.eglSwapInterval(gWebGL.display, interval);
|
|
949
974
|
}
|
|
950
975
|
if (gWebGL.eglMakeCurrent(gWebGL.display, gWebGL.surface, gWebGL.surface, gWebGL.context) == EGL_FALSE_VALUE) {
|
|
@@ -1013,6 +1038,10 @@ static bool loadGlSymbols() {
|
|
|
1013
1038
|
LOAD_GL(glActiveTexture, PFNGLACTIVETEXTUREPROC)
|
|
1014
1039
|
LOAD_GL(glAttachShader, PFNGLATTACHSHADERPROC)
|
|
1015
1040
|
LOAD_GL(glBindBuffer, PFNGLBINDBUFFERPROC)
|
|
1041
|
+
LOAD_GL(glBindBufferBase, PFNGLBINDBUFFERBASEPROC)
|
|
1042
|
+
LOAD_GL(glBindBufferRange, PFNGLBINDBUFFERRANGEPROC)
|
|
1043
|
+
LOAD_GL(glGetUniformBlockIndex, PFNGLGETUNIFORMBLOCKINDEXPROC)
|
|
1044
|
+
LOAD_GL(glUniformBlockBinding, PFNGLUNIFORMBLOCKBINDINGPROC)
|
|
1016
1045
|
LOAD_GL(glBindFramebuffer, PFNGLBINDFRAMEBUFFERPROC)
|
|
1017
1046
|
LOAD_GL(glBindRenderbuffer, PFNGLBINDRENDERBUFFERPROC)
|
|
1018
1047
|
LOAD_GL(glBindTexture, PFNGLBINDTEXTUREPROC)
|
|
@@ -1069,6 +1098,7 @@ static bool loadGlSymbols() {
|
|
|
1069
1098
|
LOAD_GL(glGetProgramiv, PFNGLGETPROGRAMIVPROC)
|
|
1070
1099
|
LOAD_GL(glGetShaderiv, PFNGLGETSHADERIVPROC)
|
|
1071
1100
|
LOAD_GL(glGetShaderInfoLog, PFNGLGETSHADERINFOLOGPROC)
|
|
1101
|
+
LOAD_GL(glGetProgramInfoLog, PFNGLGETPROGRAMINFOLOGPROC)
|
|
1072
1102
|
LOAD_GL(glGetString, PFNGLGETSTRINGPROC)
|
|
1073
1103
|
LOAD_GL(glGetUniformLocation, PFNGLGETUNIFORMLOCATIONPROC)
|
|
1074
1104
|
LOAD_GL(glLineWidth, PFNGLLINEWIDTHPROC)
|
|
@@ -2046,6 +2076,28 @@ extern "C" double gea_three_webgl_get_program_parameter(double program, double p
|
|
|
2046
2076
|
gWebGL.glGetProgramiv(asGLuint(program), asGLenum(pname), &value);
|
|
2047
2077
|
return value;
|
|
2048
2078
|
}
|
|
2079
|
+
// The driver's compile or link log, as WebGL's getShaderInfoLog and
|
|
2080
|
+
// getProgramInfoLog return it.
|
|
2081
|
+
static std::string geaInfoLog(double object, PFNGLGETSHADERIVPROC queryLength, PFNGLGETSHADERINFOLOGPROC readLog) {
|
|
2082
|
+
GLint length = 0;
|
|
2083
|
+
queryLength(asGLuint(object), GL_INFO_LOG_LENGTH_VALUE, &length);
|
|
2084
|
+
if (length <= 0) return std::string();
|
|
2085
|
+
std::string log(static_cast<std::size_t>(length), '\0');
|
|
2086
|
+
GLsizei written = 0;
|
|
2087
|
+
readLog(asGLuint(object), length, &written, log.data());
|
|
2088
|
+
log.resize(static_cast<std::size_t>(std::clamp(written, 0, length)));
|
|
2089
|
+
return log;
|
|
2090
|
+
}
|
|
2091
|
+
extern "C" std::string gea_three_webgl_get_shader_info_log(double shader) {
|
|
2092
|
+
geaTrapCheck("gea_three_webgl_get_shader_info_log");
|
|
2093
|
+
if (!ensureWebGLCurrent("getShaderInfoLog")) return std::string();
|
|
2094
|
+
return geaInfoLog(shader, gWebGL.glGetShaderiv, gWebGL.glGetShaderInfoLog);
|
|
2095
|
+
}
|
|
2096
|
+
extern "C" std::string gea_three_webgl_get_program_info_log(double program) {
|
|
2097
|
+
geaTrapCheck("gea_three_webgl_get_program_info_log");
|
|
2098
|
+
if (!ensureWebGLCurrent("getProgramInfoLog")) return std::string();
|
|
2099
|
+
return geaInfoLog(program, gWebGL.glGetProgramiv, gWebGL.glGetProgramInfoLog);
|
|
2100
|
+
}
|
|
2049
2101
|
extern "C" void gea_three_webgl_delete_program(double program) {
|
|
2050
2102
|
geaTrapCheck("gea_three_webgl_delete_program"); GEA_WEBGL_VOID("deleteProgram"); gWebGL.glDeleteProgram(asGLuint(program)); }
|
|
2051
2103
|
extern "C" void gea_three_webgl_use_program(double program) {
|
|
@@ -2362,6 +2414,23 @@ extern "C" void gea_three_webgl_draw_arrays(double mode, double first, double co
|
|
|
2362
2414
|
extern "C" void gea_three_webgl_vertex_attrib_divisor(double index, double divisor) {
|
|
2363
2415
|
geaTrapCheck("gea_three_webgl_vertex_attrib_divisor"); GEA_WEBGL_VOID("vertexAttribDivisor");
|
|
2364
2416
|
gWebGL.glVertexAttribDivisor(asGLuint(index), asGLuint(divisor)); }
|
|
2417
|
+
// Indexed binds also set the target's generic binding. The host shadows only the
|
|
2418
|
+
// ARRAY_BUFFER and COPY_READ/WRITE bindings (bindNativeBuffer), and the uniform
|
|
2419
|
+
// staging path queries UNIFORM_BUFFER_BINDING instead of shadowing it, so neither
|
|
2420
|
+
// call needs to update a shadow.
|
|
2421
|
+
extern "C" void gea_three_webgl_bind_buffer_base(double target, double index, double buffer) {
|
|
2422
|
+
geaTrapCheck("gea_three_webgl_bind_buffer_base"); GEA_WEBGL_VOID("bindBufferBase");
|
|
2423
|
+
gWebGL.glBindBufferBase(asGLenum(target), asGLuint(index), asGLuint(buffer)); }
|
|
2424
|
+
extern "C" void gea_three_webgl_bind_buffer_range(double target, double index, double buffer, double offset, double size) {
|
|
2425
|
+
geaTrapCheck("gea_three_webgl_bind_buffer_range"); GEA_WEBGL_VOID("bindBufferRange");
|
|
2426
|
+
gWebGL.glBindBufferRange(asGLenum(target), asGLuint(index), asGLuint(buffer),
|
|
2427
|
+
static_cast<GLintptr>(offset), static_cast<GLsizeiptr>(size)); }
|
|
2428
|
+
extern "C" double gea_three_webgl_get_uniform_block_index(double program, std::string name) {
|
|
2429
|
+
geaTrapCheck("gea_three_webgl_get_uniform_block_index"); GEA_WEBGL_DOUBLE("getUniformBlockIndex");
|
|
2430
|
+
return gWebGL.glGetUniformBlockIndex(asGLuint(program), name.c_str()); }
|
|
2431
|
+
extern "C" void gea_three_webgl_uniform_block_binding(double program, double blockIndex, double binding) {
|
|
2432
|
+
geaTrapCheck("gea_three_webgl_uniform_block_binding"); GEA_WEBGL_VOID("uniformBlockBinding");
|
|
2433
|
+
gWebGL.glUniformBlockBinding(asGLuint(program), asGLuint(blockIndex), asGLuint(binding)); }
|
|
2365
2434
|
extern "C" void gea_three_webgl_draw_elements_instanced(double mode, double count, double type, double offset, double instanceCount) {
|
|
2366
2435
|
geaTrapCheck("gea_three_webgl_draw_elements_instanced"); GEA_WEBGL_VOID("drawElementsInstanced");
|
|
2367
2436
|
gWebGL.glDrawElementsInstanced(asGLenum(mode), asGLsizei(count), asGLenum(type),
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// Files an app ships in its Resources folder, read whole into a typed array the
|
|
3
|
+
// program allocated (src/nativeResources.ts). Resources is the app bundle's
|
|
4
|
+
// resource directory on macOS and iOS, and the Resources folder beside the
|
|
5
|
+
// executable elsewhere (where the desktop targets stage an app's
|
|
6
|
+
// nativeResources); GEA_RESOURCE_DIR names another directory.
|
|
7
|
+
//
|
|
8
|
+
// A name is relative to that directory, with '/' between its parts; an
|
|
9
|
+
// absolute name, a backslash or a '..' part is refused, so a name never reaches
|
|
10
|
+
// outside it.
|
|
11
|
+
#include <cstdint>
|
|
12
|
+
#include <cstdio>
|
|
13
|
+
#include <cstdlib>
|
|
14
|
+
#include <string>
|
|
15
|
+
|
|
16
|
+
#if defined(_WIN32)
|
|
17
|
+
#include <windows.h>
|
|
18
|
+
#elif defined(__APPLE__)
|
|
19
|
+
#import <Foundation/Foundation.h>
|
|
20
|
+
#else
|
|
21
|
+
#include <unistd.h>
|
|
22
|
+
#include <climits>
|
|
23
|
+
#endif
|
|
24
|
+
|
|
25
|
+
namespace {
|
|
26
|
+
|
|
27
|
+
bool geaResourceNameValid(const std::string &name) {
|
|
28
|
+
if (name.empty() || name.front() == '/' || name.find('\\') != std::string::npos || name.find(':') != std::string::npos) return false;
|
|
29
|
+
size_t start = 0;
|
|
30
|
+
while (start <= name.size()) {
|
|
31
|
+
const size_t end = name.find('/', start);
|
|
32
|
+
const std::string part = name.substr(start, end == std::string::npos ? std::string::npos : end - start);
|
|
33
|
+
if (part.empty() || part == "." || part == "..") return false;
|
|
34
|
+
if (end == std::string::npos) break;
|
|
35
|
+
start = end + 1;
|
|
36
|
+
}
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
#if defined(_WIN32)
|
|
41
|
+
const std::wstring &geaResourceDirectory() {
|
|
42
|
+
static const std::wstring directory = [] {
|
|
43
|
+
wchar_t value[MAX_PATH] = {};
|
|
44
|
+
const DWORD n = GetEnvironmentVariableW(L"GEA_RESOURCE_DIR", value, MAX_PATH);
|
|
45
|
+
if (n > 0 && n < MAX_PATH) return std::wstring(value);
|
|
46
|
+
wchar_t module[MAX_PATH] = {};
|
|
47
|
+
const DWORD length = GetModuleFileNameW(nullptr, module, MAX_PATH);
|
|
48
|
+
std::wstring path(module, length < MAX_PATH ? length : 0);
|
|
49
|
+
const size_t slash = path.find_last_of(L"\\/");
|
|
50
|
+
return slash == std::wstring::npos ? std::wstring() : path.substr(0, slash) + L"\\Resources";
|
|
51
|
+
}();
|
|
52
|
+
return directory;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
FILE *geaOpenResource(const std::string &name) {
|
|
56
|
+
if (!geaResourceNameValid(name) || geaResourceDirectory().empty()) return nullptr;
|
|
57
|
+
const int length = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, name.data(), static_cast<int>(name.size()), nullptr, 0);
|
|
58
|
+
if (length <= 0) return nullptr;
|
|
59
|
+
std::wstring relative(static_cast<size_t>(length), L'\0');
|
|
60
|
+
MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, name.data(), static_cast<int>(name.size()), relative.data(), length);
|
|
61
|
+
for (wchar_t &c : relative) if (c == L'/') c = L'\\';
|
|
62
|
+
FILE *file = nullptr;
|
|
63
|
+
return _wfopen_s(&file, (geaResourceDirectory() + L"\\" + relative).c_str(), L"rb") == 0 ? file : nullptr;
|
|
64
|
+
}
|
|
65
|
+
#else
|
|
66
|
+
const std::string &geaResourceDirectory() {
|
|
67
|
+
static const std::string directory = [] {
|
|
68
|
+
if (const char *value = std::getenv("GEA_RESOURCE_DIR")) return std::string(value);
|
|
69
|
+
#if defined(__APPLE__)
|
|
70
|
+
@autoreleasepool {
|
|
71
|
+
NSString *resources = [[NSBundle mainBundle] resourcePath];
|
|
72
|
+
return resources ? std::string(resources.UTF8String) : std::string();
|
|
73
|
+
}
|
|
74
|
+
#else
|
|
75
|
+
char path[PATH_MAX] = {};
|
|
76
|
+
const ssize_t length = readlink("/proc/self/exe", path, sizeof(path) - 1);
|
|
77
|
+
if (length <= 0) return std::string();
|
|
78
|
+
const std::string executable(path, static_cast<size_t>(length));
|
|
79
|
+
const size_t slash = executable.find_last_of('/');
|
|
80
|
+
return slash == std::string::npos ? std::string() : executable.substr(0, slash) + "/Resources";
|
|
81
|
+
#endif
|
|
82
|
+
}();
|
|
83
|
+
return directory;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
FILE *geaOpenResource(const std::string &name) {
|
|
87
|
+
if (!geaResourceNameValid(name) || geaResourceDirectory().empty()) return nullptr;
|
|
88
|
+
return std::fopen((geaResourceDirectory() + "/" + name).c_str(), "rb");
|
|
89
|
+
}
|
|
90
|
+
#endif
|
|
91
|
+
|
|
92
|
+
long long geaResourceLength(FILE *file) {
|
|
93
|
+
if (std::fseek(file, 0, SEEK_END) != 0) return -1;
|
|
94
|
+
#if defined(_WIN32)
|
|
95
|
+
const long long length = _ftelli64(file);
|
|
96
|
+
#else
|
|
97
|
+
const long long length = static_cast<long long>(ftello(file));
|
|
98
|
+
#endif
|
|
99
|
+
if (length < 0 || std::fseek(file, 0, SEEK_SET) != 0) return -1;
|
|
100
|
+
return length;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
} // namespace
|
|
104
|
+
|
|
105
|
+
// The file's size in bytes, or -1 when it is missing or the name is refused.
|
|
106
|
+
extern "C" double gea_three_resource_size(std::string name) {
|
|
107
|
+
FILE *file = geaOpenResource(name);
|
|
108
|
+
if (!file) return -1;
|
|
109
|
+
const long long length = geaResourceLength(file);
|
|
110
|
+
std::fclose(file);
|
|
111
|
+
return static_cast<double>(length);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Reads the whole file into `bytes` when it holds exactly `byteLength` bytes.
|
|
115
|
+
// Answers the bytes read, or -1 (missing file, refused name, other size, short read).
|
|
116
|
+
extern "C" double gea_three_resource_read_bytes(std::string name, void *bytes, double byteLength) {
|
|
117
|
+
if (!bytes && byteLength != 0) return -1;
|
|
118
|
+
FILE *file = geaOpenResource(name);
|
|
119
|
+
if (!file) return -1;
|
|
120
|
+
const long long length = geaResourceLength(file);
|
|
121
|
+
double result = -1;
|
|
122
|
+
if (length >= 0 && static_cast<double>(length) == byteLength) {
|
|
123
|
+
const size_t wanted = static_cast<size_t>(length);
|
|
124
|
+
if (wanted == 0 || std::fread(bytes, 1, wanted, file) == wanted) result = static_cast<double>(length);
|
|
125
|
+
}
|
|
126
|
+
std::fclose(file);
|
|
127
|
+
return result;
|
|
128
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@geastack/native-webgl-angle",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.16",
|
|
4
4
|
"description": "Typed native WebGL compatibility layer backed by ANGLE/Metal",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
"./nativeWebXRManager": "./src/nativeWebXRManager.ts",
|
|
22
22
|
"./troika-three-text": "./src/troika-three-text.ts",
|
|
23
23
|
"./inflate": "./src/inflate.ts",
|
|
24
|
+
"./nativeResources": "./src/nativeResources.ts",
|
|
24
25
|
"./geatsc-plugin": "./geatsc-plugin.mjs",
|
|
25
26
|
"./native/*": "./native/*",
|
|
26
27
|
"./package.json": "./package.json",
|
|
@@ -53,7 +54,7 @@
|
|
|
53
54
|
"test:host-effects": "node test/native-host-effects-contract.test.mjs",
|
|
54
55
|
"test:allocation-contracts": "node test/render-sort-contract.test.mjs && node test/upload-array-contract.test.mjs && node test/draw-dispatch-contract.test.mjs && node test/native-upload-transport.test.mjs && node test/fixed-uniform-contract.test.mjs && node test/uniform-binding-contract.test.mjs && node test/buffer-streaming-contract.test.mjs",
|
|
55
56
|
"check": "tsc -p tsconfig.json --noEmit",
|
|
56
|
-
"test": "node test/native-blending-contract.test.mjs && node test/native-transform-contract.test.mjs && node test/troika-three-text.test.mjs && node test/typed-void-contract.test.mjs && node test/instancing-transport-contract.test.mjs && node test/automatic-instancing-contract.test.mjs && node test/jsdoc-fold-contract.test.mjs && node test/gea-native-declaration.test.mjs",
|
|
57
|
+
"test": "node test/native-blending-contract.test.mjs && node test/native-transform-contract.test.mjs && node test/troika-three-text.test.mjs && node test/typed-void-contract.test.mjs && node test/info-log-contract.test.mjs && node test/resource-host-contract.test.mjs && node test/instancing-transport-contract.test.mjs && node test/automatic-instancing-contract.test.mjs && node test/jsdoc-fold-contract.test.mjs && node test/gea-native-declaration.test.mjs && node test/native-host-effects-contract.test.mjs && node test/uniform-buffer-contract.test.mjs",
|
|
57
58
|
"test:package": "node --experimental-vm-modules test/package.test.mjs"
|
|
58
59
|
},
|
|
59
60
|
"dependencies": {
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// Files the app ships in its Resources folder (native/resource_host.mm): the
|
|
2
|
+
// app bundle's resource directory on macOS, the Resources folder beside the
|
|
3
|
+
// executable elsewhere. Names are relative to it, with '/' between parts.
|
|
4
|
+
|
|
5
|
+
/** @gea-host-inert Reads its argument and the file system only; never calls back into script. */
|
|
6
|
+
declare function threeResourceSize(name: string): number
|
|
7
|
+
/** @gea-host-typed-array-element-writes Stores the file's bytes into the destination typed array's elements only; no other property of any object, no callbacks. */
|
|
8
|
+
declare function threeResourceRead(name: string, destination: Uint8Array): number
|
|
9
|
+
|
|
10
|
+
/** The size in bytes of a file in Resources, or -1 when there is none. */
|
|
11
|
+
export function nativeResourceSize(name: string): number {
|
|
12
|
+
return threeResourceSize(name)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/** Reads a whole file from Resources; throws when it is missing or cannot be read. */
|
|
16
|
+
export function nativeReadResource(name: string): Uint8Array {
|
|
17
|
+
const size = threeResourceSize(name)
|
|
18
|
+
if (size < 0) throw new Error(`Missing resource: ${name}`)
|
|
19
|
+
const bytes = new Uint8Array(size)
|
|
20
|
+
if (threeResourceRead(name, bytes) !== size) throw new Error(`Could not read resource: ${name}`)
|
|
21
|
+
return bytes
|
|
22
|
+
}
|
package/src/nativeWebGL.ts
CHANGED
|
@@ -47,6 +47,10 @@ import {
|
|
|
47
47
|
nativeWebGLDrawArraysInstanced,
|
|
48
48
|
nativeWebGLDrawElementsInstanced,
|
|
49
49
|
nativeWebGLVertexAttribDivisor,
|
|
50
|
+
nativeWebGLBindBufferBase,
|
|
51
|
+
nativeWebGLBindBufferRange,
|
|
52
|
+
nativeWebGLGetUniformBlockIndex,
|
|
53
|
+
nativeWebGLUniformBlockBinding,
|
|
50
54
|
nativeWebGLDrawBuffers,
|
|
51
55
|
nativeWebGLDrawElements,
|
|
52
56
|
nativeWebGLEnable,
|
|
@@ -59,7 +63,9 @@ import {
|
|
|
59
63
|
nativeWebGLGetError,
|
|
60
64
|
nativeWebGLGetActiveAttribInfo,
|
|
61
65
|
nativeWebGLGetActiveUniformInfo,
|
|
66
|
+
nativeWebGLGetProgramInfoLog,
|
|
62
67
|
nativeWebGLGetProgramParameter,
|
|
68
|
+
nativeWebGLGetShaderInfoLog,
|
|
63
69
|
nativeWebGLGetShaderParameter,
|
|
64
70
|
nativeWebGLGetUniformLocation,
|
|
65
71
|
nativeWebGLHeight,
|
|
@@ -1036,7 +1042,7 @@ export class NativeWebGL2RenderingContext {
|
|
|
1036
1042
|
if (pname === this.DELETE_STATUS) return false
|
|
1037
1043
|
return nativeWebGLGetShaderParameter(nativeHandle(shader), pname) !== 0
|
|
1038
1044
|
}
|
|
1039
|
-
getShaderInfoLog(
|
|
1045
|
+
getShaderInfoLog(shader: NativeShader): string { return nativeWebGLGetShaderInfoLog(nativeHandle(shader)) }
|
|
1040
1046
|
getShaderSource(shader: NativeShader): string { return shaderSourceFor(shader) }
|
|
1041
1047
|
deleteShader(shader: NativeShader | null): void { if (shader) { shaderSourceByHandle.delete(nativeHandle(shader)); nativeWebGLDeleteShader(nativeHandle(shader)) } }
|
|
1042
1048
|
|
|
@@ -1065,7 +1071,7 @@ export class NativeWebGL2RenderingContext {
|
|
|
1065
1071
|
if (pname === this.VALIDATE_STATUS) return true
|
|
1066
1072
|
return nativeWebGLGetProgramParameter(nativeHandle(program), pname) !== 0
|
|
1067
1073
|
}
|
|
1068
|
-
getProgramInfoLog(
|
|
1074
|
+
getProgramInfoLog(program: NativeProgram): string { return nativeWebGLGetProgramInfoLog(nativeHandle(program)) }
|
|
1069
1075
|
deleteProgram(program: NativeProgram | null): void { if (program) { nativeWebGLDeleteProgram(nativeHandle(program)) } }
|
|
1070
1076
|
validateProgram(_program: NativeProgram): void {}
|
|
1071
1077
|
getAttachedShaders(program: NativeProgram): NativeShader[] { return program.shaders }
|
|
@@ -1258,10 +1264,18 @@ export class NativeWebGL2RenderingContext {
|
|
|
1258
1264
|
getVertexAttrib(_index: number, _pname: number): number { return 0 }
|
|
1259
1265
|
getVertexAttribOffset(_index: number, _pname: number): number { return 0 }
|
|
1260
1266
|
getUniform(_program: NativeProgram | null, _location: NativeHandle | null): number { return 0 }
|
|
1261
|
-
getUniformBlockIndex(
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1267
|
+
getUniformBlockIndex(program: NativeProgram | null, uniformBlockName: string): number {
|
|
1268
|
+
return nativeWebGLGetUniformBlockIndex(nullableNativeHandle(program), uniformBlockName)
|
|
1269
|
+
}
|
|
1270
|
+
uniformBlockBinding(program: NativeProgram | null, uniformBlockIndex: number, uniformBlockBinding: number): void {
|
|
1271
|
+
nativeWebGLUniformBlockBinding(nullableNativeHandle(program), uniformBlockIndex, uniformBlockBinding)
|
|
1272
|
+
}
|
|
1273
|
+
bindBufferBase(target: number, index: number, buffer: NativeHandle | null): void {
|
|
1274
|
+
nativeWebGLBindBufferBase(target, index, nullableNativeHandle(buffer))
|
|
1275
|
+
}
|
|
1276
|
+
bindBufferRange(target: number, index: number, buffer: NativeHandle | null, offset: number, size: number): void {
|
|
1277
|
+
nativeWebGLBindBufferRange(target, index, nullableNativeHandle(buffer), offset, size)
|
|
1278
|
+
}
|
|
1265
1279
|
fenceSync(_condition: number, _flags: number): NativeHandle | null {
|
|
1266
1280
|
const sync = threeWebGLFenceSync()
|
|
1267
1281
|
return sync ? createHandle('sync', sync) : null
|
package/src/nativeWebGLHost.ts
CHANGED
|
@@ -35,6 +35,16 @@ export function nativeWebGLSwap(): void {
|
|
|
35
35
|
threeWebGLSwap()
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
/**
|
|
39
|
+
* Vertical sync from the next frame on. Off presents at once, so the frame rate shows what
|
|
40
|
+
* a frame costs. On paces presents to the display: interval 1 where nothing else paces the
|
|
41
|
+
* frames (a desktop window with no display link), the host's own pacing on Apple platforms,
|
|
42
|
+
* where a second waiter would only make frames miss refreshes.
|
|
43
|
+
*/
|
|
44
|
+
export function nativeWebGLSetVsync(on: boolean): void {
|
|
45
|
+
threeWebGLSetVsync(on ? 1 : 0)
|
|
46
|
+
}
|
|
47
|
+
|
|
38
48
|
// GPU time-elapsed timers (GL_EXT_disjoint_timer_query): begin returns a timer id (0 when
|
|
39
49
|
// unsupported), end closes the open timer, and result is the elapsed nanoseconds, or -1 while the
|
|
40
50
|
// GPU has not finished it. A timer is released once its result has been read.
|
|
@@ -88,12 +98,14 @@ export function nativeWebGLCreateShader(type: number): number { return threeWebG
|
|
|
88
98
|
export function nativeWebGLShaderSource(shader: number, source: string): void { threeWebGLShaderSource(shader, source) }
|
|
89
99
|
export function nativeWebGLCompileShader(shader: number): void { threeWebGLCompileShader(shader) }
|
|
90
100
|
export function nativeWebGLGetShaderParameter(shader: number, pname: number): number { return threeWebGLGetShaderParameter(shader, pname) }
|
|
101
|
+
export function nativeWebGLGetShaderInfoLog(shader: number): string { return threeWebGLGetShaderInfoLog(shader) }
|
|
91
102
|
export function nativeWebGLDeleteShader(shader: number): void { threeWebGLDeleteShader(shader) }
|
|
92
103
|
|
|
93
104
|
export function nativeWebGLCreateProgram(): number { return threeWebGLCreateProgram() }
|
|
94
105
|
export function nativeWebGLAttachShader(program: number, shader: number): void { threeWebGLAttachShader(program, shader) }
|
|
95
106
|
export function nativeWebGLLinkProgram(program: number): void { threeWebGLLinkProgram(program) }
|
|
96
107
|
export function nativeWebGLGetProgramParameter(program: number, pname: number): number { return threeWebGLGetProgramParameter(program, pname) }
|
|
108
|
+
export function nativeWebGLGetProgramInfoLog(program: number): string { return threeWebGLGetProgramInfoLog(program) }
|
|
97
109
|
export function nativeWebGLDeleteProgram(program: number): void { threeWebGLDeleteProgram(program) }
|
|
98
110
|
export function nativeWebGLUseProgram(program: number): void { threeWebGLUseProgram(program) }
|
|
99
111
|
export function nativeWebGLGetAttribLocation(program: number, name: string): number { return threeWebGLGetAttribLocation(program, name) }
|
|
@@ -187,6 +199,8 @@ declare function threeWebGLDevicePixelRatio(): number
|
|
|
187
199
|
/** Lifecycle entry: presents the native surface and may run platform hooks; not an inert call. */
|
|
188
200
|
declare function threeWebGLSwap(): void
|
|
189
201
|
/** @gea-host-inert Native state only; retains no script references and invokes no script. */
|
|
202
|
+
declare function threeWebGLSetVsync(on: number): void
|
|
203
|
+
/** @gea-host-inert Native state only; retains no script references and invokes no script. */
|
|
190
204
|
declare function threeAngleSmokeLog(message: string): void
|
|
191
205
|
/** @gea-host-inert Native state only; retains no script references and invokes no script. */
|
|
192
206
|
declare function threeKeyPressed(code: number): boolean
|
|
@@ -207,6 +221,8 @@ declare function threeWebGLCompileShader(shader: number): void
|
|
|
207
221
|
/** @gea-host-inert Native state only; retains no script references and invokes no script. */
|
|
208
222
|
declare function threeWebGLGetShaderParameter(shader: number, pname: number): number
|
|
209
223
|
/** @gea-host-inert Native state only; retains no script references and invokes no script. */
|
|
224
|
+
declare function threeWebGLGetShaderInfoLog(shader: number): string
|
|
225
|
+
/** @gea-host-inert Native state only; retains no script references and invokes no script. */
|
|
210
226
|
declare function threeWebGLDeleteShader(shader: number): void
|
|
211
227
|
/** @gea-host-inert Native state only; retains no script references and invokes no script. */
|
|
212
228
|
declare function threeWebGLCreateProgram(): number
|
|
@@ -217,6 +233,8 @@ declare function threeWebGLLinkProgram(program: number): void
|
|
|
217
233
|
/** @gea-host-inert Native state only; retains no script references and invokes no script. */
|
|
218
234
|
declare function threeWebGLGetProgramParameter(program: number, pname: number): number
|
|
219
235
|
/** @gea-host-inert Native state only; retains no script references and invokes no script. */
|
|
236
|
+
declare function threeWebGLGetProgramInfoLog(program: number): string
|
|
237
|
+
/** @gea-host-inert Native state only; retains no script references and invokes no script. */
|
|
220
238
|
declare function threeWebGLDeleteProgram(program: number): void
|
|
221
239
|
/** @gea-host-inert Native state only; retains no script references and invokes no script. */
|
|
222
240
|
declare function threeWebGLUseProgram(program: number): void
|
|
@@ -348,6 +366,23 @@ declare function threeWebGLGetError(): number
|
|
|
348
366
|
declare function threeNativeProfilePhase(phase: number): void
|
|
349
367
|
export function nativeProfilePhase(phase: number): void { threeNativeProfilePhase(phase) }
|
|
350
368
|
|
|
369
|
+
export function nativeWebGLBindBufferBase(target: number, index: number, buffer: number): void { threeWebGLBindBufferBase(target, index, buffer) }
|
|
370
|
+
/** @gea-host-inert Native state only; retains no script references and invokes no script. */
|
|
371
|
+
declare function threeWebGLBindBufferBase(target: number, index: number, buffer: number): void
|
|
372
|
+
export function nativeWebGLBindBufferRange(target: number, index: number, buffer: number, offset: number, size: number): void {
|
|
373
|
+
threeWebGLBindBufferRange(target, index, buffer, offset, size)
|
|
374
|
+
}
|
|
375
|
+
/** @gea-host-inert Native state only; retains no script references and invokes no script. */
|
|
376
|
+
declare function threeWebGLBindBufferRange(target: number, index: number, buffer: number, offset: number, size: number): void
|
|
377
|
+
export function nativeWebGLGetUniformBlockIndex(program: number, name: string): number { return threeWebGLGetUniformBlockIndex(program, name) }
|
|
378
|
+
/** @gea-host-inert Native state only; retains no script references and invokes no script. */
|
|
379
|
+
declare function threeWebGLGetUniformBlockIndex(program: number, name: string): number
|
|
380
|
+
export function nativeWebGLUniformBlockBinding(program: number, blockIndex: number, binding: number): void {
|
|
381
|
+
threeWebGLUniformBlockBinding(program, blockIndex, binding)
|
|
382
|
+
}
|
|
383
|
+
/** @gea-host-inert Native state only; retains no script references and invokes no script. */
|
|
384
|
+
declare function threeWebGLUniformBlockBinding(program: number, blockIndex: number, binding: number): void
|
|
385
|
+
|
|
351
386
|
export function nativeWebGLVertexAttribDivisor(index: number, divisor: number): void { threeWebGLVertexAttribDivisor(index, divisor) }
|
|
352
387
|
/** @gea-host-inert Native state only; retains no script references and invokes no script. */
|
|
353
388
|
declare function threeWebGLVertexAttribDivisor(index: number, divisor: number): void
|