@flighthq/texture 0.2.1-next.841.373388f → 0.3.0-next.1032.e2b99fc
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/dist/contract.d.ts +6 -0
- package/dist/contract.d.ts.map +1 -0
- package/dist/contract.js +6 -0
- package/dist/contract.js.map +1 -0
- package/dist/cubeTexture.d.ts +8 -8
- package/dist/cubeTexture.d.ts.map +1 -1
- package/dist/cubeTexture.js +22 -59
- package/dist/cubeTexture.js.map +1 -1
- package/dist/index.d.ts +1 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -4
- package/dist/index.js.map +1 -1
- package/dist/renderTexture.d.ts +3 -0
- package/dist/renderTexture.d.ts.map +1 -0
- package/dist/renderTexture.js +44 -0
- package/dist/renderTexture.js.map +1 -0
- package/dist/sampler.d.ts +1 -1
- package/dist/sampler.d.ts.map +1 -1
- package/dist/sampler.js +1 -1
- package/dist/sampler.js.map +1 -1
- package/dist/texture.d.ts +6 -3
- package/dist/texture.d.ts.map +1 -1
- package/dist/texture.js +120 -28
- package/dist/texture.js.map +1 -1
- package/dist/videoTexture.d.ts +12 -12
- package/dist/videoTexture.d.ts.map +1 -1
- package/dist/videoTexture.js +77 -92
- package/dist/videoTexture.js.map +1 -1
- package/package.json +8 -4
- package/src/cubeTexture.test.ts +31 -30
- package/src/renderTexture.test.ts +48 -0
- package/src/texture.test.ts +142 -22
- package/src/videoTexture.test.ts +21 -19
package/dist/videoTexture.d.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import type { Matrix3Like,
|
|
2
|
-
export declare function advanceVideoTexture(
|
|
3
|
-
export declare function cloneVideoTexture(source: Readonly<
|
|
4
|
-
export declare function copyVideoTexture(out:
|
|
5
|
-
export declare function createVideoTexture(source: VideoResource, opts?: Readonly<Partial<
|
|
6
|
-
export declare function getVideoTextureHeight(
|
|
7
|
-
export declare function getVideoTextureInverseUvMatrix(out: Matrix3Like,
|
|
8
|
-
export declare function getVideoTextureUvMatrix(out: Matrix3Like,
|
|
9
|
-
export declare function getVideoTextureWidth(
|
|
10
|
-
export declare function isVideoTextureFrameReady(
|
|
11
|
-
export declare function resetVideoTextureFrame(
|
|
12
|
-
export declare function setVideoTextureSource(
|
|
1
|
+
import type { Matrix3Like, Texture, TextureLike, VideoResource } from '@flighthq/types/contract';
|
|
2
|
+
export declare function advanceVideoTexture(texture: TextureLike): number;
|
|
3
|
+
export declare function cloneVideoTexture(source: Readonly<TextureLike>): Texture;
|
|
4
|
+
export declare function copyVideoTexture(out: TextureLike, source: Readonly<TextureLike>): void;
|
|
5
|
+
export declare function createVideoTexture(source: VideoResource, opts?: Readonly<Partial<TextureLike>>): Texture;
|
|
6
|
+
export declare function getVideoTextureHeight(texture: Readonly<TextureLike>): number;
|
|
7
|
+
export declare function getVideoTextureInverseUvMatrix(out: Matrix3Like, texture: Readonly<TextureLike>): void;
|
|
8
|
+
export declare function getVideoTextureUvMatrix(out: Matrix3Like, texture: Readonly<TextureLike>): void;
|
|
9
|
+
export declare function getVideoTextureWidth(texture: Readonly<TextureLike>): number;
|
|
10
|
+
export declare function isVideoTextureFrameReady(texture: Readonly<TextureLike>): boolean;
|
|
11
|
+
export declare function resetVideoTextureFrame(texture: TextureLike): void;
|
|
12
|
+
export declare function setVideoTextureSource(texture: TextureLike, source: VideoResource): void;
|
|
13
13
|
//# sourceMappingURL=videoTexture.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"videoTexture.d.ts","sourceRoot":"","sources":["../src/videoTexture.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"videoTexture.d.ts","sourceRoot":"","sources":["../src/videoTexture.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAiB,WAAW,EAAE,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAOhH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAOhE;AAGD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,QAAQ,CAAC,WAAW,CAAC,GAAG,OAAO,CAExE;AAGD,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,CAAC,WAAW,CAAC,GAAG,IAAI,CAEtF;AAKD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,aAAa,EAAE,IAAI,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,GAAG,OAAO,CAOxG;AAGD,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,QAAQ,CAAC,WAAW,CAAC,GAAG,MAAM,CAG5E;AAGD,wBAAgB,8BAA8B,CAAC,GAAG,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,CAAC,WAAW,CAAC,GAAG,IAAI,CAGrG;AAGD,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,CAAC,WAAW,CAAC,GAAG,IAAI,CAE9F;AAGD,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,QAAQ,CAAC,WAAW,CAAC,GAAG,MAAM,CAG3E;AAGD,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,QAAQ,CAAC,WAAW,CAAC,GAAG,OAAO,CAKhF;AAGD,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,CAIjE;AAID,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,aAAa,GAAG,IAAI,CAIvF"}
|
package/dist/videoTexture.js
CHANGED
|
@@ -1,113 +1,98 @@
|
|
|
1
|
-
import { createEntity } from '@flighthq/entity';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { getTextureUvMatrix } from './texture';
|
|
5
|
-
// Marks a fresh decoded frame
|
|
6
|
-
//
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
1
|
+
import { createEntity } from '@flighthq/entity/contract';
|
|
2
|
+
import { inverseMatrix3 } from '@flighthq/geometry/contract';
|
|
3
|
+
import { VideoTextureBackingKind } from '@flighthq/types/contract';
|
|
4
|
+
import { cloneTexture, copyTexture, createTexture, getTextureUvMatrix } from './texture';
|
|
5
|
+
// Marks a fresh decoded frame on a video-backed Texture. The ImageResource is the shared CPU-origin
|
|
6
|
+
// backing and owns the upload revision; Texture.version mirrors it as the sampled object's dirty-bit.
|
|
7
|
+
export function advanceVideoTexture(texture) {
|
|
8
|
+
const image = texture.storage.image;
|
|
9
|
+
if (image == null)
|
|
10
|
+
return texture.version;
|
|
11
|
+
updateVideoImageSize(image);
|
|
12
|
+
image.version = (image.version + 1) >>> 0;
|
|
13
|
+
texture.version = image.version;
|
|
14
|
+
return texture.version;
|
|
12
15
|
}
|
|
13
|
-
//
|
|
14
|
-
// shared (an HTMLVideoElement cannot be duplicated), while the Sampler and uv-transform vectors are
|
|
15
|
-
// deep-cloned so two textures over one stream sample independently. `frameId` resets to -1 so the
|
|
16
|
-
// clone forces its own first upload.
|
|
16
|
+
// Clones sampling/UV state while sharing the borrowed video ImageResource and its upload cache key.
|
|
17
17
|
export function cloneVideoTexture(source) {
|
|
18
|
-
return
|
|
19
|
-
colorSpace: source.colorSpace,
|
|
20
|
-
flipX: source.flipX,
|
|
21
|
-
flipY: source.flipY,
|
|
22
|
-
frameId: -1,
|
|
23
|
-
sampler: cloneSampler(source.sampler),
|
|
24
|
-
source: source.source,
|
|
25
|
-
uvOffset: cloneVector2(source.uvOffset),
|
|
26
|
-
uvRotation: source.uvRotation,
|
|
27
|
-
uvScale: cloneVector2(source.uvScale),
|
|
28
|
-
});
|
|
18
|
+
return cloneTexture(source);
|
|
29
19
|
}
|
|
30
|
-
// Copies
|
|
31
|
-
// shared; the Sampler and uv-transform vectors are copied into out's existing entities. Safe when out
|
|
32
|
-
// aliases source.
|
|
20
|
+
// Copies a video-backed Texture through the universal Texture field copier.
|
|
33
21
|
export function copyVideoTexture(out, source) {
|
|
34
|
-
|
|
35
|
-
const flipX = source.flipX;
|
|
36
|
-
const flipY = source.flipY;
|
|
37
|
-
const frameId = source.frameId;
|
|
38
|
-
const src = source.source;
|
|
39
|
-
const uvRotation = source.uvRotation;
|
|
40
|
-
copySampler(out.sampler, source.sampler);
|
|
41
|
-
copyVector2(out.uvOffset, source.uvOffset);
|
|
42
|
-
copyVector2(out.uvScale, source.uvScale);
|
|
43
|
-
out.colorSpace = colorSpace;
|
|
44
|
-
out.flipX = flipX;
|
|
45
|
-
out.flipY = flipY;
|
|
46
|
-
out.frameId = frameId;
|
|
47
|
-
out.source = src;
|
|
48
|
-
out.uvRotation = uvRotation;
|
|
22
|
+
copyTexture(out, source);
|
|
49
23
|
}
|
|
50
|
-
//
|
|
51
|
-
//
|
|
52
|
-
//
|
|
24
|
+
// Wraps a VideoResource's borrowed host element in an ImageResource backing and returns the same
|
|
25
|
+
// universal Texture type used by still images and render targets. The all-ones initial revision
|
|
26
|
+
// preserves the former first advanceVideoTexture result of 0 after u32 wrap.
|
|
53
27
|
export function createVideoTexture(source, opts) {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
sampler: opts?.sampler ? cloneSampler(opts.sampler) : createSampler(),
|
|
60
|
-
source: opts?.source ?? source,
|
|
61
|
-
uvOffset: opts?.uvOffset ? cloneVector2(opts.uvOffset) : createVector2(0, 0),
|
|
62
|
-
uvRotation: opts?.uvRotation ?? 0,
|
|
63
|
-
uvScale: opts?.uvScale ? cloneVector2(opts.uvScale) : createVector2(1, 1),
|
|
28
|
+
const image = createVideoImageResource(source);
|
|
29
|
+
return createTexture({
|
|
30
|
+
...opts,
|
|
31
|
+
storage: { dimension: '2d', image },
|
|
32
|
+
version: image?.version ?? INITIAL_VIDEO_VERSION,
|
|
64
33
|
});
|
|
65
34
|
}
|
|
66
|
-
// Returns the
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
export function getVideoTextureHeight(videoTexture) {
|
|
70
|
-
const element = videoTexture.source.element;
|
|
35
|
+
// Returns the decoded frame height, or -1 while the borrowed host element is absent/unready.
|
|
36
|
+
export function getVideoTextureHeight(texture) {
|
|
37
|
+
const element = getVideoElement(texture);
|
|
71
38
|
return element !== null && element.videoHeight > 0 ? element.videoHeight : -1;
|
|
72
39
|
}
|
|
73
|
-
//
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
export function getVideoTextureInverseUvMatrix(out, videoTexture) {
|
|
77
|
-
getVideoTextureUvMatrix(out, videoTexture);
|
|
40
|
+
// Video-named compatibility entry over the universal Texture UV transform.
|
|
41
|
+
export function getVideoTextureInverseUvMatrix(out, texture) {
|
|
42
|
+
getVideoTextureUvMatrix(out, texture);
|
|
78
43
|
inverseMatrix3(out, out);
|
|
79
44
|
}
|
|
80
|
-
//
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
// kinds. Out-param form.
|
|
84
|
-
export function getVideoTextureUvMatrix(out, videoTexture) {
|
|
85
|
-
getTextureUvMatrix(out, videoTexture);
|
|
45
|
+
// Video-named compatibility entry over the universal Texture UV transform.
|
|
46
|
+
export function getVideoTextureUvMatrix(out, texture) {
|
|
47
|
+
getTextureUvMatrix(out, texture);
|
|
86
48
|
}
|
|
87
|
-
// Returns the
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
const element = videoTexture.source.element;
|
|
49
|
+
// Returns the decoded frame width, or -1 while the borrowed host element is absent/unready.
|
|
50
|
+
export function getVideoTextureWidth(texture) {
|
|
51
|
+
const element = getVideoElement(texture);
|
|
91
52
|
return element !== null && element.videoWidth > 0 ? element.videoWidth : -1;
|
|
92
53
|
}
|
|
93
|
-
// True
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
export function isVideoTextureFrameReady(videoTexture) {
|
|
97
|
-
const element = videoTexture.source.element;
|
|
54
|
+
// True once the borrowed host element exposes a decoded current frame and non-zero dimensions.
|
|
55
|
+
export function isVideoTextureFrameReady(texture) {
|
|
56
|
+
const element = getVideoElement(texture);
|
|
98
57
|
return (element !== null && element.readyState >= HAVE_CURRENT_DATA && element.videoWidth > 0 && element.videoHeight > 0);
|
|
99
58
|
}
|
|
100
|
-
// Resets
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
59
|
+
// Resets the shared backing revision so its next advance wraps to 0 and every state re-uploads.
|
|
60
|
+
export function resetVideoTextureFrame(texture) {
|
|
61
|
+
const image = texture.storage.image;
|
|
62
|
+
if (image != null)
|
|
63
|
+
image.version = INITIAL_VIDEO_VERSION;
|
|
64
|
+
texture.version = INITIAL_VIDEO_VERSION;
|
|
65
|
+
}
|
|
66
|
+
// Replaces the immutable host-backed identity and resets its upload revision. The VideoResource
|
|
67
|
+
// remains the loader/lifecycle object; Texture stores only its current host handle.
|
|
68
|
+
export function setVideoTextureSource(texture, source) {
|
|
69
|
+
if (texture.storage.dimension !== '2d')
|
|
70
|
+
throw new Error('setVideoTextureSource requires 2d texture storage');
|
|
71
|
+
texture.storage.image = createVideoImageResource(source);
|
|
72
|
+
texture.version = INITIAL_VIDEO_VERSION;
|
|
73
|
+
}
|
|
74
|
+
function createVideoImageResource(source) {
|
|
75
|
+
if (source.element === null)
|
|
76
|
+
return null;
|
|
77
|
+
const image = createEntity({
|
|
78
|
+
height: 0,
|
|
79
|
+
kind: VideoTextureBackingKind,
|
|
80
|
+
source: source.element,
|
|
81
|
+
version: INITIAL_VIDEO_VERSION,
|
|
82
|
+
width: 0,
|
|
83
|
+
});
|
|
84
|
+
updateVideoImageSize(image);
|
|
85
|
+
return image;
|
|
86
|
+
}
|
|
87
|
+
function getVideoElement(texture) {
|
|
88
|
+
return texture.storage.image?.source ?? null;
|
|
104
89
|
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
videoTexture.frameId = -1;
|
|
90
|
+
function updateVideoImageSize(image) {
|
|
91
|
+
const element = image.source;
|
|
92
|
+
image.width = element.videoWidth || 0;
|
|
93
|
+
image.height = element.videoHeight || 0;
|
|
110
94
|
}
|
|
111
|
-
// HTMLMediaElement.HAVE_CURRENT_DATA
|
|
95
|
+
// HTMLMediaElement.HAVE_CURRENT_DATA and the u32 predecessor of the first public frame revision.
|
|
112
96
|
const HAVE_CURRENT_DATA = 2;
|
|
97
|
+
const INITIAL_VIDEO_VERSION = 0xffffffff;
|
|
113
98
|
//# sourceMappingURL=videoTexture.js.map
|
package/dist/videoTexture.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"videoTexture.js","sourceRoot":"","sources":["../src/videoTexture.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"videoTexture.js","sourceRoot":"","sources":["../src/videoTexture.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flighthq/texture",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0-next.1032.e2b99fc",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/flighthq/flight.git",
|
|
@@ -13,6 +13,10 @@
|
|
|
13
13
|
".": {
|
|
14
14
|
"types": "./dist/index.d.ts",
|
|
15
15
|
"default": "./dist/index.js"
|
|
16
|
+
},
|
|
17
|
+
"./contract": {
|
|
18
|
+
"types": "./dist/contract.d.ts",
|
|
19
|
+
"default": "./dist/contract.js"
|
|
16
20
|
}
|
|
17
21
|
},
|
|
18
22
|
"files": [
|
|
@@ -32,9 +36,9 @@
|
|
|
32
36
|
"clean:dist": "tsx ../../scripts/clean-package-dist.ts"
|
|
33
37
|
},
|
|
34
38
|
"dependencies": {
|
|
35
|
-
"@flighthq/entity": "0.
|
|
36
|
-
"@flighthq/geometry": "0.
|
|
37
|
-
"@flighthq/types": "0.
|
|
39
|
+
"@flighthq/entity": "0.3.0-next.1032.e2b99fc",
|
|
40
|
+
"@flighthq/geometry": "0.3.0-next.1032.e2b99fc",
|
|
41
|
+
"@flighthq/types": "0.3.0-next.1032.e2b99fc"
|
|
38
42
|
},
|
|
39
43
|
"devDependencies": {
|
|
40
44
|
"typescript": "^5.3.0"
|
package/src/cubeTexture.test.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { ImageResource } from '@flighthq/types';
|
|
2
|
-
import { CubeFaceNegativeX, CubeFacePositiveX, CubeFacePositiveY } from '@flighthq/types';
|
|
1
|
+
import type { CubeTexture, ImageResource, TextureCubeImages } from '@flighthq/types/contract';
|
|
2
|
+
import { CubeFaceNegativeX, CubeFacePositiveX, CubeFacePositiveY } from '@flighthq/types/contract';
|
|
3
3
|
|
|
4
4
|
import {
|
|
5
5
|
cloneCubeTexture,
|
|
@@ -15,27 +15,27 @@ import { createSampler, equalsSampler } from './sampler';
|
|
|
15
15
|
const fakeFace = { width: 64, height: 64 } as ImageResource;
|
|
16
16
|
const fakeFace2 = { width: 128, height: 128 } as ImageResource;
|
|
17
17
|
|
|
18
|
-
const allFaces:
|
|
18
|
+
const allFaces: TextureCubeImages = [fakeFace, fakeFace, fakeFace, fakeFace, fakeFace, fakeFace];
|
|
19
19
|
|
|
20
20
|
describe('cloneCubeTexture', () => {
|
|
21
21
|
it('shares the face references in a fresh array and deep-clones the sampler', () => {
|
|
22
22
|
const source = createCubeTexture({
|
|
23
23
|
colorSpace: 'linear',
|
|
24
|
-
|
|
24
|
+
images: [fakeFace, null, null, null, null, null],
|
|
25
25
|
});
|
|
26
26
|
|
|
27
27
|
const copy = cloneCubeTexture(source);
|
|
28
28
|
|
|
29
29
|
expect(copy).not.toBe(source);
|
|
30
30
|
expect(copy.colorSpace).toStrictEqual('linear');
|
|
31
|
-
expect(copy.
|
|
32
|
-
expect(copy.
|
|
31
|
+
expect(copy.storage.images).not.toBe(source.storage.images);
|
|
32
|
+
expect(copy.storage.images[0]).toBe(fakeFace);
|
|
33
33
|
expect(copy.sampler).not.toBe(source.sampler);
|
|
34
34
|
expect(equalsSampler(copy.sampler, source.sampler)).toBe(true);
|
|
35
35
|
|
|
36
36
|
// A fresh faces array means reassigning a face on the clone cannot reach the source.
|
|
37
|
-
expect(copy.
|
|
38
|
-
expect(source.
|
|
37
|
+
expect(copy.storage.images).not.toBe(source.storage.images);
|
|
38
|
+
expect(source.storage.images[1]).toBeNull();
|
|
39
39
|
});
|
|
40
40
|
});
|
|
41
41
|
|
|
@@ -43,7 +43,7 @@ describe('copyCubeTexture', () => {
|
|
|
43
43
|
it('writes every field from source into a distinct out, preserving sampler identity', () => {
|
|
44
44
|
const source = createCubeTexture({
|
|
45
45
|
colorSpace: 'linear',
|
|
46
|
-
|
|
46
|
+
images: [fakeFace, null, null, null, null, null],
|
|
47
47
|
});
|
|
48
48
|
const out = createCubeTexture();
|
|
49
49
|
const outSampler = out.sampler;
|
|
@@ -51,7 +51,7 @@ describe('copyCubeTexture', () => {
|
|
|
51
51
|
copyCubeTexture(out, source);
|
|
52
52
|
|
|
53
53
|
expect(out.colorSpace).toStrictEqual('linear');
|
|
54
|
-
expect(out.
|
|
54
|
+
expect(out.storage.images[0]).toBe(fakeFace);
|
|
55
55
|
expect(out.sampler).toBe(outSampler);
|
|
56
56
|
expect(equalsSampler(out.sampler, source.sampler)).toBe(true);
|
|
57
57
|
});
|
|
@@ -59,13 +59,13 @@ describe('copyCubeTexture', () => {
|
|
|
59
59
|
it('is safe when out aliases source', () => {
|
|
60
60
|
const cube = createCubeTexture({
|
|
61
61
|
colorSpace: 'linear',
|
|
62
|
-
|
|
62
|
+
images: [fakeFace, null, null, null, null, null],
|
|
63
63
|
});
|
|
64
64
|
|
|
65
65
|
copyCubeTexture(cube, cube);
|
|
66
66
|
|
|
67
67
|
expect(cube.colorSpace).toStrictEqual('linear');
|
|
68
|
-
expect(cube.
|
|
68
|
+
expect(cube.storage.images[0]).toBe(fakeFace);
|
|
69
69
|
});
|
|
70
70
|
});
|
|
71
71
|
|
|
@@ -73,25 +73,26 @@ describe('createCubeTexture', () => {
|
|
|
73
73
|
it('applies the default six unbound faces, srgb, default sampler', () => {
|
|
74
74
|
const cube = createCubeTexture();
|
|
75
75
|
|
|
76
|
-
|
|
77
|
-
expect(cube.
|
|
76
|
+
expectTypeOf(cube).toEqualTypeOf<CubeTexture>();
|
|
77
|
+
expect(cube.storage.images).toHaveLength(6);
|
|
78
|
+
expect(cube.storage.images.every((face) => face === null)).toBe(true);
|
|
78
79
|
expect(cube.colorSpace).toStrictEqual('srgb');
|
|
79
80
|
expect(equalsSampler(cube.sampler, createSampler())).toBe(true);
|
|
80
81
|
});
|
|
81
82
|
|
|
82
83
|
it('copies a supplied faces array rather than aliasing it', () => {
|
|
83
|
-
const
|
|
84
|
-
const cube = createCubeTexture({
|
|
84
|
+
const images: TextureCubeImages = [fakeFace, null, null, null, null, null];
|
|
85
|
+
const cube = createCubeTexture({ images });
|
|
85
86
|
|
|
86
|
-
expect(cube.
|
|
87
|
-
expect(cube.
|
|
87
|
+
expect(cube.storage.images).not.toBe(images);
|
|
88
|
+
expect(cube.storage.images[0]).toBe(fakeFace);
|
|
88
89
|
});
|
|
89
90
|
});
|
|
90
91
|
|
|
91
92
|
describe('equalsCubeTexture', () => {
|
|
92
93
|
it('is true for cubes with the same color space, sampler, and face references', () => {
|
|
93
|
-
const a = createCubeTexture({ colorSpace: 'linear',
|
|
94
|
-
const b = createCubeTexture({ colorSpace: 'linear',
|
|
94
|
+
const a = createCubeTexture({ colorSpace: 'linear', images: allFaces });
|
|
95
|
+
const b = createCubeTexture({ colorSpace: 'linear', images: allFaces });
|
|
95
96
|
|
|
96
97
|
expect(equalsCubeTexture(a, b)).toBe(true);
|
|
97
98
|
expect(equalsCubeTexture(a, a)).toBe(true);
|
|
@@ -105,9 +106,9 @@ describe('equalsCubeTexture', () => {
|
|
|
105
106
|
});
|
|
106
107
|
|
|
107
108
|
it('is false when a face reference differs', () => {
|
|
108
|
-
const a = createCubeTexture({
|
|
109
|
-
const b = createCubeTexture({
|
|
110
|
-
(b.
|
|
109
|
+
const a = createCubeTexture({ images: allFaces });
|
|
110
|
+
const b = createCubeTexture({ images: allFaces });
|
|
111
|
+
(b.storage.images as unknown as (ImageResource | null)[])[0] = fakeFace2;
|
|
111
112
|
|
|
112
113
|
expect(equalsCubeTexture(a, b)).toBe(false);
|
|
113
114
|
});
|
|
@@ -130,7 +131,7 @@ describe('equalsCubeTexture', () => {
|
|
|
130
131
|
|
|
131
132
|
describe('getCubeTextureFaceSize', () => {
|
|
132
133
|
it('returns the width of the first non-null face', () => {
|
|
133
|
-
const cube = createCubeTexture({
|
|
134
|
+
const cube = createCubeTexture({ images: [null, fakeFace, null, null, null, null] });
|
|
134
135
|
|
|
135
136
|
expect(getCubeTextureFaceSize(cube)).toStrictEqual(64);
|
|
136
137
|
});
|
|
@@ -144,13 +145,13 @@ describe('getCubeTextureFaceSize', () => {
|
|
|
144
145
|
|
|
145
146
|
describe('isCubeTextureComplete', () => {
|
|
146
147
|
it('is false when any face is null', () => {
|
|
147
|
-
const cube = createCubeTexture({
|
|
148
|
+
const cube = createCubeTexture({ images: [fakeFace, null, null, null, null, null] });
|
|
148
149
|
|
|
149
150
|
expect(isCubeTextureComplete(cube)).toBe(false);
|
|
150
151
|
});
|
|
151
152
|
|
|
152
153
|
it('is true when all six faces are bound', () => {
|
|
153
|
-
const cube = createCubeTexture({
|
|
154
|
+
const cube = createCubeTexture({ images: allFaces });
|
|
154
155
|
|
|
155
156
|
expect(isCubeTextureComplete(cube)).toBe(true);
|
|
156
157
|
});
|
|
@@ -161,14 +162,14 @@ describe('setCubeTextureFace', () => {
|
|
|
161
162
|
const cube = createCubeTexture();
|
|
162
163
|
|
|
163
164
|
setCubeTextureFace(cube, CubeFacePositiveX, fakeFace);
|
|
164
|
-
expect(cube.
|
|
165
|
-
expect(cube.
|
|
165
|
+
expect(cube.storage.images[CubeFacePositiveX]).toBe(fakeFace);
|
|
166
|
+
expect(cube.storage.images[CubeFaceNegativeX]).toBeNull();
|
|
166
167
|
});
|
|
167
168
|
|
|
168
169
|
it('unbinds a face when passed null', () => {
|
|
169
|
-
const cube = createCubeTexture({
|
|
170
|
+
const cube = createCubeTexture({ images: allFaces });
|
|
170
171
|
|
|
171
172
|
setCubeTextureFace(cube, CubeFacePositiveY, null);
|
|
172
|
-
expect(cube.
|
|
173
|
+
expect(cube.storage.images[CubeFacePositiveY]).toBeNull();
|
|
173
174
|
});
|
|
174
175
|
});
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { RenderTexture } from '@flighthq/types/contract';
|
|
2
|
+
|
|
3
|
+
import { createRenderTexture } from './renderTexture';
|
|
4
|
+
import { createSampler } from './sampler';
|
|
5
|
+
|
|
6
|
+
describe('createRenderTexture', () => {
|
|
7
|
+
it('creates a linear render target with identity UVs and no depth by default', () => {
|
|
8
|
+
const texture = createRenderTexture({ height: 32, width: 64 });
|
|
9
|
+
|
|
10
|
+
expectTypeOf(texture).toEqualTypeOf<RenderTexture>();
|
|
11
|
+
expect(texture).toMatchObject({
|
|
12
|
+
colorSpace: 'linear',
|
|
13
|
+
flipX: false,
|
|
14
|
+
flipY: false,
|
|
15
|
+
storage: {
|
|
16
|
+
dimension: '2d',
|
|
17
|
+
image: null,
|
|
18
|
+
target: { colorSpace: 'linear', height: 32, width: 64 },
|
|
19
|
+
},
|
|
20
|
+
uvOffset: { x: 0, y: 0 },
|
|
21
|
+
uvRotation: 0,
|
|
22
|
+
uvScale: { x: 1, y: 1 },
|
|
23
|
+
version: 0,
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('applies sampling, depth, color-space, and uv overrides without aliasing mutable values', () => {
|
|
28
|
+
const sampler = createSampler({ magFilter: 'nearest' });
|
|
29
|
+
const uvOffset = { x: 0.25, y: 0.5 };
|
|
30
|
+
const texture = createRenderTexture({
|
|
31
|
+
colorSpace: 'srgb',
|
|
32
|
+
depth: 'depth-stencil',
|
|
33
|
+
flipY: false,
|
|
34
|
+
height: 16,
|
|
35
|
+
sampler,
|
|
36
|
+
uvOffset,
|
|
37
|
+
width: 8,
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
expect(texture.colorSpace).toBe('srgb');
|
|
41
|
+
expect(texture.storage.target.depth).toBe('depth-stencil');
|
|
42
|
+
expect(texture.flipY).toBe(false);
|
|
43
|
+
expect(texture.sampler.magFilter).toBe('nearest');
|
|
44
|
+
expect(texture.sampler).not.toBe(sampler);
|
|
45
|
+
expect(texture.uvOffset).toMatchObject(uvOffset);
|
|
46
|
+
expect(texture.uvOffset).not.toBe(uvOffset);
|
|
47
|
+
});
|
|
48
|
+
});
|