setupVertexAttributes method
void
setupVertexAttributes(
- Object3D object,
- Material material,
- WebGLProgram program,
- BufferGeometry geometry,
Implementation
void setupVertexAttributes(
Object3D object,
Material material,
WebGLProgram program,
BufferGeometry geometry,
) {
if (capabilities.isWebGL2 == false && (object is InstancedMesh || geometry is InstancedBufferGeometry)) {
if (extensions.get('ANGLE_instanced_arrays') == null) return;
}
initAttributes();
var geometryAttributes = geometry.attributes;
var programAttributes = program.getAttributes();
var materialDefaultAttributeValues = material.defaultAttributeValues;
for (var name in programAttributes.keys) {
var programAttribute = programAttributes[name];
if (programAttribute["location"] >= 0) {
// var geometryAttribute = geometryAttributes[ name ];
BufferAttribute? geometryAttribute = geometryAttributes[name];
if (geometryAttribute == null) {
if (name == 'instanceMatrix' && object is InstancedMesh) {
geometryAttribute = object.instanceMatrix;
}
if (name == 'instanceColor' && object is InstancedMesh && object.instanceColor != null) {
geometryAttribute = object.instanceColor;
}
}
if (geometryAttribute != null) {
var normalized = geometryAttribute.normalized;
var size = geometryAttribute.itemSize;
var attribute = attributes.get(geometryAttribute);
// TODO Attribute may not be available on context restore
if (attribute == null) {
print("WebGLBindingState setupVertexAttributes name: $name attribute == null ");
continue;
}
var buffer = attribute["buffer"];
var type = attribute["type"];
var bytesPerElement = attribute["bytesPerElement"];
if (geometryAttribute is InterleavedBufferAttribute) {
var data = geometryAttribute.data;
var stride = data?.stride;
var offset = geometryAttribute.offset;
if (data != null && data is InstancedInterleavedBuffer) {
// enableAttributeAndDivisor( programAttribute, data.meshPerAttribute );
for (var i = 0; i < programAttribute["locationSize"]; i++) {
enableAttributeAndDivisor(programAttribute["location"] + i, data.meshPerAttribute);
}
if (object is! InstancedMesh && geometry.maxInstanceCount == null) {
geometry.maxInstanceCount = data.meshPerAttribute * data.count;
}
} else {
// enableAttribute( programAttribute );
for (var i = 0; i < programAttribute["locationSize"]; i++) {
enableAttribute(programAttribute["location"] + i);
}
}
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
// vertexAttribPointer( programAttribute, size, type, normalized, stride * bytesPerElement, offset * bytesPerElement );
for (var i = 0; i < programAttribute["locationSize"]; i++) {
vertexAttribPointer(
programAttribute["location"] + i,
size ~/ programAttribute["locationSize"],
type,
normalized,
stride! * bytesPerElement,
(offset + (size ~/ programAttribute["locationSize"]) * i) * bytesPerElement);
}
} else {
if (geometryAttribute is InstancedBufferAttribute) {
// enableAttributeAndDivisor( programAttribute, geometryAttribute.meshPerAttribute );
for (var i = 0; i < programAttribute["locationSize"]; i++) {
enableAttributeAndDivisor(programAttribute["location"] + i, geometryAttribute.meshPerAttribute);
}
geometry.maxInstanceCount ??= geometryAttribute.meshPerAttribute * geometryAttribute.count;
} else {
// enableAttribute( programAttribute );
for (var i = 0; i < programAttribute["locationSize"]; i++) {
enableAttribute(programAttribute["location"] + i);
}
}
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
// vertexAttribPointer( programAttribute, size, type, normalized, 0, 0 );
for (var i = 0; i < programAttribute["locationSize"]; i++) {
vertexAttribPointer(programAttribute["location"] + i, size ~/ programAttribute["locationSize"], type,
normalized, size * bytesPerElement, (size ~/ programAttribute["locationSize"]) * i * bytesPerElement);
}
}
} else if (materialDefaultAttributeValues != null) {
var value = materialDefaultAttributeValues[name];
if (value != null) {
switch (value.length) {
case 2:
gl.vertexAttrib2fv(programAttribute["location"], value);
break;
case 3:
gl.vertexAttrib3fv(programAttribute["location"], value);
break;
case 4:
gl.vertexAttrib4fv(programAttribute["location"], value);
break;
default:
gl.vertexAttrib1fv(programAttribute["location"], value);
}
}
}
}
}
disableUnusedAttributes();
}