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();
final geometryAttributes = geometry.attributes;
final programAttributes = program.getAttributes();
final materialDefaultAttributeValues = material.defaultAttributeValues;
for (final name in programAttributes.keys) {
final programAttribute = programAttributes[name];
if (programAttribute!.location.id >= 0) {
// final 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) {
final normalized = geometryAttribute.normalized;
final size = geometryAttribute.itemSize;
final attribute = attributes.get(geometryAttribute);
// TODO Attribute may not be available on context restore
if (attribute == null) {
console.warning("WebGLBindingState setupVertexAttributes name: $name attribute == null ");
continue;
}
final buffer = attribute["buffer"];
final type = attribute["type"];
final bytesPerElement = attribute["bytesPerElement"];
if (geometryAttribute is InterleavedBufferAttribute) {
final data = geometryAttribute.data;
final stride = data?.stride;
final offset = geometryAttribute.offset;
if (data != null && data is InstancedInterleavedBuffer) {
// enableAttributeAndDivisor( programAttribute, data.meshPerAttribute );
for (int i = 0; i < programAttribute.locationSize; i++) {
enableAttributeAndDivisor(programAttribute.location.id + i, data.meshPerAttribute);
}
if (object is! InstancedMesh && geometry.maxInstanceCount == null) {
geometry.maxInstanceCount = data.meshPerAttribute * data.count;
}
} else {
// enableAttribute( programAttribute );
for (int i = 0; i < programAttribute.locationSize; i++) {
enableAttribute(programAttribute.location.id + i);
}
}
gl.bindBuffer(WebGL.ARRAY_BUFFER, buffer);
// vertexAttribPointer( programAttribute, size, type, normalized, stride * bytesPerElement, offset * bytesPerElement );
for (int i = 0; i < programAttribute.locationSize; i++) {
vertexAttribPointer(
programAttribute.location.id + i,
size ~/ programAttribute.locationSize,
type,
normalized,
(stride! * bytesPerElement).toInt(),
((offset + (size ~/ programAttribute.locationSize) * i) * bytesPerElement).toInt()
);
}
}
else {
if (geometryAttribute is InstancedBufferAttribute) {
// enableAttributeAndDivisor( programAttribute, geometryAttribute.meshPerAttribute );
for (int i = 0; i < programAttribute.locationSize; i++) {
enableAttributeAndDivisor(programAttribute.location.id + i, geometryAttribute.meshPerAttribute);
}
geometry.maxInstanceCount ??= geometryAttribute.meshPerAttribute * geometryAttribute.count;
}
else {
// enableAttribute( programAttribute );
for (int i = 0; i < programAttribute.locationSize; i++) {
enableAttribute(programAttribute.location.id + i);
}
}
gl.bindBuffer(WebGL.ARRAY_BUFFER, buffer);
//vertexAttribPointer( programAttribute, size, type, normalized, 0, 0 );
for (int i = 0; i < programAttribute.locationSize; i++) {
vertexAttribPointer(
programAttribute.location.id + i,
size ~/ programAttribute.locationSize,
type,
normalized,
(size * bytesPerElement).toInt(),
((size ~/ programAttribute.locationSize) * i * bytesPerElement).toInt()
);
}
}
}
else if (materialDefaultAttributeValues != null) {
final value = materialDefaultAttributeValues[name];
if (value != null) {
switch (value.length) {
case 2:
gl.vertexAttrib2fv(programAttribute.location.id, value);
break;
case 3:
gl.vertexAttrib3fv(programAttribute.location.id, value);
break;
case 4:
gl.vertexAttrib4fv(programAttribute.location.id, value);
break;
default:
gl.vertexAttrib1fv(programAttribute.location.id, value);
}
}
}
}
}
disableUnusedAttributes();
}