bplinejs 0.0.101-beta.10

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.
Files changed (129) hide show
  1. package/README.md +215 -0
  2. package/docs/API.md +471 -0
  3. package/lib/Camera/index.d.ts +88 -0
  4. package/lib/Camera/index.js +178 -0
  5. package/lib/Camera/index.js.map +1 -0
  6. package/lib/Color/index.d.ts +99 -0
  7. package/lib/Color/index.js +178 -0
  8. package/lib/Color/index.js.map +1 -0
  9. package/lib/Geometry/Geo.d.ts +131 -0
  10. package/lib/Geometry/Geo.js +180 -0
  11. package/lib/Geometry/Geo.js.map +1 -0
  12. package/lib/Geometry/Poly2D.d.ts +53 -0
  13. package/lib/Geometry/Poly2D.js +133 -0
  14. package/lib/Geometry/Poly2D.js.map +1 -0
  15. package/lib/Geometry/Rect2d.d.ts +89 -0
  16. package/lib/Geometry/Rect2d.js +128 -0
  17. package/lib/Geometry/Rect2d.js.map +1 -0
  18. package/lib/Geometry/index.d.ts +6 -0
  19. package/lib/Geometry/index.js +4 -0
  20. package/lib/Group/index.d.ts +70 -0
  21. package/lib/Group/index.js +110 -0
  22. package/lib/Group/index.js.map +1 -0
  23. package/lib/ID.d.ts +6 -0
  24. package/lib/ID.js +15 -0
  25. package/lib/ID.js.map +1 -0
  26. package/lib/IMesh/index.d.ts +104 -0
  27. package/lib/IMesh/index.js +333 -0
  28. package/lib/IMesh/index.js.map +1 -0
  29. package/lib/Material/Material.d.ts +158 -0
  30. package/lib/Material/Material.js +229 -0
  31. package/lib/Material/Material.js.map +1 -0
  32. package/lib/Material/baseMaterial.d.ts +15 -0
  33. package/lib/Material/baseMaterial.js +24 -0
  34. package/lib/Material/baseMaterial.js.map +1 -0
  35. package/lib/Material/index.d.ts +4 -0
  36. package/lib/Material/index.js +3 -0
  37. package/lib/Material/shaders/base/poly/fragment.js +6 -0
  38. package/lib/Material/shaders/base/poly/fragment.js.map +1 -0
  39. package/lib/Material/shaders/base/poly/vertex.js +6 -0
  40. package/lib/Material/shaders/base/poly/vertex.js.map +1 -0
  41. package/lib/Material/shaders/base/rect/fragment.js +6 -0
  42. package/lib/Material/shaders/base/rect/fragment.js.map +1 -0
  43. package/lib/Material/shaders/base/rect/vertex.js +6 -0
  44. package/lib/Material/shaders/base/rect/vertex.js.map +1 -0
  45. package/lib/Material/shaders/line/fragment.js +6 -0
  46. package/lib/Material/shaders/line/fragment.js.map +1 -0
  47. package/lib/Material/shaders/line/vertex.js +6 -0
  48. package/lib/Material/shaders/line/vertex.js.map +1 -0
  49. package/lib/Mesh/index.d.ts +154 -0
  50. package/lib/Mesh/index.js +254 -0
  51. package/lib/Mesh/index.js.map +1 -0
  52. package/lib/Object/index.d.ts +95 -0
  53. package/lib/Object/index.js +212 -0
  54. package/lib/Object/index.js.map +1 -0
  55. package/lib/Raws/index.d.ts +87 -0
  56. package/lib/Raws/index.js +164 -0
  57. package/lib/Raws/index.js.map +1 -0
  58. package/lib/Render/BufferManager.d.ts +93 -0
  59. package/lib/Render/BufferManager.js +281 -0
  60. package/lib/Render/BufferManager.js.map +1 -0
  61. package/lib/Render/DepthManager.d.ts +22 -0
  62. package/lib/Render/DepthManager.js +95 -0
  63. package/lib/Render/DepthManager.js.map +1 -0
  64. package/lib/Render/DestroyManager.d.ts +74 -0
  65. package/lib/Render/DestroyManager.js +221 -0
  66. package/lib/Render/DestroyManager.js.map +1 -0
  67. package/lib/Render/DevelopmentValidator.d.ts +73 -0
  68. package/lib/Render/DevelopmentValidator.js +188 -0
  69. package/lib/Render/DevelopmentValidator.js.map +1 -0
  70. package/lib/Render/DrawCallManager.d.ts +58 -0
  71. package/lib/Render/DrawCallManager.js +267 -0
  72. package/lib/Render/DrawCallManager.js.map +1 -0
  73. package/lib/Render/PipelineManager.d.ts +46 -0
  74. package/lib/Render/PipelineManager.js +254 -0
  75. package/lib/Render/PipelineManager.js.map +1 -0
  76. package/lib/Render/SamplerManager.d.ts +26 -0
  77. package/lib/Render/SamplerManager.js +42 -0
  78. package/lib/Render/SamplerManager.js.map +1 -0
  79. package/lib/Render/SceneUpdate.d.ts +9 -0
  80. package/lib/Render/SceneUpdate.js +18 -0
  81. package/lib/Render/SceneUpdate.js.map +1 -0
  82. package/lib/Render/TextureManager.d.ts +33 -0
  83. package/lib/Render/TextureManager.js +152 -0
  84. package/lib/Render/TextureManager.js.map +1 -0
  85. package/lib/Render/index.d.ts +212 -0
  86. package/lib/Render/index.js +347 -0
  87. package/lib/Render/index.js.map +1 -0
  88. package/lib/Render/types.d.ts +191 -0
  89. package/lib/Scene/index.d.ts +124 -0
  90. package/lib/Scene/index.js +225 -0
  91. package/lib/Scene/index.js.map +1 -0
  92. package/lib/Style/EdgeStyle.d.ts +28 -0
  93. package/lib/Style/EdgeStyle.js +67 -0
  94. package/lib/Style/EdgeStyle.js.map +1 -0
  95. package/lib/Style/JoinStyle.d.ts +27 -0
  96. package/lib/Style/JoinStyle.js +53 -0
  97. package/lib/Style/JoinStyle.js.map +1 -0
  98. package/lib/Style/PartStyle.d.ts +50 -0
  99. package/lib/Style/PartStyle.js +92 -0
  100. package/lib/Style/PartStyle.js.map +1 -0
  101. package/lib/Style/PointsStyle.d.ts +43 -0
  102. package/lib/Style/PointsStyle.js +98 -0
  103. package/lib/Style/PointsStyle.js.map +1 -0
  104. package/lib/Style/SolidStyle.d.ts +37 -0
  105. package/lib/Style/SolidStyle.js +83 -0
  106. package/lib/Style/SolidStyle.js.map +1 -0
  107. package/lib/Style/TexturedStyle.d.ts +29 -0
  108. package/lib/Style/TexturedStyle.js +66 -0
  109. package/lib/Style/TexturedStyle.js.map +1 -0
  110. package/lib/Style/WireframeStyle.d.ts +7 -0
  111. package/lib/Style/WireframeStyle.js +13 -0
  112. package/lib/Style/WireframeStyle.js.map +1 -0
  113. package/lib/Style/WriteStyleData.d.ts +10 -0
  114. package/lib/Style/WriteStyleData.js +59 -0
  115. package/lib/Style/WriteStyleData.js.map +1 -0
  116. package/lib/Style/index.d.ts +50 -0
  117. package/lib/Style/index.js +92 -0
  118. package/lib/Style/index.js.map +1 -0
  119. package/lib/Style/types.d.ts +21 -0
  120. package/lib/Texture/Layers.d.ts +26 -0
  121. package/lib/Texture/Layers.js +42 -0
  122. package/lib/Texture/Layers.js.map +1 -0
  123. package/lib/Texture/index.d.ts +116 -0
  124. package/lib/Texture/index.js +198 -0
  125. package/lib/Texture/index.js.map +1 -0
  126. package/lib/global-types.d.ts +8 -0
  127. package/lib/index.d.ts +43 -0
  128. package/lib/index.js +34 -0
  129. package/package.json +130 -0
@@ -0,0 +1,42 @@
1
+ //#region src/scripts/Render/SamplerManager.ts
2
+ /**
3
+ * 管理当前 Render 对应 GPUDevice 创建的 Sampler 缓存。
4
+ * 相同 U/V 寻址组合在多个材质和 DrawCall 之间复用同一个 GPUSampler。
5
+ * @class
6
+ */
7
+ var SamplerManager = class {
8
+ pipeline;
9
+ /**
10
+ * 创建 Sampler 管理器。
11
+ * @param pipeline 当前 Render 的共享管线资源
12
+ */
13
+ constructor(pipeline) {
14
+ this.pipeline = pipeline;
15
+ }
16
+ /**
17
+ * 获取或创建指定寻址组合的 Sampler。
18
+ * @param addressModeU 水平方向寻址方式
19
+ * @param addressModeV 垂直方向寻址方式
20
+ * @returns 可复用 Sampler,GPUDevice 尚未就绪时返回 undefined
21
+ */
22
+ get(addressModeU, addressModeV) {
23
+ const device = this.pipeline.device;
24
+ if (device === void 0) return;
25
+ const key = addressModeU + "_" + addressModeV;
26
+ const cachedSampler = this.pipeline.samplers.get(key);
27
+ if (cachedSampler !== void 0) return cachedSampler;
28
+ const sampler = device.createSampler({
29
+ label: "Texture Sampler " + key,
30
+ addressModeU,
31
+ addressModeV,
32
+ magFilter: "linear",
33
+ minFilter: "linear"
34
+ });
35
+ this.pipeline.samplers.set(key, sampler);
36
+ return sampler;
37
+ }
38
+ };
39
+ //#endregion
40
+ export { SamplerManager as default };
41
+
42
+ //# sourceMappingURL=SamplerManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SamplerManager.js","names":[],"sources":["../../src/scripts/Render/SamplerManager.ts"],"sourcesContent":["import type { PipelineLike } from \"./types\";\n\ninterface SamplerManagerLike {\n get(addressModeU: GPUAddressMode, addressModeV: GPUAddressMode): GPUSampler | undefined;\n}\n\n/**\n * 管理当前 Render 对应 GPUDevice 创建的 Sampler 缓存。\n * 相同 U/V 寻址组合在多个材质和 DrawCall 之间复用同一个 GPUSampler。\n * @class\n */\nclass SamplerManager implements SamplerManagerLike {\n private readonly pipeline: PipelineLike;\n\n /**\n * 创建 Sampler 管理器。\n * @param pipeline 当前 Render 的共享管线资源\n */\n public constructor(pipeline: PipelineLike) {\n this.pipeline = pipeline;\n }\n\n /**\n * 获取或创建指定寻址组合的 Sampler。\n * @param addressModeU 水平方向寻址方式\n * @param addressModeV 垂直方向寻址方式\n * @returns 可复用 Sampler,GPUDevice 尚未就绪时返回 undefined\n */\n public get(addressModeU: GPUAddressMode, addressModeV: GPUAddressMode): GPUSampler | undefined {\n const device: GPUDevice | undefined = this.pipeline.device;\n\n if (device === undefined) {\n return undefined;\n }\n\n const key: string = addressModeU + \"_\" + addressModeV;\n const cachedSampler: GPUSampler | undefined = this.pipeline.samplers.get(key);\n\n if (cachedSampler !== undefined) {\n return cachedSampler;\n }\n\n const sampler: GPUSampler = device.createSampler({\n label: \"Texture Sampler \" + key,\n addressModeU,\n addressModeV,\n magFilter: \"linear\",\n minFilter: \"linear\",\n });\n\n this.pipeline.samplers.set(key, sampler);\n return sampler;\n }\n}\n\nexport default SamplerManager;\nexport type { SamplerManagerLike };\n"],"mappings":";;;;;;AAWA,IAAM,iBAAN,MAAmD;CAC/C;;;;;CAMA,YAAmB,UAAwB;EACvC,KAAK,WAAW;CACpB;;;;;;;CAQA,IAAW,cAA8B,cAAsD;EAC3F,MAAM,SAAgC,KAAK,SAAS;EAEpD,IAAI,WAAW,KAAA,GACX;EAGJ,MAAM,MAAc,eAAe,MAAM;EACzC,MAAM,gBAAwC,KAAK,SAAS,SAAS,IAAI,GAAG;EAE5E,IAAI,kBAAkB,KAAA,GAClB,OAAO;EAGX,MAAM,UAAsB,OAAO,cAAc;GAC7C,OAAO,qBAAqB;GAC5B;GACA;GACA,WAAW;GACX,WAAW;EACf,CAAC;EAED,KAAK,SAAS,SAAS,IAAI,KAAK,OAAO;EACvC,OAAO;CACX;AACJ"}
@@ -0,0 +1,9 @@
1
+ import type Camera from "../Camera";
2
+ import type Scene from "../Scene";
3
+ /** @param scene 场景对象;祖先按版本更新,静止节点不重复计算矩阵 */
4
+ declare const MatrixUpdate: (scene: Scene) => void;
5
+ /** @param scene 场景对象;按版本准备 CPU 列表,不清除任何 Render 的上传状态 */
6
+ declare const InitScene: (scene: Scene) => void;
7
+ /** @param camera 相机对象;按输入和世界矩阵版本准备投影及视图矩阵 */
8
+ declare const InitCamera: (camera: Camera) => void;
9
+ export { InitCamera, InitScene, MatrixUpdate };
@@ -0,0 +1,18 @@
1
+ //#region src/scripts/Render/SceneUpdate.ts
2
+ /** @param scene 场景对象;祖先按版本更新,静止节点不重复计算矩阵 */
3
+ var MatrixUpdate = (scene) => {
4
+ scene.ensureWorldMatrix();
5
+ for (const mesh of scene.drawList) mesh.ensureWorldMatrix();
6
+ };
7
+ /** @param scene 场景对象;按版本准备 CPU 列表,不清除任何 Render 的上传状态 */
8
+ var InitScene = (scene) => {
9
+ scene.ensureLists();
10
+ };
11
+ /** @param camera 相机对象;按输入和世界矩阵版本准备投影及视图矩阵 */
12
+ var InitCamera = (camera) => {
13
+ camera.ensureCameraMatrix();
14
+ };
15
+ //#endregion
16
+ export { InitCamera, InitScene, MatrixUpdate };
17
+
18
+ //# sourceMappingURL=SceneUpdate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SceneUpdate.js","names":[],"sources":["../../src/scripts/Render/SceneUpdate.ts"],"sourcesContent":["import type Camera from \"../Camera\";\nimport type Scene from \"../Scene\";\n\n/** @param scene 场景对象;祖先按版本更新,静止节点不重复计算矩阵 */\nconst MatrixUpdate = (scene: Scene): void => {\n scene.ensureWorldMatrix();\n for (const mesh of scene.drawList) mesh.ensureWorldMatrix();\n};\n\n/** @param scene 场景对象;按版本准备 CPU 列表,不清除任何 Render 的上传状态 */\nconst InitScene = (scene: Scene): void => {\n scene.ensureLists();\n};\n\n/** @param camera 相机对象;按输入和世界矩阵版本准备投影及视图矩阵 */\nconst InitCamera = (camera: Camera): void => {\n camera.ensureCameraMatrix();\n};\n\nexport { InitCamera, InitScene, MatrixUpdate };\n"],"mappings":";;AAIA,IAAM,gBAAgB,UAAuB;CACzC,MAAM,kBAAkB;CACxB,KAAK,MAAM,QAAQ,MAAM,UAAU,KAAK,kBAAkB;AAC9D;;AAGA,IAAM,aAAa,UAAuB;CACtC,MAAM,YAAY;AACtB;;AAGA,IAAM,cAAc,WAAyB;CACzC,OAAO,mBAAmB;AAC9B"}
@@ -0,0 +1,33 @@
1
+ import type Scene from "../Scene";
2
+ import type { GPUTextureResourceLike, PipelineLike } from "./types";
3
+ interface TextureManagerLike {
4
+ draw(scene: Scene): void;
5
+ createFallbackTexture(device: GPUDevice): GPUTextureResourceLike;
6
+ }
7
+ /** 按 textureList 上传图片;单张图片和多层图片统一使用 2d-array 视图。 */
8
+ declare class TextureManager implements TextureManagerLike {
9
+ private readonly pipeline;
10
+ /** @param pipeline Render 资源 */
11
+ constructor(pipeline: PipelineLike);
12
+ /** @param scene 当前场景,按资源自己的版本更新,不清除共享版本 */
13
+ draw(scene: Scene): void;
14
+ /** @param device 当前设备 @returns 只有一层的白色后备贴图 */
15
+ createFallbackTexture(device: GPUDevice): GPUTextureResourceLike;
16
+ /**
17
+ * 释放旧纹理及引用其视图的绑定缓存,重建时不会误用旧视图。
18
+ * @param resource 被替换或失效的纹理资源
19
+ */
20
+ private releaseTexture;
21
+ /**
22
+ * 层号由 CPU 层表决定,空源和 loading 都写白色,不能跳过层造成编号错位。
23
+ * 同组图片统一到最大宽高,缩放整张图片,不裁切 UV。
24
+ * @param device 当前设备
25
+ * @param textureId 数组资源 ID
26
+ * @param version 本次上传版本
27
+ * @param layers 有序图片,单图长度为 1
28
+ * @returns 完整纹理资源
29
+ */
30
+ private createTexture;
31
+ }
32
+ export default TextureManager;
33
+ export type { TextureManagerLike };
@@ -0,0 +1,152 @@
1
+ import TextureLayers from "../Texture/Layers.js";
2
+ //#region src/scripts/Render/TextureManager.ts
3
+ /** 按 textureList 上传图片;单张图片和多层图片统一使用 2d-array 视图。 */
4
+ var TextureManager = class {
5
+ pipeline;
6
+ /** @param pipeline Render 资源 */
7
+ constructor(pipeline) {
8
+ this.pipeline = pipeline;
9
+ }
10
+ /** @param scene 当前场景,按资源自己的版本更新,不清除共享版本 */
11
+ draw(scene) {
12
+ const device = this.pipeline.device;
13
+ if (device === void 0) return;
14
+ for (const resource of scene.textureList) {
15
+ const cached = this.pipeline.textures.get(resource.id);
16
+ if (cached?.version === resource.version) continue;
17
+ const layers = resource instanceof TextureLayers ? resource.layers : [resource];
18
+ if (layers.length === 0 || !(resource instanceof TextureLayers) && !IsReady(resource)) {
19
+ this.releaseTexture(cached);
20
+ this.pipeline.textures.delete(resource.id);
21
+ continue;
22
+ }
23
+ const created = this.createTexture(device, resource.id, resource.version, layers);
24
+ this.releaseTexture(cached);
25
+ this.pipeline.textures.set(resource.id, created);
26
+ }
27
+ }
28
+ /** @param device 当前设备 @returns 只有一层的白色后备贴图 */
29
+ createFallbackTexture(device) {
30
+ return this.createTexture(device, -1, 0, [void 0]);
31
+ }
32
+ /**
33
+ * 释放旧纹理及引用其视图的绑定缓存,重建时不会误用旧视图。
34
+ * @param resource 被替换或失效的纹理资源
35
+ */
36
+ releaseTexture(resource) {
37
+ if (resource === void 0) return;
38
+ for (const entry of this.pipeline.buffers.meshStyle.values()) {
39
+ const binding = entry.bindGroup;
40
+ if (binding?.baseView === resource.view || binding?.edgeView === resource.view || binding?.pointsView === resource.view) entry.bindGroup = void 0;
41
+ }
42
+ resource.texture.destroy();
43
+ }
44
+ /**
45
+ * 层号由 CPU 层表决定,空源和 loading 都写白色,不能跳过层造成编号错位。
46
+ * 同组图片统一到最大宽高,缩放整张图片,不裁切 UV。
47
+ * @param device 当前设备
48
+ * @param textureId 数组资源 ID
49
+ * @param version 本次上传版本
50
+ * @param layers 有序图片,单图长度为 1
51
+ * @returns 完整纹理资源
52
+ */
53
+ createTexture(device, textureId, version, layers) {
54
+ let width = 1;
55
+ let height = 1;
56
+ const sourceIds = /* @__PURE__ */ new Set();
57
+ for (const image of layers) {
58
+ if (image !== void 0) sourceIds.add(image.id);
59
+ if (IsReady(image)) {
60
+ width = Math.max(width, image.width);
61
+ height = Math.max(height, image.height);
62
+ }
63
+ }
64
+ if (layers.length > device.limits.maxTextureArrayLayers) throw new RangeError("Texture layers exceed maxTextureArrayLayers.");
65
+ if (width > device.limits.maxTextureDimension2D || height > device.limits.maxTextureDimension2D) throw new RangeError("Texture dimensions exceed maxTextureDimension2D.");
66
+ const texture = device.createTexture({
67
+ label: textureId === -1 ? "Fallback White Texture" : "Texture " + String(textureId),
68
+ size: {
69
+ width,
70
+ height,
71
+ depthOrArrayLayers: layers.length
72
+ },
73
+ format: "rgba8unorm",
74
+ usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT
75
+ });
76
+ try {
77
+ let staging;
78
+ for (let layer = 0; layer < layers.length; layer++) {
79
+ const image = layers[layer];
80
+ const source = IsReady(image) ? image.source : null;
81
+ const destination = {
82
+ texture,
83
+ origin: {
84
+ x: 0,
85
+ y: 0,
86
+ z: layer
87
+ }
88
+ };
89
+ const extent = {
90
+ width,
91
+ height,
92
+ depthOrArrayLayers: 1
93
+ };
94
+ if (source === null && width === 1 && height === 1) {
95
+ device.queue.writeTexture(destination, new Uint8Array([
96
+ 255,
97
+ 255,
98
+ 255,
99
+ 255
100
+ ]), {
101
+ bytesPerRow: 4,
102
+ rowsPerImage: 1
103
+ }, extent);
104
+ continue;
105
+ }
106
+ const imageData = typeof ImageData !== "undefined" && source instanceof ImageData;
107
+ if (source !== null && !imageData && image?.width === width && image.height === height) {
108
+ device.queue.copyExternalImageToTexture({
109
+ source,
110
+ flipY: true
111
+ }, destination, extent);
112
+ continue;
113
+ }
114
+ staging ??= new OffscreenCanvas(width, height);
115
+ const context = staging.getContext("2d");
116
+ if (context === null) throw new Error("Cannot create texture normalization canvas.");
117
+ context.clearRect(0, 0, width, height);
118
+ if (source === null) {
119
+ context.fillStyle = "#ffffff";
120
+ context.fillRect(0, 0, width, height);
121
+ } else if (imageData) {
122
+ const pixels = source;
123
+ const input = new OffscreenCanvas(pixels.width, pixels.height);
124
+ const inputContext = input.getContext("2d");
125
+ if (inputContext === null) throw new Error("Cannot upload ImageData.");
126
+ inputContext.putImageData(pixels, 0, 0);
127
+ context.drawImage(input, 0, 0, width, height);
128
+ } else context.drawImage(source, 0, 0, width, height);
129
+ device.queue.copyExternalImageToTexture({
130
+ source: staging,
131
+ flipY: true
132
+ }, destination, extent);
133
+ }
134
+ return {
135
+ textureId,
136
+ version,
137
+ sourceIds,
138
+ texture,
139
+ view: texture.createView({ dimension: "2d-array" })
140
+ };
141
+ } catch (error) {
142
+ texture.destroy();
143
+ throw error;
144
+ }
145
+ }
146
+ };
147
+ /** @param image 源图 @returns 是否具有可上传的有效源 */
148
+ var IsReady = (image) => image !== void 0 && image.loaded && image.source !== null && Number.isInteger(image.width) && Number.isInteger(image.height) && image.width > 0 && image.height > 0;
149
+ //#endregion
150
+ export { TextureManager as default };
151
+
152
+ //# sourceMappingURL=TextureManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TextureManager.js","names":[],"sources":["../../src/scripts/Render/TextureManager.ts"],"sourcesContent":["import type Scene from \"../Scene\";\nimport type { TextureLike, TextureSource } from \"../Texture\";\nimport TextureLayers from \"../Texture/Layers\";\nimport type { GPUTextureResourceLike, PipelineLike } from \"./types\";\n\ninterface TextureManagerLike {\n draw(scene: Scene): void;\n createFallbackTexture(device: GPUDevice): GPUTextureResourceLike;\n}\n\n/** 按 textureList 上传图片;单张图片和多层图片统一使用 2d-array 视图。 */\nclass TextureManager implements TextureManagerLike {\n private readonly pipeline: PipelineLike;\n\n /** @param pipeline Render 资源 */\n public constructor(pipeline: PipelineLike) {\n this.pipeline = pipeline;\n }\n\n /** @param scene 当前场景,按资源自己的版本更新,不清除共享版本 */\n public draw(scene: Scene): void {\n const device: GPUDevice | undefined = this.pipeline.device;\n if (device === undefined) return;\n for (const resource of scene.textureList) {\n const cached = this.pipeline.textures.get(resource.id);\n if (cached?.version === resource.version) continue;\n const layers = resource instanceof TextureLayers ? resource.layers : [resource];\n if (layers.length === 0 || (!(resource instanceof TextureLayers) && !IsReady(resource))) {\n // 无效单图只移除自己的视图,不能反复误删其他仍使用此源的层组。\n this.releaseTexture(cached);\n this.pipeline.textures.delete(resource.id);\n continue;\n }\n const created = this.createTexture(device, resource.id, resource.version, layers);\n // 新资源全部创建成功后才释放旧资源,失败不会留下一个“已上传”的假快照。\n this.releaseTexture(cached);\n this.pipeline.textures.set(resource.id, created);\n }\n }\n\n /** @param device 当前设备 @returns 只有一层的白色后备贴图 */\n public createFallbackTexture(device: GPUDevice): GPUTextureResourceLike {\n return this.createTexture(device, -1, 0, [undefined]);\n }\n\n /**\n * 释放旧纹理及引用其视图的绑定缓存,重建时不会误用旧视图。\n * @param resource 被替换或失效的纹理资源\n */\n private releaseTexture(resource: GPUTextureResourceLike | undefined): void {\n if (resource === undefined) return;\n for (const entry of this.pipeline.buffers.meshStyle.values()) {\n const binding = entry.bindGroup;\n if (binding?.baseView === resource.view || binding?.edgeView === resource.view\n || binding?.pointsView === resource.view) entry.bindGroup = undefined;\n }\n resource.texture.destroy();\n }\n\n /**\n * 层号由 CPU 层表决定,空源和 loading 都写白色,不能跳过层造成编号错位。\n * 同组图片统一到最大宽高,缩放整张图片,不裁切 UV。\n * @param device 当前设备\n * @param textureId 数组资源 ID\n * @param version 本次上传版本\n * @param layers 有序图片,单图长度为 1\n * @returns 完整纹理资源\n */\n private createTexture(device: GPUDevice, textureId: number, version: number, layers: readonly (TextureLike | undefined)[]): GPUTextureResourceLike {\n let width: number = 1;\n let height: number = 1;\n const sourceIds = new Set<number>();\n for (const image of layers) {\n if (image !== undefined) sourceIds.add(image.id);\n if (IsReady(image)) {\n width = Math.max(width, image.width);\n height = Math.max(height, image.height);\n }\n }\n if (layers.length > device.limits.maxTextureArrayLayers) throw new RangeError(\"Texture layers exceed maxTextureArrayLayers.\");\n if (width > device.limits.maxTextureDimension2D || height > device.limits.maxTextureDimension2D) {\n throw new RangeError(\"Texture dimensions exceed maxTextureDimension2D.\");\n }\n const texture = device.createTexture({\n label: textureId === -1 ? \"Fallback White Texture\" : \"Texture \" + String(textureId),\n size: { width, height, depthOrArrayLayers: layers.length },\n format: \"rgba8unorm\",\n usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT,\n });\n try {\n let staging: OffscreenCanvas | undefined;\n for (let layer = 0; layer < layers.length; layer++) {\n const image = layers[layer];\n const source: TextureSource | null = IsReady(image) ? image.source : null;\n const destination: GPUCopyExternalImageDestInfo = { texture, origin: { x: 0, y: 0, z: layer } };\n const extent: GPUExtent3DDict = { width, height, depthOrArrayLayers: 1 };\n if (source === null && width === 1 && height === 1) {\n device.queue.writeTexture(destination, new Uint8Array([255, 255, 255, 255]), { bytesPerRow: 4, rowsPerImage: 1 }, extent);\n continue;\n }\n const imageData: boolean = typeof ImageData !== \"undefined\" && source instanceof ImageData;\n if (source !== null && !imageData && image?.width === width && image.height === height) {\n device.queue.copyExternalImageToTexture({ source: source, flipY: true }, destination, extent);\n continue;\n }\n staging ??= new OffscreenCanvas(width, height);\n const context = staging.getContext(\"2d\");\n if (context === null) throw new Error(\"Cannot create texture normalization canvas.\");\n context.clearRect(0, 0, width, height);\n if (source === null) {\n context.fillStyle = \"#ffffff\";\n context.fillRect(0, 0, width, height);\n } else if (imageData) {\n const pixels = source as ImageData;\n const input = new OffscreenCanvas(pixels.width, pixels.height);\n const inputContext = input.getContext(\"2d\");\n if (inputContext === null) throw new Error(\"Cannot upload ImageData.\");\n inputContext.putImageData(pixels, 0, 0);\n context.drawImage(input, 0, 0, width, height);\n } else {\n context.drawImage(source as HTMLImageElement | ImageBitmap, 0, 0, width, height);\n }\n device.queue.copyExternalImageToTexture({ source: staging, flipY: true }, destination, extent);\n }\n return { textureId, version, sourceIds, texture, view: texture.createView({ dimension: \"2d-array\" }) };\n } catch (error) {\n texture.destroy();\n throw error;\n }\n }\n}\n\n/** @param image 源图 @returns 是否具有可上传的有效源 */\nconst IsReady = (image: TextureLike | undefined): image is TextureLike => image !== undefined\n && image.loaded && image.source !== null && Number.isInteger(image.width) && Number.isInteger(image.height)\n && image.width > 0 && image.height > 0;\n\nexport default TextureManager;\nexport type { TextureManagerLike };\n"],"mappings":"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"}
@@ -0,0 +1,212 @@
1
+ import type Camera from "../Camera";
2
+ import type { GeoData } from "../Geometry";
3
+ import type { Material2d } from "../global-types";
4
+ import type { MeshLike } from "../Mesh";
5
+ import type Scene from "../Scene";
6
+ import type { TextureResource } from "../Texture/Layers";
7
+ import BufferManager from "./BufferManager";
8
+ import DevelopmentValidator from "./DevelopmentValidator";
9
+ import DepthManager from "./DepthManager";
10
+ import DestroyManager from "./DestroyManager";
11
+ import DrawCallManager from "./DrawCallManager";
12
+ import PipelineManager from "./PipelineManager";
13
+ import SamplerManager from "./SamplerManager";
14
+ import { InitCamera, InitScene, MatrixUpdate } from "./SceneUpdate";
15
+ import TextureManager from "./TextureManager";
16
+ import type { PipelineLike, RenderLike, RenderMode } from "./types";
17
+ /**
18
+ * WebGPU 2D 渲染器。
19
+ * 负责生命周期和渲染流程调度,具体 GPU 资源由各管理器维护。
20
+ * @class
21
+ * @implements RenderLike
22
+ */
23
+ declare class Render implements RenderLike {
24
+ /**
25
+ * 当前 Render 的全局唯一 ID。
26
+ */
27
+ readonly id: number;
28
+ /**
29
+ * 对象类型。
30
+ */
31
+ readonly type: string;
32
+ /**
33
+ * 画布容器。
34
+ */
35
+ container: HTMLElement;
36
+ /**
37
+ * 渲染画布。
38
+ */
39
+ canvas: HTMLCanvasElement;
40
+ /**
41
+ * 每帧开始前用于清空画布的 RGBA 颜色。
42
+ */
43
+ backgroundColor: GPUColorDict;
44
+ /**
45
+ * 当前 Render 的共享 WebGPU 资源。
46
+ */
47
+ pipeline: PipelineLike;
48
+ /**
49
+ * WebGPU 初始化完成状态。
50
+ */
51
+ readonly ready: Promise<void>;
52
+ private _alphaMode;
53
+ private _resizeTimer;
54
+ private _destroyed;
55
+ private _dpr;
56
+ private _renderMode;
57
+ private readonly bufferManager;
58
+ private readonly destroyManager;
59
+ private readonly drawCallManager;
60
+ private readonly pipelineManager;
61
+ private readonly textureManager;
62
+ /**
63
+ * 创建渲染器并开始异步初始化 WebGPU。
64
+ * @param div 容器节点或容器 ID
65
+ * @param renderMode Render 运行模式
66
+ */
67
+ constructor(div: HTMLElement | string, renderMode?: RenderMode);
68
+ /**
69
+ * 创建当前画布对应的 WebGPU 设备与呈现上下文。
70
+ * @returns WebGPU 初始化完成状态
71
+ */
72
+ initWebGPU(): Promise<void>;
73
+ /**
74
+ * 设置 Canvas 与下层 HTML 内容的 Alpha 合成方式。
75
+ * @param alphaMode Alpha 合成方式
76
+ */
77
+ set alphaMode(alphaMode: GPUCanvasAlphaMode);
78
+ /**
79
+ * 获取 Canvas Alpha 合成方式。
80
+ * @returns Alpha 合成方式
81
+ */
82
+ get alphaMode(): GPUCanvasAlphaMode;
83
+ /**
84
+ * 获取当前 Canvas 使用的设备像素比。
85
+ * @returns 设备像素比
86
+ */
87
+ get dpr(): number;
88
+ /**
89
+ * 设置 Render 运行模式。
90
+ * production 会跳过 GPUBuffer 创建前的全部开发检查。
91
+ * @param renderMode Render 运行模式
92
+ */
93
+ set renderMode(renderMode: RenderMode);
94
+ /**
95
+ * 获取 Render 运行模式。
96
+ * @returns 当前 Render 运行模式
97
+ */
98
+ get renderMode(): RenderMode;
99
+ /**
100
+ * 预热场景所需缓存,但不提交 DrawCall。
101
+ * @param scene 场景对象
102
+ * @param camera 相机对象
103
+ * @returns 无返回值
104
+ */
105
+ warmup(scene: Scene, camera: Camera): void;
106
+ /**
107
+ * 预热缓存并绘制当前场景。
108
+ * @param scene 场景对象
109
+ * @param camera 相机对象
110
+ * @returns 无返回值
111
+ */
112
+ render(scene: Scene, camera: Camera): void;
113
+ /**
114
+ * 创建或更新当前场景的 GPUBuffer。
115
+ * @param scene 场景对象
116
+ * @param camera 相机对象
117
+ * @returns 无返回值
118
+ */
119
+ drawBuffers(scene: Scene, camera: Camera): void;
120
+ /**
121
+ * 创建或更新当前场景的 GPUTexture。
122
+ * @param scene 场景对象
123
+ * @returns 无返回值
124
+ */
125
+ drawTextures(scene: Scene): void;
126
+ /**
127
+ * 创建或更新当前场景的 Pipeline 模板。
128
+ * @param scene 场景对象
129
+ * @returns 无返回值
130
+ */
131
+ drawPipelines(scene: Scene): void;
132
+ /**
133
+ * 编码并提交当前场景的绘制命令。
134
+ * @param scene 场景对象
135
+ * @returns 无返回值
136
+ */
137
+ drawCall(scene: Scene): void;
138
+ /**
139
+ * 销毁指定 Mesh 缓存。
140
+ * @param mesh Mesh 对象或全局 ID
141
+ * @returns 是否销毁了任意资源
142
+ */
143
+ destroyMesh(mesh: MeshLike | number): boolean;
144
+ /**
145
+ * 销毁指定 Texture 缓存。
146
+ * @param texture Texture 对象或全局 ID
147
+ * @returns 是否销毁了对应资源
148
+ */
149
+ destroyTexture(texture: TextureResource | number): boolean;
150
+ /**
151
+ * 销毁指定 Material 缓存。
152
+ * @param material Material 对象或全局 ID
153
+ * @returns 是否销毁了任意资源
154
+ */
155
+ destroyMaterial(material: Material2d | number): boolean;
156
+ /**
157
+ * 销毁指定 Geometry 缓存。
158
+ * @param geometry Geometry 对象或全局 ID
159
+ * @returns 是否销毁了对应资源
160
+ */
161
+ destroyGeometry(geometry: GeoData | number): boolean;
162
+ /**
163
+ * 回收所有场景均未引用的 GPU 缓存。
164
+ * @param scene 需要同步资源使用记录的场景
165
+ * @returns 无返回值
166
+ */
167
+ trim(scene: Scene): void;
168
+ /**
169
+ * 更新场景版本落后的节点矩阵。
170
+ * @param scene 场景对象
171
+ * @returns 无返回值
172
+ */
173
+ matrixUpdate(scene: Scene): void;
174
+ /**
175
+ * 根据版本更新 Scene 列表。
176
+ * @param scene 场景对象
177
+ * @returns 无返回值
178
+ */
179
+ initScene(scene: Scene): void;
180
+ /**
181
+ * 根据版本更新 Camera 矩阵。
182
+ * @param camera 相机对象
183
+ * @returns 无返回值
184
+ */
185
+ initCamera(camera: Camera): void;
186
+ /**
187
+ * 销毁当前 Render 持有的全部资源并移除 Canvas。
188
+ * @returns 无返回值
189
+ */
190
+ destroy(): void;
191
+ /**
192
+ * 延迟更新 Canvas 实际像素尺寸。
193
+ * 连续 100ms 没有新的调用时才执行。
194
+ * @returns 无返回值
195
+ */
196
+ resize(): void;
197
+ /**
198
+ * 获取当前 Render 销毁状态。
199
+ * @returns 是否已经销毁
200
+ */
201
+ private isDestroyed;
202
+ }
203
+ export default Render;
204
+ export { BufferManager, DepthManager, DevelopmentValidator, DestroyManager, DrawCallManager, InitCamera, InitScene, MatrixUpdate, PipelineManager, SamplerManager, TextureManager, };
205
+ export type { DepthTextureLike, MeshDepthBufferLike, GeometryBufferPartLike, GeometryBufferLike, GPUTextureResourceLike, MeshMatrixBufferLike, MeshStyleBufferLike, PipelineBuffersLike, PipelineLike, PipelineTemplateLike, RenderLike, RenderMode, SceneResourcesLike, } from "./types";
206
+ export type { BufferManagerLike } from "./BufferManager";
207
+ export type { DevelopmentValidatorLike } from "./DevelopmentValidator";
208
+ export type { DestroyManagerLike } from "./DestroyManager";
209
+ export type { DrawCallManagerLike } from "./DrawCallManager";
210
+ export type { PipelineManagerLike } from "./PipelineManager";
211
+ export type { SamplerManagerLike } from "./SamplerManager";
212
+ export type { TextureManagerLike } from "./TextureManager";