-
Notifications
You must be signed in to change notification settings - Fork 5
/
MaterialFactory.ts
81 lines (70 loc) · 3.27 KB
/
MaterialFactory.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
import ShaderHeader from "raw-loader!../Shaders/header.glsl";
import NameResolver from "../Asset/NameResolver";
import TextFileResolver from "../Asset/TextFileResolver";
import GLRelatedRegistryBase from "../Resource/GLRelatedRegistryBase";
import SortParser from "../Sort/Parser";
import MacroRegistory from "./MacroRegistory";
import Material from "./Material";
/**
* Manage materialGenerators for materials.
* Materials can be instanciated with this instance.
* Every gl reference can contain 1 of MaterialFactory at most.
*/
export default class MaterialFactory extends GLRelatedRegistryBase {
public static registryName = "MaterialFactory";
public static defaultShaderHeader: string = ShaderHeader;
public static materialGeneratorResolver: NameResolver<(factory: MaterialFactory) => Material> = new NameResolver<(factory: MaterialFactory) => Material>();
/**
* Obtain an instance of MaterialFactory from WebGLRenderingContext
* @param {WebGLRenderingContext} gl [description]
* @return {MaterialFactory} [description]
*/
public static get(gl: WebGLRenderingContext): MaterialFactory {
return GLRelatedRegistryBase.__get(gl, MaterialFactory);
}
public static addMaterialType(typeName: string, materialGenerator: (factory: MaterialFactory) => Material): void {
this.materialGeneratorResolver.register(typeName, Promise.resolve(materialGenerator));
}
/**
* Add source of .sort material as specified typename.
* @param {string} typeName [description]
* @param {string} source [description]
* @return {Promise<void>} [description]
*/
public static async addSORTMaterial(typeName: string, source: string): Promise<(factory: MaterialFactory) => Material> {
return this.materialGeneratorResolver.register(typeName, (async() => {
const techniques = await SortParser.parse(source);
return (factory) => {
return new Material(factory.gl, techniques);
};
})());
}
/**
* Add source of .sort material from external url as specified typeName.
* @param {string} typeName [description]
* @param {string} url [description]
* @return {Promise<void>} [description]
*/
public static addSORTMaterialFromURL(typeName: string, url: string): Promise<(factory: MaterialFactory) => Material> {
return this.materialGeneratorResolver.register(typeName, (async() => {
const source = await TextFileResolver.resolve(url);
const techniques = await SortParser.parse(source);
return (factory) => {
return new Material(factory.gl, techniques);
};
})());
}
public static getMaterialStatus(typeName: string): number{
return this.materialGeneratorResolver.getStatus(typeName);
}
public shaderHeader: string = MaterialFactory.defaultShaderHeader;
public macro: MacroRegistory;
constructor(public gl: WebGLRenderingContext) {
super();
this.macro = new MacroRegistory();
}
public async instanciate(typeName: string): Promise<Material> {
const generator = await MaterialFactory.materialGeneratorResolver.get(typeName);
return generator(this);
}
}