Improve API
This commit is contained in:
parent
b2c2cfcb41
commit
78444d8cc6
24 changed files with 193 additions and 325 deletions
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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');
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue