Skip to content

Commit

Permalink
Make text buffers caclucations distance independant.
Browse files Browse the repository at this point in the history
  • Loading branch information
kalenkevich committed Apr 7, 2024
1 parent a7b8976 commit d441087
Show file tree
Hide file tree
Showing 23 changed files with 208 additions and 95 deletions.
11 changes: 5 additions & 6 deletions src/map/renderer/webgl/objects/glyph/glyph_group_builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,12 @@ export class GlyphGroupBuilder extends ObjectGroupBuilder<GlyphMapFeature, WebGl

const textureWidth = textureAtlas.width;
const textureHeight = textureAtlas.height;
const glyphScaledWidth = this.scalarScale(glyphMapping.width / glyphMapping.pixelRatio, distance);
const glyphScaledHeight = this.scalarScale(glyphMapping.height / glyphMapping.pixelRatio, distance);
const marginTop = this.scalarScale((glyph.margin?.top || 0) / this.pixelRatio, distance);
const marginLeft = this.scalarScale((glyph.margin?.left || 0) / this.pixelRatio, distance);
const glyphScaledWidth = glyphMapping.width / glyphMapping.pixelRatio / distance;
const glyphScaledHeight = glyphMapping.height / glyphMapping.pixelRatio / distance;

let [x1, y1] = [glyph.center[0], glyph.center[1]];
x1 = x1 - glyphScaledWidth / 2 + marginTop;
y1 = y1 - glyphScaledHeight / 2 + marginLeft;
x1 = x1 - glyphScaledWidth / 2;
y1 = y1 - glyphScaledHeight / 2;
const x2 = x1 + glyphScaledWidth;
const y2 = y1 + glyphScaledHeight;

Expand Down Expand Up @@ -101,6 +99,7 @@ export class GlyphGroupBuilder extends ObjectGroupBuilder<GlyphMapFeature, WebGl
size: 2,
buffer: createdSharedArrayBuffer(texcoordBuffer),
},

color: {
type: WebGlObjectAttributeType.FLOAT,
size: 4,
Expand Down
1 change: 1 addition & 0 deletions src/map/renderer/webgl/objects/glyph/glyph_shaders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export default {
uniform mat3 u_matrix;
uniform float u_width;
uniform float u_height;
uniform float u_distance;
attribute vec2 a_position;
attribute vec2 a_texCoord;
Expand Down
1 change: 1 addition & 0 deletions src/map/renderer/webgl/objects/image/image_shader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export default {
uniform mat3 u_matrix;
uniform float u_width;
uniform float u_height;
uniform float u_distance;
attribute vec2 a_position;
attribute vec2 a_texCoord;
Expand Down
36 changes: 5 additions & 31 deletions src/map/renderer/webgl/objects/line/line_builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ export class LineGroupBuilder extends ObjectGroupBuilder<LineMapFeature, WebGlLi
verticesFromLine(
distance: number,
result: number[],
coordinates: Array<[number, number] | vec2>,
coordinates: Array<[number, number]>,
lineWidth: number,
joinStyle?: LineJoinStyle,
): number {
Expand All @@ -147,14 +147,8 @@ export class LineGroupBuilder extends ObjectGroupBuilder<LineMapFeature, WebGlLi
return result.length - start;
}

lineToTriangles(
distance: number,
result: number[],
p1: [number, number] | vec2,
p2: [number, number] | vec2,
lineWidth: number,
) {
const scaledLineWidth = this.scalarScale(lineWidth, distance);
lineToTriangles(distance: number, result: number[], p1: [number, number], p2: [number, number], lineWidth: number) {
const scaledLineWidth = lineWidth / distance;
const p1Projected = vec2.fromValues(p1[0], p1[1]);
const p2Projected = vec2.fromValues(p2[0], p2[1]);

Expand All @@ -178,8 +172,8 @@ export class LineGroupBuilder extends ObjectGroupBuilder<LineMapFeature, WebGlLi
}
}

roundJoinToTriangles(distance: number, result: number[], center: [number, number] | vec2, lineWidth: number) {
const scaledLineWidth = this.scalarScale(lineWidth, distance);
roundJoinToTriangles(distance: number, result: number[], center: [number, number], lineWidth: number) {
const scaledLineWidth = lineWidth / distance;
const centerVec = vec2.fromValues(center[0], center[1]);

for (const pos of ROUND_JOIN_POSITION) {
Expand All @@ -193,23 +187,3 @@ export class LineGroupBuilder extends ObjectGroupBuilder<LineMapFeature, WebGlLi
}
}
}

export function getRoundJoinPositions(componets = 16): vec2[] {
const positions: vec2[] = [
vec2.fromValues(0, 0),
vec2.fromValues(0.5, 0),
vec2.fromValues(0.5 * Math.cos((2 * Math.PI * 1) / componets), 0.5 * Math.sin((2 * Math.PI * 1) / componets)),
];

for (let wedge = 2; wedge <= componets; wedge++) {
const theta = (2 * Math.PI * wedge) / componets;
const next = vec2.fromValues(0.5 * Math.cos(theta), 0.5 * Math.sin(theta));
const prev = positions[positions.length - 1];

positions.push(vec2.fromValues(0, 0));
positions.push(prev);
positions.push(next);
}

return positions.map(v => [v[0], v[1]]);
}
1 change: 1 addition & 0 deletions src/map/renderer/webgl/objects/line/line_shaders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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]);
Expand All @@ -31,7 +30,7 @@ export class LineShaiderBuilder extends ObjectGroupBuilder<LineMapFeature, WebGl
const selectionColor: number[] = [];

for (const line of this.objects) {
const halfWidth = (this.scalarScale(line.borderWidth, distance) + this.scalarScale(line.width, distance)) / 2;
const halfWidth = (line.borderWidth + line.width) / distance / 2;
const idAsVector4 = integerToVector4(line.id);

for (let i = 1; i < line.vertecies.length; i++) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export default {
uniform float u_height;
uniform float u_tile_size;
uniform float u_renderType;
uniform float u_distance;
attribute vec2 a_vertecies;
attribute vec2 a_prevPoint;
Expand Down
7 changes: 0 additions & 7 deletions src/map/renderer/webgl/objects/object/object_group_builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,6 @@ export abstract class ObjectGroupBuilder<
return this.objects.length === 0;
}

/**
* Scales value for webgl canvas value according to the current zoom and tileSize.
* */
scalarScale(val: number, distance: number): number {
return val / distance;
}

abstract build(distance: number, name: string, zIndex: number): OutputObjectType | Promise<OutputObjectType>;

clear(): void {
Expand Down
7 changes: 6 additions & 1 deletion src/map/renderer/webgl/objects/object/object_program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<string, WebGLUniformLocation>;

Expand Down Expand Up @@ -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 = {};
Expand Down Expand Up @@ -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);
}
Expand Down
7 changes: 3 additions & 4 deletions src/map/renderer/webgl/objects/point/point_builder.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { vec2 } from 'gl-matrix';
import { MapFeatureType, PointMapFeature } from '../../../../tile/feature';
import { WebGlPointBufferredGroup } from './point';
import { WebGlObjectAttributeType } from '../object/object';
Expand All @@ -17,8 +16,8 @@ export class PointGroupBuilder extends ObjectGroupBuilder<PointMapFeature, WebGl
const selectionColorBuffer: number[] = [];

for (const point of this.objects) {
const scaledRadius = this.scalarScale(point.radius, distance);
const scaledBorderWidth = this.scalarScale(point.borderWidth, distance);
const scaledRadius = point.radius / distance;
const scaledBorderWidth = point.borderWidth / distance;
const numberOfAddedVertecies = verticesFromPoint(vertecies, point.center, scaledRadius, point.components);
const xTimes = numberOfAddedVertecies / 2;

Expand Down Expand Up @@ -71,7 +70,7 @@ export class PointGroupBuilder extends ObjectGroupBuilder<PointMapFeature, WebGl

export function verticesFromPoint(
result: number[],
center: vec2 | [number, number],
center: [number, number],
radius = 0.0001,
components = 32,
): number {
Expand Down
1 change: 1 addition & 0 deletions src/map/renderer/webgl/objects/point/point_shaders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
3 changes: 1 addition & 2 deletions src/map/renderer/webgl/objects/polygon/polygon_builder.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { vec2 } from 'gl-matrix';
import earcut from 'earcut';
import { MapFeatureType, PolygonMapFeature } from '../../../../tile/feature';
import { WebGlPolygonBufferredGroup } from './polygon';
Expand Down Expand Up @@ -61,7 +60,7 @@ export class PolygonGroupBuilder extends ObjectGroupBuilder<PolygonMapFeature, W
}
}

export function verticesFromPolygon(result: number[], coordinates: Array<Array<vec2>>): number {
export function verticesFromPolygon(result: number[], coordinates: Array<Array<[number, number]>>): number {
const start = result.length;
const data = earcut.flatten(coordinates);
const triangles = earcut(data.vertices, data.holes, 2);
Expand Down
1 change: 1 addition & 0 deletions src/map/renderer/webgl/objects/polygon/polygon_shaders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
12 changes: 7 additions & 5 deletions src/map/renderer/webgl/objects/text_texture/text_texture.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ export interface WebGlTextTextureBufferredGroup extends WebGlObjectBufferredGrou
numElements: number; // number of elements
textureIndex: number;
sfdTexture: boolean;
vertecies: WebGlObjectAttributeDescriptor<WebGlObjectAttributeType.FLOAT, 2, Float32Array>; // Array<vec2>;
textcoords: WebGlObjectAttributeDescriptor<WebGlObjectAttributeType.FLOAT, 2, Float32Array>; // Array<vec2>;
color: WebGlObjectAttributeDescriptor<WebGlObjectAttributeType.FLOAT, 4, Float32Array>; // Array<vec4>;
borderColor: WebGlObjectAttributeDescriptor<WebGlObjectAttributeType.FLOAT, 4, Float32Array>; // Array<vec4>;
selectionColor: WebGlObjectAttributeDescriptor<WebGlObjectAttributeType.FLOAT, 4, Float32Array>; // Array<vec4>;
vertecies: WebGlObjectAttributeDescriptor<WebGlObjectAttributeType.FLOAT, 3, Float32Array>;
textcoords: WebGlObjectAttributeDescriptor<WebGlObjectAttributeType.FLOAT, 2, Float32Array>;
// [width, height, ascend, offset]
textProperties: WebGlObjectAttributeDescriptor<WebGlObjectAttributeType.FLOAT, 4, Float32Array>;
color: WebGlObjectAttributeDescriptor<WebGlObjectAttributeType.FLOAT, 4, Float32Array>;
borderColor: WebGlObjectAttributeDescriptor<WebGlObjectAttributeType.FLOAT, 4, Float32Array>;
selectionColor: WebGlObjectAttributeDescriptor<WebGlObjectAttributeType.FLOAT, 4, Float32Array>;
}
71 changes: 47 additions & 24 deletions src/map/renderer/webgl/objects/text_texture/text_texture_builder.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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<TextMapFeature, WebGlTextTextureBufferredGroup> {
Expand All @@ -46,52 +52,64 @@ export class TextTextureGroupBuilder extends ObjectGroupBuilder<TextMapFeature,
const size = this.objects.length;
const verteciesBuffer: number[] = [];
const texcoordBuffer: number[] = [];
const textProperties: number[] = [];
const colorBuffer: number[] = [];
const borderColorBuffer: number[] = [];
const selectionColorBuffer: number[] = [];
// TODO: support any font
const fontAtlas = this.fontManager.getFontAtlas('defaultFont') as TextureFontAtlas | SdfFontAtlas;
const texture = fontAtlas.sources[0];
let numElements = 0;

for (const text of this.objects) {
let offset = 0;
const selectionColorId = integerToVector4(text.id);
// vertex coordinates
const x1 = text.center[0];
const y1 = text.center[1];

for (const char of text.text) {
const glyphMapping = this.getGlyphMapping(text, char, fontAtlas);
const scaleFactor = text.fontSize / glyphMapping.glyph.fontSize / glyphMapping.glyph.pixelRatio;
const textScaledWidth = this.scalarScale(glyphMapping.glyph.width, distance) * scaleFactor;
const textScaledHeight = this.scalarScale(glyphMapping.glyph.height, distance) * scaleFactor;
const ascend = this.scalarScale(glyphMapping.glyph.actualBoundingBoxAscent, distance) * scaleFactor;

// vertex coordinates
let [x1, y1] = text.center;
x1 = offset + x1;
y1 = y1 - ascend;
const x2 = x1 + textScaledWidth;
const y2 = y1 + textScaledHeight;

offset += textScaledWidth;
const textScaledWidth = glyphMapping.glyph.width * scaleFactor;
const textScaledHeight = glyphMapping.glyph.height * scaleFactor;
const ascend = glyphMapping.glyph.actualBoundingBoxAscent * scaleFactor;

// texture coordinates
const u1 = glyphMapping.glyph.x / texture.source.width;
const v1 = glyphMapping.glyph.y / texture.source.height;
const u2 = (glyphMapping.glyph.x + glyphMapping.glyph.width) / texture.source.width;
const v2 = (glyphMapping.glyph.y + glyphMapping.glyph.height) / texture.source.height;

// first triangle
verteciesBuffer.push(x1, y1, x2, y1, x1, y2);
texcoordBuffer.push(u1, v1, u2, v1, u1, v2);

// second triangle
verteciesBuffer.push(x1, y2, x2, y1, x2, y2);
texcoordBuffer.push(u1, v2, u2, v1, u2, v2);

verteciesBuffer.push(
x1,
y1,
VERTEX_POSITION.TOP_LEFT,
x1,
y1,
VERTEX_POSITION.TOP_RIGHT,
x1,
y1,
VERTEX_POSITION.BOTTOM_LEFT,
x1,
y1,
VERTEX_POSITION.BOTTOM_LEFT,
x1,
y1,
VERTEX_POSITION.TOP_RIGHT,
x1,
y1,
VERTEX_POSITION.BOTTOM_RIGHT,
);
texcoordBuffer.push(u1, v1, u2, v1, u1, v2, u1, v2, u2, v1, u2, v2);

addXTimes(textProperties, [textScaledWidth, textScaledHeight, ascend, offset], 6);
addXTimes(colorBuffer, text.color, 6);
addXTimes(borderColorBuffer, text.borderColor, 6);
addXTimes(selectionColorBuffer, selectionColorId, 6);

numElements += 6;
offset += textScaledWidth;
}
}

Expand All @@ -105,14 +123,19 @@ export class TextTextureGroupBuilder extends ObjectGroupBuilder<TextMapFeature,
sfdTexture: fontAtlas.type === FontFormatType.sdf,
vertecies: {
type: WebGlObjectAttributeType.FLOAT,
size: 2,
size: 3,
buffer: createdSharedArrayBuffer(verteciesBuffer),
},
textcoords: {
type: WebGlObjectAttributeType.FLOAT,
size: 2,
buffer: createdSharedArrayBuffer(texcoordBuffer),
},
textProperties: {
type: WebGlObjectAttributeType.FLOAT,
size: 4,
buffer: createdSharedArrayBuffer(textProperties),
},
color: {
type: WebGlObjectAttributeType.FLOAT,
size: 4,
Expand Down
Loading

0 comments on commit d441087

Please sign in to comment.