From d441087a03fdc3bb2e04227766ae6995424c754c Mon Sep 17 00:00:00 2001 From: Alexey Kalenkevich Date: Sun, 7 Apr 2024 03:25:20 +0000 Subject: [PATCH] Make text buffers caclucations distance independant. --- .../objects/glyph/glyph_group_builder.ts | 11 ++- .../webgl/objects/glyph/glyph_shaders.ts | 1 + .../webgl/objects/image/image_shader.ts | 1 + .../webgl/objects/line/line_builder.ts | 36 ++-------- .../webgl/objects/line/line_shaders.ts | 1 + .../line_shader/line_shader_builder.ts | 5 +- .../line_shader/line_shader_shaders.ts | 1 + .../objects/object/object_group_builder.ts | 7 -- .../webgl/objects/object/object_program.ts | 7 +- .../webgl/objects/point/point_builder.ts | 7 +- .../webgl/objects/point/point_shaders.ts | 1 + .../webgl/objects/polygon/polygon_builder.ts | 3 +- .../webgl/objects/polygon/polygon_shaders.ts | 1 + .../objects/text_texture/text_texture.ts | 12 ++-- .../text_texture/text_texture_builder.ts | 71 ++++++++++++------- .../text_texture/text_texture_program.ts | 9 ++- .../text_texture/text_texture_shaders.ts | 35 ++++++++- .../text_vector/text_vector_builder.ts | 4 +- .../text_vector/text_vector_shaders.ts | 2 +- .../webgl/utils/object_properties_texture.ts | 47 ++++++++++++ src/map/renderer/webgl/webgl_renderer.ts | 1 + src/map/texture/texture.ts | 13 +++- src/map/texture/texture_utils.ts | 27 ++++++- 23 files changed, 208 insertions(+), 95 deletions(-) create mode 100644 src/map/renderer/webgl/utils/object_properties_texture.ts diff --git a/src/map/renderer/webgl/objects/glyph/glyph_group_builder.ts b/src/map/renderer/webgl/objects/glyph/glyph_group_builder.ts index ba99425..847719a 100644 --- a/src/map/renderer/webgl/objects/glyph/glyph_group_builder.ts +++ b/src/map/renderer/webgl/objects/glyph/glyph_group_builder.ts @@ -49,14 +49,12 @@ export class GlyphGroupBuilder extends ObjectGroupBuilder, + coordinates: Array<[number, number]>, lineWidth: number, joinStyle?: LineJoinStyle, ): number { @@ -147,14 +147,8 @@ export class LineGroupBuilder extends ObjectGroupBuilder [v[0], v[1]]); -} diff --git a/src/map/renderer/webgl/objects/line/line_shaders.ts b/src/map/renderer/webgl/objects/line/line_shaders.ts index 0e9b24a..b6b28b0 100644 --- a/src/map/renderer/webgl/objects/line/line_shaders.ts +++ b/src/map/renderer/webgl/objects/line/line_shaders.ts @@ -10,6 +10,7 @@ export default { uniform mat3 u_matrix; uniform float u_width; uniform float u_height; + uniform float u_distance; attribute vec2 point_a; attribute vec4 a_color; diff --git a/src/map/renderer/webgl/objects/line_shader/line_shader_builder.ts b/src/map/renderer/webgl/objects/line_shader/line_shader_builder.ts index a886bb4..8172791 100644 --- a/src/map/renderer/webgl/objects/line_shader/line_shader_builder.ts +++ b/src/map/renderer/webgl/objects/line_shader/line_shader_builder.ts @@ -1,4 +1,3 @@ -import { vec2 } from 'gl-matrix'; import { MapFeatureType, LineMapFeature } from '../../../../tile/feature'; import { WebGlObjectAttributeType } from '../object/object'; import { ObjectGroupBuilder } from '../object/object_group_builder'; @@ -7,7 +6,7 @@ import { createdSharedArrayBuffer } from '../../utils/array_buffer'; import { integerToVector4 } from '../../utils/number2vec'; import { addXTimes } from '../../utils/array_utils'; -const getBbox = (p1: [number, number] | vec2, p2: [number, number] | vec2): [number, number, number, number] => { +const getBbox = (p1: [number, number], p2: [number, number]): [number, number, number, number] => { const minX = Math.min(p1[0], p2[0]); const minY = Math.min(p1[1], p2[1]); const maxX = Math.max(p1[0], p2[0]); @@ -31,7 +30,7 @@ export class LineShaiderBuilder extends ObjectGroupBuilder; clear(): void { diff --git a/src/map/renderer/webgl/objects/object/object_program.ts b/src/map/renderer/webgl/objects/object/object_program.ts index ad81498..ae801db 100644 --- a/src/map/renderer/webgl/objects/object/object_program.ts +++ b/src/map/renderer/webgl/objects/object/object_program.ts @@ -18,7 +18,7 @@ export abstract class ObjectProgram { protected u_matrixLocation: WebGLUniformLocation; protected u_widthLocation: WebGLUniformLocation; protected u_heightLocation: WebGLUniformLocation; - protected u_tile_sizeLocation: WebGLUniformLocation; + protected u_distanceLocation: WebGLUniformLocation; protected u_is_read_pixel_render_modeLocation: WebGLUniformLocation; protected u_feature_flagsLocations: Record; @@ -96,6 +96,7 @@ export abstract class ObjectProgram { this.u_matrixLocation = this.gl.getUniformLocation(this.program, 'u_matrix'); this.u_widthLocation = this.gl.getUniformLocation(this.program, 'u_width'); this.u_heightLocation = this.gl.getUniformLocation(this.program, 'u_height'); + this.u_distanceLocation = this.gl.getUniformLocation(this.program, 'u_distance'); this.u_is_read_pixel_render_modeLocation = this.gl.getUniformLocation(this.program, 'u_is_read_pixel_render_mode'); this.u_feature_flagsLocations = {}; @@ -132,6 +133,10 @@ export abstract class ObjectProgram { this.gl.uniform1f(this.u_heightLocation, height); } + setDistance(distance: number) { + this.gl.uniform1f(this.u_distanceLocation, distance); + } + setReadPixelRenderMode(isReadPixelRenderMode: boolean) { this.gl.uniform1i(this.u_is_read_pixel_render_modeLocation, isReadPixelRenderMode ? 1 : 0); } diff --git a/src/map/renderer/webgl/objects/point/point_builder.ts b/src/map/renderer/webgl/objects/point/point_builder.ts index 9a1b9ac..673755c 100644 --- a/src/map/renderer/webgl/objects/point/point_builder.ts +++ b/src/map/renderer/webgl/objects/point/point_builder.ts @@ -1,4 +1,3 @@ -import { vec2 } from 'gl-matrix'; import { MapFeatureType, PointMapFeature } from '../../../../tile/feature'; import { WebGlPointBufferredGroup } from './point'; import { WebGlObjectAttributeType } from '../object/object'; @@ -17,8 +16,8 @@ export class PointGroupBuilder extends ObjectGroupBuilder>): number { +export function verticesFromPolygon(result: number[], coordinates: Array>): number { const start = result.length; const data = earcut.flatten(coordinates); const triangles = earcut(data.vertices, data.holes, 2); diff --git a/src/map/renderer/webgl/objects/polygon/polygon_shaders.ts b/src/map/renderer/webgl/objects/polygon/polygon_shaders.ts index ddc262f..d9db133 100644 --- a/src/map/renderer/webgl/objects/polygon/polygon_shaders.ts +++ b/src/map/renderer/webgl/objects/polygon/polygon_shaders.ts @@ -10,6 +10,7 @@ export default { uniform mat3 u_matrix; uniform float u_width; uniform float u_height; + uniform float u_distance; uniform bool u_is_read_pixel_render_mode; attribute vec2 a_position; diff --git a/src/map/renderer/webgl/objects/text_texture/text_texture.ts b/src/map/renderer/webgl/objects/text_texture/text_texture.ts index d3722e5..229192e 100644 --- a/src/map/renderer/webgl/objects/text_texture/text_texture.ts +++ b/src/map/renderer/webgl/objects/text_texture/text_texture.ts @@ -7,9 +7,11 @@ export interface WebGlTextTextureBufferredGroup extends WebGlObjectBufferredGrou numElements: number; // number of elements textureIndex: number; sfdTexture: boolean; - vertecies: WebGlObjectAttributeDescriptor; // Array; - textcoords: WebGlObjectAttributeDescriptor; // Array; - color: WebGlObjectAttributeDescriptor; // Array; - borderColor: WebGlObjectAttributeDescriptor; // Array; - selectionColor: WebGlObjectAttributeDescriptor; // Array; + vertecies: WebGlObjectAttributeDescriptor; + textcoords: WebGlObjectAttributeDescriptor; + // [width, height, ascend, offset] + textProperties: WebGlObjectAttributeDescriptor; + color: WebGlObjectAttributeDescriptor; + borderColor: WebGlObjectAttributeDescriptor; + selectionColor: WebGlObjectAttributeDescriptor; } diff --git a/src/map/renderer/webgl/objects/text_texture/text_texture_builder.ts b/src/map/renderer/webgl/objects/text_texture/text_texture_builder.ts index 2e3ba37..aa6c207 100644 --- a/src/map/renderer/webgl/objects/text_texture/text_texture_builder.ts +++ b/src/map/renderer/webgl/objects/text_texture/text_texture_builder.ts @@ -1,4 +1,3 @@ -import { vec4 } from 'gl-matrix'; import { MapFeatureType, TextMapFeature } from '../../../../tile/feature'; import { WebGlTextTextureBufferredGroup } from './text_texture'; import { WebGlObjectAttributeType } from '../object/object'; @@ -17,12 +16,19 @@ import { } from '../../../../font/font_config'; import { addXTimes } from '../../utils/array_utils'; +enum VERTEX_POSITION { + TOP_LEFT = 0, + TOP_RIGHT = 1, + BOTTOM_LEFT = 2, + BOTTOM_RIGHT = 3, +} + export interface GlyphMapping { glyph: TextureFontGlyph | SdfFontGlyph; font: string; fontSize: number; - color: vec4 | [number, number, number, number]; - borderColor: vec4 | [number, number, number, number]; + color: [number, number, number, number]; + borderColor: [number, number, number, number]; } export class TextTextureGroupBuilder extends ObjectGroupBuilder { @@ -46,9 +52,11 @@ export class TextTextureGroupBuilder extends ObjectGroupBuilder; + +export function createObjectPropertiesTexture(): PropertiesTexture { + const arrayBuffer: number[] = []; + + return { + addValue(value: ObjectPropertyValue): number { + const ref = arrayBuffer.length; + + if (Array.isArray(value)) { + if (value.length === 2) { + arrayBuffer.push(...value, 0, 0); + } else if (value.length === 3) { + arrayBuffer.push(...value, 0); + } else { + arrayBuffer.push(...value); + } + } else { + arrayBuffer.push(value, 0, 0, 0); + } + + return ref; + }, + compileTexture(): Float32ArrayBufferTextureSource { + const width = Math.ceil(Math.sqrt(arrayBuffer.length / 4)); + const height = width; + + const zerosToAdd = width * height * 4 - arrayBuffer.length; + for (let i = 0; i < zerosToAdd; i++) { + arrayBuffer.push(0); + } + + return floatArrayBufferToSharebleTextureSource(arrayBuffer, width, height); + }, + }; +} diff --git a/src/map/renderer/webgl/webgl_renderer.ts b/src/map/renderer/webgl/webgl_renderer.ts index b1e8f42..8534e23 100644 --- a/src/map/renderer/webgl/webgl_renderer.ts +++ b/src/map/renderer/webgl/webgl_renderer.ts @@ -234,6 +234,7 @@ export class WebGlRenderer { program.setMatrix(camera.viewMatrix); program.setWidth(this.rootEl.offsetWidth); program.setHeight(this.rootEl.offsetHeight); + program.setDistance(camera.distance); program.setReadPixelRenderMode(options.readPixelRenderMode || false); } } diff --git a/src/map/texture/texture.ts b/src/map/texture/texture.ts index 50860a4..13ceb86 100644 --- a/src/map/texture/texture.ts +++ b/src/map/texture/texture.ts @@ -1,9 +1,10 @@ export enum TextureSourceType { ARRAY_BUFFER = 0, - IMAGE_BITMAP = 1, + FLOAT_ARRAY_BUFFER = 1, + IMAGE_BITMAP = 2, } -export type TextureSource = ArrayBufferTextureSource | ImageBitmapTextureSource; +export type TextureSource = ArrayBufferTextureSource | ImageBitmapTextureSource | Float32ArrayBufferTextureSource; /** Bynary source of the image. */ export interface ArrayBufferTextureSource { @@ -13,6 +14,14 @@ export interface ArrayBufferTextureSource { data: Uint8ClampedArray; } +/** Bynary source of the image. */ +export interface Float32ArrayBufferTextureSource { + type: TextureSourceType.FLOAT_ARRAY_BUFFER; + width: number; + height: number; + data: Float32Array; +} + /** Bitmap image source. Ready to be used in canvas by GPU. */ export interface ImageBitmapTextureSource { type: TextureSourceType.IMAGE_BITMAP; diff --git a/src/map/texture/texture_utils.ts b/src/map/texture/texture_utils.ts index bbe9e4e..027b73e 100644 --- a/src/map/texture/texture_utils.ts +++ b/src/map/texture/texture_utils.ts @@ -1,4 +1,10 @@ -import { ArrayBufferTextureSource, TextureSource, TextureSourceType, ImageBitmapTextureSource } from './texture'; +import { + ArrayBufferTextureSource, + TextureSource, + TextureSourceType, + ImageBitmapTextureSource, + Float32ArrayBufferTextureSource, +} from './texture'; export function canvasToArrayBufferTextureSource( canvas: HTMLCanvasElement | OffscreenCanvas, @@ -30,7 +36,7 @@ export function canvasToSharebleArrayBufferTextureSource( } export function arrayBufferToSharebleTextureSource( - originalBuffer: Uint8ClampedArray, + originalBuffer: Uint8ClampedArray | number[], width: number, height: number, ): ArrayBufferTextureSource { @@ -46,6 +52,23 @@ export function arrayBufferToSharebleTextureSource( }; } +export function floatArrayBufferToSharebleTextureSource( + originalBuffer: Float32Array | number[], + width: number, + height: number, +): Float32ArrayBufferTextureSource { + const sharedMemoryBuffer = new SharedArrayBuffer(originalBuffer.length * Uint8ClampedArray.BYTES_PER_ELEMENT); + const resultBuffer = new Float32Array(sharedMemoryBuffer); + resultBuffer.set(originalBuffer); + + return { + type: TextureSourceType.FLOAT_ARRAY_BUFFER, + width, + height, + data: resultBuffer, + }; +} + export async function toImageBitmapTexture( texture: TextureSource, options?: ImageBitmapOptions,