UNPKG

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