1 | import './index.mjs';
|
2 | import { uniformParsers } from './uniformParsers.mjs';
|
3 | import { mapSize } from './mapSize.mjs';
|
4 |
|
5 | function uboUpdate(_ud, _uv, _renderer, _syncData, buffer) {
|
6 | _renderer.buffer.update(buffer);
|
7 | }
|
8 | const UBO_TO_SINGLE_SETTERS = {
|
9 | float: `
|
10 | data[offset] = v;
|
11 | `,
|
12 | vec2: `
|
13 | data[offset] = v[0];
|
14 | data[offset+1] = v[1];
|
15 | `,
|
16 | vec3: `
|
17 | data[offset] = v[0];
|
18 | data[offset+1] = v[1];
|
19 | data[offset+2] = v[2];
|
20 |
|
21 | `,
|
22 | vec4: `
|
23 | data[offset] = v[0];
|
24 | data[offset+1] = v[1];
|
25 | data[offset+2] = v[2];
|
26 | data[offset+3] = v[3];
|
27 | `,
|
28 | mat2: `
|
29 | data[offset] = v[0];
|
30 | data[offset+1] = v[1];
|
31 |
|
32 | data[offset+4] = v[2];
|
33 | data[offset+5] = v[3];
|
34 | `,
|
35 | mat3: `
|
36 | data[offset] = v[0];
|
37 | data[offset+1] = v[1];
|
38 | data[offset+2] = v[2];
|
39 |
|
40 | data[offset + 4] = v[3];
|
41 | data[offset + 5] = v[4];
|
42 | data[offset + 6] = v[5];
|
43 |
|
44 | data[offset + 8] = v[6];
|
45 | data[offset + 9] = v[7];
|
46 | data[offset + 10] = v[8];
|
47 | `,
|
48 | mat4: `
|
49 | for(var i = 0; i < 16; i++)
|
50 | {
|
51 | data[offset + i] = v[i];
|
52 | }
|
53 | `
|
54 | };
|
55 | const GLSL_TO_STD40_SIZE = {
|
56 | float: 4,
|
57 | vec2: 8,
|
58 | vec3: 12,
|
59 | vec4: 16,
|
60 | int: 4,
|
61 | ivec2: 8,
|
62 | ivec3: 12,
|
63 | ivec4: 16,
|
64 | uint: 4,
|
65 | uvec2: 8,
|
66 | uvec3: 12,
|
67 | uvec4: 16,
|
68 | bool: 4,
|
69 | bvec2: 8,
|
70 | bvec3: 12,
|
71 | bvec4: 16,
|
72 | mat2: 16 * 2,
|
73 | mat3: 16 * 3,
|
74 | mat4: 16 * 4
|
75 | };
|
76 | function createUBOElements(uniformData) {
|
77 | const uboElements = uniformData.map((data) => ({
|
78 | data,
|
79 | offset: 0,
|
80 | dataLen: 0,
|
81 | dirty: 0
|
82 | }));
|
83 | let size = 0;
|
84 | let chunkSize = 0;
|
85 | let offset = 0;
|
86 | for (let i = 0; i < uboElements.length; i++) {
|
87 | const uboElement = uboElements[i];
|
88 | size = GLSL_TO_STD40_SIZE[uboElement.data.type];
|
89 | if (uboElement.data.size > 1) {
|
90 | size = Math.max(size, 16) * uboElement.data.size;
|
91 | }
|
92 | uboElement.dataLen = size;
|
93 | if (chunkSize % size !== 0 && chunkSize < 16) {
|
94 | const lineUpValue = chunkSize % size % 16;
|
95 | chunkSize += lineUpValue;
|
96 | offset += lineUpValue;
|
97 | }
|
98 | if (chunkSize + size > 16) {
|
99 | offset = Math.ceil(offset / 16) * 16;
|
100 | uboElement.offset = offset;
|
101 | offset += size;
|
102 | chunkSize = size;
|
103 | } else {
|
104 | uboElement.offset = offset;
|
105 | chunkSize += size;
|
106 | offset += size;
|
107 | }
|
108 | }
|
109 | offset = Math.ceil(offset / 16) * 16;
|
110 | return { uboElements, size: offset };
|
111 | }
|
112 | function getUBOData(uniforms, uniformData) {
|
113 | const usedUniformDatas = [];
|
114 | for (const i in uniforms) {
|
115 | if (uniformData[i]) {
|
116 | usedUniformDatas.push(uniformData[i]);
|
117 | }
|
118 | }
|
119 | usedUniformDatas.sort((a, b) => a.index - b.index);
|
120 | return usedUniformDatas;
|
121 | }
|
122 | function generateUniformBufferSync(group, uniformData) {
|
123 | if (!group.autoManage) {
|
124 | return { size: 0, syncFunc: uboUpdate };
|
125 | }
|
126 | const usedUniformDatas = getUBOData(group.uniforms, uniformData);
|
127 | const { uboElements, size } = createUBOElements(usedUniformDatas);
|
128 | const funcFragments = [`
|
129 | var v = null;
|
130 | var v2 = null;
|
131 | var cv = null;
|
132 | var t = 0;
|
133 | var gl = renderer.gl
|
134 | var index = 0;
|
135 | var data = buffer.data;
|
136 | `];
|
137 | for (let i = 0; i < uboElements.length; i++) {
|
138 | const uboElement = uboElements[i];
|
139 | const uniform = group.uniforms[uboElement.data.name];
|
140 | const name = uboElement.data.name;
|
141 | let parsed = false;
|
142 | for (let j = 0; j < uniformParsers.length; j++) {
|
143 | const uniformParser = uniformParsers[j];
|
144 | if (uniformParser.codeUbo && uniformParser.test(uboElement.data, uniform)) {
|
145 | funcFragments.push(`offset = ${uboElement.offset / 4};`, uniformParsers[j].codeUbo(uboElement.data.name, uniform));
|
146 | parsed = true;
|
147 | break;
|
148 | }
|
149 | }
|
150 | if (!parsed) {
|
151 | if (uboElement.data.size > 1) {
|
152 | const size2 = mapSize(uboElement.data.type);
|
153 | const rowSize = Math.max(GLSL_TO_STD40_SIZE[uboElement.data.type] / 16, 1);
|
154 | const elementSize = size2 / rowSize;
|
155 | const remainder = (4 - elementSize % 4) % 4;
|
156 | funcFragments.push(`
|
157 | cv = ud.${name}.value;
|
158 | v = uv.${name};
|
159 | offset = ${uboElement.offset / 4};
|
160 |
|
161 | t = 0;
|
162 |
|
163 | for(var i=0; i < ${uboElement.data.size * rowSize}; i++)
|
164 | {
|
165 | for(var j = 0; j < ${elementSize}; j++)
|
166 | {
|
167 | data[offset++] = v[t++];
|
168 | }
|
169 | offset += ${remainder};
|
170 | }
|
171 |
|
172 | `);
|
173 | } else {
|
174 | const template = UBO_TO_SINGLE_SETTERS[uboElement.data.type];
|
175 | funcFragments.push(`
|
176 | cv = ud.${name}.value;
|
177 | v = uv.${name};
|
178 | offset = ${uboElement.offset / 4};
|
179 | ${template};
|
180 | `);
|
181 | }
|
182 | }
|
183 | }
|
184 | funcFragments.push(`
|
185 | renderer.buffer.update(buffer);
|
186 | `);
|
187 | return {
|
188 | size,
|
189 | syncFunc: new Function("ud", "uv", "renderer", "syncData", "buffer", funcFragments.join("\n"))
|
190 | };
|
191 | }
|
192 |
|
193 | export { createUBOElements, generateUniformBufferSync, getUBOData };
|
194 | //# sourceMappingURL=generateUniformBufferSync.mjs.map
|
195 |
|
\ | No newline at end of file |