2017-08-26 16:47:18 -04:00
|
|
|
// pathfinder/client/src/aa-strategy.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 * as glmatrix from 'gl-matrix';
|
|
|
|
|
2017-11-01 19:09:58 -04:00
|
|
|
import {createFramebuffer, createFramebufferColorTexture} from './gl-utils';
|
|
|
|
import {createFramebufferDepthTexture} from './gl-utils';
|
2017-10-16 22:29:13 -04:00
|
|
|
import {Renderer} from './renderer';
|
2017-11-01 19:09:58 -04:00
|
|
|
import {unwrapNull} from './utils';
|
2017-10-16 22:29:13 -04:00
|
|
|
import {DemoView} from './view';
|
2017-08-26 16:47:18 -04:00
|
|
|
|
2017-10-09 17:14:24 -04:00
|
|
|
export type AntialiasingStrategyName = 'none' | 'ssaa' | 'xcaa';
|
2017-08-28 20:18:44 -04:00
|
|
|
|
2017-10-31 15:41:38 -04:00
|
|
|
export type DirectRenderingMode = 'none' | 'color' | 'color-depth';
|
2017-10-21 01:04:53 -04:00
|
|
|
|
2017-10-09 17:14:24 -04:00
|
|
|
export type SubpixelAAType = 'none' | 'medium';
|
|
|
|
|
2017-11-07 20:24:19 -05:00
|
|
|
export type GammaCorrectionMode = 'off' | 'on';
|
|
|
|
|
2017-10-09 17:14:24 -04:00
|
|
|
export type StemDarkeningMode = 'none' | 'dark';
|
2017-09-30 01:12:09 -04:00
|
|
|
|
2017-08-29 15:29:16 -04:00
|
|
|
export abstract class AntialiasingStrategy {
|
2017-10-21 01:04:53 -04:00
|
|
|
// The type of direct rendering that should occur, if any.
|
|
|
|
abstract readonly directRenderingMode: DirectRenderingMode;
|
2017-09-28 17:34:48 -04:00
|
|
|
|
2017-08-26 16:47:18 -04:00
|
|
|
// Prepares any OpenGL data. This is only called on startup and canvas resize.
|
2017-10-16 16:36:22 -04:00
|
|
|
init(renderer: Renderer): void {
|
|
|
|
this.setFramebufferSize(renderer);
|
2017-08-29 15:29:16 -04:00
|
|
|
}
|
2017-08-26 16:47:18 -04:00
|
|
|
|
|
|
|
// Uploads any mesh data. This is called whenever a new set of meshes is supplied.
|
2017-10-16 16:36:22 -04:00
|
|
|
abstract attachMeshes(renderer: Renderer): void;
|
2017-08-26 16:47:18 -04:00
|
|
|
|
|
|
|
// This is called whenever the framebuffer has changed.
|
2017-10-16 16:36:22 -04:00
|
|
|
abstract setFramebufferSize(renderer: Renderer): void;
|
2017-08-26 16:47:18 -04:00
|
|
|
|
|
|
|
// Returns the transformation matrix that should be applied when directly rendering.
|
2017-08-29 15:29:16 -04:00
|
|
|
abstract get transform(): glmatrix.mat4;
|
2017-08-26 16:47:18 -04:00
|
|
|
|
2017-11-08 15:20:57 -05:00
|
|
|
// Called before rendering.
|
2017-08-26 16:47:18 -04:00
|
|
|
//
|
2017-11-08 15:20:57 -05:00
|
|
|
// Typically, this redirects rendering to a framebuffer of some sort.
|
2017-11-01 19:09:58 -04:00
|
|
|
abstract prepareForRendering(renderer: Renderer): void;
|
|
|
|
|
2017-11-08 15:20:57 -05:00
|
|
|
// Called before directly rendering.
|
|
|
|
//
|
|
|
|
// Typically, this redirects rendering to a framebuffer of some sort.
|
|
|
|
abstract prepareForDirectRendering(renderer: Renderer): void;
|
|
|
|
|
2017-11-01 19:09:58 -04:00
|
|
|
// Called before directly rendering a single object.
|
2017-11-08 15:20:57 -05:00
|
|
|
abstract prepareToRenderObject(renderer: Renderer, objectIndex: number): void;
|
2017-11-01 19:09:58 -04:00
|
|
|
|
|
|
|
abstract finishDirectlyRenderingObject(renderer: Renderer, objectIndex: number): void;
|
2017-08-26 16:47:18 -04:00
|
|
|
|
|
|
|
// Called after direct rendering.
|
|
|
|
//
|
2017-09-26 16:34:40 -04:00
|
|
|
// This usually performs the actual antialiasing.
|
2017-11-08 15:20:57 -05:00
|
|
|
abstract antialiasObject(renderer: Renderer, objectIndex: number): void;
|
|
|
|
|
|
|
|
// Called after antialiasing each object.
|
|
|
|
abstract resolveAAForObject(renderer: Renderer, objectIndex: number): void;
|
2017-09-26 16:34:40 -04:00
|
|
|
|
|
|
|
// Called after antialiasing.
|
|
|
|
//
|
|
|
|
// This usually blits to the real framebuffer.
|
2017-10-16 16:36:22 -04:00
|
|
|
abstract resolve(renderer: Renderer): void;
|
2017-08-26 16:47:18 -04:00
|
|
|
}
|
|
|
|
|
2017-08-29 15:29:16 -04:00
|
|
|
export class NoAAStrategy extends AntialiasingStrategy {
|
2017-09-28 17:34:48 -04:00
|
|
|
framebufferSize: glmatrix.vec2;
|
|
|
|
|
2017-11-01 19:09:58 -04:00
|
|
|
private renderTargetColorTextures: WebGLTexture[];
|
|
|
|
private renderTargetDepthTextures: WebGLTexture[];
|
|
|
|
private renderTargetFramebuffers: WebGLFramebuffer[];
|
|
|
|
|
2017-09-30 01:12:09 -04:00
|
|
|
constructor(level: number, subpixelAA: SubpixelAAType) {
|
2017-08-29 15:29:16 -04:00
|
|
|
super();
|
2017-08-26 16:47:18 -04:00
|
|
|
this.framebufferSize = glmatrix.vec2.create();
|
2017-11-01 19:09:58 -04:00
|
|
|
this.renderTargetColorTextures = [];
|
|
|
|
this.renderTargetDepthTextures = [];
|
|
|
|
this.renderTargetFramebuffers = [];
|
2017-08-26 16:47:18 -04:00
|
|
|
}
|
|
|
|
|
2017-10-16 16:36:22 -04:00
|
|
|
attachMeshes(renderer: Renderer) {}
|
2017-08-26 16:47:18 -04:00
|
|
|
|
2017-10-16 16:36:22 -04:00
|
|
|
setFramebufferSize(renderer: Renderer) {
|
|
|
|
this.framebufferSize = renderer.destAllocatedSize;
|
2017-08-26 16:47:18 -04:00
|
|
|
}
|
|
|
|
|
2017-08-29 15:29:16 -04:00
|
|
|
get transform(): glmatrix.mat4 {
|
2017-08-26 16:47:18 -04:00
|
|
|
return glmatrix.mat4.create();
|
|
|
|
}
|
|
|
|
|
2017-11-01 19:09:58 -04:00
|
|
|
prepareForRendering(renderer: Renderer): void {
|
|
|
|
const renderContext = renderer.renderContext;
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2017-11-08 15:20:57 -05:00
|
|
|
prepareForDirectRendering(renderer: Renderer): void {}
|
|
|
|
|
|
|
|
prepareToRenderObject(renderer: Renderer, objectIndex: number): void {
|
2017-10-16 19:48:02 -04:00
|
|
|
const renderContext = renderer.renderContext;
|
2017-11-01 19:09:58 -04:00
|
|
|
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);
|
2017-08-26 16:47:18 -04:00
|
|
|
}
|
|
|
|
|
2017-11-08 15:20:57 -05:00
|
|
|
antialiasObject(renderer: Renderer, objectIndex: number): void {}
|
|
|
|
|
|
|
|
resolveAAForObject(renderer: Renderer): void {}
|
2017-09-26 16:34:40 -04:00
|
|
|
|
2017-11-08 15:20:57 -05:00
|
|
|
resolve(renderer: Renderer): void {}
|
2017-08-26 16:47:18 -04:00
|
|
|
|
2017-10-21 01:04:53 -04:00
|
|
|
get directRenderingMode(): DirectRenderingMode {
|
|
|
|
return 'color';
|
2017-08-26 16:47:18 -04:00
|
|
|
}
|
|
|
|
}
|