|
@@ -322,9 +322,16 @@
|
|
|
|
|
|
const programAttribute = programAttributes[ name ];
|
|
|
|
|
|
- if ( programAttribute >= 0 ) {
|
|
|
+ if ( programAttribute.location >= 0 ) {
|
|
|
|
|
|
- const geometryAttribute = geometryAttributes[ name ];
|
|
|
+ let geometryAttribute = geometryAttributes[ name ];
|
|
|
+
|
|
|
+ if ( geometryAttribute === undefined ) {
|
|
|
+
|
|
|
+ if ( name === 'instanceMatrix' && object.instanceMatrix ) geometryAttribute = object.instanceMatrix;
|
|
|
+ if ( name === 'instanceColor' && object.instanceColor ) geometryAttribute = object.instanceColor;
|
|
|
+
|
|
|
+ }
|
|
|
|
|
|
if ( geometryAttribute !== undefined ) {
|
|
|
|
|
@@ -349,85 +356,85 @@
|
|
|
|
|
|
if ( data && data.isInstancedInterleavedBuffer ) {
|
|
|
|
|
|
- enableAttributeAndDivisor( programAttribute, data.meshPerAttribute );
|
|
|
-
|
|
|
- if ( geometry._maxInstanceCount === undefined ) {
|
|
|
+ for ( let i = 0; i < programAttribute.locationSize; i ++ ) {
|
|
|
|
|
|
- geometry._maxInstanceCount = data.meshPerAttribute * data.count;
|
|
|
+ enableAttributeAndDivisor( programAttribute.location + i, data.meshPerAttribute );
|
|
|
|
|
|
}
|
|
|
|
|
|
- } else {
|
|
|
-
|
|
|
- enableAttribute( programAttribute );
|
|
|
+ if ( object.isInstancedMesh !== true && geometry._maxInstanceCount === undefined ) {
|
|
|
|
|
|
- }
|
|
|
+ geometry._maxInstanceCount = data.meshPerAttribute * data.count;
|
|
|
|
|
|
- gl.bindBuffer( gl.ARRAY_BUFFER, buffer );
|
|
|
- vertexAttribPointer( programAttribute, size, type, normalized, stride * bytesPerElement, offset * bytesPerElement );
|
|
|
+ }
|
|
|
|
|
|
- } else {
|
|
|
+ } else {
|
|
|
|
|
|
- if ( geometryAttribute.isInstancedBufferAttribute ) {
|
|
|
+ for ( let i = 0; i < programAttribute.locationSize; i ++ ) {
|
|
|
|
|
|
- enableAttributeAndDivisor( programAttribute, geometryAttribute.meshPerAttribute );
|
|
|
+ enableAttribute( programAttribute.location + i );
|
|
|
|
|
|
- if ( geometry._maxInstanceCount === undefined ) {
|
|
|
+ }
|
|
|
|
|
|
- geometry._maxInstanceCount = geometryAttribute.meshPerAttribute * geometryAttribute.count;
|
|
|
+ }
|
|
|
|
|
|
- }
|
|
|
+ gl.bindBuffer( gl.ARRAY_BUFFER, buffer );
|
|
|
|
|
|
- } else {
|
|
|
+ for ( let i = 0; i < programAttribute.locationSize; i ++ ) {
|
|
|
|
|
|
- enableAttribute( programAttribute );
|
|
|
+ vertexAttribPointer(
|
|
|
+ programAttribute.location + i,
|
|
|
+ size / programAttribute.locationSize,
|
|
|
+ type,
|
|
|
+ normalized,
|
|
|
+ stride * bytesPerElement,
|
|
|
+ ( offset + ( size / programAttribute.locationSize ) * i ) * bytesPerElement
|
|
|
+ );
|
|
|
|
|
|
}
|
|
|
|
|
|
- gl.bindBuffer( gl.ARRAY_BUFFER, buffer );
|
|
|
- vertexAttribPointer( programAttribute, size, type, normalized, 0, 0 );
|
|
|
+ } else {
|
|
|
|
|
|
- }
|
|
|
+ if ( geometryAttribute.isInstancedBufferAttribute ) {
|
|
|
|
|
|
- } else if ( name === 'instanceMatrix' ) {
|
|
|
+ for ( let i = 0; i < programAttribute.locationSize; i ++ ) {
|
|
|
|
|
|
- const attribute = attributes.get( object.instanceMatrix );
|
|
|
+ enableAttributeAndDivisor( programAttribute.location + i, geometryAttribute.meshPerAttribute );
|
|
|
|
|
|
- // TODO Attribute may not be available on context restore
|
|
|
+ }
|
|
|
|
|
|
- if ( attribute === undefined ) continue;
|
|
|
+ if ( object.isInstancedMesh !== true && geometry._maxInstanceCount === undefined ) {
|
|
|
|
|
|
- const buffer = attribute.buffer;
|
|
|
- const type = attribute.type;
|
|
|
+ geometry._maxInstanceCount = geometryAttribute.meshPerAttribute * geometryAttribute.count;
|
|
|
|
|
|
- enableAttributeAndDivisor( programAttribute + 0, 1 );
|
|
|
- enableAttributeAndDivisor( programAttribute + 1, 1 );
|
|
|
- enableAttributeAndDivisor( programAttribute + 2, 1 );
|
|
|
- enableAttributeAndDivisor( programAttribute + 3, 1 );
|
|
|
+ }
|
|
|
|
|
|
- gl.bindBuffer( gl.ARRAY_BUFFER, buffer );
|
|
|
+ } else {
|
|
|
|
|
|
- gl.vertexAttribPointer( programAttribute + 0, 4, type, false, 64, 0 );
|
|
|
- gl.vertexAttribPointer( programAttribute + 1, 4, type, false, 64, 16 );
|
|
|
- gl.vertexAttribPointer( programAttribute + 2, 4, type, false, 64, 32 );
|
|
|
- gl.vertexAttribPointer( programAttribute + 3, 4, type, false, 64, 48 );
|
|
|
+ for ( let i = 0; i < programAttribute.locationSize; i ++ ) {
|
|
|
|
|
|
- } else if ( name === 'instanceColor' ) {
|
|
|
+ enableAttribute( programAttribute.location + i );
|
|
|
|
|
|
- const attribute = attributes.get( object.instanceColor );
|
|
|
+ }
|
|
|
|
|
|
- // TODO Attribute may not be available on context restore
|
|
|
+ }
|
|
|
|
|
|
- if ( attribute === undefined ) continue;
|
|
|
+ gl.bindBuffer( gl.ARRAY_BUFFER, buffer );
|
|
|
|
|
|
- const buffer = attribute.buffer;
|
|
|
- const type = attribute.type;
|
|
|
+ for ( let i = 0; i < programAttribute.locationSize; i ++ ) {
|
|
|
|
|
|
- enableAttributeAndDivisor( programAttribute, 1 );
|
|
|
+ vertexAttribPointer(
|
|
|
+ programAttribute.location + i,
|
|
|
+ size / programAttribute.locationSize,
|
|
|
+ type,
|
|
|
+ normalized,
|
|
|
+ size * bytesPerElement,
|
|
|
+ ( size / programAttribute.locationSize ) * i * bytesPerElement
|
|
|
+ );
|
|
|
|
|
|
- gl.bindBuffer( gl.ARRAY_BUFFER, buffer );
|
|
|
+ }
|
|
|
|
|
|
- gl.vertexAttribPointer( programAttribute, 3, type, false, 12, 0 );
|
|
|
+ }
|
|
|
|
|
|
} else if ( materialDefaultAttributeValues !== undefined ) {
|
|
|
|
|
@@ -438,19 +445,19 @@
|
|
|
switch ( value.length ) {
|
|
|
|
|
|
case 2:
|
|
|
- gl.vertexAttrib2fv( programAttribute, value );
|
|
|
+ gl.vertexAttrib2fv( programAttribute.location, value );
|
|
|
break;
|
|
|
|
|
|
case 3:
|
|
|
- gl.vertexAttrib3fv( programAttribute, value );
|
|
|
+ gl.vertexAttrib3fv( programAttribute.location, value );
|
|
|
break;
|
|
|
|
|
|
case 4:
|
|
|
- gl.vertexAttrib4fv( programAttribute, value );
|
|
|
+ gl.vertexAttrib4fv( programAttribute.location, value );
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
- gl.vertexAttrib1fv( programAttribute, value );
|
|
|
+ gl.vertexAttrib1fv( programAttribute.location, value );
|
|
|
|
|
|
}
|
|
|
|