Add partial support for clip paths in the SVG demo.
At the moment, this only works when antialiasing is off.
This commit is contained in:
parent
511e5956d8
commit
4cbc2a8800
|
@ -359,8 +359,8 @@ class ThreeDRenderer extends Renderer {
|
|||
return this.destAllocatedSize;
|
||||
}
|
||||
|
||||
protected get depthFunction(): GLenum {
|
||||
return this.renderContext.gl.LESS;
|
||||
get backgroundColor(): glmatrix.vec4 {
|
||||
return glmatrix.vec4.clone([1.0, 1.0, 1.0, 1.0]);
|
||||
}
|
||||
|
||||
protected get pathIDsAreInstanced(): boolean {
|
||||
|
@ -375,6 +375,10 @@ class ThreeDRenderer extends Renderer {
|
|||
return glmatrix.vec2.clone([1.0, 1.0]);
|
||||
}
|
||||
|
||||
protected get objectCount(): number {
|
||||
return this.meshes.length;
|
||||
}
|
||||
|
||||
private cubeVertexPositionBuffer: WebGLBuffer;
|
||||
private cubeIndexBuffer: WebGLBuffer;
|
||||
|
||||
|
@ -431,9 +435,17 @@ class ThreeDRenderer extends Renderer {
|
|||
this.renderContext.gl.uniform4f(uniforms.uHints, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
protected clearColorForObject(objectIndex: number): glmatrix.vec4 | null {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected drawSceneryIfNecessary(): void {
|
||||
const gl = this.renderContext.gl;
|
||||
|
||||
// Set up the depth buffer for drawing the monument.
|
||||
gl.clearDepth(1.0);
|
||||
gl.clear(gl.DEPTH_BUFFER_BIT);
|
||||
|
||||
this.drawMonument();
|
||||
|
||||
// Clear to avoid Z-fighting.
|
||||
|
@ -441,6 +453,10 @@ class ThreeDRenderer extends Renderer {
|
|||
gl.clear(gl.DEPTH_BUFFER_BIT);
|
||||
|
||||
this.drawDistantGlyphs();
|
||||
|
||||
// Set up the depth buffer for direct rendering.
|
||||
gl.clearDepth(0.0);
|
||||
gl.clear(gl.DEPTH_BUFFER_BIT);
|
||||
}
|
||||
|
||||
protected compositeIfNecessary(): void {}
|
||||
|
@ -473,8 +489,12 @@ class ThreeDRenderer extends Renderer {
|
|||
throw new PathfinderError("Unsupported antialiasing type!");
|
||||
}
|
||||
|
||||
protected clearForDirectRendering(): void {
|
||||
protected clearDestFramebuffer(): void {
|
||||
const gl = this.renderContext.gl;
|
||||
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, this.destFramebuffer);
|
||||
gl.viewport(0, 0, this.destAllocatedSize[0], this.destAllocatedSize[1]);
|
||||
|
||||
gl.clearColor(1.0, 1.0, 1.0, 1.0);
|
||||
gl.clearDepth(1.0);
|
||||
gl.depthMask(true);
|
||||
|
@ -605,7 +625,7 @@ class ThreeDRenderer extends Renderer {
|
|||
|
||||
// Set state for the monument.
|
||||
gl.enable(gl.DEPTH_TEST);
|
||||
gl.depthFunc(this.depthFunction);
|
||||
gl.depthFunc(gl.LESS);
|
||||
gl.depthMask(true);
|
||||
gl.disable(gl.SCISSOR_TEST);
|
||||
gl.disable(gl.BLEND);
|
||||
|
|
|
@ -10,7 +10,10 @@
|
|||
|
||||
import * as glmatrix from 'gl-matrix';
|
||||
|
||||
import {createFramebuffer, createFramebufferColorTexture} from './gl-utils';
|
||||
import {createFramebufferDepthTexture} from './gl-utils';
|
||||
import {Renderer} from './renderer';
|
||||
import {unwrapNull} from './utils';
|
||||
import {DemoView} from './view';
|
||||
|
||||
export type AntialiasingStrategyName = 'none' | 'ssaa' | 'xcaa';
|
||||
|
@ -42,7 +45,12 @@ export abstract class AntialiasingStrategy {
|
|||
// Called before direct rendering.
|
||||
//
|
||||
// Typically, this redirects direct rendering to a framebuffer of some sort.
|
||||
abstract prepareForDirectRendering(renderer: Renderer): void;
|
||||
abstract prepareForRendering(renderer: Renderer): void;
|
||||
|
||||
// Called before directly rendering a single object.
|
||||
abstract prepareToDirectlyRenderObject(renderer: Renderer, objectIndex: number): void;
|
||||
|
||||
abstract finishDirectlyRenderingObject(renderer: Renderer, objectIndex: number): void;
|
||||
|
||||
// Called after direct rendering.
|
||||
//
|
||||
|
@ -58,9 +66,16 @@ export abstract class AntialiasingStrategy {
|
|||
export class NoAAStrategy extends AntialiasingStrategy {
|
||||
framebufferSize: glmatrix.vec2;
|
||||
|
||||
private renderTargetColorTextures: WebGLTexture[];
|
||||
private renderTargetDepthTextures: WebGLTexture[];
|
||||
private renderTargetFramebuffers: WebGLFramebuffer[];
|
||||
|
||||
constructor(level: number, subpixelAA: SubpixelAAType) {
|
||||
super();
|
||||
this.framebufferSize = glmatrix.vec2.create();
|
||||
this.renderTargetColorTextures = [];
|
||||
this.renderTargetDepthTextures = [];
|
||||
this.renderTargetFramebuffers = [];
|
||||
}
|
||||
|
||||
attachMeshes(renderer: Renderer) {}
|
||||
|
@ -73,11 +88,61 @@ export class NoAAStrategy extends AntialiasingStrategy {
|
|||
return glmatrix.mat4.create();
|
||||
}
|
||||
|
||||
prepareForDirectRendering(renderer: Renderer) {
|
||||
prepareForRendering(renderer: Renderer): void {
|
||||
const renderContext = renderer.renderContext;
|
||||
renderContext.gl.bindFramebuffer(renderContext.gl.FRAMEBUFFER, renderer.destFramebuffer);
|
||||
renderContext.gl.viewport(0, 0, this.framebufferSize[0], this.framebufferSize[1]);
|
||||
renderContext.gl.disable(renderContext.gl.SCISSOR_TEST);
|
||||
const gl = renderContext.gl;
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, renderer.destFramebuffer);
|
||||
gl.viewport(0, 0, this.framebufferSize[0], this.framebufferSize[1]);
|
||||
gl.disable(gl.SCISSOR_TEST);
|
||||
}
|
||||
|
||||
prepareToDirectlyRenderObject(renderer: Renderer, objectIndex: number): void {
|
||||
const renderContext = renderer.renderContext;
|
||||
const gl = renderContext.gl;
|
||||
|
||||
if (renderer.usesIntermediateRenderTargets &&
|
||||
(renderer.renderTaskTypeForObject(objectIndex) === 'clip' ||
|
||||
renderer.compositingOperationForObject(objectIndex) != null)) {
|
||||
if (this.renderTargetColorTextures[objectIndex] == null) {
|
||||
this.renderTargetColorTextures[objectIndex] =
|
||||
createFramebufferColorTexture(gl,
|
||||
this.framebufferSize,
|
||||
renderContext.colorAlphaFormat);
|
||||
}
|
||||
if (this.renderTargetDepthTextures[objectIndex] == null) {
|
||||
this.renderTargetDepthTextures[objectIndex] =
|
||||
createFramebufferDepthTexture(gl, this.framebufferSize);
|
||||
}
|
||||
if (this.renderTargetFramebuffers[objectIndex] == null) {
|
||||
this.renderTargetFramebuffers[objectIndex] =
|
||||
createFramebuffer(gl,
|
||||
this.renderTargetColorTextures[objectIndex],
|
||||
this.renderTargetDepthTextures[objectIndex]);
|
||||
}
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, this.renderTargetFramebuffers[objectIndex]);
|
||||
} else {
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, renderer.destFramebuffer);
|
||||
}
|
||||
|
||||
gl.viewport(0, 0, this.framebufferSize[0], this.framebufferSize[1]);
|
||||
gl.disable(gl.SCISSOR_TEST);
|
||||
}
|
||||
|
||||
finishDirectlyRenderingObject(renderer: Renderer, objectIndex: number): void {
|
||||
if (!renderer.usesIntermediateRenderTargets)
|
||||
return;
|
||||
|
||||
const compositingOperation = renderer.compositingOperationForObject(objectIndex);
|
||||
if (compositingOperation == null)
|
||||
return;
|
||||
|
||||
const gl = renderer.renderContext.gl;
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, renderer.destFramebuffer);
|
||||
gl.viewport(0, 0, renderer.destAllocatedSize[0], renderer.destAllocatedSize[1]);
|
||||
gl.disable(gl.DEPTH_TEST);
|
||||
gl.disable(gl.BLEND);
|
||||
|
||||
compositingOperation.composite(renderer, objectIndex, this.renderTargetColorTextures);
|
||||
}
|
||||
|
||||
antialias(renderer: Renderer) {}
|
||||
|
|
|
@ -309,10 +309,6 @@ class BenchmarkRenderer extends Renderer {
|
|||
return glmatrix.vec2.clone([1.0, 1.0]);
|
||||
}
|
||||
|
||||
protected get depthFunction(): number {
|
||||
return this.renderContext.gl.GREATER;
|
||||
}
|
||||
|
||||
protected get worldTransform() {
|
||||
const canvas = this.renderContext.canvas;
|
||||
|
||||
|
@ -329,6 +325,10 @@ class BenchmarkRenderer extends Renderer {
|
|||
return transform;
|
||||
}
|
||||
|
||||
protected get objectCount(): number {
|
||||
return this.meshes.length;
|
||||
}
|
||||
|
||||
private _pixelsPerEm: number = 32.0;
|
||||
|
||||
private get pixelsPerUnit(): number {
|
||||
|
|
|
@ -203,6 +203,20 @@ const RANGE_TO_RANGE_BUFFER_TABLE: RangeToRangeBufferTable = {
|
|||
segmentLineRanges: 'segmentLinePathIDs',
|
||||
};
|
||||
|
||||
const RANGE_KEYS: Array<keyof PathRanges> = [
|
||||
'bQuadPathRanges',
|
||||
'bVertexPathRanges',
|
||||
'coverInteriorIndexRanges',
|
||||
'coverCurveIndexRanges',
|
||||
'edgeBoundingBoxRanges',
|
||||
'edgeUpperLineIndexRanges',
|
||||
'edgeUpperCurveIndexRanges',
|
||||
'edgeLowerLineIndexRanges',
|
||||
'edgeLowerCurveIndexRanges',
|
||||
'segmentCurveRanges',
|
||||
'segmentLineRanges',
|
||||
];
|
||||
|
||||
type BufferType = 'ARRAY_BUFFER' | 'ELEMENT_ARRAY_BUFFER';
|
||||
|
||||
export interface Meshes<T> {
|
||||
|
@ -375,7 +389,7 @@ export class PathfinderMeshData implements Meshes<ArrayBuffer>, MeshDataCounts,
|
|||
tempOriginalRanges[key] = this[key];
|
||||
|
||||
const newExpandedRanges = [];
|
||||
for (const newPathID of pathIDs)
|
||||
for (const pathIndex of pathIDs)
|
||||
newExpandedRanges.push(new Range(0, 0));
|
||||
tempExpandedRanges[key] = newExpandedRanges;
|
||||
}
|
||||
|
@ -544,7 +558,7 @@ export class PathfinderMeshData implements Meshes<ArrayBuffer>, MeshDataCounts,
|
|||
}
|
||||
}
|
||||
|
||||
export class PathfinderMeshBuffers implements Meshes<WebGLBuffer> {
|
||||
export class PathfinderMeshBuffers implements Meshes<WebGLBuffer>, PathRanges {
|
||||
readonly bQuads: WebGLBuffer;
|
||||
readonly bVertexPositions: WebGLBuffer;
|
||||
readonly bVertexPathIDs: WebGLBuffer;
|
||||
|
@ -569,6 +583,18 @@ export class PathfinderMeshBuffers implements Meshes<WebGLBuffer> {
|
|||
readonly segmentLineNormals: WebGLBuffer;
|
||||
readonly segmentCurveNormals: WebGLBuffer;
|
||||
|
||||
readonly bQuadPathRanges: Range[];
|
||||
readonly bVertexPathRanges: Range[];
|
||||
readonly coverInteriorIndexRanges: Range[];
|
||||
readonly coverCurveIndexRanges: Range[];
|
||||
readonly edgeBoundingBoxRanges: Range[];
|
||||
readonly edgeUpperLineIndexRanges: Range[];
|
||||
readonly edgeUpperCurveIndexRanges: Range[];
|
||||
readonly edgeLowerLineIndexRanges: Range[];
|
||||
readonly edgeLowerCurveIndexRanges: Range[];
|
||||
readonly segmentCurveRanges: Range[];
|
||||
readonly segmentLineRanges: Range[];
|
||||
|
||||
constructor(gl: WebGLRenderingContext, meshData: PathfinderMeshData) {
|
||||
for (const bufferName of Object.keys(BUFFER_TYPES) as Array<keyof Meshes<void>>) {
|
||||
const bufferType = gl[BUFFER_TYPES[bufferName]];
|
||||
|
@ -577,6 +603,9 @@ export class PathfinderMeshBuffers implements Meshes<WebGLBuffer> {
|
|||
gl.bufferData(bufferType, meshData[bufferName], gl.STATIC_DRAW);
|
||||
this[bufferName] = buffer;
|
||||
}
|
||||
|
||||
for (const rangeName of RANGE_KEYS)
|
||||
this[rangeName] = meshData[rangeName];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -656,7 +685,7 @@ function copyIndices(destIndices: number[],
|
|||
|
||||
const lastDestIndex = destIndices.length;
|
||||
|
||||
destRanges[expandedPathID + 1] = new Range(firstExpandedIndex, lastDestIndex - firstDestIndex);
|
||||
destRanges[expandedPathID - 1] = new Range(firstDestIndex, lastDestIndex);
|
||||
}
|
||||
|
||||
function copySegments(segmentBufferNames: Array<keyof Meshes<void>>,
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
// pathfinder/client/src/render-task.ts
|
||||
//
|
||||
// Copyright © 2017 The Pathfinder Project Developers.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
import {Renderer} from "./renderer";
|
||||
import {Range} from "./utils";
|
||||
|
||||
export type RenderTaskType = 'color' | 'clip';
|
||||
|
||||
export class RenderTask {
|
||||
type: RenderTaskType;
|
||||
instanceIndices: Range;
|
||||
compositingOperation: CompositingOperation | null;
|
||||
|
||||
constructor(type: RenderTaskType,
|
||||
instanceIndices: Range,
|
||||
compositingOperation?: CompositingOperation) {
|
||||
this.type = type;
|
||||
this.instanceIndices = instanceIndices;
|
||||
this.compositingOperation = compositingOperation != null ? compositingOperation : null;
|
||||
}
|
||||
}
|
||||
|
||||
export type CompositingOperation = AlphaMaskCompositingOperation;
|
||||
|
||||
export class AlphaMaskCompositingOperation {
|
||||
alphaFramebufferIndex: number;
|
||||
|
||||
constructor(alphaFramebufferIndex: number) {
|
||||
this.alphaFramebufferIndex = alphaFramebufferIndex;
|
||||
}
|
||||
|
||||
composite(renderer: Renderer, sourceTextureIndex: number, textures: WebGLTexture[]): void {
|
||||
const renderContext = renderer.renderContext;
|
||||
const gl = renderContext.gl;
|
||||
|
||||
const program = renderContext.shaderPrograms.compositeAlphaMask;
|
||||
|
||||
gl.useProgram(program.program);
|
||||
renderContext.initQuadVAO(program.attributes);
|
||||
|
||||
// Composite to the current framebuffer.
|
||||
gl.activeTexture(gl.TEXTURE0);
|
||||
gl.bindTexture(gl.TEXTURE_2D, textures[sourceTextureIndex]);
|
||||
gl.uniform1i(program.uniforms.uSource, 0);
|
||||
gl.activeTexture(gl.TEXTURE1);
|
||||
gl.bindTexture(gl.TEXTURE_2D, textures[this.alphaFramebufferIndex]);
|
||||
gl.uniform1i(program.uniforms.uMask, 1);
|
||||
renderer.setTransformAndTexScaleUniformsForDest(program.uniforms);
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, renderContext.quadElementsBuffer);
|
||||
gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_BYTE, 0);
|
||||
}
|
||||
}
|
|
@ -9,14 +9,16 @@
|
|||
// except according to those terms.
|
||||
|
||||
import * as glmatrix from 'gl-matrix';
|
||||
import * as _ from 'lodash';
|
||||
|
||||
import {AntialiasingStrategy, AntialiasingStrategyName, NoAAStrategy} from './aa-strategy';
|
||||
import {StemDarkeningMode, SubpixelAAType} from './aa-strategy';
|
||||
import PathfinderBufferTexture from "./buffer-texture";
|
||||
import {UniformMap} from './gl-utils';
|
||||
import {PathfinderMeshBuffers, PathfinderMeshData} from "./meshes";
|
||||
import {CompositingOperation, RenderTaskType} from './render-task';
|
||||
import {ShaderMap} from './shader-loader';
|
||||
import {FLOAT32_SIZE, Range, UINT16_SIZE, UINT32_SIZE, unwrapNull} from './utils';
|
||||
import {FLOAT32_SIZE, Range, UINT16_SIZE, UINT32_SIZE, unwrapNull, unwrapUndef} from './utils';
|
||||
import {RenderContext, Timings} from "./view";
|
||||
import {MCAAMulticolorStrategy} from './xcaa-strategy';
|
||||
|
||||
|
@ -48,6 +50,14 @@ export abstract class Renderer {
|
|||
return null;
|
||||
}
|
||||
|
||||
get backgroundColor(): glmatrix.vec4 {
|
||||
return glmatrix.vec4.create();
|
||||
}
|
||||
|
||||
get usesIntermediateRenderTargets(): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
abstract get destFramebuffer(): WebGLFramebuffer | null;
|
||||
abstract get destAllocatedSize(): glmatrix.vec2;
|
||||
abstract get destUsedSize(): glmatrix.vec2;
|
||||
|
@ -60,11 +70,7 @@ export abstract class Renderer {
|
|||
return false;
|
||||
}
|
||||
|
||||
protected get backgroundColor(): glmatrix.vec4 {
|
||||
return glmatrix.vec4.create();
|
||||
}
|
||||
|
||||
protected abstract get depthFunction(): GLenum;
|
||||
protected abstract get objectCount(): number;
|
||||
protected abstract get usedSizeFactor(): glmatrix.vec2;
|
||||
protected abstract get worldTransform(): glmatrix.mat4;
|
||||
|
||||
|
@ -111,19 +117,17 @@ export abstract class Renderer {
|
|||
renderContext.atlasRenderingTimerQuery);
|
||||
}
|
||||
|
||||
// Antialias.
|
||||
this.clearDestFramebuffer();
|
||||
|
||||
const antialiasingStrategy = unwrapNull(this.antialiasingStrategy);
|
||||
antialiasingStrategy.antialias(this);
|
||||
|
||||
// Prepare for direct rendering.
|
||||
antialiasingStrategy.prepareForDirectRendering(this);
|
||||
|
||||
// Clear.
|
||||
this.clearForDirectRendering();
|
||||
antialiasingStrategy.prepareForRendering(this);
|
||||
|
||||
// Draw "scenery" (used in the 3D view).
|
||||
this.drawSceneryIfNecessary();
|
||||
|
||||
// Antialias.
|
||||
antialiasingStrategy.antialias(this);
|
||||
|
||||
// Perform direct rendering (Loop-Blinn).
|
||||
if (antialiasingStrategy.directRenderingMode !== 'none')
|
||||
this.renderDirect();
|
||||
|
@ -249,7 +253,20 @@ export abstract class Renderer {
|
|||
|
||||
setPathColorsUniform(objectIndex: number, uniforms: UniformMap, textureUnit: number): void {
|
||||
const gl = this.renderContext.gl;
|
||||
this.pathColorsBufferTextures[objectIndex].bind(gl, uniforms, textureUnit);
|
||||
const meshIndex = this.meshIndexForObject(objectIndex);
|
||||
this.pathColorsBufferTextures[meshIndex].bind(gl, uniforms, textureUnit);
|
||||
}
|
||||
|
||||
renderTaskTypeForObject(objectIndex: number): RenderTaskType {
|
||||
return 'color';
|
||||
}
|
||||
|
||||
compositingOperationForObject(objectIndex: number): CompositingOperation | null {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected clearColorForObject(objectIndex: number): glmatrix.vec4 | null {
|
||||
return glmatrix.vec4.create();
|
||||
}
|
||||
|
||||
protected abstract createAAStrategy(aaType: AntialiasingStrategyName,
|
||||
|
@ -266,12 +283,26 @@ export abstract class Renderer {
|
|||
|
||||
protected drawSceneryIfNecessary(): void {}
|
||||
|
||||
protected clearForDirectRendering(): void {
|
||||
const renderingMode = unwrapNull(this.antialiasingStrategy).directRenderingMode;
|
||||
protected clearDestFramebuffer(): void {
|
||||
const renderContext = this.renderContext;
|
||||
const gl = renderContext.gl;
|
||||
|
||||
const clearColor = this.backgroundColor;
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, this.destFramebuffer);
|
||||
gl.viewport(0, 0, this.destAllocatedSize[0], this.destAllocatedSize[1]);
|
||||
gl.clearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
}
|
||||
|
||||
protected clearForDirectRendering(objectIndex: number): void {
|
||||
const renderingMode = unwrapNull(this.antialiasingStrategy).directRenderingMode;
|
||||
const renderContext = this.renderContext;
|
||||
const gl = renderContext.gl;
|
||||
|
||||
const clearColor = this.clearColorForObject(objectIndex);
|
||||
if (clearColor == null)
|
||||
return;
|
||||
|
||||
gl.clearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
|
||||
|
||||
switch (renderingMode) {
|
||||
|
@ -298,6 +329,15 @@ export abstract class Renderer {
|
|||
return new Range(0, 1);
|
||||
}
|
||||
|
||||
protected meshIndexForObject(objectIndex: number): number {
|
||||
return objectIndex;
|
||||
}
|
||||
|
||||
protected pathRangeForObject(objectIndex: number): Range {
|
||||
const bVertexPathRanges = this.meshes[objectIndex].bVertexPathRanges;
|
||||
return new Range(1, bVertexPathRanges.length + 1);
|
||||
}
|
||||
|
||||
/// Called whenever new GPU timing statistics are available.
|
||||
protected newTimingsReceived(): void {}
|
||||
|
||||
|
@ -307,16 +347,27 @@ export abstract class Renderer {
|
|||
|
||||
const antialiasingStrategy = unwrapNull(this.antialiasingStrategy);
|
||||
const renderingMode = antialiasingStrategy.directRenderingMode;
|
||||
const objectCount = this.objectCount;
|
||||
|
||||
for (let objectIndex = 0; objectIndex < this.meshes.length; objectIndex++) {
|
||||
for (let objectIndex = 0; objectIndex < objectCount; objectIndex++) {
|
||||
const instanceRange = this.instanceRangeForObject(objectIndex);
|
||||
if (instanceRange.isEmpty)
|
||||
continue;
|
||||
|
||||
const meshData = this.meshData[objectIndex];
|
||||
const pathRange = this.pathRangeForObject(objectIndex);
|
||||
const meshIndex = this.meshIndexForObject(objectIndex);
|
||||
|
||||
// Prepare for direct rendering.
|
||||
antialiasingStrategy.prepareToDirectlyRenderObject(this, objectIndex);
|
||||
|
||||
// Clear.
|
||||
this.clearForDirectRendering(objectIndex);
|
||||
|
||||
const meshes = this.meshes[meshIndex];
|
||||
const meshData = this.meshData[meshIndex];
|
||||
|
||||
// Set up implicit cover state.
|
||||
gl.depthFunc(this.depthFunction);
|
||||
gl.depthFunc(gl.GREATER);
|
||||
gl.depthMask(true);
|
||||
gl.enable(gl.DEPTH_TEST);
|
||||
gl.disable(gl.BLEND);
|
||||
|
@ -336,21 +387,26 @@ export abstract class Renderer {
|
|||
this.setFramebufferSizeUniform(directInteriorProgram.uniforms);
|
||||
this.setHintsUniform(directInteriorProgram.uniforms);
|
||||
this.setPathColorsUniform(objectIndex, directInteriorProgram.uniforms, 0);
|
||||
this.pathTransformBufferTextures[objectIndex]
|
||||
this.pathTransformBufferTextures[meshIndex]
|
||||
.bind(gl, directInteriorProgram.uniforms, 1);
|
||||
if (renderingMode === 'color-depth') {
|
||||
const strategy = antialiasingStrategy as MCAAMulticolorStrategy;
|
||||
strategy.bindEdgeDepthTexture(gl, directInteriorProgram.uniforms, 2);
|
||||
}
|
||||
let indexCount = meshData.coverInteriorIndices.byteLength / UINT32_SIZE;
|
||||
const coverInteriorRange = getMeshIndexRange(meshes.coverInteriorIndexRanges,
|
||||
pathRange);
|
||||
if (!this.pathIDsAreInstanced) {
|
||||
gl.drawElements(gl.TRIANGLES, indexCount, gl.UNSIGNED_INT, 0);
|
||||
gl.drawElements(gl.TRIANGLES,
|
||||
coverInteriorRange.length,
|
||||
gl.UNSIGNED_INT,
|
||||
coverInteriorRange.start * UINT32_SIZE);
|
||||
} else {
|
||||
renderContext.instancedArraysExt.drawElementsInstancedANGLE(gl.TRIANGLES,
|
||||
indexCount,
|
||||
gl.UNSIGNED_INT,
|
||||
0,
|
||||
instanceRange.length);
|
||||
renderContext.instancedArraysExt
|
||||
.drawElementsInstancedANGLE(gl.TRIANGLES,
|
||||
coverInteriorRange.length,
|
||||
gl.UNSIGNED_INT,
|
||||
0,
|
||||
instanceRange.length);
|
||||
}
|
||||
|
||||
// Set up direct curve state.
|
||||
|
@ -381,23 +437,29 @@ export abstract class Renderer {
|
|||
this.setFramebufferSizeUniform(directCurveProgram.uniforms);
|
||||
this.setHintsUniform(directCurveProgram.uniforms);
|
||||
this.setPathColorsUniform(objectIndex, directCurveProgram.uniforms, 0);
|
||||
this.pathTransformBufferTextures[objectIndex].bind(gl, directCurveProgram.uniforms, 1);
|
||||
this.pathTransformBufferTextures[meshIndex].bind(gl, directCurveProgram.uniforms, 1);
|
||||
if (renderingMode === 'color-depth') {
|
||||
const strategy = antialiasingStrategy as MCAAMulticolorStrategy;
|
||||
strategy.bindEdgeDepthTexture(gl, directCurveProgram.uniforms, 2);
|
||||
}
|
||||
indexCount = meshData.coverCurveIndices.byteLength / UINT32_SIZE;
|
||||
const coverCurveRange = getMeshIndexRange(meshes.coverCurveIndexRanges, pathRange);
|
||||
if (!this.pathIDsAreInstanced) {
|
||||
gl.drawElements(gl.TRIANGLES, indexCount, gl.UNSIGNED_INT, 0);
|
||||
gl.drawElements(gl.TRIANGLES,
|
||||
coverCurveRange.length,
|
||||
gl.UNSIGNED_INT,
|
||||
coverCurveRange.start * UINT32_SIZE);
|
||||
} else {
|
||||
renderContext.instancedArraysExt.drawElementsInstancedANGLE(gl.TRIANGLES,
|
||||
indexCount,
|
||||
coverCurveRange.length,
|
||||
gl.UNSIGNED_INT,
|
||||
0,
|
||||
instanceRange.length);
|
||||
}
|
||||
|
||||
renderContext.vertexArrayObjectExt.bindVertexArrayOES(null);
|
||||
|
||||
// Finish direct rendering. Right now, this performs compositing if necessary.
|
||||
antialiasingStrategy.finishDirectlyRenderingObject(this, objectIndex);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -444,7 +506,9 @@ export abstract class Renderer {
|
|||
private initImplicitCoverCurveVAO(objectIndex: number, instanceRange: Range): void {
|
||||
const renderContext = this.renderContext;
|
||||
const gl = renderContext.gl;
|
||||
const meshes = this.meshes[objectIndex];
|
||||
|
||||
const meshIndex = this.meshIndexForObject(objectIndex);
|
||||
const meshes = this.meshes[meshIndex];
|
||||
|
||||
const directCurveProgramName = this.directCurveProgramName();
|
||||
const directCurveProgram = renderContext.shaderPrograms[directCurveProgramName];
|
||||
|
@ -490,7 +554,9 @@ export abstract class Renderer {
|
|||
private initImplicitCoverInteriorVAO(objectIndex: number, instanceRange: Range): void {
|
||||
const renderContext = this.renderContext;
|
||||
const gl = renderContext.gl;
|
||||
const meshes = this.meshes[objectIndex];
|
||||
|
||||
const meshIndex = this.meshIndexForObject(objectIndex);
|
||||
const meshes = this.meshes[meshIndex];
|
||||
|
||||
const directInteriorProgramName = this.directInteriorProgramName();
|
||||
const directInteriorProgram = renderContext.shaderPrograms[directInteriorProgramName];
|
||||
|
@ -543,3 +609,22 @@ export abstract class Renderer {
|
|||
this.renderContext.gl.uniformMatrix4fv(uniforms.uTransform, false, transform);
|
||||
}
|
||||
}
|
||||
|
||||
function getMeshIndexRange(indexRanges: Range[], pathRange: Range): Range {
|
||||
if (indexRanges.length === 0)
|
||||
return new Range(0, 0);
|
||||
|
||||
let firstIndex;
|
||||
if (pathRange.start - 1 >= indexRanges.length)
|
||||
firstIndex = unwrapUndef(_.last(indexRanges)).end;
|
||||
else
|
||||
firstIndex = indexRanges[pathRange.start - 1].start;
|
||||
|
||||
let lastIndex;
|
||||
if (pathRange.end - 1 >= indexRanges.length)
|
||||
lastIndex = unwrapUndef(_.last(indexRanges)).end;
|
||||
else
|
||||
lastIndex = indexRanges[pathRange.end - 1].start;
|
||||
|
||||
return new Range(firstIndex, lastIndex);
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import {expectNotNull, PathfinderError, unwrapNull} from './utils';
|
|||
|
||||
export interface ShaderMap<T> {
|
||||
blit: T;
|
||||
compositeAlphaMask: T;
|
||||
demo3DDistantGlyph: T;
|
||||
demo3DMonument: T;
|
||||
directCurve: T;
|
||||
|
@ -43,6 +44,7 @@ const COMMON_SHADER_URL: string = '/glsl/gles2/common.inc.glsl';
|
|||
|
||||
export const SHADER_NAMES: Array<keyof ShaderMap<void>> = [
|
||||
'blit',
|
||||
'compositeAlphaMask',
|
||||
'directCurve',
|
||||
'directInterior',
|
||||
'direct3DCurve',
|
||||
|
@ -69,6 +71,10 @@ const SHADER_URLS: ShaderMap<ShaderProgramURLs> = {
|
|||
fragment: "/glsl/gles2/blit.fs.glsl",
|
||||
vertex: "/glsl/gles2/blit.vs.glsl",
|
||||
},
|
||||
compositeAlphaMask: {
|
||||
fragment: "/glsl/gles2/composite-alpha-mask.fs.glsl",
|
||||
vertex: "/glsl/gles2/composite-alpha-mask.vs.glsl",
|
||||
},
|
||||
demo3DDistantGlyph: {
|
||||
fragment: "/glsl/gles2/demo-3d-distant-glyph.fs.glsl",
|
||||
vertex: "/glsl/gles2/demo-3d-distant-glyph.vs.glsl",
|
||||
|
|
|
@ -80,7 +80,7 @@ export default class SSAAStrategy extends AntialiasingStrategy {
|
|||
return transform;
|
||||
}
|
||||
|
||||
prepareForDirectRendering(renderer: Renderer) {
|
||||
prepareForRendering(renderer: Renderer): void {
|
||||
const renderContext = renderer.renderContext;
|
||||
const gl = renderContext.gl;
|
||||
|
||||
|
@ -90,6 +90,18 @@ export default class SSAAStrategy extends AntialiasingStrategy {
|
|||
gl.viewport(0, 0, framebufferSize[0], framebufferSize[1]);
|
||||
gl.scissor(0, 0, usedSize[0], usedSize[1]);
|
||||
gl.enable(gl.SCISSOR_TEST);
|
||||
|
||||
const clearColor = renderer.backgroundColor;
|
||||
gl.clearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
}
|
||||
|
||||
prepareToDirectlyRenderObject(renderer: Renderer, objectIndex: number): void {
|
||||
// TODO(pcwalton)
|
||||
}
|
||||
|
||||
finishDirectlyRenderingObject(renderer: Renderer, objectIndex: number): void {
|
||||
// TODO(pcwalton)
|
||||
}
|
||||
|
||||
antialias(renderer: Renderer) {}
|
||||
|
|
|
@ -18,11 +18,12 @@ import PathfinderBufferTexture from "./buffer-texture";
|
|||
import {OrthographicCamera} from "./camera";
|
||||
import {UniformMap} from './gl-utils';
|
||||
import {PathfinderMeshData} from "./meshes";
|
||||
import {CompositingOperation, RenderTaskType} from './render-task';
|
||||
import {Renderer} from './renderer';
|
||||
import {ShaderMap, ShaderProgramSource} from './shader-loader';
|
||||
import SSAAStrategy from "./ssaa-strategy";
|
||||
import {BUILTIN_SVG_URI, SVGLoader} from './svg-loader';
|
||||
import {panic, unwrapNull} from './utils';
|
||||
import {panic, Range, unwrapNull} from './utils';
|
||||
import {DemoView, Timings} from './view';
|
||||
import {MCAAMulticolorStrategy, XCAAStrategy} from "./xcaa-strategy";
|
||||
|
||||
|
@ -127,10 +128,19 @@ class SVGDemoRenderer extends Renderer {
|
|||
return this.destAllocatedSize;
|
||||
}
|
||||
|
||||
protected get backgroundColor(): glmatrix.vec4 {
|
||||
get usesIntermediateRenderTargets(): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
get backgroundColor(): glmatrix.vec4 {
|
||||
return glmatrix.vec4.clone([1.0, 1.0, 1.0, 1.0]);
|
||||
}
|
||||
|
||||
protected get objectCount(): number {
|
||||
const loader = this.renderContext.appController.loader;
|
||||
return loader.renderTasks.length;
|
||||
}
|
||||
|
||||
constructor(renderContext: SVGDemoView) {
|
||||
super(renderContext);
|
||||
|
||||
|
@ -159,8 +169,14 @@ class SVGDemoRenderer extends Renderer {
|
|||
this.camera.zoomToFit();
|
||||
}
|
||||
|
||||
protected get depthFunction(): GLenum {
|
||||
return this.renderContext.gl.GREATER;
|
||||
renderTaskTypeForObject(objectIndex: number): RenderTaskType {
|
||||
const loader = this.renderContext.appController.loader;
|
||||
return loader.renderTasks[objectIndex].type;
|
||||
}
|
||||
|
||||
compositingOperationForObject(objectIndex: number): CompositingOperation | null {
|
||||
const loader = this.renderContext.appController.loader;
|
||||
return loader.renderTasks[objectIndex].compositingOperation;
|
||||
}
|
||||
|
||||
protected get usedSizeFactor(): glmatrix.vec2 {
|
||||
|
@ -193,6 +209,15 @@ class SVGDemoRenderer extends Renderer {
|
|||
return 'directInterior';
|
||||
}
|
||||
|
||||
protected meshIndexForObject(objectIndex: number): number {
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected pathRangeForObject(objectIndex: number): Range {
|
||||
const loader = this.renderContext.appController.loader;
|
||||
return loader.renderTasks[objectIndex].instanceIndices;
|
||||
}
|
||||
|
||||
protected newTimingsReceived(): void {
|
||||
this.renderContext.appController.newTimingsReceived(this.lastTimings);
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ import * as _ from 'lodash';
|
|||
|
||||
import 'path-data-polyfill.js';
|
||||
import {parseServerTiming, PathfinderMeshData} from "./meshes";
|
||||
import {AlphaMaskCompositingOperation, RenderTask, RenderTaskType} from './render-task';
|
||||
import {panic, Range, unwrapNull, unwrapUndef} from "./utils";
|
||||
|
||||
export const BUILTIN_SVG_URI: string = "/svg/demo";
|
||||
|
@ -65,26 +66,12 @@ export class SVGStroke extends SVGPath {
|
|||
}
|
||||
}
|
||||
|
||||
export type SVGRenderTaskType = 'color' | 'clip';
|
||||
|
||||
export class SVGRenderTask {
|
||||
type: SVGRenderTaskType;
|
||||
instanceIndices: Range;
|
||||
clipIndex: number | null;
|
||||
|
||||
constructor(type: SVGRenderTaskType, instanceIndices: Range, clipIndex?: number) {
|
||||
this.type = type;
|
||||
this.instanceIndices = instanceIndices;
|
||||
this.clipIndex = clipIndex != null ? clipIndex : null;
|
||||
}
|
||||
}
|
||||
|
||||
interface ClipPathIDTable {
|
||||
[id: string]: number;
|
||||
}
|
||||
|
||||
export class SVGLoader {
|
||||
renderTasks: SVGRenderTask[];
|
||||
renderTasks: RenderTask[];
|
||||
pathInstances: SVGPath[];
|
||||
scale: number;
|
||||
bounds: glmatrix.vec4;
|
||||
|
@ -202,7 +189,8 @@ export class SVGLoader {
|
|||
!this.clipPathIDs.hasOwnProperty(matches[1])) {
|
||||
hasClip = false;
|
||||
} else {
|
||||
currentRenderTask.clipIndex = this.clipPathIDs[matches[1]];
|
||||
currentRenderTask.compositingOperation =
|
||||
new AlphaMaskCompositingOperation(this.clipPathIDs[matches[1]]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -231,7 +219,7 @@ export class SVGLoader {
|
|||
const currentRenderTask = unwrapUndef(_.last(this.renderTasks));
|
||||
this.pathInstances.push(pathInstance);
|
||||
currentRenderTask.instanceIndices.end = Math.max(currentRenderTask.instanceIndices.end,
|
||||
this.pathInstances.length);
|
||||
this.pathInstances.length + 1);
|
||||
}
|
||||
|
||||
private popTopRenderTaskIfEmpty(): void {
|
||||
|
@ -240,10 +228,10 @@ export class SVGLoader {
|
|||
this.renderTasks.pop();
|
||||
}
|
||||
|
||||
private pushNewRenderTask(taskType: SVGRenderTaskType): void {
|
||||
private pushNewRenderTask(taskType: RenderTaskType): void {
|
||||
this.popTopRenderTaskIfEmpty();
|
||||
const emptyRange = new Range(this.pathInstances.length, this.pathInstances.length);
|
||||
this.renderTasks.push(new SVGRenderTask(taskType, emptyRange));
|
||||
const emptyRange = new Range(this.pathInstances.length + 1, this.pathInstances.length + 1);
|
||||
this.renderTasks.push(new RenderTask(taskType, emptyRange));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -109,10 +109,6 @@ export abstract class TextRenderer extends Renderer {
|
|||
return glmatrix.vec2.create();
|
||||
}
|
||||
|
||||
protected get depthFunction(): number {
|
||||
return this.renderContext.gl.GREATER;
|
||||
}
|
||||
|
||||
protected get usedSizeFactor(): glmatrix.vec2 {
|
||||
const usedSize = glmatrix.vec2.create();
|
||||
glmatrix.vec2.div(usedSize, this.renderContext.atlas.usedSize, ATLAS_SIZE);
|
||||
|
@ -123,6 +119,10 @@ export abstract class TextRenderer extends Renderer {
|
|||
return this.renderContext.glyphStore.glyphIDs.length * SUBPIXEL_GRANULARITY;
|
||||
}
|
||||
|
||||
protected get objectCount(): number {
|
||||
return this.meshes.length;
|
||||
}
|
||||
|
||||
private stemDarkening: StemDarkeningMode;
|
||||
private subpixelAA: SubpixelAAType;
|
||||
|
||||
|
|
|
@ -60,16 +60,16 @@ export abstract class XCAAStrategy extends AntialiasingStrategy {
|
|||
this.destFramebufferSize = glmatrix.vec2.create();
|
||||
}
|
||||
|
||||
init(renderer: Renderer) {
|
||||
init(renderer: Renderer): void {
|
||||
super.init(renderer);
|
||||
}
|
||||
|
||||
attachMeshes(renderer: Renderer) {
|
||||
attachMeshes(renderer: Renderer): void {
|
||||
const renderContext = renderer.renderContext;
|
||||
this.createResolveVAO(renderer);
|
||||
}
|
||||
|
||||
setFramebufferSize(renderer: Renderer) {
|
||||
setFramebufferSize(renderer: Renderer): void {
|
||||
const renderContext = renderer.renderContext;
|
||||
|
||||
this.destFramebufferSize = glmatrix.vec2.clone(renderer.destAllocatedSize);
|
||||
|
@ -82,7 +82,7 @@ export abstract class XCAAStrategy extends AntialiasingStrategy {
|
|||
renderContext.gl.bindFramebuffer(renderContext.gl.FRAMEBUFFER, null);
|
||||
}
|
||||
|
||||
prepareForDirectRendering(renderer: Renderer) {
|
||||
prepareForRendering(renderer: Renderer): void {
|
||||
const renderContext = renderer.renderContext;
|
||||
const gl = renderContext.gl;
|
||||
|
||||
|
@ -102,7 +102,16 @@ export abstract class XCAAStrategy extends AntialiasingStrategy {
|
|||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
||||
}
|
||||
|
||||
antialias(renderer: Renderer) {
|
||||
prepareToDirectlyRenderObject(renderer: Renderer, objectIndex: number): void {
|
||||
// TODO(pcwalton)
|
||||
this.prepareForRendering(renderer);
|
||||
}
|
||||
|
||||
finishDirectlyRenderingObject(renderer: Renderer, objectIndex: number): void {
|
||||
// TODO(pcwalton)
|
||||
}
|
||||
|
||||
antialias(renderer: Renderer): void {
|
||||
// Perform early preparations.
|
||||
this.createPathBoundsBufferTexture(renderer);
|
||||
|
||||
|
@ -116,7 +125,7 @@ export abstract class XCAAStrategy extends AntialiasingStrategy {
|
|||
this.clearForAA(renderer);
|
||||
}
|
||||
|
||||
resolve(renderer: Renderer) {
|
||||
resolve(renderer: Renderer): void {
|
||||
// Resolve the antialiasing.
|
||||
this.resolveAA(renderer);
|
||||
}
|
||||
|
@ -125,7 +134,7 @@ export abstract class XCAAStrategy extends AntialiasingStrategy {
|
|||
return glmatrix.mat4.create();
|
||||
}
|
||||
|
||||
protected initDirectFramebufferIfNecessary(renderer: Renderer) {
|
||||
protected initDirectFramebufferIfNecessary(renderer: Renderer): void {
|
||||
const renderContext = renderer.renderContext;
|
||||
const gl = renderContext.gl;
|
||||
|
||||
|
@ -156,7 +165,7 @@ export abstract class XCAAStrategy extends AntialiasingStrategy {
|
|||
renderContext.gl.enable(renderContext.gl.SCISSOR_TEST);
|
||||
}
|
||||
|
||||
protected setAAState(renderer: Renderer) {
|
||||
protected setAAState(renderer: Renderer): void {
|
||||
const renderContext = renderer.renderContext;
|
||||
const usedSize = this.supersampledUsedSize(renderer);
|
||||
renderContext.gl.bindFramebuffer(renderContext.gl.FRAMEBUFFER, this.aaFramebuffer);
|
||||
|
@ -170,7 +179,7 @@ export abstract class XCAAStrategy extends AntialiasingStrategy {
|
|||
this.setAADepthState(renderer);
|
||||
}
|
||||
|
||||
protected setAAUniforms(renderer: Renderer, uniforms: UniformMap) {
|
||||
protected setAAUniforms(renderer: Renderer, uniforms: UniformMap): void {
|
||||
const renderContext = renderer.renderContext;
|
||||
const gl = renderContext.gl;
|
||||
|
||||
|
@ -183,7 +192,7 @@ export abstract class XCAAStrategy extends AntialiasingStrategy {
|
|||
renderer.setHintsUniform(uniforms);
|
||||
}
|
||||
|
||||
protected resolveAA(renderer: Renderer) {
|
||||
protected resolveAA(renderer: Renderer): void {
|
||||
const renderContext = renderer.renderContext;
|
||||
const gl = renderContext.gl;
|
||||
|
||||
|
@ -238,7 +247,7 @@ export abstract class XCAAStrategy extends AntialiasingStrategy {
|
|||
protected abstract setAADepthState(renderer: Renderer): void;
|
||||
protected abstract clearForResolve(renderer: Renderer): void;
|
||||
|
||||
private initAAAlphaFramebuffer(renderer: Renderer) {
|
||||
private initAAAlphaFramebuffer(renderer: Renderer): void {
|
||||
const renderContext = renderer.renderContext;
|
||||
this.aaAlphaTexture = unwrapNull(renderContext.gl.createTexture());
|
||||
renderContext.gl.activeTexture(renderContext.gl.TEXTURE0);
|
||||
|
@ -262,7 +271,7 @@ export abstract class XCAAStrategy extends AntialiasingStrategy {
|
|||
this.aaDepthTexture);
|
||||
}
|
||||
|
||||
private createPathBoundsBufferTexture(renderer: Renderer) {
|
||||
private createPathBoundsBufferTexture(renderer: Renderer): void {
|
||||
const renderContext = renderer.renderContext;
|
||||
const pathBounds = renderer.pathBoundingRects(0);
|
||||
this.pathBoundsBufferTexture = new PathfinderBufferTexture(renderContext.gl,
|
||||
|
@ -270,7 +279,7 @@ export abstract class XCAAStrategy extends AntialiasingStrategy {
|
|||
this.pathBoundsBufferTexture.upload(renderContext.gl, pathBounds);
|
||||
}
|
||||
|
||||
private createResolveVAO(renderer: Renderer) {
|
||||
private createResolveVAO(renderer: Renderer): void {
|
||||
const renderContext = renderer.renderContext;
|
||||
this.resolveVAO = renderContext.vertexArrayObjectExt.createVertexArrayOES();
|
||||
renderContext.vertexArrayObjectExt.bindVertexArrayOES(this.resolveVAO);
|
||||
|
@ -296,7 +305,7 @@ export abstract class MCAAStrategy extends XCAAStrategy {
|
|||
private lineVAOs: FastEdgeVAOs;
|
||||
private curveVAOs: FastEdgeVAOs;
|
||||
|
||||
attachMeshes(renderer: Renderer) {
|
||||
attachMeshes(renderer: Renderer): void {
|
||||
super.attachMeshes(renderer);
|
||||
|
||||
this.createCoverVAO(renderer);
|
||||
|
@ -304,7 +313,7 @@ export abstract class MCAAStrategy extends XCAAStrategy {
|
|||
this.createCurveVAOs(renderer);
|
||||
}
|
||||
|
||||
antialias(renderer: Renderer) {
|
||||
antialias(renderer: Renderer): void {
|
||||
super.antialias(renderer);
|
||||
|
||||
// Conservatively cover.
|
||||
|
@ -391,7 +400,7 @@ export abstract class MCAAStrategy extends XCAAStrategy {
|
|||
renderContext.vertexArrayObjectExt.bindVertexArrayOES(null);
|
||||
}
|
||||
|
||||
private createCoverVAO(renderer: Renderer) {
|
||||
private createCoverVAO(renderer: Renderer): void {
|
||||
const renderContext = renderer.renderContext;
|
||||
|
||||
this.coverVAO = renderContext.vertexArrayObjectExt.createVertexArrayOES();
|
||||
|
@ -445,7 +454,7 @@ export abstract class MCAAStrategy extends XCAAStrategy {
|
|||
renderContext.vertexArrayObjectExt.bindVertexArrayOES(null);
|
||||
}
|
||||
|
||||
private createLineVAOs(renderer: Renderer) {
|
||||
private createLineVAOs(renderer: Renderer): void {
|
||||
const renderContext = renderer.renderContext;
|
||||
const vaos: Partial<FastEdgeVAOs> = {};
|
||||
const lineProgram = renderContext.shaderPrograms.mcaaLine;
|
||||
|
@ -517,7 +526,7 @@ export abstract class MCAAStrategy extends XCAAStrategy {
|
|||
this.lineVAOs = vaos as FastEdgeVAOs;
|
||||
}
|
||||
|
||||
private createCurveVAOs(renderer: Renderer) {
|
||||
private createCurveVAOs(renderer: Renderer): void {
|
||||
const renderContext = renderer.renderContext;
|
||||
const vaos: Partial<FastEdgeVAOs> = {};
|
||||
const curveProgram = renderContext.shaderPrograms.mcaaCurve;
|
||||
|
@ -612,14 +621,14 @@ export abstract class MCAAStrategy extends XCAAStrategy {
|
|||
renderContext.vertexArrayObjectExt.bindVertexArrayOES(null);
|
||||
}
|
||||
|
||||
private setBlendModeForAA(renderer: Renderer, direction: 'upper' | 'lower') {
|
||||
private setBlendModeForAA(renderer: Renderer, direction: 'upper' | 'lower'): void {
|
||||
const renderContext = renderer.renderContext;
|
||||
renderContext.gl.blendEquation(renderContext.gl.FUNC_ADD);
|
||||
renderContext.gl.blendFunc(renderContext.gl.ONE, renderContext.gl.ONE);
|
||||
renderContext.gl.enable(renderContext.gl.BLEND);
|
||||
}
|
||||
|
||||
private antialiasLines(renderer: Renderer) {
|
||||
private antialiasLines(renderer: Renderer): void {
|
||||
const renderContext = renderer.renderContext;
|
||||
this.setAAState(renderer);
|
||||
|
||||
|
@ -630,7 +639,7 @@ export abstract class MCAAStrategy extends XCAAStrategy {
|
|||
this.antialiasLinesWithProgram(renderer, lineProgram);
|
||||
}
|
||||
|
||||
private antialiasCurves(renderer: Renderer) {
|
||||
private antialiasCurves(renderer: Renderer): void {
|
||||
const renderContext = renderer.renderContext;
|
||||
|
||||
this.setAAState(renderer);
|
||||
|
@ -641,7 +650,6 @@ export abstract class MCAAStrategy extends XCAAStrategy {
|
|||
|
||||
this.antialiasCurvesWithProgram(renderer, curveProgram);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class ECAAStrategy extends XCAAStrategy {
|
||||
|
@ -652,14 +660,14 @@ export class ECAAStrategy extends XCAAStrategy {
|
|||
return 'none';
|
||||
}
|
||||
|
||||
attachMeshes(renderer: Renderer) {
|
||||
attachMeshes(renderer: Renderer): void {
|
||||
super.attachMeshes(renderer);
|
||||
|
||||
this.createLineVAO(renderer);
|
||||
this.createCurveVAO(renderer);
|
||||
}
|
||||
|
||||
antialias(renderer: Renderer) {
|
||||
antialias(renderer: Renderer): void {
|
||||
super.antialias(renderer);
|
||||
|
||||
// Antialias.
|
||||
|
@ -667,7 +675,7 @@ export class ECAAStrategy extends XCAAStrategy {
|
|||
this.antialiasCurves(renderer);
|
||||
}
|
||||
|
||||
protected setAAUniforms(renderer: Renderer, uniforms: UniformMap) {
|
||||
protected setAAUniforms(renderer: Renderer, uniforms: UniformMap): void {
|
||||
super.setAAUniforms(renderer, uniforms);
|
||||
|
||||
const renderContext = renderer.renderContext;
|
||||
|
@ -681,9 +689,9 @@ export class ECAAStrategy extends XCAAStrategy {
|
|||
return renderContext.shaderPrograms.xcaaMonoResolve;
|
||||
}
|
||||
|
||||
protected maskEdgesIfNecessary(renderer: Renderer) {}
|
||||
protected maskEdgesIfNecessary(renderer: Renderer): void {}
|
||||
|
||||
protected clearForAA(renderer: Renderer) {
|
||||
protected clearForAA(renderer: Renderer): void {
|
||||
const renderContext = renderer.renderContext;
|
||||
renderContext.gl.clearColor(0.0, 0.0, 0.0, 0.0);
|
||||
renderContext.gl.clearDepth(0.0);
|
||||
|
@ -691,25 +699,25 @@ export class ECAAStrategy extends XCAAStrategy {
|
|||
renderContext.gl.DEPTH_BUFFER_BIT);
|
||||
}
|
||||
|
||||
protected setAADepthState(renderer: Renderer) {
|
||||
protected setAADepthState(renderer: Renderer): void {
|
||||
const renderContext = renderer.renderContext;
|
||||
renderContext.gl.disable(renderContext.gl.DEPTH_TEST);
|
||||
}
|
||||
|
||||
protected clearForResolve(renderer: Renderer) {
|
||||
protected clearForResolve(renderer: Renderer): void {
|
||||
const renderContext = renderer.renderContext;
|
||||
renderContext.gl.clearColor(0.0, 0.0, 0.0, 0.0);
|
||||
renderContext.gl.clear(renderContext.gl.COLOR_BUFFER_BIT);
|
||||
}
|
||||
|
||||
private setBlendModeForAA(renderer: Renderer) {
|
||||
private setBlendModeForAA(renderer: Renderer): void {
|
||||
const renderContext = renderer.renderContext;
|
||||
renderContext.gl.blendEquation(renderContext.gl.FUNC_ADD);
|
||||
renderContext.gl.blendFunc(renderContext.gl.ONE, renderContext.gl.ONE);
|
||||
renderContext.gl.enable(renderContext.gl.BLEND);
|
||||
}
|
||||
|
||||
private createLineVAO(renderer: Renderer) {
|
||||
private createLineVAO(renderer: Renderer): void {
|
||||
const renderContext = renderer.renderContext;
|
||||
|
||||
const lineProgram = renderContext.shaderPrograms.ecaaLine;
|
||||
|
@ -786,7 +794,7 @@ export class ECAAStrategy extends XCAAStrategy {
|
|||
this.lineVAO = vao;
|
||||
}
|
||||
|
||||
private createCurveVAO(renderer: Renderer) {
|
||||
private createCurveVAO(renderer: Renderer): void {
|
||||
const renderContext = renderer.renderContext;
|
||||
|
||||
const curveProgram = renderContext.shaderPrograms.ecaaCurve;
|
||||
|
@ -864,7 +872,7 @@ export class ECAAStrategy extends XCAAStrategy {
|
|||
this.curveVAO = vao;
|
||||
}
|
||||
|
||||
private antialiasLines(renderer: Renderer) {
|
||||
private antialiasLines(renderer: Renderer): void {
|
||||
const renderContext = renderer.renderContext;
|
||||
|
||||
this.setAAState(renderer);
|
||||
|
@ -890,7 +898,7 @@ export class ECAAStrategy extends XCAAStrategy {
|
|||
renderContext.vertexArrayObjectExt.bindVertexArrayOES(null);
|
||||
}
|
||||
|
||||
private antialiasCurves(renderer: Renderer) {
|
||||
private antialiasCurves(renderer: Renderer): void {
|
||||
const renderContext = renderer.renderContext;
|
||||
|
||||
this.setAAState(renderer);
|
||||
|
@ -924,9 +932,9 @@ export class MCAAMonochromeStrategy extends MCAAStrategy {
|
|||
return renderContext.shaderPrograms.xcaaMonoResolve;
|
||||
}
|
||||
|
||||
protected maskEdgesIfNecessary(renderer: Renderer) {}
|
||||
protected maskEdgesIfNecessary(renderer: Renderer): void {}
|
||||
|
||||
protected clearForAA(renderer: Renderer) {
|
||||
protected clearForAA(renderer: Renderer): void {
|
||||
const renderContext = renderer.renderContext;
|
||||
renderContext.gl.clearColor(0.0, 0.0, 0.0, 0.0);
|
||||
renderContext.gl.clearDepth(0.0);
|
||||
|
@ -934,12 +942,12 @@ export class MCAAMonochromeStrategy extends MCAAStrategy {
|
|||
renderContext.gl.DEPTH_BUFFER_BIT);
|
||||
}
|
||||
|
||||
protected setAADepthState(renderer: Renderer) {
|
||||
protected setAADepthState(renderer: Renderer): void {
|
||||
const renderContext = renderer.renderContext;
|
||||
renderContext.gl.disable(renderContext.gl.DEPTH_TEST);
|
||||
}
|
||||
|
||||
protected clearForResolve(renderer: Renderer) {
|
||||
protected clearForResolve(renderer: Renderer): void {
|
||||
const renderContext = renderer.renderContext;
|
||||
renderContext.gl.clearColor(0.0, 0.0, 0.0, 0.0);
|
||||
renderContext.gl.clear(renderContext.gl.COLOR_BUFFER_BIT);
|
||||
|
@ -985,8 +993,16 @@ export class AdaptiveMonochromeXCAAStrategy implements AntialiasingStrategy {
|
|||
return this.mcaaStrategy.transform;
|
||||
}
|
||||
|
||||
prepareForDirectRendering(renderer: Renderer): void {
|
||||
this.getAppropriateStrategy(renderer).prepareForDirectRendering(renderer);
|
||||
prepareForRendering(renderer: Renderer): void {
|
||||
this.getAppropriateStrategy(renderer).prepareForRendering(renderer);
|
||||
}
|
||||
|
||||
prepareToDirectlyRenderObject(renderer: Renderer, objectIndex: number): void {
|
||||
this.getAppropriateStrategy(renderer).prepareToDirectlyRenderObject(renderer, objectIndex);
|
||||
}
|
||||
|
||||
finishDirectlyRenderingObject(renderer: Renderer, objectIndex: number): void {
|
||||
this.getAppropriateStrategy(renderer).finishDirectlyRenderingObject(renderer, objectIndex);
|
||||
}
|
||||
|
||||
antialias(renderer: Renderer): void {
|
||||
|
@ -1018,9 +1034,9 @@ export class MCAAMulticolorStrategy extends MCAAStrategy {
|
|||
return renderContext.shaderPrograms.xcaaMultiResolve;
|
||||
}
|
||||
|
||||
protected initDirectFramebufferIfNecessary(renderer: Renderer) {}
|
||||
protected initDirectFramebufferIfNecessary(renderer: Renderer): void {}
|
||||
|
||||
protected maskEdgesIfNecessary(renderer: Renderer) {
|
||||
protected maskEdgesIfNecessary(renderer: Renderer): void {
|
||||
const renderContext = renderer.renderContext;
|
||||
const gl = renderContext.gl;
|
||||
|
||||
|
@ -1053,14 +1069,14 @@ export class MCAAMulticolorStrategy extends MCAAStrategy {
|
|||
renderContext.vertexArrayObjectExt.bindVertexArrayOES(null);
|
||||
}
|
||||
|
||||
protected setCoverDepthState(renderer: Renderer) {
|
||||
protected setCoverDepthState(renderer: Renderer): void {
|
||||
const renderContext = renderer.renderContext;
|
||||
renderContext.gl.depthMask(false);
|
||||
renderContext.gl.depthFunc(renderContext.gl.EQUAL);
|
||||
renderContext.gl.enable(renderContext.gl.DEPTH_TEST);
|
||||
}
|
||||
|
||||
protected clearForAA(renderer: Renderer) {
|
||||
protected clearForAA(renderer: Renderer): void {
|
||||
const renderContext = renderer.renderContext;
|
||||
const gl = renderContext.gl;
|
||||
|
||||
|
@ -1068,7 +1084,7 @@ export class MCAAMulticolorStrategy extends MCAAStrategy {
|
|||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
}
|
||||
|
||||
protected setAADepthState(renderer: Renderer) {
|
||||
protected setAADepthState(renderer: Renderer): void {
|
||||
const renderContext = renderer.renderContext;
|
||||
const gl = renderContext.gl;
|
||||
|
||||
|
@ -1089,7 +1105,7 @@ export class MCAAMulticolorStrategy extends MCAAStrategy {
|
|||
gl.enable(gl.BLEND);
|
||||
}
|
||||
|
||||
protected clearForResolve(renderer: Renderer) {}
|
||||
protected clearForResolve(renderer: Renderer): void {}
|
||||
|
||||
protected setAdditionalStateForResolveIfNecessary(renderer: Renderer,
|
||||
resolveProgram: PathfinderShaderProgram,
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
// pathfinder/shaders/gles2/composite-alpha-mask.fs.glsl
|
||||
//
|
||||
// Copyright (c) 2017 The Pathfinder Project Developers.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
precision mediump float;
|
||||
|
||||
uniform sampler2D uSource;
|
||||
uniform sampler2D uMask;
|
||||
|
||||
varying vec2 vTexCoord;
|
||||
|
||||
void main() {
|
||||
vec4 color = texture2D(uSource, vTexCoord);
|
||||
float alpha = texture2D(uMask, vTexCoord).a;
|
||||
gl_FragColor = vec4(color.rgb, color.a * alpha);
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
// pathfinder/shaders/gles2/composite-alpha-mask.vs.glsl
|
||||
//
|
||||
// Copyright (c) 2017 The Pathfinder Project Developers.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
precision mediump float;
|
||||
|
||||
/// A 3D transform to apply to the scene.
|
||||
uniform mat4 uTransform;
|
||||
|
||||
/// The 2D vertex position.
|
||||
attribute vec2 aPosition;
|
||||
/// The texture coordinate.
|
||||
attribute vec2 aTexCoord;
|
||||
|
||||
varying vec2 vTexCoord;
|
||||
|
||||
void main() {
|
||||
gl_Position = uTransform * vec4(aPosition, 0.0, 1.0);
|
||||
vTexCoord = aTexCoord;
|
||||
}
|
Loading…
Reference in New Issue