Improve API

This commit is contained in:
schmelczerandras 2020-09-16 11:31:26 +02:00
parent b2c2cfcb41
commit 78444d8cc6
24 changed files with 193 additions and 325 deletions

View file

@ -1,21 +1,19 @@
import { waitWhileFalse } from '../../../helper/wait-while-false';
import { tryEnableExtension } from '../helper/enable-extension';
import { checkProgram } from './check-program';
import { createShader } from './create-shader';
export const createProgram = async (
export const createProgram = (
gl: WebGL2RenderingContext,
vertexShaderSource: string,
fragmentShaderSource: string,
substitutions: { [name: string]: string }
): Promise<WebGLProgram> => {
): WebGLProgram => {
const program = gl.createProgram();
if (!program) {
throw new Error('Could not create program');
}
const extension = tryEnableExtension(gl, 'KHR_parallel_shader_compile');
// const extension = tryEnableExtension(gl, 'KHR_parallel_shader_compile');
const vertexShader = createShader(
gl,
@ -31,16 +29,17 @@ export const createProgram = async (
fragmentShaderSource,
substitutions
);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
if (extension) {
/*if (extension) {
const checkCompileStatus = () =>
gl.getProgramParameter(program, extension.COMPLETION_STATUS_KHR);
await waitWhileFalse(checkCompileStatus);
}
}*/
checkProgram(gl, program);

View file

@ -9,10 +9,6 @@ export class FragmentShaderOnlyProgram extends Program {
substitutions: { [name: string]: string }
) {
super(gl, sources, substitutions);
}
public async initialize(): Promise<void> {
await super.initialize();
this.prepareScreenQuad('vertexPosition');
}

View file

@ -1,7 +1,6 @@
import { vec2 } from 'gl-matrix';
export interface IProgram {
initialize(): Promise<void>;
setDrawingRectangleUV(bottomLeft: vec2, size: vec2): void;
bindAndSetUniforms(values: { [name: string]: any }): void;
draw(): void;

View file

@ -7,7 +7,6 @@ import { IProgram } from './i-program';
export default abstract class Program implements IProgram {
protected program?: WebGLProgram;
private programPromise: Promise<WebGLProgram>;
private modelTransform = mat2d.identity(mat2d.create());
private readonly ndcToUv = mat2d.fromValues(0.5, 0, 0, 0.5, 0.5, 0.5);
private uniforms: Array<{
@ -23,16 +22,13 @@ export default abstract class Program implements IProgram {
) {
substitutions = { ...settings.shaderMacros, ...substitutions };
this.programPromise = createProgram(
this.program = createProgram(
this.gl,
vertexShaderSource,
fragmentShaderSource,
substitutions
);
}
public async initialize(): Promise<void> {
this.program = await this.programPromise;
this.queryUniforms();
}

View file

@ -20,18 +20,13 @@ export class UniformArrayAutoScalingProgram implements IProgram {
shaderSources: [string, string],
private descriptors: Array<DrawableDescriptor>
) {
const names = descriptors.map((o) => o.countMacroName);
for (const combination of getCombinations(
descriptors.map((o) => o.shaderCombinationSteps)
)) {
this.createProgram(names, combination, shaderSources);
this.createProgram(descriptors, combination, shaderSources);
}
}
public async initialize(): Promise<void> {
await Promise.all(this.programs.map((p) => p.program.initialize()));
}
public bindAndSetUniforms(uniforms: { [name: string]: any }): void {
const values = this.descriptors.map((d) =>
uniforms[d.uniformName] ? uniforms[d.uniformName].length : 0
@ -45,7 +40,7 @@ export class UniformArrayAutoScalingProgram implements IProgram {
this.descriptors.map((d, i) => {
const difference = closest.values[i] - values[i];
for (let i = 0; i < difference; i++) {
d.empty.serializeToUniforms(uniforms, 0, mat2d.create());
d.empty.serializeToUniforms(uniforms, mat2d.create(), 0);
}
});
}
@ -75,12 +70,15 @@ export class UniformArrayAutoScalingProgram implements IProgram {
}
private createProgram(
names: Array<string>,
descriptors: Array<DrawableDescriptor>,
combination: Array<number>,
shaderSources: [string, string]
): FragmentShaderOnlyProgram {
const substitutions = {};
names.forEach((v, i) => (substitutions[v] = combination[i].toString()));
const substitutions = {
macroDefinitions: this.getMacroDefinitions(combination, descriptors),
declarations: this.getDeclarations(combination, descriptors),
functionCalls: this.getFunctionCalls(combination, descriptors),
};
const program = new FragmentShaderOnlyProgram(this.gl, shaderSources, substitutions);
@ -91,4 +89,43 @@ export class UniformArrayAutoScalingProgram implements IProgram {
return program;
}
private getMacroDefinitions(
combination: Array<number>,
descriptors: Array<DrawableDescriptor>
): string {
return combination
.map((v, i) => `#define ${descriptors[i].uniformCountMacroName} ${v}`)
.join('\n');
}
private getDeclarations(
combination: Array<number>,
descriptors: Array<DrawableDescriptor>
): string {
return combination
.map((v, i) => {
if (v == 0 || descriptors[i].sdf === undefined) {
return '';
}
return descriptors[i].sdf!.shader;
})
.join('\n');
}
private getFunctionCalls(
combination: Array<number>,
descriptors: Array<DrawableDescriptor>
): string {
return combination
.map((v, i) => {
if (v == 0 || descriptors[i].sdf === undefined) {
return '';
}
return `${descriptors[i].sdf!.distanceFunctionName}(minDistance, color);`;
})
.join('\n');
}
}