1 | import { GLProgram } from '../GLProgram.mjs';
|
2 | import { compileShader } from './compileShader.mjs';
|
3 | import { defaultValue } from './defaultValue.mjs';
|
4 | import { getAttributeData } from './getAttributeData.mjs';
|
5 | import { getUniformData } from './getUniformData.mjs';
|
6 | import { logProgramError } from './logProgramError.mjs';
|
7 |
|
8 | function generateProgram(gl, program) {
|
9 | const glVertShader = compileShader(gl, gl.VERTEX_SHADER, program.vertexSrc);
|
10 | const glFragShader = compileShader(gl, gl.FRAGMENT_SHADER, program.fragmentSrc);
|
11 | const webGLProgram = gl.createProgram();
|
12 | gl.attachShader(webGLProgram, glVertShader);
|
13 | gl.attachShader(webGLProgram, glFragShader);
|
14 | const transformFeedbackVaryings = program.extra?.transformFeedbackVaryings;
|
15 | if (transformFeedbackVaryings) {
|
16 | if (typeof gl.transformFeedbackVaryings !== "function") {
|
17 | console.warn(`TransformFeedback is not supported but TransformFeedbackVaryings are given.`);
|
18 | } else {
|
19 | gl.transformFeedbackVaryings(webGLProgram, transformFeedbackVaryings.names, transformFeedbackVaryings.bufferMode === "separate" ? gl.SEPARATE_ATTRIBS : gl.INTERLEAVED_ATTRIBS);
|
20 | }
|
21 | }
|
22 | gl.linkProgram(webGLProgram);
|
23 | if (!gl.getProgramParameter(webGLProgram, gl.LINK_STATUS)) {
|
24 | logProgramError(gl, webGLProgram, glVertShader, glFragShader);
|
25 | }
|
26 | program.attributeData = getAttributeData(webGLProgram, gl);
|
27 | program.uniformData = getUniformData(webGLProgram, gl);
|
28 | if (!/^[ \t]*#[ \t]*version[ \t]+300[ \t]+es[ \t]*$/m.test(program.vertexSrc)) {
|
29 | const keys = Object.keys(program.attributeData);
|
30 | keys.sort((a, b) => a > b ? 1 : -1);
|
31 | for (let i = 0; i < keys.length; i++) {
|
32 | program.attributeData[keys[i]].location = i;
|
33 | gl.bindAttribLocation(webGLProgram, i, keys[i]);
|
34 | }
|
35 | gl.linkProgram(webGLProgram);
|
36 | }
|
37 | gl.deleteShader(glVertShader);
|
38 | gl.deleteShader(glFragShader);
|
39 | const uniformData = {};
|
40 | for (const i in program.uniformData) {
|
41 | const data = program.uniformData[i];
|
42 | uniformData[i] = {
|
43 | location: gl.getUniformLocation(webGLProgram, i),
|
44 | value: defaultValue(data.type, data.size)
|
45 | };
|
46 | }
|
47 | const glProgram = new GLProgram(webGLProgram, uniformData);
|
48 | return glProgram;
|
49 | }
|
50 |
|
51 | export { generateProgram };
|
52 |
|