@tangram.gl/tangram-renderer 0.0.0-stage → 0.0.0
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 +59 -2
- package/dist/core.js +36923 -0
- package/dist/core.js.map +6 -0
- package/dist/index.js +32 -0
- package/dist/loaders-gl-worker.js +82 -0
- package/dist/loaders-gl-worker.js.map +6 -0
- package/dist/map-logic.js +2 -0
- package/dist/map-logic.js.map +6 -0
- package/dist/projected-basemaps-worker.js +3 -0
- package/dist/projected-basemaps-worker.js.map +6 -0
- package/dist/shader-modules.js +141 -0
- package/dist/shader-modules.js.map +6 -0
- package/dist/style-schema.js +126 -0
- package/dist/style-schema.js.map +6 -0
- package/dist/tangram-style.schema.json +882 -0
- package/dist/tangram.debug.mjs +37139 -0
- package/dist/tangram.debug.mjs.map +6 -0
- package/dist/tangram.min.mjs +4950 -0
- package/dist/types/builders/earcut.d.ts +15 -0
- package/dist/types/core.d.ts +29 -0
- package/dist/types/gl/constants.d.ts +2 -0
- package/dist/types/gl/globe_mesh.d.ts +48 -0
- package/dist/types/gl/glsl.d.ts +17 -0
- package/dist/types/gl/vertex-constants.d.ts +4 -0
- package/dist/types/gl/vertex-types.d.ts +34 -0
- package/dist/types/gl/vertex_data.d.ts +32 -0
- package/dist/types/gl/vertex_elements.d.ts +8 -0
- package/dist/types/gl/vertex_layout.d.ts +32 -0
- package/dist/types/glsl.d.ts +14 -0
- package/dist/types/gpu/luma_device_renderer.d.ts +66 -0
- package/dist/types/gpu/resource_lifecycle.d.ts +4 -0
- package/dist/types/gpu/tangram_gpu_backend.d.ts +151 -0
- package/dist/types/index.d.ts +155 -0
- package/dist/types/lights/light-definitions.d.ts +121 -0
- package/dist/types/map-logic/draped-terrain-bounds.d.ts +41 -0
- package/dist/types/map-logic/globe-terrain-preparation.d.ts +85 -0
- package/dist/types/map-logic/globe-terrain.d.ts +54 -0
- package/dist/types/map-logic/index.d.ts +33 -0
- package/dist/types/map-logic/label-identity.d.ts +22 -0
- package/dist/types/map-logic/label-placement.d.ts +32 -0
- package/dist/types/map-logic/screen-bounds.d.ts +15 -0
- package/dist/types/map-logic/terrain-data.d.ts +55 -0
- package/dist/types/map-logic/terrain-error.d.ts +51 -0
- package/dist/types/map-logic/terrain-ground-topology.d.ts +26 -0
- package/dist/types/map-logic/terrain-height-field.d.ts +59 -0
- package/dist/types/map-logic/terrain-navigation.d.ts +27 -0
- package/dist/types/map-logic/terrain-neighborhood.d.ts +5 -0
- package/dist/types/map-logic/terrain-query.d.ts +33 -0
- package/dist/types/map-logic/terrain-resource-budget.d.ts +51 -0
- package/dist/types/map-logic/terrain-transition-topology.d.ts +23 -0
- package/dist/types/map-logic/tile-build-queue.d.ts +51 -0
- package/dist/types/map-logic/tile-cache-policy.d.ts +46 -0
- package/dist/types/map-logic/tile-residency.d.ts +17 -0
- package/dist/types/map-logic/triangle-query-index.d.ts +87 -0
- package/dist/types/procedures/js-yaml.d.ts +15 -0
- package/dist/types/procedures/mesh-projector.d.ts +107 -0
- package/dist/types/procedures/mvt-dependencies.d.ts +20 -0
- package/dist/types/procedures/projected-coordinate-transform.d.ts +27 -0
- package/dist/types/procedures/projection-batch-executor.d.ts +53 -0
- package/dist/types/procedures/scene-yaml-legacy.d.ts +6 -0
- package/dist/types/procedures/terrain-draping.d.ts +165 -0
- package/dist/types/procedures/terrain-globe.d.ts +6 -0
- package/dist/types/procedures/terrain-styled-topology.d.ts +34 -0
- package/dist/types/procedures/web-mercator-legacy.d.ts +4 -0
- package/dist/types/procedures/web-mercator-math.d.ts +4 -0
- package/dist/types/scene/globals.d.ts +11 -0
- package/dist/types/scene/ground_footprint.d.ts +16 -0
- package/dist/types/scene/host_frame.d.ts +54 -0
- package/dist/types/scene/projection_math.d.ts +52 -0
- package/dist/types/scene/scene-resource-types.d.ts +177 -0
- package/dist/types/scene/scene_bundle.d.ts +69 -0
- package/dist/types/scene/visibility_adapter.d.ts +106 -0
- package/dist/types/selection/draped-terrain-surface.d.ts +78 -0
- package/dist/types/selection/terrain_surface.d.ts +149 -0
- package/dist/types/shader-modules/globe-horizon.d.ts +15 -0
- package/dist/types/shader-modules/height-decode.d.ts +13 -0
- package/dist/types/shader-modules/hillshade.d.ts +13 -0
- package/dist/types/shader-modules/index.d.ts +6 -0
- package/dist/types/shader-modules/planar.d.ts +12 -0
- package/dist/types/shader-modules/sphere-map.d.ts +13 -0
- package/dist/types/shader-modules/triplanar.d.ts +15 -0
- package/dist/types/sources/decoded_tile_store.d.ts +95 -0
- package/dist/types/sources/tile_source_metadata.d.ts +32 -0
- package/dist/types/styles/text/fontfaceobserver.d.ts +10 -0
- package/dist/types/tile/tile_id.d.ts +37 -0
- package/dist/types/tile/tile_traversal_adapter.d.ts +63 -0
- package/dist/types/types.d.ts +293 -0
- package/dist/types/utils/geo.d.ts +57 -0
- package/dist/types/utils/hash.d.ts +1 -0
- package/dist/types/utils/log.d.ts +27 -0
- package/dist/types/utils/props.d.ts +6 -0
- package/dist/types/utils/subscribe.d.ts +10 -0
- package/dist/types/utils/thread.d.ts +6 -0
- package/dist/types/utils/urls.d.ts +26 -0
- package/dist/types/utils/utils.d.ts +26 -0
- package/dist/types/utils/version.d.ts +2 -0
- package/dist/types/utils/worker-types.d.ts +68 -0
- package/dist/types/utils/worker_broker.d.ts +3 -0
- package/package.json +103 -3
- package/src/builders/common.ts +41 -0
- package/src/builders/earcut.d.ts +15 -0
- package/src/builders/geometry-types.ts +60 -0
- package/src/builders/points.ts +115 -0
- package/src/builders/polygons.ts +225 -0
- package/src/builders/polylines.ts +682 -0
- package/src/builders/wireframe.ts +31 -0
- package/src/core.d.ts +29 -0
- package/src/core.ts +33 -0
- package/src/experimental/loaders-gl-worker.ts +19 -0
- package/src/experimental/projected-basemaps-worker.ts +13 -0
- package/src/experimental/projected-mesh-cache.ts +137 -0
- package/src/experimental/projected-mesh-domain.ts +110 -0
- package/src/experimental/projected-mesh-refinement.ts +193 -0
- package/src/experimental/projected-mesh.ts +399 -0
- package/src/experimental/projected-normal.ts +26 -0
- package/src/experimental/projected-symbol-mesh.ts +74 -0
- package/src/gl/constants.ts +18 -0
- package/src/gl/context.ts +103 -0
- package/src/gl/extensions.ts +30 -0
- package/src/gl/globe_mesh.ts +285 -0
- package/src/gl/glsl.ts +257 -0
- package/src/gl/mesh-types.ts +56 -0
- package/src/gl/render_state.ts +111 -0
- package/src/gl/shader_program.ts +1310 -0
- package/src/gl/texture.ts +814 -0
- package/src/gl/uniform_buffer.ts +340 -0
- package/src/gl/vao.ts +154 -0
- package/src/gl/vbo_mesh.ts +349 -0
- package/src/gl/vertex-constants.ts +19 -0
- package/src/gl/vertex-types.ts +35 -0
- package/src/gl/vertex_data.ts +126 -0
- package/src/gl/vertex_elements.ts +54 -0
- package/src/gl/vertex_layout.ts +241 -0
- package/src/glsl.d.ts +14 -0
- package/src/gpu/luma_device_renderer.ts +579 -0
- package/src/gpu/pixel_readback.ts +51 -0
- package/src/gpu/resource_lifecycle.ts +32 -0
- package/src/gpu/tangram_gpu_backend.ts +195 -0
- package/src/index.d.ts +155 -0
- package/src/index.ts +105 -0
- package/src/labels/collision-types.ts +94 -0
- package/src/labels/collision.ts +273 -0
- package/src/labels/collision_grid.ts +61 -0
- package/src/labels/intersect.ts +30 -0
- package/src/labels/label-types.ts +91 -0
- package/src/labels/label.ts +207 -0
- package/src/labels/label_line.ts +801 -0
- package/src/labels/label_point.ts +131 -0
- package/src/labels/main-pass-types.ts +73 -0
- package/src/labels/main_pass.ts +221 -0
- package/src/labels/point_anchor.ts +100 -0
- package/src/labels/point_placement.ts +150 -0
- package/src/labels/projected-pass.ts +259 -0
- package/src/labels/repeat_group.ts +72 -0
- package/src/lights/ambient_light.glsl +18 -0
- package/src/lights/directional_light.glsl +39 -0
- package/src/lights/geographic-lights.ts +21 -0
- package/src/lights/light-definitions.ts +285 -0
- package/src/lights/light.ts +590 -0
- package/src/lights/lighting-uniforms.ts +80 -0
- package/src/lights/lighting-wgsl.ts +116 -0
- package/src/lights/material.glsl +237 -0
- package/src/lights/material.ts +145 -0
- package/src/lights/native-falloff.ts +37 -0
- package/src/lights/point_light.glsl +96 -0
- package/src/lights/spot_light.glsl +111 -0
- package/src/map-logic/draped-terrain-bounds.ts +71 -0
- package/src/map-logic/globe-terrain-preparation.ts +217 -0
- package/src/map-logic/globe-terrain.ts +296 -0
- package/src/map-logic/index.ts +37 -0
- package/src/map-logic/label-identity.ts +36 -0
- package/src/map-logic/label-placement.ts +117 -0
- package/src/map-logic/screen-bounds.ts +34 -0
- package/src/map-logic/terrain-data.ts +107 -0
- package/src/map-logic/terrain-error.ts +134 -0
- package/src/map-logic/terrain-ground-topology.ts +164 -0
- package/src/map-logic/terrain-height-field.ts +254 -0
- package/src/map-logic/terrain-navigation.ts +50 -0
- package/src/map-logic/terrain-neighborhood.ts +43 -0
- package/src/map-logic/terrain-query.ts +51 -0
- package/src/map-logic/terrain-resource-budget.ts +124 -0
- package/src/map-logic/terrain-transition-topology.ts +164 -0
- package/src/map-logic/tile-build-queue.ts +110 -0
- package/src/map-logic/tile-cache-policy.ts +89 -0
- package/src/map-logic/tile-residency.ts +50 -0
- package/src/map-logic/triangle-query-index.ts +265 -0
- package/src/procedures/js-yaml.d.ts +15 -0
- package/src/procedures/mesh-projector.ts +191 -0
- package/src/procedures/mlt-loaders.ts +55 -0
- package/src/procedures/mvt-dependencies.d.ts +20 -0
- package/src/procedures/mvt-legacy.ts +150 -0
- package/src/procedures/mvt-loaders.ts +53 -0
- package/src/procedures/mvt-parser.ts +48 -0
- package/src/procedures/mvt-properties.ts +36 -0
- package/src/procedures/mvt-tile-provider.ts +72 -0
- package/src/procedures/pmtiles-loader.ts +75 -0
- package/src/procedures/projected-coordinate-transform.ts +79 -0
- package/src/procedures/projection-batch-executor.ts +140 -0
- package/src/procedures/scene-yaml-legacy.ts +16 -0
- package/src/procedures/scene-yaml-loaders.ts +10 -0
- package/src/procedures/terrain-draping.ts +713 -0
- package/src/procedures/terrain-globe.ts +32 -0
- package/src/procedures/terrain-styled-topology.ts +184 -0
- package/src/procedures/web-mercator-legacy.ts +24 -0
- package/src/procedures/web-mercator-math.ts +50 -0
- package/src/scene/camera.ts +298 -0
- package/src/scene/camera_base.ts +116 -0
- package/src/scene/classic_scene.ts +20 -0
- package/src/scene/external_camera.ts +101 -0
- package/src/scene/globals.ts +120 -0
- package/src/scene/ground_footprint.ts +139 -0
- package/src/scene/host_frame.ts +326 -0
- package/src/scene/projected_tile_lod.ts +125 -0
- package/src/scene/projection_math.ts +142 -0
- package/src/scene/projection_shaders.ts +183 -0
- package/src/scene/renderer.ts +516 -0
- package/src/scene/scene-resource-types.ts +174 -0
- package/src/scene/scene.ts +2378 -0
- package/src/scene/scene_bundle.ts +304 -0
- package/src/scene/scene_debug.ts +129 -0
- package/src/scene/scene_loader.ts +402 -0
- package/src/scene/scene_worker.ts +528 -0
- package/src/scene/view.ts +683 -0
- package/src/scene/visibility_adapter.ts +319 -0
- package/src/scene/worker_url.ts +15 -0
- package/src/selection/draped-terrain-surface.ts +377 -0
- package/src/selection/selection-types.ts +79 -0
- package/src/selection/selection.ts +542 -0
- package/src/selection/selection_fragment.glsl +18 -0
- package/src/selection/selection_globals.glsl +9 -0
- package/src/selection/selection_pixels.ts +59 -0
- package/src/selection/selection_vertex.glsl +15 -0
- package/src/selection/terrain_surface.ts +298 -0
- package/src/shader-modules/globe-horizon.ts +52 -0
- package/src/shader-modules/height-decode.ts +41 -0
- package/src/shader-modules/hillshade.ts +70 -0
- package/src/shader-modules/index.ts +10 -0
- package/src/shader-modules/planar.ts +24 -0
- package/src/shader-modules/sphere-map.ts +38 -0
- package/src/shader-modules/triplanar.ts +45 -0
- package/src/sources/aligned_tile_source.ts +122 -0
- package/src/sources/data_source.ts +655 -0
- package/src/sources/decoded_tile_store.ts +245 -0
- package/src/sources/geojson.ts +300 -0
- package/src/sources/mvt.ts +247 -0
- package/src/sources/raster.ts +341 -0
- package/src/sources/shared_tile_source_adapter.ts +117 -0
- package/src/sources/sources.ts +10 -0
- package/src/sources/tile_source_adapter.ts +84 -0
- package/src/sources/tile_source_metadata.ts +65 -0
- package/src/sources/tile_source_state.ts +112 -0
- package/src/sources/topojson.ts +90 -0
- package/src/styles/feature_annotations.ts +16 -0
- package/src/styles/filter.ts +190 -0
- package/src/styles/geometry-style-types.ts +209 -0
- package/src/styles/globe_visibility_wgsl.ts +22 -0
- package/src/styles/layer-types.ts +45 -0
- package/src/styles/layer.ts +586 -0
- package/src/styles/lines/dasharray.ts +49 -0
- package/src/styles/lines/lines.ts +707 -0
- package/src/styles/lines/lines_wgsl.ts +224 -0
- package/src/styles/points/point-runtime-types.ts +125 -0
- package/src/styles/points/points.ts +1079 -0
- package/src/styles/points/points_fragment.glsl +126 -0
- package/src/styles/points/points_vertex.glsl +230 -0
- package/src/styles/points/points_wgsl.ts +189 -0
- package/src/styles/polygons/polygons.ts +268 -0
- package/src/styles/polygons/polygons_fragment.glsl +173 -0
- package/src/styles/polygons/polygons_vertex.glsl +213 -0
- package/src/styles/polygons/polygons_wgsl.ts +127 -0
- package/src/styles/property-types.ts +125 -0
- package/src/styles/raster/raster.ts +33 -0
- package/src/styles/raster/raster_globals.glsl +46 -0
- package/src/styles/style-mixing-types.ts +101 -0
- package/src/styles/style-runtime-types.ts +220 -0
- package/src/styles/style-schema.ts +133 -0
- package/src/styles/style.ts +1033 -0
- package/src/styles/style_globals.glsl +69 -0
- package/src/styles/style_manager.ts +464 -0
- package/src/styles/style_parser.ts +620 -0
- package/src/styles/text/font_manager.ts +180 -0
- package/src/styles/text/fontfaceobserver.d.ts +10 -0
- package/src/styles/text/text-types.ts +220 -0
- package/src/styles/text/text.ts +378 -0
- package/src/styles/text/text_canvas.ts +773 -0
- package/src/styles/text/text_labels.ts +436 -0
- package/src/styles/text/text_segments.ts +142 -0
- package/src/styles/text/text_settings.ts +228 -0
- package/src/styles/text/text_wgsl.ts +159 -0
- package/src/styles/text/text_wrap.ts +194 -0
- package/src/tile/globe_tile_preload.ts +40 -0
- package/src/tile/tangram_tileset_2d.ts +108 -0
- package/src/tile/tile-build-types.ts +155 -0
- package/src/tile/tile.ts +807 -0
- package/src/tile/tile_id.ts +172 -0
- package/src/tile/tile_manager.ts +889 -0
- package/src/tile/tile_pyramid.ts +119 -0
- package/src/tile/tile_resource_cache.ts +91 -0
- package/src/tile/tile_traversal_adapter.ts +132 -0
- package/src/types.ts +332 -0
- package/src/utils/debounce.ts +17 -0
- package/src/utils/debug_settings.ts +43 -0
- package/src/utils/errors.ts +12 -0
- package/src/utils/functions.ts +95 -0
- package/src/utils/geo.ts +364 -0
- package/src/utils/hash.ts +14 -0
- package/src/utils/log.ts +108 -0
- package/src/utils/media_capture.ts +193 -0
- package/src/utils/merge.ts +44 -0
- package/src/utils/obb.ts +134 -0
- package/src/utils/props.ts +43 -0
- package/src/utils/slice.ts +14 -0
- package/src/utils/subscribe.ts +58 -0
- package/src/utils/task.ts +154 -0
- package/src/utils/thread.ts +26 -0
- package/src/utils/urls.ts +223 -0
- package/src/utils/utils.ts +310 -0
- package/src/utils/vector.ts +197 -0
- package/src/utils/version.ts +8 -0
- package/src/utils/worker-types.ts +79 -0
- package/src/utils/worker_broker.ts +523 -0
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
// tangram-layers
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) vis.gl contributors
|
|
4
|
+
|
|
5
|
+
// WebGL2 uniform buffer wrapper with std140-compatible CPU-side packing.
|
|
6
|
+
import type {UniformBufferBindingLayout} from '@luma.gl/core';
|
|
7
|
+
import type {TangramUniformBufferOptions} from '../gpu/tangram_gpu_backend';
|
|
8
|
+
|
|
9
|
+
/** Numeric scalar or vector accepted by std140 packing. */
|
|
10
|
+
export type UniformBufferValue = number | boolean | ArrayLike<number | boolean>;
|
|
11
|
+
|
|
12
|
+
/** Portable uniform resource; independent of a concrete backend implementation. */
|
|
13
|
+
export type UniformBufferResource = {
|
|
14
|
+
write(data: Uint8Array): unknown;
|
|
15
|
+
destroy(): unknown;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/** Allocation and layout of a scene-owned uniform block. */
|
|
19
|
+
export type UniformBufferOptions = {
|
|
20
|
+
id?: string;
|
|
21
|
+
name?: string;
|
|
22
|
+
binding?: number;
|
|
23
|
+
snapshotPerMesh?: boolean;
|
|
24
|
+
usage?: number;
|
|
25
|
+
uniforms?: Record<string, string>;
|
|
26
|
+
bufferFactory?: (options: TangramUniformBufferOptions) => UniformBufferResource;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/** Supported std140 element layout and corresponding shader declarations. */
|
|
30
|
+
type UniformTypeInfo = {
|
|
31
|
+
alignment: number;
|
|
32
|
+
size: number;
|
|
33
|
+
kind: 'float' | 'int';
|
|
34
|
+
glsl?: string;
|
|
35
|
+
wgsl: string;
|
|
36
|
+
} & ({components: number; columns?: undefined; rows?: undefined} |
|
|
37
|
+
{columns: 3 | 4; rows: 3 | 4; components?: undefined});
|
|
38
|
+
|
|
39
|
+
/** Byte location of one named member within a uniform block. */
|
|
40
|
+
type UniformLayoutMember = UniformTypeInfo & {name: string; type: string; offset: number};
|
|
41
|
+
|
|
42
|
+
/** Packed block size and ordered named members. */
|
|
43
|
+
type UniformLayout = {byte_length: number; uniforms: Record<string, UniformLayoutMember>};
|
|
44
|
+
|
|
45
|
+
const BLOCK_ALIGNMENT = 16;
|
|
46
|
+
const INVALID_INDEX = 0xFFFFFFFF;
|
|
47
|
+
|
|
48
|
+
const TYPES: Readonly<Record<string, UniformTypeInfo>> = {
|
|
49
|
+
float: { alignment: 4, size: 4, components: 1, kind: 'float', wgsl: 'f32' },
|
|
50
|
+
int: { alignment: 4, size: 4, components: 1, kind: 'int', glsl: 'highp int', wgsl: 'i32' },
|
|
51
|
+
bool: { alignment: 4, size: 4, components: 1, kind: 'int', wgsl: 'u32' },
|
|
52
|
+
vec2: { alignment: 8, size: 8, components: 2, kind: 'float', wgsl: 'vec2<f32>' },
|
|
53
|
+
ivec2: { alignment: 8, size: 8, components: 2, kind: 'int', glsl: 'highp ivec2', wgsl: 'vec2<i32>' },
|
|
54
|
+
vec3: { alignment: 16, size: 12, components: 3, kind: 'float', wgsl: 'vec3<f32>' },
|
|
55
|
+
ivec3: { alignment: 16, size: 12, components: 3, kind: 'int', glsl: 'highp ivec3', wgsl: 'vec3<i32>' },
|
|
56
|
+
vec4: { alignment: 16, size: 16, components: 4, kind: 'float', wgsl: 'vec4<f32>' },
|
|
57
|
+
ivec4: { alignment: 16, size: 16, components: 4, kind: 'int', glsl: 'highp ivec4', wgsl: 'vec4<i32>' },
|
|
58
|
+
mat3: { alignment: 16, size: 48, columns: 3, rows: 3, kind: 'float', wgsl: 'mat3x3<f32>' },
|
|
59
|
+
mat4: { alignment: 16, size: 64, columns: 4, rows: 4, kind: 'float', wgsl: 'mat4x4<f32>' }
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
export default class UniformBuffer {
|
|
63
|
+
/** Legacy context, absent for portable resources and after destruction. */
|
|
64
|
+
declare gl: WebGL2RenderingContext | null;
|
|
65
|
+
/** Stable block identity. */
|
|
66
|
+
declare readonly id: string;
|
|
67
|
+
/** Shader block name. */
|
|
68
|
+
declare readonly name: string;
|
|
69
|
+
/** Shader binding location. */
|
|
70
|
+
declare readonly binding: number;
|
|
71
|
+
/** Whether encoded mesh draws need immutable copies of this block. */
|
|
72
|
+
declare readonly snapshot_per_mesh: boolean;
|
|
73
|
+
/** Legacy allocation hint, absent for portable buffers. */
|
|
74
|
+
declare readonly usage: number | null;
|
|
75
|
+
/** Immutable std140 layout. */
|
|
76
|
+
declare readonly layout: UniformLayout;
|
|
77
|
+
/** CPU storage, released during destruction. */
|
|
78
|
+
declare data: ArrayBuffer | null;
|
|
79
|
+
/** CPU packing view, released during destruction. */
|
|
80
|
+
declare data_view: DataView | null;
|
|
81
|
+
/** Portable resource, or false when the legacy allocation path was used. */
|
|
82
|
+
declare buffer_resource: UniformBufferResource | false | null;
|
|
83
|
+
/** Active portable resource or legacy WebGL handle. */
|
|
84
|
+
declare buffer: UniformBufferResource | WebGLBuffer | false | null;
|
|
85
|
+
/** Program block indices; a null entry means that block is inactive. */
|
|
86
|
+
declare program_indices: WeakMap<WebGLProgram, {index: number} | null> | null;
|
|
87
|
+
/** Whether CPU writes need uploading. */
|
|
88
|
+
declare dirty: boolean;
|
|
89
|
+
|
|
90
|
+
static isSupported(gl: WebGLRenderingContext | null | undefined): gl is WebGL2RenderingContext {
|
|
91
|
+
return Boolean(gl &&
|
|
92
|
+
'UNIFORM_BUFFER' in gl && gl.UNIFORM_BUFFER != null &&
|
|
93
|
+
'bindBufferBase' in gl && typeof gl.bindBufferBase === 'function' &&
|
|
94
|
+
'getUniformBlockIndex' in gl && typeof gl.getUniformBlockIndex === 'function' &&
|
|
95
|
+
'uniformBlockBinding' in gl && typeof gl.uniformBlockBinding === 'function');
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
static createLayout(uniforms: Record<string, string>): UniformLayout {
|
|
99
|
+
let offset = 0;
|
|
100
|
+
const layout: Record<string, UniformLayoutMember> = {};
|
|
101
|
+
|
|
102
|
+
for (const [name, type] of Object.entries(uniforms)) {
|
|
103
|
+
const type_info = TYPES[type];
|
|
104
|
+
if (!type_info) {
|
|
105
|
+
throw new Error(`UniformBuffer: unsupported std140 type '${type}' for '${name}'`);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
offset = align(offset, type_info.alignment);
|
|
109
|
+
layout[name] = Object.assign({ name, type, offset }, type_info);
|
|
110
|
+
offset += type_info.size;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return {
|
|
114
|
+
byte_length: align(offset, BLOCK_ALIGNMENT),
|
|
115
|
+
uniforms: layout
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
constructor(gl: WebGL2RenderingContext | null, options: UniformBufferOptions = {}) {
|
|
120
|
+
const bufferFactory = options.bufferFactory;
|
|
121
|
+
const has_buffer_factory = typeof bufferFactory === 'function';
|
|
122
|
+
if (!UniformBuffer.isSupported(gl) && !has_buffer_factory) {
|
|
123
|
+
throw new Error('UniformBuffer requires a WebGL2 context');
|
|
124
|
+
}
|
|
125
|
+
if (!options.name) {
|
|
126
|
+
throw new Error('UniformBuffer requires a uniform block name');
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
this.gl = gl;
|
|
130
|
+
this.id = options.id || options.name;
|
|
131
|
+
this.name = options.name;
|
|
132
|
+
this.binding = options.binding || 0;
|
|
133
|
+
this.snapshot_per_mesh = options.snapshotPerMesh === true;
|
|
134
|
+
this.usage = options.usage || (has_buffer_factory ? null : requireContext(gl).DYNAMIC_DRAW);
|
|
135
|
+
this.layout = UniformBuffer.createLayout(options.uniforms || {});
|
|
136
|
+
this.data = new ArrayBuffer(this.layout.byte_length);
|
|
137
|
+
this.data_view = new DataView(this.data);
|
|
138
|
+
this.buffer_resource = has_buffer_factory && bufferFactory({
|
|
139
|
+
id: this.id,
|
|
140
|
+
byteLength: this.layout.byte_length,
|
|
141
|
+
usage: 'uniform'
|
|
142
|
+
});
|
|
143
|
+
this.buffer = has_buffer_factory ? this.buffer_resource : requireContext(gl).createBuffer();
|
|
144
|
+
this.program_indices = new WeakMap();
|
|
145
|
+
this.dirty = false;
|
|
146
|
+
|
|
147
|
+
if (!this.buffer) {
|
|
148
|
+
throw new Error(`UniformBuffer: could not create buffer '${this.name}'`);
|
|
149
|
+
}
|
|
150
|
+
if (this.buffer_resource) {
|
|
151
|
+
if (typeof this.buffer_resource.write !== 'function' ||
|
|
152
|
+
typeof this.buffer_resource.destroy !== 'function') {
|
|
153
|
+
throw new Error('UniformBuffer: bufferFactory must return a resource with write and destroy');
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
this.withBufferBinding(() => {
|
|
158
|
+
const context = requireContext(gl);
|
|
159
|
+
context.bufferData(context.UNIFORM_BUFFER, this.layout.byte_length, this.usage ?? context.DYNAMIC_DRAW);
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
get byteLength() {
|
|
165
|
+
return this.layout.byte_length;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
getDeclaration({ language = 'glsl', group = 0, variableName }: {language?: string; group?: number; variableName?: string} = {}) {
|
|
169
|
+
if (language === 'wgsl') {
|
|
170
|
+
return this.getWGSLDeclaration({ group, variableName });
|
|
171
|
+
}
|
|
172
|
+
if (language !== 'glsl') {
|
|
173
|
+
throw new Error(`UniformBuffer: unsupported shader language '${language}'`);
|
|
174
|
+
}
|
|
175
|
+
const declarations = Object.values(this.layout.uniforms)
|
|
176
|
+
.map(uniform => ` ${uniform.glsl || uniform.type} ${uniform.name};`)
|
|
177
|
+
.join('\n');
|
|
178
|
+
return `layout(std140) uniform ${this.name} {\n${declarations}\n};`;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
getWGSLDeclaration({ group = 0, variableName }: {group?: number; variableName?: string} = {}) {
|
|
182
|
+
variableName = variableName || this.name;
|
|
183
|
+
const struct_name = `${this.name}Uniforms`;
|
|
184
|
+
const declarations = Object.values(this.layout.uniforms)
|
|
185
|
+
.map(uniform => ` ${uniform.name}: ${uniform.wgsl},`)
|
|
186
|
+
.join('\n');
|
|
187
|
+
return [
|
|
188
|
+
`struct ${struct_name} {`,
|
|
189
|
+
declarations,
|
|
190
|
+
'};',
|
|
191
|
+
`@group(${group}) @binding(${this.binding}) var<uniform> ${variableName}: ${struct_name};`
|
|
192
|
+
].join('\n');
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
getBindingLayout({ group = 0 } = {}): UniformBufferBindingLayout {
|
|
196
|
+
return {
|
|
197
|
+
type: 'uniform',
|
|
198
|
+
name: this.name,
|
|
199
|
+
group,
|
|
200
|
+
location: this.binding,
|
|
201
|
+
minBindingSize: this.byteLength
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
setUniform(name: string, value: UniformBufferValue) {
|
|
206
|
+
const uniform = this.layout.uniforms[name];
|
|
207
|
+
if (!uniform) {
|
|
208
|
+
throw new Error(`UniformBuffer '${this.name}' has no uniform '${name}'`);
|
|
209
|
+
}
|
|
210
|
+
const dataView = this.data_view;
|
|
211
|
+
if (!dataView) throw new Error(`UniformBuffer '${this.name}' has been destroyed`);
|
|
212
|
+
|
|
213
|
+
const values = (typeof value === 'number' || typeof value === 'boolean') ? [value] : value;
|
|
214
|
+
const required = uniform.columns ? uniform.columns * uniform.rows : uniform.components;
|
|
215
|
+
if (!values || values.length !== required) {
|
|
216
|
+
throw new Error(`UniformBuffer '${this.name}.${name}' requires ${required} values`);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
if (uniform.columns) {
|
|
220
|
+
for (let column = 0; column < uniform.columns; column++) {
|
|
221
|
+
for (let row = 0; row < uniform.rows; row++) {
|
|
222
|
+
const index = column * uniform.rows + row;
|
|
223
|
+
dataView.setFloat32(uniform.offset + column * BLOCK_ALIGNMENT + row * 4, Number(values[index]), true);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
for (let component = 0; component < uniform.components; component++) {
|
|
229
|
+
const offset = uniform.offset + component * 4;
|
|
230
|
+
if (uniform.kind === 'int') {
|
|
231
|
+
dataView.setInt32(offset, Number(values[component]), true);
|
|
232
|
+
}
|
|
233
|
+
else {
|
|
234
|
+
dataView.setFloat32(offset, Number(values[component]), true);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
this.dirty = true;
|
|
240
|
+
return this;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
setUniforms(uniforms: Record<string, UniformBufferValue>) {
|
|
244
|
+
for (const [name, value] of Object.entries(uniforms)) {
|
|
245
|
+
this.setUniform(name, value);
|
|
246
|
+
}
|
|
247
|
+
return this;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
upload() {
|
|
251
|
+
if (!this.buffer || !this.dirty || !this.data) {
|
|
252
|
+
return false;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
const data = new Uint8Array(this.data);
|
|
256
|
+
if (this.buffer_resource) {
|
|
257
|
+
this.buffer_resource.write(data);
|
|
258
|
+
}
|
|
259
|
+
else {
|
|
260
|
+
this.withBufferBinding(() => {
|
|
261
|
+
const gl = requireContext(this.gl);
|
|
262
|
+
gl.bufferSubData(gl.UNIFORM_BUFFER, 0, data);
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
this.dirty = false;
|
|
266
|
+
return true;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
bind(program: WebGLProgram | null | undefined) {
|
|
270
|
+
if (!this.buffer || !program || !this.program_indices || !UniformBuffer.isSupported(this.gl)) {
|
|
271
|
+
return false;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
let program_binding = this.program_indices.get(program);
|
|
275
|
+
if (program_binding === undefined) {
|
|
276
|
+
const index = this.gl.getUniformBlockIndex(program, this.name);
|
|
277
|
+
if (index === this.gl.INVALID_INDEX || index === INVALID_INDEX) {
|
|
278
|
+
program_binding = null;
|
|
279
|
+
}
|
|
280
|
+
else {
|
|
281
|
+
program_binding = { index };
|
|
282
|
+
this.gl.uniformBlockBinding(program, index, this.binding);
|
|
283
|
+
}
|
|
284
|
+
this.program_indices.set(program, program_binding);
|
|
285
|
+
}
|
|
286
|
+
if (program_binding == null) {
|
|
287
|
+
return false;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
this.upload();
|
|
291
|
+
this.gl.bindBufferBase(this.gl.UNIFORM_BUFFER, this.binding, this.buffer);
|
|
292
|
+
return true;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
invalidateProgram(program: WebGLProgram | null | undefined) {
|
|
296
|
+
if (this.program_indices && program) {
|
|
297
|
+
this.program_indices.delete(program);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
destroy() {
|
|
302
|
+
if (this.buffer) {
|
|
303
|
+
if (this.buffer_resource) {
|
|
304
|
+
this.buffer_resource.destroy();
|
|
305
|
+
}
|
|
306
|
+
else {
|
|
307
|
+
requireContext(this.gl).deleteBuffer(this.buffer);
|
|
308
|
+
}
|
|
309
|
+
this.buffer = null;
|
|
310
|
+
}
|
|
311
|
+
this.buffer_resource = null;
|
|
312
|
+
this.gl = null;
|
|
313
|
+
this.data = null;
|
|
314
|
+
this.data_view = null;
|
|
315
|
+
this.program_indices = null;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
withBufferBinding<Result>(callback: () => Result): Result {
|
|
319
|
+
const gl = requireContext(this.gl);
|
|
320
|
+
const previous = typeof gl.getParameter === 'function' && gl.UNIFORM_BUFFER_BINDING != null ?
|
|
321
|
+
gl.getParameter(gl.UNIFORM_BUFFER_BINDING) : null;
|
|
322
|
+
gl.bindBuffer(gl.UNIFORM_BUFFER, this.buffer);
|
|
323
|
+
try {
|
|
324
|
+
return callback();
|
|
325
|
+
}
|
|
326
|
+
finally {
|
|
327
|
+
gl.bindBuffer(gl.UNIFORM_BUFFER, previous);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
function align(value: number, alignment: number) {
|
|
333
|
+
return Math.ceil(value / alignment) * alignment;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/** Require the legacy context only when no portable resource owns the operation. */
|
|
337
|
+
function requireContext(gl: WebGL2RenderingContext | null): WebGL2RenderingContext {
|
|
338
|
+
if (!gl) throw new Error('UniformBuffer requires a WebGL2 context');
|
|
339
|
+
return gl;
|
|
340
|
+
}
|
package/src/gl/vao.ts
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
// Tangram
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
3
|
+
// Copyright (c) 2013-2016 Brett Camper and Mapzen
|
|
4
|
+
// Copyright (c) 2026 vis.gl contributors
|
|
5
|
+
|
|
6
|
+
// Creates a Vertex Array Object if the extension is available, or falls back on standard attribute calls
|
|
7
|
+
|
|
8
|
+
import getExtension from './extensions';
|
|
9
|
+
import log from '../utils/log';
|
|
10
|
+
|
|
11
|
+
/** Extension shape shared by WebGL 1's OES API and the native WebGL 2 adapter. */
|
|
12
|
+
interface VertexArrayExtension {
|
|
13
|
+
createVertexArrayOES(): WebGLVertexArrayObject | null;
|
|
14
|
+
deleteVertexArrayOES(array: WebGLVertexArrayObject | null): void;
|
|
15
|
+
bindVertexArrayOES(array: WebGLVertexArrayObject | null): void;
|
|
16
|
+
}
|
|
17
|
+
/** Context operations needed to create or emulate vertex-array state. */
|
|
18
|
+
export type VertexArrayContext = Pick<WebGLRenderingContext, 'getExtension'> &
|
|
19
|
+
Partial<Pick<WebGL2RenderingContext, 'createVertexArray' | 'deleteVertexArray' | 'bindVertexArray'>>;
|
|
20
|
+
/** Stored setup/teardown hooks and an optional native vertex-array handle. */
|
|
21
|
+
export interface VertexArrayBinding {
|
|
22
|
+
setup(): void;
|
|
23
|
+
teardown?: () => void;
|
|
24
|
+
_vao?: WebGLVertexArrayObject | null;
|
|
25
|
+
}
|
|
26
|
+
/** Per-context VAO tracking with the legacy fallback behavior retained. */
|
|
27
|
+
interface VertexArrayRuntime {
|
|
28
|
+
disabled: boolean;
|
|
29
|
+
bound_vao: [VertexArrayContext, VertexArrayBinding | null][];
|
|
30
|
+
init(context: VertexArrayContext): void;
|
|
31
|
+
getExtension(context: VertexArrayContext, name: string): unknown;
|
|
32
|
+
create(context: VertexArrayContext, setup: () => void, teardown?: () => void): VertexArrayBinding;
|
|
33
|
+
getCurrentBinding(context: VertexArrayContext): VertexArrayBinding | null | undefined;
|
|
34
|
+
setCurrentBinding(context: VertexArrayContext, binding: VertexArrayBinding | null): void;
|
|
35
|
+
bind(context: VertexArrayContext, binding: VertexArrayBinding | null): void;
|
|
36
|
+
destroy(context: VertexArrayContext, binding: VertexArrayBinding | null | undefined): void;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const native_extensions = new WeakMap<object, VertexArrayExtension>();
|
|
40
|
+
|
|
41
|
+
function getVertexArrayExtension(gl: VertexArrayContext): VertexArrayExtension | null | undefined {
|
|
42
|
+
const extension = getExtension(gl, 'OES_vertex_array_object') as VertexArrayExtension | null;
|
|
43
|
+
if (extension || typeof gl.createVertexArray !== 'function') {
|
|
44
|
+
return extension;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (!native_extensions.has(gl)) {
|
|
48
|
+
native_extensions.set(gl, {
|
|
49
|
+
createVertexArrayOES: () => gl.createVertexArray!(),
|
|
50
|
+
deleteVertexArrayOES: vao => gl.deleteVertexArray!(vao),
|
|
51
|
+
bindVertexArrayOES: vao => gl.bindVertexArray!(vao)
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
return native_extensions.get(gl);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const Vao: VertexArrayRuntime = {
|
|
58
|
+
|
|
59
|
+
disabled: false, // set to true to disable VAOs even if extension is available
|
|
60
|
+
bound_vao: [], // currently bound VAO, by GL context
|
|
61
|
+
|
|
62
|
+
init (gl) {
|
|
63
|
+
let ext;
|
|
64
|
+
if (this.disabled !== true) {
|
|
65
|
+
ext = getVertexArrayExtension(gl);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (ext != null) {
|
|
69
|
+
log('info', 'Vertex Array Object extension available');
|
|
70
|
+
}
|
|
71
|
+
else if (this.disabled !== true) {
|
|
72
|
+
log('warn', 'Vertex Array Object extension NOT available');
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
log('warn', 'Vertex Array Object extension force disabled');
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
|
|
79
|
+
getExtension(gl, ext_name) {
|
|
80
|
+
if (this.disabled !== true) {
|
|
81
|
+
if (ext_name === 'OES_vertex_array_object') {
|
|
82
|
+
return getVertexArrayExtension(gl);
|
|
83
|
+
}
|
|
84
|
+
return getExtension(gl, ext_name);
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
|
|
88
|
+
create (gl, setup, teardown) {
|
|
89
|
+
let vao = {} as VertexArrayBinding; // Hooks are assigned before the binding escapes.
|
|
90
|
+
vao.setup = setup;
|
|
91
|
+
vao.teardown = teardown;
|
|
92
|
+
|
|
93
|
+
let ext = this.getExtension(gl, 'OES_vertex_array_object') as VertexArrayExtension | null | undefined;
|
|
94
|
+
if (ext != null) {
|
|
95
|
+
vao._vao = ext.createVertexArrayOES();
|
|
96
|
+
ext.bindVertexArrayOES(vao._vao);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
vao.setup();
|
|
100
|
+
|
|
101
|
+
return vao;
|
|
102
|
+
},
|
|
103
|
+
|
|
104
|
+
getCurrentBinding (gl) {
|
|
105
|
+
let bound = this.bound_vao.filter(e => e[0] === gl)[0];
|
|
106
|
+
return bound && bound[1];
|
|
107
|
+
},
|
|
108
|
+
|
|
109
|
+
setCurrentBinding (gl, vao) {
|
|
110
|
+
let bound_vao = this.bound_vao;
|
|
111
|
+
let binding = bound_vao.filter(e => e[0] === gl)[0];
|
|
112
|
+
if (binding == null) {
|
|
113
|
+
bound_vao.push([gl, vao]);
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
binding[1] = vao;
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
|
|
120
|
+
bind (gl, vao) {
|
|
121
|
+
let ext = this.getExtension(gl, 'OES_vertex_array_object') as VertexArrayExtension | null | undefined;
|
|
122
|
+
if (vao != null) {
|
|
123
|
+
if (ext != null && vao._vao != null) {
|
|
124
|
+
ext.bindVertexArrayOES(vao._vao);
|
|
125
|
+
this.setCurrentBinding(gl, vao);
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
vao.setup();
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
let bound_vao = this.getCurrentBinding(gl);
|
|
133
|
+
if (ext != null) {
|
|
134
|
+
ext.bindVertexArrayOES(null);
|
|
135
|
+
}
|
|
136
|
+
else if (bound_vao != null && typeof bound_vao.teardown === 'function') {
|
|
137
|
+
bound_vao.teardown();
|
|
138
|
+
}
|
|
139
|
+
this.setCurrentBinding(gl, null);
|
|
140
|
+
}
|
|
141
|
+
},
|
|
142
|
+
|
|
143
|
+
destroy (gl, vao) {
|
|
144
|
+
let ext = this.getExtension(gl, 'OES_vertex_array_object') as VertexArrayExtension | null | undefined;
|
|
145
|
+
if (ext != null && vao != null && vao._vao != null) {
|
|
146
|
+
ext.deleteVertexArrayOES(vao._vao);
|
|
147
|
+
vao._vao = null;
|
|
148
|
+
}
|
|
149
|
+
// destroy is a no-op if VAO extension isn't available
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
export default Vao;
|