pathfinder/demo/client/src/ssaa-strategy.ts

214 lines
8.7 KiB
TypeScript
Raw Normal View History

2017-11-08 15:20:57 -05:00
// pathfinder/demo/client/src/ssaa-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';
import {AntialiasingStrategy, DirectRenderingMode, SubpixelAAType} from './aa-strategy';
import {createFramebuffer, createFramebufferColorTexture} from './gl-utils';
import {createFramebufferDepthTexture, setTextureParameters} from './gl-utils';
import {Renderer} from './renderer';
import {unwrapNull} from './utils';
import {DemoView} from './view';
2017-08-29 15:29:16 -04:00
export default class SSAAStrategy extends AntialiasingStrategy {
2017-09-28 17:34:48 -04:00
private level: number;
private subpixelAA: SubpixelAAType;
2017-09-28 17:34:48 -04:00
private destFramebufferSize: glmatrix.vec2;
private supersampledFramebufferSize: glmatrix.vec2;
private supersampledColorTexture: WebGLTexture;
private supersampledDepthTexture: WebGLTexture;
private supersampledFramebuffer: WebGLFramebuffer;
private renderTargetColorTextures: WebGLTexture[];
private renderTargetDepthTextures: WebGLTexture[];
private renderTargetFramebuffers: WebGLFramebuffer[];
2017-09-28 17:34:48 -04:00
constructor(level: number, subpixelAA: SubpixelAAType) {
2017-08-29 15:29:16 -04:00
super();
this.level = level;
this.subpixelAA = subpixelAA;
this.destFramebufferSize = glmatrix.vec2.create();
this.supersampledFramebufferSize = glmatrix.vec2.create();
this.renderTargetColorTextures = [];
this.renderTargetDepthTextures = [];
this.renderTargetFramebuffers = [];
}
2017-11-08 15:20:57 -05:00
attachMeshes(renderer: Renderer): void {}
2017-11-08 15:20:57 -05:00
setFramebufferSize(renderer: Renderer): void {
const renderContext = renderer.renderContext;
const gl = renderContext.gl;
this.destFramebufferSize = glmatrix.vec2.clone(renderer.destAllocatedSize);
this.supersampledFramebufferSize = glmatrix.vec2.create();
glmatrix.vec2.mul(this.supersampledFramebufferSize,
2017-08-29 15:29:16 -04:00
this.destFramebufferSize,
this.supersampleScale);
this.supersampledColorTexture = unwrapNull(gl.createTexture());
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, this.supersampledColorTexture);
gl.texImage2D(gl.TEXTURE_2D,
0,
renderContext.colorAlphaFormat,
this.supersampledFramebufferSize[0],
this.supersampledFramebufferSize[1],
0,
renderContext.colorAlphaFormat,
gl.UNSIGNED_BYTE,
null);
setTextureParameters(gl, gl.LINEAR);
this.supersampledDepthTexture =
createFramebufferDepthTexture(gl, this.supersampledFramebufferSize);
this.supersampledFramebuffer = createFramebuffer(gl,
this.supersampledColorTexture,
this.supersampledDepthTexture);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
}
2017-08-29 15:29:16 -04:00
get transform(): glmatrix.mat4 {
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;
}
prepareForRendering(renderer: Renderer): void {
const renderContext = renderer.renderContext;
const gl = renderContext.gl;
const framebufferSize = this.supersampledFramebufferSize;
const usedSize = this.usedSupersampledFramebufferSize(renderer);
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);
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-08 15:20:57 -05:00
prepareForDirectRendering(renderer: Renderer): void {}
prepareToRenderObject(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.supersampledFramebufferSize,
renderContext.colorAlphaFormat);
}
if (this.renderTargetDepthTextures[objectIndex] == null) {
this.renderTargetDepthTextures[objectIndex] =
createFramebufferDepthTexture(gl, this.supersampledFramebufferSize);
}
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, this.supersampledFramebuffer);
}
gl.viewport(0,
0,
this.supersampledFramebufferSize[0],
this.supersampledFramebufferSize[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, this.supersampledFramebuffer);
gl.viewport(0,
0,
this.supersampledFramebufferSize[0],
this.supersampledFramebufferSize[1]);
gl.disable(gl.DEPTH_TEST);
gl.disable(gl.BLEND);
compositingOperation.composite(renderer, objectIndex, this.renderTargetColorTextures);
}
2017-11-08 15:20:57 -05:00
antialiasObject(renderer: Renderer): void {}
resolveAAForObject(renderer: Renderer): void {}
2017-11-08 15:20:57 -05:00
resolve(renderer: Renderer): void {
const renderContext = renderer.renderContext;
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);
// Set up the blit program VAO.
let resolveProgram;
if (this.subpixelAA !== 'none')
resolveProgram = renderContext.shaderPrograms.ssaaSubpixelResolve;
else
resolveProgram = renderContext.shaderPrograms.blitLinear;
gl.useProgram(resolveProgram.program);
renderContext.initQuadVAO(resolveProgram.attributes);
// Resolve framebuffer.
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]);
renderer.setTransformAndTexScaleUniformsForDest(resolveProgram.uniforms);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, renderContext.quadElementsBuffer);
gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_BYTE, 0);
}
get directRenderingMode(): DirectRenderingMode {
return 'color';
}
private get supersampleScale(): glmatrix.vec2 {
return glmatrix.vec2.clone([this.subpixelAA !== 'none' ? 3 : 2, this.level === 2 ? 1 : 2]);
}
private usedSupersampledFramebufferSize(renderer: Renderer): glmatrix.vec2 {
const result = glmatrix.vec2.create();
glmatrix.vec2.mul(result, renderer.destUsedSize, this.supersampleScale);
return result;
}
}