Add basic tiled rendering
This commit is contained in:
parent
854e5a55a1
commit
edffd22c2e
7 changed files with 353 additions and 170 deletions
|
|
@ -1,9 +1,8 @@
|
|||
import { IProgram } from '../program/i-program';
|
||||
import { FrameBuffer } from './frame-buffer';
|
||||
|
||||
export class DefaultFrameBuffer extends FrameBuffer {
|
||||
constructor(gl: WebGL2RenderingContext, programs: Array<IProgram>) {
|
||||
super(gl, programs);
|
||||
constructor(gl: WebGL2RenderingContext) {
|
||||
super(gl);
|
||||
this.frameBuffer = null;
|
||||
|
||||
this.setSize();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import { vec2 } from 'gl-matrix';
|
||||
import { IProgram } from '../program/i-program';
|
||||
|
||||
export abstract class FrameBuffer {
|
||||
public renderScale = 1;
|
||||
|
|
@ -8,12 +7,9 @@ export abstract class FrameBuffer {
|
|||
protected size: vec2;
|
||||
protected frameBuffer: WebGLFramebuffer;
|
||||
|
||||
constructor(
|
||||
protected gl: WebGL2RenderingContext,
|
||||
protected programs: Array<IProgram>
|
||||
) {}
|
||||
constructor(protected gl: WebGL2RenderingContext) {}
|
||||
|
||||
public render(uniforms: any, colorInput?: WebGLTexture) {
|
||||
public bindAndClear(colorInput?: WebGLTexture) {
|
||||
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, this.frameBuffer);
|
||||
|
||||
if (colorInput !== null) {
|
||||
|
|
@ -23,11 +19,6 @@ export abstract class FrameBuffer {
|
|||
this.gl.viewport(0, 0, this.size.x, this.size.y);
|
||||
this.gl.clearColor(0, 0, 0, 0);
|
||||
this.gl.clear(this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT);
|
||||
|
||||
this.programs.forEach((p) => {
|
||||
p.bindAndSetUniforms(uniforms);
|
||||
p.draw();
|
||||
});
|
||||
}
|
||||
|
||||
public setSize() {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,10 @@
|
|||
import { IProgram } from '../program/i-program';
|
||||
import { FrameBuffer } from './frame-buffer';
|
||||
|
||||
export class IntermediateFrameBuffer extends FrameBuffer {
|
||||
private frameTexture: WebGLTexture;
|
||||
|
||||
constructor(gl: WebGL2RenderingContext, programs: Array<IProgram>) {
|
||||
super(gl, programs);
|
||||
constructor(gl: WebGL2RenderingContext) {
|
||||
super(gl);
|
||||
|
||||
this.frameTexture = this.gl.createTexture();
|
||||
this.configureTexture();
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ export class FragmentShaderOnlyProgram extends Program {
|
|||
substitutions: { [name: string]: string }
|
||||
) {
|
||||
super(gl, vertexShaderSource, fragmentShaderSource, substitutions);
|
||||
this.prepareScreenQuad('a_position');
|
||||
this.prepareScreenQuad('vertexPosition');
|
||||
}
|
||||
|
||||
public bind() {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
import { vec2 } from 'gl-matrix';
|
||||
|
||||
export interface IProgram {
|
||||
bindAndSetUniforms(values: { [name: string]: any }): void;
|
||||
setDrawingRectangle(topLeft: vec2, size: vec2): void;
|
||||
draw(): void;
|
||||
delete(): void;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { mat2d, vec2 } from 'gl-matrix';
|
||||
import { createShader } from '../helper/create-shader';
|
||||
import { loadUniform } from '../helper/load-uniform';
|
||||
import { IProgram } from './i-program';
|
||||
|
|
@ -5,6 +6,8 @@ import { IProgram } from './i-program';
|
|||
export abstract class Program implements IProgram {
|
||||
protected program: WebGLProgram;
|
||||
private shaders: Array<WebGLShader> = [];
|
||||
private modelTransform = mat2d.identity(mat2d.create());
|
||||
private readonly ndcToUv: mat2d;
|
||||
|
||||
private uniforms: Array<{
|
||||
name: Array<string>;
|
||||
|
|
@ -20,15 +23,22 @@ export abstract class Program implements IProgram {
|
|||
) {
|
||||
this.createProgram(vertexShaderSource, fragmentShaderSource, substitutions);
|
||||
this.queryUniforms();
|
||||
|
||||
this.ndcToUv = mat2d.fromScaling(mat2d.create(), vec2.fromValues(0.5, 0.5));
|
||||
mat2d.translate(this.ndcToUv, this.ndcToUv, vec2.fromValues(1, 1));
|
||||
}
|
||||
|
||||
public bindAndSetUniforms(values: { [name: string]: any }) {
|
||||
this.bind();
|
||||
this.setUniforms(values);
|
||||
this.setUniforms({ modelTransform: this.modelTransform, ...values });
|
||||
}
|
||||
|
||||
public bind() {
|
||||
this.gl.useProgram(this.program);
|
||||
public setDrawingRectangle(topLeft: vec2, size: vec2) {
|
||||
mat2d.invert(this.modelTransform, this.ndcToUv);
|
||||
|
||||
mat2d.translate(this.modelTransform, this.modelTransform, topLeft);
|
||||
mat2d.scale(this.modelTransform, this.modelTransform, size);
|
||||
mat2d.multiply(this.modelTransform, this.modelTransform, this.ndcToUv);
|
||||
}
|
||||
|
||||
public setUniforms(values: { [name: string]: any }) {
|
||||
|
|
@ -51,6 +61,10 @@ export abstract class Program implements IProgram {
|
|||
|
||||
public abstract draw(): void;
|
||||
|
||||
protected bind() {
|
||||
this.gl.useProgram(this.program);
|
||||
}
|
||||
|
||||
private queryUniforms() {
|
||||
const uniformCount = this.gl.getProgramParameter(
|
||||
this.program,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { InfoText } from '../../../objects/types/info-text';
|
||||
import { vec2 } from 'gl-matrix';
|
||||
import { FragmentShaderOnlyProgram } from './fragment-shader-only-program';
|
||||
import { IProgram } from './i-program';
|
||||
|
||||
|
|
@ -9,6 +9,9 @@ export class UniformArrayAutoScalingProgram implements IProgram {
|
|||
}> = [];
|
||||
private current: FragmentShaderOnlyProgram;
|
||||
|
||||
private drawingRectangleTopLeft = vec2.fromValues(0, 0);
|
||||
private drawingRectangleSize = vec2.fromValues(1, 1);
|
||||
|
||||
constructor(
|
||||
private gl: WebGL2RenderingContext,
|
||||
private vertexShaderSource: string,
|
||||
|
|
@ -17,6 +20,7 @@ export class UniformArrayAutoScalingProgram implements IProgram {
|
|||
private options: {
|
||||
getValueFromUniforms: (values: { [name: string]: any }) => number;
|
||||
uniformArraySizeName: string;
|
||||
enablingMacro: string;
|
||||
startingValue: number;
|
||||
steps: number;
|
||||
maximumValue: number;
|
||||
|
|
@ -31,12 +35,10 @@ export class UniformArrayAutoScalingProgram implements IProgram {
|
|||
}
|
||||
}
|
||||
|
||||
bindAndSetUniforms(values: { [name: string]: any }): void {
|
||||
public bindAndSetUniforms(values: { [name: string]: any }): void {
|
||||
let value = this.options.getValueFromUniforms(values);
|
||||
value = Math.min(this.options.maximumValue, value);
|
||||
|
||||
InfoText.modifyRecord(this.options.uniformArraySizeName, value.toString());
|
||||
|
||||
const closest = this.programs.find(
|
||||
(p) => value < p.value && value + this.options.steps >= p.value
|
||||
);
|
||||
|
|
@ -46,14 +48,23 @@ export class UniformArrayAutoScalingProgram implements IProgram {
|
|||
this.current = this.createProgram(value + this.options.steps);
|
||||
}
|
||||
|
||||
this.current.setDrawingRectangle(
|
||||
this.drawingRectangleTopLeft,
|
||||
this.drawingRectangleSize
|
||||
);
|
||||
this.current.bindAndSetUniforms(values);
|
||||
}
|
||||
|
||||
draw(): void {
|
||||
public setDrawingRectangle(topLeft: vec2, size: vec2) {
|
||||
this.drawingRectangleTopLeft = topLeft;
|
||||
this.drawingRectangleSize = size;
|
||||
}
|
||||
|
||||
public draw(): void {
|
||||
this.current.draw();
|
||||
}
|
||||
|
||||
delete(): void {
|
||||
public delete(): void {
|
||||
this.programs.forEach((p) => p.program.delete());
|
||||
}
|
||||
|
||||
|
|
@ -64,6 +75,7 @@ export class UniformArrayAutoScalingProgram implements IProgram {
|
|||
this.fragmentShaderSource,
|
||||
{
|
||||
[this.options.uniformArraySizeName]: Math.floor(arraySize).toString(),
|
||||
[this.options.enablingMacro]: arraySize > 0 ? '1' : '0',
|
||||
...this.substitutions,
|
||||
}
|
||||
);
|
||||
|
|
|
|||
Loading…
Reference in a new issue