Stub support for multiple text frames
This commit is contained in:
parent
3ee066bdf0
commit
e34ca3d3e4
|
@ -17,7 +17,8 @@ import {PerspectiveCamera} from "./camera";
|
|||
import {mat4, vec2} from "gl-matrix";
|
||||
import {PathfinderMeshData} from "./meshes";
|
||||
import {ShaderMap, ShaderProgramSource} from "./shader-loader";
|
||||
import {BUILTIN_FONT_URI, PathfinderGlyph, TextRun, TextLayout, GlyphStorage} from "./text";
|
||||
import {BUILTIN_FONT_URI, ExpandedMeshData, GlyphStorage, PathfinderGlyph} from "./text";
|
||||
import {SimpleTextLayout, TextFrame, TextRun} from "./text";
|
||||
import {PathfinderError, assert, panic, unwrapNull} from "./utils";
|
||||
import {PathfinderDemoView, Timings} from "./view";
|
||||
import SSAAStrategy from "./ssaa-strategy";
|
||||
|
@ -114,15 +115,18 @@ class ThreeDController extends DemoAppController<ThreeDView> {
|
|||
}
|
||||
}
|
||||
|
||||
this.glyphStorage = new GlyphStorage(this.fileData, textRuns, createGlyph, font);
|
||||
// TODO(pcwalton)
|
||||
const textFrame = new TextFrame(textRuns, glmatrix.vec3.create());
|
||||
|
||||
this.glyphStorage = new GlyphStorage(this.fileData, [textFrame], createGlyph, font);
|
||||
this.glyphStorage.layoutRuns();
|
||||
|
||||
this.glyphStorage.partition().then((baseMeshes: PathfinderMeshData) => {
|
||||
this.baseMeshes = baseMeshes;
|
||||
this.expandedMeshes = this.glyphStorage.expandMeshes(baseMeshes).meshes;
|
||||
this.expandedMeshes = this.glyphStorage.expandMeshes(baseMeshes);
|
||||
this.view.then(view => {
|
||||
view.uploadPathMetadata();
|
||||
view.attachMeshes(this.expandedMeshes);
|
||||
view.attachMeshes(this.expandedMeshes.map(meshes => meshes.meshes));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -144,7 +148,7 @@ class ThreeDController extends DemoAppController<ThreeDView> {
|
|||
glyphStorage: GlyphStorage<ThreeDGlyph>;
|
||||
|
||||
private baseMeshes: PathfinderMeshData;
|
||||
private expandedMeshes: PathfinderMeshData;
|
||||
private expandedMeshes: ExpandedMeshData[];
|
||||
|
||||
private textPromise: Promise<string[][]>;
|
||||
}
|
||||
|
|
|
@ -43,8 +43,8 @@ export abstract class ECAAStrategy extends AntialiasingStrategy {
|
|||
}
|
||||
|
||||
attachMeshes(view: MonochromePathfinderView) {
|
||||
const bVertexPositions = new Float32Array(view.meshData.bVertexPositions);
|
||||
const bVertexPathIDs = new Uint8Array(view.meshData.bVertexPathIDs);
|
||||
const bVertexPositions = new Float32Array(view.meshData[0].bVertexPositions);
|
||||
const bVertexPathIDs = new Uint8Array(view.meshData[0].bVertexPathIDs);
|
||||
this.bVertexPositionBufferTexture.upload(view.gl, bVertexPositions);
|
||||
this.bVertexPathIDBufferTexture.upload(view.gl, bVertexPathIDs);
|
||||
|
||||
|
@ -115,7 +115,7 @@ export abstract class ECAAStrategy extends AntialiasingStrategy {
|
|||
view.gl.useProgram(coverProgram.program);
|
||||
view.gl.bindBuffer(view.gl.ARRAY_BUFFER, view.quadPositionsBuffer);
|
||||
view.gl.vertexAttribPointer(attributes.aQuadPosition, 2, view.gl.FLOAT, false, 0, 0);
|
||||
view.gl.bindBuffer(view.gl.ARRAY_BUFFER, view.meshes.bQuads);
|
||||
view.gl.bindBuffer(view.gl.ARRAY_BUFFER, view.meshes[0].bQuads);
|
||||
view.gl.vertexAttribPointer(attributes.aUpperPointIndices,
|
||||
4,
|
||||
view.gl.UNSIGNED_SHORT,
|
||||
|
@ -148,8 +148,8 @@ export abstract class ECAAStrategy extends AntialiasingStrategy {
|
|||
view.vertexArrayObjectExt.bindVertexArrayOES(vaos[direction]);
|
||||
|
||||
const lineIndexBuffer = {
|
||||
upper: view.meshes.edgeUpperLineIndices,
|
||||
lower: view.meshes.edgeLowerLineIndices,
|
||||
upper: view.meshes[0].edgeUpperLineIndices,
|
||||
lower: view.meshes[0].edgeLowerLineIndices,
|
||||
}[direction];
|
||||
|
||||
view.gl.useProgram(lineProgram.program);
|
||||
|
@ -183,8 +183,8 @@ export abstract class ECAAStrategy extends AntialiasingStrategy {
|
|||
view.vertexArrayObjectExt.bindVertexArrayOES(vaos[direction]);
|
||||
|
||||
const curveIndexBuffer = {
|
||||
upper: view.meshes.edgeUpperCurveIndices,
|
||||
lower: view.meshes.edgeLowerCurveIndices,
|
||||
upper: view.meshes[0].edgeUpperCurveIndices,
|
||||
lower: view.meshes[0].edgeLowerCurveIndices,
|
||||
}[direction];
|
||||
|
||||
view.gl.useProgram(curveProgram.program);
|
||||
|
@ -310,7 +310,7 @@ export abstract class ECAAStrategy extends AntialiasingStrategy {
|
|||
6,
|
||||
view.gl.UNSIGNED_BYTE,
|
||||
0,
|
||||
view.meshData.bQuadCount);
|
||||
view.meshData[0].bQuadCount);
|
||||
view.vertexArrayObjectExt.bindVertexArrayOES(null);
|
||||
}
|
||||
|
||||
|
@ -351,8 +351,8 @@ export abstract class ECAAStrategy extends AntialiasingStrategy {
|
|||
view.vertexArrayObjectExt.bindVertexArrayOES(this.lineVAOs[direction]);
|
||||
view.gl.uniform1i(uniforms.uLowerPart, direction === 'lower' ? 1 : 0);
|
||||
const count = {
|
||||
upper: view.meshData.edgeUpperLineIndexCount,
|
||||
lower: view.meshData.edgeLowerLineIndexCount,
|
||||
upper: view.meshData[0].edgeUpperLineIndexCount,
|
||||
lower: view.meshData[0].edgeLowerLineIndexCount,
|
||||
}[direction];
|
||||
view.instancedArraysExt.drawElementsInstancedANGLE(view.gl.TRIANGLES,
|
||||
6,
|
||||
|
@ -376,8 +376,8 @@ export abstract class ECAAStrategy extends AntialiasingStrategy {
|
|||
view.vertexArrayObjectExt.bindVertexArrayOES(this.curveVAOs[direction]);
|
||||
view.gl.uniform1i(uniforms.uLowerPart, direction === 'lower' ? 1 : 0);
|
||||
const count = {
|
||||
upper: view.meshData.edgeUpperCurveIndexCount,
|
||||
lower: view.meshData.edgeLowerCurveIndexCount,
|
||||
upper: view.meshData[0].edgeUpperCurveIndexCount,
|
||||
lower: view.meshData[0].edgeLowerCurveIndexCount,
|
||||
}[direction];
|
||||
view.instancedArraysExt.drawElementsInstancedANGLE(view.gl.TRIANGLES,
|
||||
6,
|
||||
|
|
|
@ -17,7 +17,7 @@ import {B_QUAD_UPPER_RIGHT_VERTEX_OFFSET} from "./meshes";
|
|||
import {B_QUAD_UPPER_CONTROL_POINT_VERTEX_OFFSET, B_QUAD_LOWER_LEFT_VERTEX_OFFSET} from "./meshes";
|
||||
import {B_QUAD_LOWER_RIGHT_VERTEX_OFFSET} from "./meshes";
|
||||
import {B_QUAD_LOWER_CONTROL_POINT_VERTEX_OFFSET, PathfinderMeshData} from "./meshes";
|
||||
import { BUILTIN_FONT_URI, GlyphStorage, PathfinderGlyph, TextRun } from "./text";
|
||||
import {BUILTIN_FONT_URI, GlyphStorage, PathfinderGlyph, TextRun, TextFrame} from "./text";
|
||||
import {unwrapNull, UINT32_SIZE, UINT32_MAX, assert} from "./utils";
|
||||
import {PathfinderView} from "./view";
|
||||
import * as opentype from "opentype.js";
|
||||
|
@ -45,7 +45,8 @@ class MeshDebuggerAppController extends AppController {
|
|||
|
||||
const createGlyph = (glyph: opentype.Glyph) => new MeshDebuggerGlyph(glyph);
|
||||
const textRun = new TextRun<MeshDebuggerGlyph>(CHARACTER, [0, 0], font, createGlyph);
|
||||
this.glyphStorage = new GlyphStorage(this.fileData, [textRun], createGlyph, font);
|
||||
const textFrame = new TextFrame([textRun], glmatrix.vec3.create());
|
||||
this.glyphStorage = new GlyphStorage(this.fileData, [textFrame], createGlyph, font);
|
||||
|
||||
this.glyphStorage.partition().then(meshes => {
|
||||
this.meshes = meshes;
|
||||
|
|
|
@ -157,7 +157,7 @@ class SVGDemoController extends DemoAppController<SVGDemoView> {
|
|||
private meshesReceived() {
|
||||
this.view.then(view => {
|
||||
view.uploadPathMetadata(this.pathElements);
|
||||
view.attachMeshes(this.meshes);
|
||||
view.attachMeshes([this.meshes]);
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ import {createFramebufferDepthTexture, QUAD_ELEMENTS, setTextureParameters} from
|
|||
import {UniformMap} from './gl-utils';
|
||||
import {PathfinderMeshBuffers, PathfinderMeshData} from './meshes';
|
||||
import {PathfinderShaderProgram, ShaderMap, ShaderProgramSource} from './shader-loader';
|
||||
import {BUILTIN_FONT_URI, PathfinderGlyph, TextLayout} from "./text";
|
||||
import {BUILTIN_FONT_URI, PathfinderGlyph, SimpleTextLayout} from "./text";
|
||||
import {PathfinderError, assert, expectNotNull, UINT32_SIZE, unwrapNull, panic} from './utils';
|
||||
import {MonochromePathfinderView, Timings} from './view';
|
||||
import PathfinderBufferTexture from './buffer-texture';
|
||||
|
@ -162,13 +162,13 @@ class TextDemoController extends DemoAppController<TextDemoView> {
|
|||
}
|
||||
|
||||
private recreateLayout() {
|
||||
this.layout = new TextLayout(this.fileData, this.text, glyph => new GlyphInstance(glyph));
|
||||
this.layout = new SimpleTextLayout(this.fileData, this.text, glyph => new GlyphInstance(glyph));
|
||||
this.layout.glyphStorage.partition().then((meshes: PathfinderMeshData) => {
|
||||
this.meshes = meshes;
|
||||
this.view.then(view => {
|
||||
view.attachText();
|
||||
view.uploadPathMetadata(this.layout.glyphStorage.uniqueGlyphs.length);
|
||||
view.attachMeshes(this.meshes);
|
||||
view.attachMeshes([this.meshes]);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -218,7 +218,7 @@ class TextDemoController extends DemoAppController<TextDemoView> {
|
|||
|
||||
private text: string;
|
||||
|
||||
layout: TextLayout<GlyphInstance>;
|
||||
layout: SimpleTextLayout<GlyphInstance>;
|
||||
}
|
||||
|
||||
class TextDemoView extends MonochromePathfinderView {
|
||||
|
|
|
@ -21,6 +21,28 @@ export const BUILTIN_FONT_URI: string = "/otf/demo";
|
|||
|
||||
const PARTITION_FONT_ENDPOINT_URI: string = "/partition-font";
|
||||
|
||||
export interface ExpandedMeshData {
|
||||
meshes: PathfinderMeshData;
|
||||
}
|
||||
|
||||
type CreateGlyphFn<Glyph> = (glyph: opentype.Glyph) => Glyph;
|
||||
|
||||
export interface PixelMetrics {
|
||||
left: number;
|
||||
right: number;
|
||||
ascent: number;
|
||||
descent: number;
|
||||
}
|
||||
|
||||
opentype.Font.prototype.isSupported = function() {
|
||||
return (this as any).supported;
|
||||
}
|
||||
|
||||
opentype.Font.prototype.lineHeight = function() {
|
||||
const os2Table = this.tables.os2;
|
||||
return os2Table.sTypoAscender - os2Table.sTypoDescender + os2Table.sTypoLineGap;
|
||||
};
|
||||
|
||||
export class TextRun<Glyph extends PathfinderGlyph> {
|
||||
constructor(text: string | Glyph[],
|
||||
origin: number[],
|
||||
|
@ -45,81 +67,13 @@ export class TextRun<Glyph extends PathfinderGlyph> {
|
|||
readonly origin: number[];
|
||||
}
|
||||
|
||||
export interface ExpandedMeshData {
|
||||
meshes: PathfinderMeshData;
|
||||
export class TextFrame<Glyph extends PathfinderGlyph> {
|
||||
constructor(runs: TextRun<Glyph>[], origin: glmatrix.vec3) {
|
||||
this.runs = runs;
|
||||
this.origin = origin;
|
||||
}
|
||||
|
||||
type CreateGlyphFn<Glyph> = (glyph: opentype.Glyph) => Glyph;
|
||||
|
||||
export interface PixelMetrics {
|
||||
left: number;
|
||||
right: number;
|
||||
ascent: number;
|
||||
descent: number;
|
||||
}
|
||||
|
||||
opentype.Font.prototype.isSupported = function() {
|
||||
return (this as any).supported;
|
||||
}
|
||||
|
||||
opentype.Font.prototype.lineHeight = function() {
|
||||
const os2Table = this.tables.os2;
|
||||
return os2Table.sTypoAscender - os2Table.sTypoDescender + os2Table.sTypoLineGap;
|
||||
};
|
||||
|
||||
export class GlyphStorage<Glyph extends PathfinderGlyph> {
|
||||
constructor(fontData: ArrayBuffer,
|
||||
textRuns: TextRun<Glyph>[],
|
||||
createGlyph: CreateGlyphFn<Glyph>,
|
||||
font?: Font) {
|
||||
if (font == null) {
|
||||
font = opentype.parse(fontData);
|
||||
assert(font.isSupported(), "The font type is unsupported!");
|
||||
}
|
||||
|
||||
this.fontData = fontData;
|
||||
this.textRuns = textRuns;
|
||||
this.font = font;
|
||||
|
||||
// Determine all glyphs potentially needed.
|
||||
this.uniqueGlyphs = _.flatMap(this.textRuns, textRun => textRun.glyphs);
|
||||
this.uniqueGlyphs.sort((a, b) => a.index - b.index);
|
||||
this.uniqueGlyphs = _.sortedUniqBy(this.uniqueGlyphs, glyph => glyph.index);
|
||||
}
|
||||
|
||||
partition(): Promise<PathfinderMeshData> {
|
||||
// Build the partitioning request to the server.
|
||||
//
|
||||
// FIXME(pcwalton): If this is a builtin font, don't resend it to the server!
|
||||
const request = {
|
||||
face: {
|
||||
Custom: base64js.fromByteArray(new Uint8Array(this.fontData)),
|
||||
},
|
||||
fontIndex: 0,
|
||||
glyphs: this.uniqueGlyphs.map(glyph => {
|
||||
const metrics = glyph.metrics;
|
||||
return {
|
||||
id: glyph.index,
|
||||
transform: [1, 0, 0, 1, 0, 0],
|
||||
};
|
||||
}),
|
||||
pointSize: this.font.unitsPerEm,
|
||||
};
|
||||
|
||||
// Make the request.
|
||||
return window.fetch(PARTITION_FONT_ENDPOINT_URI, {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify(request),
|
||||
}).then(response => response.text()).then(responseText => {
|
||||
const response = JSON.parse(responseText);
|
||||
if (!('Ok' in response))
|
||||
panic("Failed to partition the font!");
|
||||
return new PathfinderMeshData(response.Ok.pathData);
|
||||
});
|
||||
}
|
||||
|
||||
expandMeshes(meshes: PathfinderMeshData): ExpandedMeshData {
|
||||
expandMeshes(uniqueGlyphs: Glyph[], meshes: PathfinderMeshData): ExpandedMeshData {
|
||||
const bQuads = _.chunk(new Uint32Array(meshes.bQuads), B_QUAD_SIZE / UINT32_SIZE);
|
||||
const bVertexPositions = new Float32Array(meshes.bVertexPositions);
|
||||
const bVertexPathIDs = new Uint16Array(meshes.bVertexPathIDs);
|
||||
|
@ -133,9 +87,9 @@ export class GlyphStorage<Glyph extends PathfinderGlyph> {
|
|||
const expandedCoverCurveIndices: number[] = [];
|
||||
|
||||
let textGlyphIndex = 0;
|
||||
for (const textRun of this.textRuns) {
|
||||
for (const textRun of this.runs) {
|
||||
for (const textGlyph of textRun.glyphs) {
|
||||
const uniqueGlyphIndex = _.sortedIndexBy(this.uniqueGlyphs, textGlyph, 'index');
|
||||
const uniqueGlyphIndex = _.sortedIndexBy(uniqueGlyphs, textGlyph, 'index');
|
||||
if (uniqueGlyphIndex < 0)
|
||||
continue;
|
||||
const firstBVertexIndex = _.sortedIndex(bVertexPathIDs, uniqueGlyphIndex + 1);
|
||||
|
@ -208,21 +162,87 @@ export class GlyphStorage<Glyph extends PathfinderGlyph> {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
get allGlyphs(): Glyph[] {
|
||||
return _.flatMap(this.runs, run => run.glyphs);
|
||||
}
|
||||
|
||||
readonly runs: TextRun<Glyph>[];
|
||||
readonly origin: glmatrix.vec3;
|
||||
}
|
||||
|
||||
export class GlyphStorage<Glyph extends PathfinderGlyph> {
|
||||
constructor(fontData: ArrayBuffer,
|
||||
textFrames: TextFrame<Glyph>[],
|
||||
createGlyph: CreateGlyphFn<Glyph>,
|
||||
font?: Font) {
|
||||
if (font == null) {
|
||||
font = opentype.parse(fontData);
|
||||
assert(font.isSupported(), "The font type is unsupported!");
|
||||
}
|
||||
|
||||
this.fontData = fontData;
|
||||
this.textFrames = textFrames;
|
||||
this.font = font;
|
||||
|
||||
// Determine all glyphs potentially needed.
|
||||
this.uniqueGlyphs = this.allGlyphs;
|
||||
this.uniqueGlyphs.sort((a, b) => a.index - b.index);
|
||||
this.uniqueGlyphs = _.sortedUniqBy(this.uniqueGlyphs, glyph => glyph.index);
|
||||
}
|
||||
|
||||
expandMeshes(meshes: PathfinderMeshData): ExpandedMeshData[] {
|
||||
return this.textFrames.map(textFrame => textFrame.expandMeshes(this.uniqueGlyphs, meshes));
|
||||
}
|
||||
|
||||
partition(): Promise<PathfinderMeshData> {
|
||||
// Build the partitioning request to the server.
|
||||
//
|
||||
// FIXME(pcwalton): If this is a builtin font, don't resend it to the server!
|
||||
const request = {
|
||||
face: {
|
||||
Custom: base64js.fromByteArray(new Uint8Array(this.fontData)),
|
||||
},
|
||||
fontIndex: 0,
|
||||
glyphs: this.uniqueGlyphs.map(glyph => {
|
||||
const metrics = glyph.metrics;
|
||||
return {
|
||||
id: glyph.index,
|
||||
transform: [1, 0, 0, 1, 0, 0],
|
||||
};
|
||||
}),
|
||||
pointSize: this.font.unitsPerEm,
|
||||
};
|
||||
|
||||
// Make the request.
|
||||
return window.fetch(PARTITION_FONT_ENDPOINT_URI, {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify(request),
|
||||
}).then(response => response.text()).then(responseText => {
|
||||
const response = JSON.parse(responseText);
|
||||
if (!('Ok' in response))
|
||||
panic("Failed to partition the font!");
|
||||
return new PathfinderMeshData(response.Ok.pathData);
|
||||
});
|
||||
}
|
||||
|
||||
layoutRuns() {
|
||||
this.textRuns.forEach(textRun => textRun.layout());
|
||||
for (const textFrame of this.textFrames)
|
||||
textFrame.runs.forEach(textRun => textRun.layout());
|
||||
}
|
||||
|
||||
get allGlyphs(): Glyph[] {
|
||||
return _.flatMap(this.textRuns, textRun => textRun.glyphs);
|
||||
return _.flatMap(this.textFrames, textRun => textRun.allGlyphs);
|
||||
}
|
||||
|
||||
readonly fontData: ArrayBuffer;
|
||||
readonly font: Font;
|
||||
readonly textRuns: TextRun<Glyph>[];
|
||||
readonly textFrames: TextFrame<Glyph>[];
|
||||
readonly uniqueGlyphs: Glyph[];
|
||||
}
|
||||
|
||||
export class TextLayout<Glyph extends PathfinderGlyph> {
|
||||
export class SimpleTextLayout<Glyph extends PathfinderGlyph> {
|
||||
constructor(fontData: ArrayBuffer, text: string, createGlyph: CreateGlyphFn<Glyph>) {
|
||||
const font = opentype.parse(fontData);
|
||||
assert(font.isSupported(), "The font type is unsupported!");
|
||||
|
@ -230,22 +250,23 @@ export class TextLayout<Glyph extends PathfinderGlyph> {
|
|||
const os2Table = font.tables.os2;
|
||||
const lineHeight = os2Table.sTypoAscender - os2Table.sTypoDescender +
|
||||
os2Table.sTypoLineGap;
|
||||
this.textRuns = text.split("\n").map((line, lineNumber) => {
|
||||
const textRuns: TextRun<Glyph>[] = text.split("\n").map((line, lineNumber) => {
|
||||
return new TextRun<Glyph>(line, [0.0, -lineHeight * lineNumber], font, createGlyph);
|
||||
});
|
||||
this.textFrame = new TextFrame(textRuns, glmatrix.vec3.create());
|
||||
|
||||
this.glyphStorage = new GlyphStorage(fontData, this.textRuns, createGlyph, font);
|
||||
this.glyphStorage = new GlyphStorage(fontData, [this.textFrame], createGlyph, font);
|
||||
}
|
||||
|
||||
layoutRuns() {
|
||||
this.textRuns.forEach(textRun => textRun.layout());
|
||||
this.textFrame.runs.forEach(textRun => textRun.layout());
|
||||
}
|
||||
|
||||
get allGlyphs(): Glyph[] {
|
||||
return _.flatMap(this.textRuns, textRun => textRun.glyphs);
|
||||
return this.textFrame.allGlyphs;
|
||||
}
|
||||
|
||||
readonly textRuns: TextRun<Glyph>[];
|
||||
readonly textFrame: TextFrame<Glyph>;
|
||||
readonly glyphStorage: GlyphStorage<Glyph>;
|
||||
}
|
||||
|
||||
|
|
|
@ -124,9 +124,9 @@ export abstract class PathfinderDemoView extends PathfinderView {
|
|||
this.setDirty();
|
||||
}
|
||||
|
||||
attachMeshes(meshes: PathfinderMeshData) {
|
||||
attachMeshes(meshes: PathfinderMeshData[]) {
|
||||
this.meshData = meshes;
|
||||
this.meshes = new PathfinderMeshBuffers(this.gl, meshes);
|
||||
this.meshes = meshes.map(meshes => new PathfinderMeshBuffers(this.gl, meshes));
|
||||
unwrapNull(this.antialiasingStrategy).attachMeshes(this);
|
||||
|
||||
this.setDirty();
|
||||
|
@ -274,6 +274,7 @@ export abstract class PathfinderDemoView extends PathfinderView {
|
|||
}
|
||||
|
||||
private renderDirect() {
|
||||
for (const meshes of this.meshes) {
|
||||
// Set up implicit cover state.
|
||||
this.gl.depthFunc(this.gl.GREATER);
|
||||
this.gl.depthMask(true);
|
||||
|
@ -283,14 +284,14 @@ export abstract class PathfinderDemoView extends PathfinderView {
|
|||
// Set up the implicit cover interior VAO.
|
||||
const directInteriorProgram = this.shaderPrograms[this.directInteriorProgramName];
|
||||
this.gl.useProgram(directInteriorProgram.program);
|
||||
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.meshes.bVertexPositions);
|
||||
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, meshes.bVertexPositions);
|
||||
this.gl.vertexAttribPointer(directInteriorProgram.attributes.aPosition,
|
||||
2,
|
||||
this.gl.FLOAT,
|
||||
false,
|
||||
0,
|
||||
0);
|
||||
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.meshes.bVertexPathIDs);
|
||||
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, meshes.bVertexPathIDs);
|
||||
this.gl.vertexAttribPointer(directInteriorProgram.attributes.aPathID,
|
||||
1,
|
||||
this.gl.UNSIGNED_SHORT,
|
||||
|
@ -299,7 +300,7 @@ export abstract class PathfinderDemoView extends PathfinderView {
|
|||
0);
|
||||
this.gl.enableVertexAttribArray(directInteriorProgram.attributes.aPosition);
|
||||
this.gl.enableVertexAttribArray(directInteriorProgram.attributes.aPathID);
|
||||
this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.meshes.coverInteriorIndices);
|
||||
this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, meshes.coverInteriorIndices);
|
||||
|
||||
// Draw direct interior parts.
|
||||
this.setTransformUniform(directInteriorProgram.uniforms);
|
||||
|
@ -319,21 +320,21 @@ export abstract class PathfinderDemoView extends PathfinderView {
|
|||
// Set up the direct curve VAO.
|
||||
const directCurveProgram = this.shaderPrograms[this.directCurveProgramName];
|
||||
this.gl.useProgram(directCurveProgram.program);
|
||||
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.meshes.bVertexPositions);
|
||||
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, meshes.bVertexPositions);
|
||||
this.gl.vertexAttribPointer(directCurveProgram.attributes.aPosition,
|
||||
2,
|
||||
this.gl.FLOAT,
|
||||
false,
|
||||
0,
|
||||
0);
|
||||
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.meshes.bVertexPathIDs);
|
||||
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, meshes.bVertexPathIDs);
|
||||
this.gl.vertexAttribPointer(directCurveProgram.attributes.aPathID,
|
||||
1,
|
||||
this.gl.UNSIGNED_SHORT,
|
||||
false,
|
||||
0,
|
||||
0);
|
||||
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.meshes.bVertexLoopBlinnData);
|
||||
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, meshes.bVertexLoopBlinnData);
|
||||
this.gl.vertexAttribPointer(directCurveProgram.attributes.aTexCoord,
|
||||
2,
|
||||
this.gl.UNSIGNED_BYTE,
|
||||
|
@ -350,7 +351,7 @@ export abstract class PathfinderDemoView extends PathfinderView {
|
|||
this.gl.enableVertexAttribArray(directCurveProgram.attributes.aTexCoord);
|
||||
this.gl.enableVertexAttribArray(directCurveProgram.attributes.aPathID);
|
||||
this.gl.enableVertexAttribArray(directCurveProgram.attributes.aSign);
|
||||
this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.meshes.coverCurveIndices);
|
||||
this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, meshes.coverCurveIndices);
|
||||
|
||||
// Draw direct curve parts.
|
||||
this.setTransformUniform(directCurveProgram.uniforms);
|
||||
|
@ -361,6 +362,7 @@ export abstract class PathfinderDemoView extends PathfinderView {
|
|||
this.gl.BUFFER_SIZE) / UINT32_SIZE;
|
||||
this.gl.drawElements(this.gl.TRIANGLES, indexCount, this.gl.UNSIGNED_INT, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private finishTiming() {
|
||||
if (this.timerQueryPollInterval != null)
|
||||
|
@ -449,8 +451,8 @@ export abstract class PathfinderDemoView extends PathfinderView {
|
|||
quadTexCoordsBuffer: WebGLBuffer;
|
||||
quadElementsBuffer: WebGLBuffer;
|
||||
|
||||
meshes: PathfinderMeshBuffers;
|
||||
meshData: PathfinderMeshData;
|
||||
meshes: PathfinderMeshBuffers[];
|
||||
meshData: PathfinderMeshData[];
|
||||
|
||||
pathTransformBufferTexture: PathfinderBufferTexture;
|
||||
protected pathColorsBufferTexture: PathfinderBufferTexture;
|
||||
|
|
Loading…
Reference in New Issue