prepareUniformsGroup method
Implementation
WebGLUniformsGroups prepareUniformsGroup(UniformsGroup uniformsGroup ) {
// determine total buffer size according to the STD140 layout
// Hint: STD140 is the only supported layout in WebGL 2
final uniforms = uniformsGroup.uniforms;
int offset = 0; // global buffer offset in bytes
const int chunkSize = 16; // size of a chunk in bytes
for (int i = 0, l = uniforms.length; i < l; i ++ ) {
final List<Uniform> uniformArray = [uniforms[ i ]];
for (int j = 0, jl = uniformArray.length; j < jl; j ++ ) {
final uniform = uniformArray[ j ];
final values = uniform.value is List ? uniform.value : [ uniform.value ];
for (int k = 0, kl = values.length; k < kl; k ++ ) {
final value = values[ k ];
final info = getUniformSize( value );
// Calculate the chunk offset
final chunkOffset = offset % chunkSize;
final chunkPadding = chunkOffset % info['boundary']!; // required padding to match boundary
final chunkStart = chunkOffset + chunkPadding; // the start position in the current chunk for the data
offset += chunkPadding;
// Check for chunk overflow
if ( chunkStart != 0 && ( chunkSize - chunkStart ) < info['storage']! ) {
// Add padding and adjust offset
offset += ( chunkSize - chunkStart );
}
// the following two properties will be used for partial buffer updates
uniform.data = Float32Array( info['storage']! ~/ Float32List.bytesPerElement);
uniform.offset = offset;
// Update the global offset
offset += info['storage']!;
}
}
}
// ensure correct final padding
final chunkOffset = offset % chunkSize;
if ( chunkOffset > 0 ) offset += ( chunkSize - chunkOffset );
uniformsGroup.size = offset;
uniformsGroup.cache = {};
return this;
}