2017-11-08 15:20:57 -05:00
|
|
|
// pathfinder/demo/client/src/ssaa-strategy.ts
|
2017-08-26 16:47:18 -04:00
|
|
|
//
|
|
|
|
// 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-12-11 21:56:26 -05:00
|
|
|
import {AntialiasingStrategy, DirectRenderingMode, SubpixelAAType, TileInfo} from './aa-strategy';
|
2017-11-03 17:29:31 -04:00
|
|
|
import {createFramebuffer, createFramebufferColorTexture} from './gl-utils';
|
|
|
|
import {createFramebufferDepthTexture, setTextureParameters} from './gl-utils';
|
2017-10-16 22:29:13 -04:00
|
|
|
import {Renderer} from './renderer';
|
2017-08-26 16:47:18 -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-08-29 15:29:16 -04:00
|
|
|
export default class SSAAStrategy extends AntialiasingStrategy {
|
2017-12-11 21:56:26 -05:00
|
|
|
get passCount(): number {
|
|
|
|
switch (this.level) {
|
|
|
|
case 16:
|
|
|
|
return 4;
|
|
|
|
case 8:
|
|
|
|
return 2;
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2017-09-28 17:34:48 -04:00
|
|
|
private level: number;
|
|
|
|
|
|
|
|
private destFramebufferSize: glmatrix.vec2;
|
|
|
|
private supersampledFramebufferSize: glmatrix.vec2;
|
2018-02-19 14:52:00 -05:00
|
|
|
private supersampledColorTexture!: WebGLTexture;
|
|
|
|
private supersampledDepthTexture!: WebGLTexture;
|
|
|
|
private supersampledFramebuffer!: WebGLFramebuffer;
|
2017-09-28 17:34:48 -04:00
|
|
|
|
2017-09-30 01:12:09 -04:00
|
|
|
constructor(level: number, subpixelAA: SubpixelAAType) {
|
2018-03-09 12:20:27 -05:00
|
|
|
super(subpixelAA);
|
2017-11-03 17:29:31 -04:00
|
|
|
|
2017-08-26 16:47:18 -04:00
|
|
|
this.level = level;
|
2017-09-06 19:32:11 -04:00
|
|
|
this.subpixelAA = subpixelAA;
|
2017-08-26 16:47:18 -04:00
|
|
|
this.destFramebufferSize = glmatrix.vec2.create();
|
|
|
|
this.supersampledFramebufferSize = glmatrix.vec2.create();
|
|
|
|
}
|
|
|
|
|
2017-11-08 15:20:57 -05:00
|
|
|
attachMeshes(renderer: Renderer): void {}
|
2017-09-19 16:57:56 -04:00
|
|
|
|
2017-11-08 15:20:57 -05:00
|
|
|
setFramebufferSize(renderer: Renderer): void {
|
2017-10-16 19:48:02 -04:00
|
|
|
const renderContext = renderer.renderContext;
|
2017-10-30 16:34:55 -04:00
|
|
|
const gl = renderContext.gl;
|
2017-10-16 19:48:02 -04:00
|
|
|
|
2017-10-16 16:36:22 -04:00
|
|
|
this.destFramebufferSize = glmatrix.vec2.clone(renderer.destAllocatedSize);
|
2017-08-26 16:47:18 -04:00
|
|
|
|
|
|
|
this.supersampledFramebufferSize = glmatrix.vec2.create();
|
|
|
|
glmatrix.vec2.mul(this.supersampledFramebufferSize,
|
2017-08-29 15:29:16 -04:00
|
|
|
this.destFramebufferSize,
|
2017-08-26 16:47:18 -04:00
|
|
|
this.supersampleScale);
|
|
|
|
|
2017-12-11 15:18:48 -05:00
|
|
|
this.supersampledColorTexture =
|
|
|
|
createFramebufferColorTexture(gl,
|
|
|
|
this.supersampledFramebufferSize,
|
|
|
|
renderContext.colorAlphaFormat,
|
|
|
|
gl.LINEAR);
|
2017-08-26 16:47:18 -04:00
|
|
|
|
|
|
|
this.supersampledDepthTexture =
|
2017-10-30 16:34:55 -04:00
|
|
|
createFramebufferDepthTexture(gl, this.supersampledFramebufferSize);
|
2017-08-26 16:47:18 -04:00
|
|
|
|
2017-10-30 16:34:55 -04:00
|
|
|
this.supersampledFramebuffer = createFramebuffer(gl,
|
2017-10-21 01:04:53 -04:00
|
|
|
this.supersampledColorTexture,
|
2017-08-26 16:47:18 -04:00
|
|
|
this.supersampledDepthTexture);
|
|
|
|
|
2017-10-30 16:34:55 -04:00
|
|
|
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
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
|
|
|
const scale = glmatrix.vec2.create();
|
|
|
|
glmatrix.vec2.div(scale, this.supersampledFramebufferSize, this.destFramebufferSize);
|
|
|
|
|
|
|
|
const transform = glmatrix.mat4.create();
|
|
|
|
glmatrix.mat4.fromScaling(transform, [scale[0], scale[1], 1.0]);
|
|
|
|
return transform;
|
|
|
|
}
|
|
|
|
|
2017-11-01 19:09:58 -04:00
|
|
|
prepareForRendering(renderer: Renderer): void {
|
2017-10-16 19:48:02 -04:00
|
|
|
const renderContext = renderer.renderContext;
|
2017-10-26 23:15:41 -04:00
|
|
|
const gl = renderContext.gl;
|
|
|
|
|
2017-08-26 16:47:18 -04:00
|
|
|
const framebufferSize = this.supersampledFramebufferSize;
|
2017-10-16 16:36:22 -04:00
|
|
|
const usedSize = this.usedSupersampledFramebufferSize(renderer);
|
2017-10-26 23:15:41 -04:00
|
|
|
gl.bindFramebuffer(gl.FRAMEBUFFER, this.supersampledFramebuffer);
|
|
|
|
gl.viewport(0, 0, framebufferSize[0], framebufferSize[1]);
|
|
|
|
gl.scissor(0, 0, usedSize[0], usedSize[1]);
|
|
|
|
gl.enable(gl.SCISSOR_TEST);
|
2017-11-01 19:09:58 -04:00
|
|
|
|
|
|
|
const clearColor = renderer.backgroundColor;
|
|
|
|
gl.clearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
|
2017-11-15 17:36:59 -05:00
|
|
|
gl.clearDepth(0.0);
|
|
|
|
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
2017-11-01 19:09:58 -04:00
|
|
|
}
|
|
|
|
|
2017-11-08 15:20:57 -05:00
|
|
|
prepareForDirectRendering(renderer: Renderer): void {}
|
|
|
|
|
|
|
|
prepareToRenderObject(renderer: Renderer, objectIndex: number): void {
|
2017-11-03 17:29:31 -04:00
|
|
|
const renderContext = renderer.renderContext;
|
|
|
|
const gl = renderContext.gl;
|
|
|
|
|
2017-12-22 19:30:24 -05:00
|
|
|
gl.bindFramebuffer(gl.FRAMEBUFFER, this.supersampledFramebuffer);
|
2017-11-03 17:29:31 -04:00
|
|
|
gl.viewport(0,
|
|
|
|
0,
|
|
|
|
this.supersampledFramebufferSize[0],
|
|
|
|
this.supersampledFramebufferSize[1]);
|
|
|
|
gl.disable(gl.SCISSOR_TEST);
|
2017-11-01 19:09:58 -04:00
|
|
|
}
|
|
|
|
|
2017-12-22 19:30:24 -05:00
|
|
|
finishDirectlyRenderingObject(renderer: Renderer, objectIndex: number): void {}
|
2017-08-26 16:47:18 -04:00
|
|
|
|
2017-11-08 15:20:57 -05:00
|
|
|
antialiasObject(renderer: Renderer): void {}
|
|
|
|
|
2017-12-15 16:41:27 -05:00
|
|
|
finishAntialiasingObject(renderer: Renderer, objectIndex: number): void {}
|
|
|
|
|
2017-11-08 15:20:57 -05:00
|
|
|
resolveAAForObject(renderer: Renderer): void {}
|
2017-09-26 16:34:40 -04:00
|
|
|
|
2017-12-11 21:56:26 -05:00
|
|
|
resolve(pass: number, renderer: Renderer): void {
|
2017-10-16 19:48:02 -04:00
|
|
|
const renderContext = renderer.renderContext;
|
2017-10-30 16:34:55 -04:00
|
|
|
const gl = 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);
|
2017-08-26 16:47:18 -04:00
|
|
|
|
|
|
|
// Set up the blit program VAO.
|
2017-09-06 19:32:11 -04:00
|
|
|
let resolveProgram;
|
2017-09-30 01:12:09 -04:00
|
|
|
if (this.subpixelAA !== 'none')
|
2017-10-16 19:48:02 -04:00
|
|
|
resolveProgram = renderContext.shaderPrograms.ssaaSubpixelResolve;
|
2017-09-06 19:32:11 -04:00
|
|
|
else
|
2017-11-07 20:24:19 -05:00
|
|
|
resolveProgram = renderContext.shaderPrograms.blitLinear;
|
2017-10-30 16:34:55 -04:00
|
|
|
gl.useProgram(resolveProgram.program);
|
2017-10-16 19:48:02 -04:00
|
|
|
renderContext.initQuadVAO(resolveProgram.attributes);
|
2017-08-26 16:47:18 -04:00
|
|
|
|
|
|
|
// Resolve framebuffer.
|
2017-10-30 16:34:55 -04:00
|
|
|
gl.activeTexture(gl.TEXTURE0);
|
|
|
|
gl.bindTexture(gl.TEXTURE_2D, this.supersampledColorTexture);
|
|
|
|
gl.uniform1i(resolveProgram.uniforms.uSource, 0);
|
|
|
|
gl.uniform2i(resolveProgram.uniforms.uSourceDimensions,
|
|
|
|
this.supersampledFramebufferSize[0],
|
|
|
|
this.supersampledFramebufferSize[1]);
|
2017-12-11 21:56:26 -05:00
|
|
|
const tileInfo = this.tileInfoForPass(pass);
|
|
|
|
renderer.setTransformAndTexScaleUniformsForDest(resolveProgram.uniforms, tileInfo);
|
2017-10-30 16:34:55 -04:00
|
|
|
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, renderContext.quadElementsBuffer);
|
|
|
|
gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_BYTE, 0);
|
2017-08-26 16:47:18 -04:00
|
|
|
}
|
|
|
|
|
2017-12-11 21:56:26 -05:00
|
|
|
worldTransformForPass(renderer: Renderer, pass: number): glmatrix.mat4 {
|
|
|
|
const tileInfo = this.tileInfoForPass(pass);
|
|
|
|
const usedSize = renderer.destUsedSize;
|
|
|
|
const transform = glmatrix.mat4.create();
|
2017-12-12 10:46:38 -05:00
|
|
|
glmatrix.mat4.fromTranslation(transform, [-1.0, -1.0, 0.0]);
|
2017-12-11 21:56:26 -05:00
|
|
|
glmatrix.mat4.scale(transform, transform, [tileInfo.size[0], tileInfo.size[1], 1.0]);
|
|
|
|
glmatrix.mat4.translate(transform, transform, [
|
|
|
|
-tileInfo.position[0] / tileInfo.size[0] * 2.0,
|
|
|
|
-tileInfo.position[1] / tileInfo.size[1] * 2.0,
|
|
|
|
0.0,
|
|
|
|
]);
|
2017-12-12 10:46:38 -05:00
|
|
|
glmatrix.mat4.translate(transform, transform, [1.0, 1.0, 0.0]);
|
2017-12-11 21:56:26 -05:00
|
|
|
return transform;
|
|
|
|
}
|
|
|
|
|
|
|
|
private tileInfoForPass(pass: number): TileInfo {
|
|
|
|
const tileSize = this.tileSize;
|
|
|
|
return {
|
|
|
|
position: glmatrix.vec2.clone([pass % tileSize[0], Math.floor(pass / tileSize[0])]),
|
|
|
|
size: tileSize,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2017-10-21 01:04:53 -04:00
|
|
|
get directRenderingMode(): DirectRenderingMode {
|
|
|
|
return 'color';
|
2017-08-26 16:47:18 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
private get supersampleScale(): glmatrix.vec2 {
|
2017-09-30 01:12:09 -04:00
|
|
|
return glmatrix.vec2.clone([this.subpixelAA !== 'none' ? 3 : 2, this.level === 2 ? 1 : 2]);
|
2017-08-26 16:47:18 -04:00
|
|
|
}
|
|
|
|
|
2017-12-11 21:56:26 -05:00
|
|
|
private get tileSize(): glmatrix.vec2 {
|
|
|
|
switch (this.level) {
|
|
|
|
case 16:
|
|
|
|
return glmatrix.vec2.clone([2.0, 2.0]);
|
|
|
|
case 8:
|
|
|
|
return glmatrix.vec2.clone([2.0, 1.0]);
|
|
|
|
}
|
|
|
|
return glmatrix.vec2.clone([1.0, 1.0]);
|
|
|
|
}
|
|
|
|
|
2017-10-16 16:36:22 -04:00
|
|
|
private usedSupersampledFramebufferSize(renderer: Renderer): glmatrix.vec2 {
|
2017-08-26 16:47:18 -04:00
|
|
|
const result = glmatrix.vec2.create();
|
2017-10-16 16:36:22 -04:00
|
|
|
glmatrix.vec2.mul(result, renderer.destUsedSize, this.supersampleScale);
|
2017-08-26 16:47:18 -04:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|