Get the SVG demo rendering something
This commit is contained in:
parent
8e2172f06f
commit
c47aa5c4d0
|
@ -14,47 +14,48 @@ import {PathfinderView} from './view';
|
|||
|
||||
export type AntialiasingStrategyName = 'none' | 'ssaa' | 'ecaa';
|
||||
|
||||
export interface AntialiasingStrategy {
|
||||
export abstract class AntialiasingStrategy {
|
||||
// Prepares any OpenGL data. This is only called on startup and canvas resize.
|
||||
init(view: PathfinderView): void;
|
||||
init(view: PathfinderView): void {
|
||||
this.setFramebufferSize(view);
|
||||
}
|
||||
|
||||
// Uploads any mesh data. This is called whenever a new set of meshes is supplied.
|
||||
attachMeshes(view: PathfinderView): void;
|
||||
abstract attachMeshes(view: PathfinderView): void;
|
||||
|
||||
// This is called whenever the framebuffer has changed.
|
||||
setFramebufferSize(view: PathfinderView, framebufferSize: glmatrix.vec2): void;
|
||||
abstract setFramebufferSize(view: PathfinderView): void;
|
||||
|
||||
// Returns the transformation matrix that should be applied when directly rendering.
|
||||
transform(): glmatrix.mat4;
|
||||
abstract get transform(): glmatrix.mat4;
|
||||
|
||||
// Called before direct rendering.
|
||||
//
|
||||
// Typically, this redirects direct rendering to a framebuffer of some sort.
|
||||
prepare(view: PathfinderView): void;
|
||||
abstract prepare(view: PathfinderView): void;
|
||||
|
||||
// Called after direct rendering.
|
||||
//
|
||||
// This usually performs the actual antialiasing and blits to the real framebuffer.
|
||||
resolve(view: PathfinderView): void;
|
||||
abstract resolve(view: PathfinderView): void;
|
||||
|
||||
// True if direct rendering should occur.
|
||||
shouldRenderDirect: boolean;
|
||||
}
|
||||
|
||||
export class NoAAStrategy implements AntialiasingStrategy {
|
||||
export class NoAAStrategy extends AntialiasingStrategy {
|
||||
constructor(level: number) {
|
||||
super();
|
||||
this.framebufferSize = glmatrix.vec2.create();
|
||||
}
|
||||
|
||||
init(view: PathfinderView) {}
|
||||
|
||||
attachMeshes(view: PathfinderView) {}
|
||||
|
||||
setFramebufferSize(view: PathfinderView, framebufferSize: glmatrix.vec2) {
|
||||
this.framebufferSize = framebufferSize;
|
||||
setFramebufferSize(view: PathfinderView) {
|
||||
this.framebufferSize = view.destAllocatedSize;
|
||||
}
|
||||
|
||||
transform(): glmatrix.mat4 {
|
||||
get transform(): glmatrix.mat4 {
|
||||
return glmatrix.mat4.create();
|
||||
}
|
||||
|
||||
|
|
|
@ -25,12 +25,14 @@ interface UpperAndLower<T> {
|
|||
lower: T;
|
||||
}
|
||||
|
||||
export abstract class ECAAStrategy implements AntialiasingStrategy {
|
||||
export abstract class ECAAStrategy extends AntialiasingStrategy {
|
||||
constructor(level: number) {
|
||||
super();
|
||||
this.framebufferSize = glmatrix.vec2.create();
|
||||
}
|
||||
|
||||
init(view: MonochromePathfinderView) {
|
||||
super.init(view);
|
||||
this.bVertexPositionBufferTexture = new PathfinderBufferTexture(view.gl,
|
||||
'uBVertexPosition');
|
||||
this.bVertexPathIDBufferTexture = new PathfinderBufferTexture(view.gl, 'uBVertexPathID');
|
||||
|
@ -49,8 +51,8 @@ export abstract class ECAAStrategy implements AntialiasingStrategy {
|
|||
this.createResolveVAO(view);
|
||||
}
|
||||
|
||||
setFramebufferSize(view: MonochromePathfinderView, framebufferSize: glmatrix.vec2) {
|
||||
this.framebufferSize = framebufferSize;
|
||||
setFramebufferSize(view: MonochromePathfinderView) {
|
||||
this.framebufferSize = view.destAllocatedSize;
|
||||
|
||||
this.initDirectFramebuffer(view);
|
||||
this.initEdgeDetectFramebuffer(view);
|
||||
|
@ -58,7 +60,7 @@ export abstract class ECAAStrategy implements AntialiasingStrategy {
|
|||
view.gl.bindFramebuffer(view.gl.FRAMEBUFFER, null);
|
||||
}
|
||||
|
||||
transform(): glmatrix.mat4 {
|
||||
get transform(): glmatrix.mat4 {
|
||||
return glmatrix.mat4.create();
|
||||
}
|
||||
|
||||
|
@ -288,7 +290,7 @@ export abstract class ECAAStrategy implements AntialiasingStrategy {
|
|||
view.setFramebufferSizeUniform(uniforms);
|
||||
this.bVertexPositionBufferTexture.bind(view.gl, uniforms, 0);
|
||||
this.bVertexPathIDBufferTexture.bind(view.gl, uniforms, 1);
|
||||
view.atlasTransformBuffer.bind(view.gl, uniforms, 2);
|
||||
view.pathTransformBufferTexture.bind(view.gl, uniforms, 2);
|
||||
view.instancedArraysExt.drawElementsInstancedANGLE(view.gl.TRIANGLES,
|
||||
6,
|
||||
view.gl.UNSIGNED_BYTE,
|
||||
|
@ -315,7 +317,7 @@ export abstract class ECAAStrategy implements AntialiasingStrategy {
|
|||
view.setFramebufferSizeUniform(uniforms);
|
||||
this.bVertexPositionBufferTexture.bind(view.gl, uniforms, 0);
|
||||
this.bVertexPathIDBufferTexture.bind(view.gl, uniforms, 1);
|
||||
view.atlasTransformBuffer.bind(view.gl, uniforms, 2);
|
||||
view.pathTransformBufferTexture.bind(view.gl, uniforms, 2);
|
||||
}
|
||||
|
||||
private antialiasLines(view: MonochromePathfinderView) {
|
||||
|
|
|
@ -15,23 +15,22 @@ import {createFramebufferDepthTexture, createFramebuffer, setTextureParameters}
|
|||
import {unwrapNull} from './utils';
|
||||
import {PathfinderView} from './view';
|
||||
|
||||
export default class SSAAStrategy implements AntialiasingStrategy {
|
||||
export default class SSAAStrategy extends AntialiasingStrategy {
|
||||
constructor(level: number) {
|
||||
super();
|
||||
this.level = level;
|
||||
this.destFramebufferSize = glmatrix.vec2.create();
|
||||
this.supersampledFramebufferSize = glmatrix.vec2.create();
|
||||
}
|
||||
|
||||
init(view: PathfinderView) {}
|
||||
|
||||
attachMeshes(view: PathfinderView) {}
|
||||
|
||||
setFramebufferSize(view: PathfinderView, framebufferSize: glmatrix.vec2) {
|
||||
this.destFramebufferSize = framebufferSize;
|
||||
setFramebufferSize(view: PathfinderView) {
|
||||
this.destFramebufferSize = view.destAllocatedSize;
|
||||
|
||||
this.supersampledFramebufferSize = glmatrix.vec2.create();
|
||||
glmatrix.vec2.mul(this.supersampledFramebufferSize,
|
||||
framebufferSize,
|
||||
this.destFramebufferSize,
|
||||
this.supersampleScale);
|
||||
|
||||
this.supersampledColorTexture = unwrapNull(view.gl.createTexture());
|
||||
|
@ -59,7 +58,7 @@ export default class SSAAStrategy implements AntialiasingStrategy {
|
|||
view.gl.bindFramebuffer(view.gl.FRAMEBUFFER, null);
|
||||
}
|
||||
|
||||
transform(): glmatrix.mat4 {
|
||||
get transform(): glmatrix.mat4 {
|
||||
const scale = glmatrix.vec2.create();
|
||||
glmatrix.vec2.div(scale, this.supersampledFramebufferSize, this.destFramebufferSize);
|
||||
|
||||
|
|
|
@ -143,7 +143,10 @@ class SVGDemoView extends PathfinderView {
|
|||
this._scale = 1.0;
|
||||
}
|
||||
|
||||
protected resized(initialSize: boolean) {}
|
||||
protected resized(initialSize: boolean) {
|
||||
this.antialiasingStrategy.init(this);
|
||||
this.setDirty();
|
||||
}
|
||||
|
||||
get destAllocatedSize(): glmatrix.vec2 {
|
||||
return glmatrix.vec2.fromValues(this.canvas.width, this.canvas.height);
|
||||
|
@ -157,17 +160,29 @@ class SVGDemoView extends PathfinderView {
|
|||
return this.destAllocatedSize;
|
||||
}
|
||||
|
||||
protected panned(): void {}
|
||||
protected panned(): void {
|
||||
this.setDirty();
|
||||
}
|
||||
|
||||
uploadPathData(elements: SVGPathElement[]) {
|
||||
const pathColors = new Uint8Array(4 * (elements.length + 1));
|
||||
const pathTransforms = new Float32Array(4 * (elements.length + 1));
|
||||
for (let pathIndex = 0; pathIndex < elements.length; pathIndex++) {
|
||||
const startOffset = (pathIndex + 1) * 4;
|
||||
|
||||
// Set color.
|
||||
const style = window.getComputedStyle(elements[pathIndex]);
|
||||
const fillColor = style.fill === 'none' ? [0, 0, 0, 0] : parseColor(style.fill).rgba;
|
||||
pathColors.set(fillColor, (pathIndex + 1) * 4);
|
||||
const fillColor: number[] =
|
||||
style.fill === 'none' ? [0, 0, 0, 0] : parseColor(style.fill).rgba;
|
||||
pathColors.set(fillColor.slice(0, 3), startOffset);
|
||||
pathColors[startOffset + 3] = fillColor[3] * 255;
|
||||
|
||||
// TODO(pcwalton): Set transform.
|
||||
pathTransforms.set([1, 1, 0, 0], startOffset);
|
||||
}
|
||||
|
||||
this.pathColorsBufferTexture.upload(this.gl, pathColors);
|
||||
this.pathTransformBufferTexture.upload(this.gl, pathTransforms);
|
||||
}
|
||||
|
||||
protected createAAStrategy(aaType: AntialiasingStrategyName, aaLevel: number):
|
||||
|
@ -182,7 +197,7 @@ class SVGDemoView extends PathfinderView {
|
|||
}
|
||||
|
||||
protected get usedSizeFactor(): glmatrix.vec2 {
|
||||
return glmatrix.vec2.create();
|
||||
return glmatrix.vec2.fromValues(1.0, 1.0);
|
||||
}
|
||||
|
||||
protected get scale(): number {
|
||||
|
@ -194,6 +209,13 @@ class SVGDemoView extends PathfinderView {
|
|||
this.setDirty();
|
||||
}
|
||||
|
||||
protected get worldTransform() {
|
||||
const transform = glmatrix.mat4.create();
|
||||
glmatrix.mat4.fromTranslation(transform, [this.translation[0], this.translation[1], 0]);
|
||||
glmatrix.mat4.scale(transform, transform, [this.scale, this.scale, 1.0]);
|
||||
return transform;
|
||||
}
|
||||
|
||||
private _scale: number;
|
||||
|
||||
private appController: SVGDemoController;
|
||||
|
|
|
@ -380,7 +380,7 @@ class TextDemoView extends MonochromePathfinderView {
|
|||
transforms[pathID * 4 + 3] = atlasLocation[1] - bottom;
|
||||
}
|
||||
|
||||
this.atlasTransformBuffer.upload(this.gl, transforms);
|
||||
this.pathTransformBufferTexture.upload(this.gl, transforms);
|
||||
}
|
||||
|
||||
private createAtlasFramebuffer() {
|
||||
|
@ -392,7 +392,7 @@ class TextDemoView extends MonochromePathfinderView {
|
|||
this.atlasDepthTexture);
|
||||
|
||||
// Allow the antialiasing strategy to set up framebuffers as necessary.
|
||||
this.antialiasingStrategy.setFramebufferSize(this, ATLAS_SIZE);
|
||||
this.antialiasingStrategy.setFramebufferSize(this);
|
||||
}
|
||||
|
||||
private setGlyphTexCoords() {
|
||||
|
@ -551,6 +551,10 @@ class TextDemoView extends MonochromePathfinderView {
|
|||
this.appController.updateTimings(timings);
|
||||
}
|
||||
|
||||
protected get worldTransform() {
|
||||
return glmatrix.mat4.create();
|
||||
}
|
||||
|
||||
atlasFramebuffer: WebGLFramebuffer;
|
||||
atlasDepthTexture: WebGLTexture;
|
||||
|
||||
|
@ -560,8 +564,6 @@ class TextDemoView extends MonochromePathfinderView {
|
|||
glyphTexCoordsBuffer: WebGLBuffer;
|
||||
glyphElementsBuffer: WebGLBuffer;
|
||||
|
||||
atlasTransformBuffer: PathfinderBufferTexture;
|
||||
|
||||
appController: TextDemoController;
|
||||
}
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ export abstract class PathfinderView {
|
|||
const shaderSource = this.compileShaders(commonShaderSource, shaderSources);
|
||||
this.shaderPrograms = this.linkShaders(shaderSource);
|
||||
|
||||
this.atlasTransformBuffer = new PathfinderBufferTexture(this.gl, 'uPathTransform');
|
||||
this.pathTransformBufferTexture = new PathfinderBufferTexture(this.gl, 'uPathTransform');
|
||||
this.pathColorsBufferTexture = new PathfinderBufferTexture(this.gl, 'uPathColors');
|
||||
|
||||
this.antialiasingStrategy = new NoAAStrategy(0);
|
||||
|
@ -77,7 +77,6 @@ export abstract class PathfinderView {
|
|||
|
||||
let canvas = this.canvas;
|
||||
this.antialiasingStrategy.init(this);
|
||||
this.antialiasingStrategy.setFramebufferSize(this, this.destAllocatedSize);
|
||||
if (this.meshData != null)
|
||||
this.antialiasingStrategy.attachMeshes(this);
|
||||
|
||||
|
@ -233,14 +232,15 @@ export abstract class PathfinderView {
|
|||
// Draw the glyphs with the resolved atlas to the default framebuffer.
|
||||
this.compositeIfNecessary();
|
||||
|
||||
// Finish timing, clear dirty bit and finish.
|
||||
// Finish timing, clear dirty bit, and finish.
|
||||
this.finishTiming();
|
||||
this.dirty = false;
|
||||
}
|
||||
|
||||
private setTransformUniform(uniforms: UniformMap) {
|
||||
const transform = this.antialiasingStrategy.transform();
|
||||
this.gl.uniformMatrix4fv(uniforms.uTransform, false, this.antialiasingStrategy.transform());
|
||||
const transform = glmatrix.mat4.create();
|
||||
glmatrix.mat4.mul(transform, this.worldTransform, this.antialiasingStrategy.transform);
|
||||
this.gl.uniformMatrix4fv(uniforms.uTransform, false, transform);
|
||||
}
|
||||
|
||||
private renderDirect() {
|
||||
|
@ -275,7 +275,7 @@ export abstract class PathfinderView {
|
|||
this.setTransformUniform(directInteriorProgram.uniforms);
|
||||
this.setFramebufferSizeUniform(directInteriorProgram.uniforms);
|
||||
this.pathColorsBufferTexture.bind(this.gl, directInteriorProgram.uniforms, 0);
|
||||
this.atlasTransformBuffer.bind(this.gl, directInteriorProgram.uniforms, 1);
|
||||
this.pathTransformBufferTexture.bind(this.gl, directInteriorProgram.uniforms, 1);
|
||||
let indexCount = this.gl.getBufferParameter(this.gl.ELEMENT_ARRAY_BUFFER,
|
||||
this.gl.BUFFER_SIZE) / UINT32_SIZE;
|
||||
this.gl.drawElements(this.gl.TRIANGLES, indexCount, this.gl.UNSIGNED_INT, 0);
|
||||
|
@ -326,7 +326,7 @@ export abstract class PathfinderView {
|
|||
this.setTransformUniform(directCurveProgram.uniforms);
|
||||
this.setFramebufferSizeUniform(directCurveProgram.uniforms);
|
||||
this.pathColorsBufferTexture.bind(this.gl, directCurveProgram.uniforms, 0);
|
||||
this.atlasTransformBuffer.bind(this.gl, directCurveProgram.uniforms, 1);
|
||||
this.pathTransformBufferTexture.bind(this.gl, directCurveProgram.uniforms, 1);
|
||||
indexCount = this.gl.getBufferParameter(this.gl.ELEMENT_ARRAY_BUFFER,
|
||||
this.gl.BUFFER_SIZE) / UINT32_SIZE;
|
||||
this.gl.drawElements(this.gl.TRIANGLES, indexCount, this.gl.UNSIGNED_INT, 0);
|
||||
|
@ -437,6 +437,8 @@ export abstract class PathfinderView {
|
|||
protected abstract get scale(): number;
|
||||
protected abstract set scale(newScale: number);
|
||||
|
||||
protected abstract get worldTransform(): glmatrix.mat4;
|
||||
|
||||
protected antialiasingStrategy: AntialiasingStrategy;
|
||||
|
||||
protected translation: glmatrix.vec2;
|
||||
|
@ -461,7 +463,7 @@ export abstract class PathfinderView {
|
|||
meshes: PathfinderMeshBuffers;
|
||||
meshData: PathfinderMeshData;
|
||||
|
||||
atlasTransformBuffer: PathfinderBufferTexture;
|
||||
pathTransformBufferTexture: PathfinderBufferTexture;
|
||||
protected pathColorsBufferTexture: PathfinderBufferTexture;
|
||||
|
||||
private atlasRenderingTimerQuery: WebGLQuery;
|
||||
|
|
Loading…
Reference in New Issue