提交 98dc31d2 编写于 作者: M Mr.doob

Moved more core out of WebGLRenderer.

上级 234861ac
......@@ -34,9 +34,6 @@ THREE.WebGLRenderer = function ( parameters ) {
var lights = [];
var _webglObjects = {};
var _webglObjectsImmediate = [];
var opaqueObjects = [];
var transparentObjects = [];
......@@ -184,7 +181,7 @@ THREE.WebGLRenderer = function ( parameters ) {
resetGLState();
setDefaultGLState();
_webglObjects = {};
objects.objects = {};
}, false);
......@@ -211,7 +208,7 @@ THREE.WebGLRenderer = function ( parameters ) {
}
var extensions = new THREE.WebGLExtensions( _gl );
var buffers = new THREE.WebGLBuffers( _gl, this.info, extensions, getBufferMaterial );
var objects = new THREE.WebGLObjects( _gl, this.info, extensions, getBufferMaterial );
extensions.get( 'OES_texture_float' );
extensions.get( 'OES_texture_float_linear' );
......@@ -285,7 +282,7 @@ THREE.WebGLRenderer = function ( parameters ) {
// shadow map
var shadowMap = new THREE.WebGLShadowMap( this, lights, _webglObjects, _webglObjectsImmediate );
var shadowMap = new THREE.WebGLShadowMap( this, lights, objects );
this.shadowMap = shadowMap;
......@@ -607,30 +604,6 @@ THREE.WebGLRenderer = function ( parameters ) {
// Events
var onObjectRemoved = function ( event ) {
var object = event.target;
object.traverse( function ( child ) {
child.removeEventListener( 'remove', onObjectRemoved );
removeObject( child );
} );
};
var onGeometryDispose = function ( event ) {
var geometry = event.target;
geometry.removeEventListener( 'dispose', onGeometryDispose );
deallocateGeometry( geometry );
};
var onTextureDispose = function ( event ) {
var texture = event.target;
......@@ -668,82 +641,6 @@ THREE.WebGLRenderer = function ( parameters ) {
// Buffer deallocation
var deallocateGeometry = function ( geometry ) {
delete geometry.__webglInit;
if ( geometry instanceof THREE.BufferGeometry ) {
for ( var name in geometry.attributes ) {
var attribute = geometry.attributes[ name ];
if ( attribute.buffer !== undefined ) {
_gl.deleteBuffer( attribute.buffer );
delete attribute.buffer;
}
}
_this.info.memory.geometries --;
} else {
var geometryGroupsList = geometryGroups[ geometry.id ];
if ( geometryGroupsList !== undefined ) {
for ( var i = 0, l = geometryGroupsList.length; i < l; i ++ ) {
var geometryGroup = geometryGroupsList[ i ];
if ( geometryGroup.numMorphTargets !== undefined ) {
for ( var m = 0, ml = geometryGroup.numMorphTargets; m < ml; m ++ ) {
_gl.deleteBuffer( geometryGroup.__webglMorphTargetsBuffers[ m ] );
}
delete geometryGroup.__webglMorphTargetsBuffers;
}
if ( geometryGroup.numMorphNormals !== undefined ) {
for ( var m = 0, ml = geometryGroup.numMorphNormals; m < ml; m ++ ) {
_gl.deleteBuffer( geometryGroup.__webglMorphNormalsBuffers[ m ] );
}
delete geometryGroup.__webglMorphNormalsBuffers;
}
buffers.delete( geometryGroup );
}
delete geometryGroups[ geometry.id ];
} else {
buffers.delete( geometry );
}
}
// TOFIX: Workaround for deleted geometry being currently bound
_currentGeometryProgram = '';
};
var deallocateTexture = function ( texture ) {
if ( texture.image && texture.image.__webglTextureCube ) {
......@@ -1094,7 +991,7 @@ THREE.WebGLRenderer = function ( parameters ) {
if ( material.visible === false ) return;
updateObject( object );
objects.update( object );
var program = setProgram( camera, lights, fog, material, object );
......@@ -1499,7 +1396,7 @@ THREE.WebGLRenderer = function ( parameters ) {
if ( material.visible === false ) return;
updateObject( object );
objects.update( object );
var program = setProgram( camera, lights, fog, material, object );
......@@ -2043,9 +1940,9 @@ THREE.WebGLRenderer = function ( parameters ) {
// set matrices for immediate objects
for ( var i = 0, il = _webglObjectsImmediate.length; i < il; i ++ ) {
for ( var i = 0, il = objects.objectsImmediate.length; i < il; i ++ ) {
var webglObject = _webglObjectsImmediate[ i ];
var webglObject = objects.objectsImmediate[ i ];
var object = webglObject.object;
if ( object.visible ) {
......@@ -2066,7 +1963,7 @@ THREE.WebGLRenderer = function ( parameters ) {
renderObjects( opaqueObjects, camera, lights, fog, overrideMaterial );
renderObjects( transparentObjects, camera, lights, fog, overrideMaterial );
renderObjectsImmediate( _webglObjectsImmediate, '', camera, lights, fog, overrideMaterial );
renderObjectsImmediate( objects.objectsImmediate, '', camera, lights, fog, overrideMaterial );
} else {
......@@ -2075,12 +1972,12 @@ THREE.WebGLRenderer = function ( parameters ) {
state.setBlending( THREE.NoBlending );
renderObjects( opaqueObjects, camera, lights, fog, null );
renderObjectsImmediate( _webglObjectsImmediate, 'opaque', camera, lights, fog, null );
renderObjectsImmediate( objects.objectsImmediate, 'opaque', camera, lights, fog, null );
// transparent pass (back-to-front order)
renderObjects( transparentObjects, camera, lights, fog, null );
renderObjectsImmediate( _webglObjectsImmediate, 'transparent', camera, lights, fog, null );
renderObjectsImmediate( objects.objectsImmediate, 'transparent', camera, lights, fog, null );
}
......@@ -2117,7 +2014,7 @@ THREE.WebGLRenderer = function ( parameters ) {
} else {
initObject( object );
objects.init( object );
if ( object instanceof THREE.Light ) {
......@@ -2133,7 +2030,7 @@ THREE.WebGLRenderer = function ( parameters ) {
} else {
var webglObjects = _webglObjects[ object.id ];
var webglObjects = objects.objects[ object.id ];
if ( webglObjects && ( object.frustumCulled === false || _frustum.intersectsObject( object ) === true ) ) {
......@@ -2329,453 +2226,6 @@ THREE.WebGLRenderer = function ( parameters ) {
}
function initObject( object ) {
if ( object.__webglInit === undefined ) {
object.__webglInit = true;
object._modelViewMatrix = new THREE.Matrix4();
object._normalMatrix = new THREE.Matrix3();
object.addEventListener( 'removed', onObjectRemoved );
}
var geometry = object.geometry;
if ( geometry === undefined ) {
// ImmediateRenderObject
} else if ( geometry.__webglInit === undefined ) {
geometry.__webglInit = true;
geometry.addEventListener( 'dispose', onGeometryDispose );
if ( geometry instanceof THREE.BufferGeometry ) {
_this.info.memory.geometries ++;
} else if ( object instanceof THREE.Mesh ) {
initGeometryGroups( object, geometry );
} else if ( object instanceof THREE.Line ) {
buffers.initLineBuffers( geometry, object );
} else if ( object instanceof THREE.PointCloud ) {
buffers.initPointCloudBuffers( geometry, object );
}
}
if ( object.__webglActive === undefined) {
object.__webglActive = true;
if ( object instanceof THREE.Mesh ) {
if ( geometry instanceof THREE.BufferGeometry ) {
addBuffer( _webglObjects, geometry, object );
} else if ( geometry instanceof THREE.Geometry ) {
var geometryGroupsList = geometryGroups[ geometry.id ];
for ( var i = 0,l = geometryGroupsList.length; i < l; i ++ ) {
addBuffer( _webglObjects, geometryGroupsList[ i ], object );
}
}
} else if ( object instanceof THREE.Line || object instanceof THREE.PointCloud ) {
addBuffer( _webglObjects, geometry, object );
} else if ( object instanceof THREE.ImmediateRenderObject || object.immediateRenderCallback ) {
addBufferImmediate( _webglObjectsImmediate, object );
}
}
}
// Geometry splitting
var geometryGroups = {};
var geometryGroupCounter = 0;
function makeGroups( geometry, usesFaceMaterial ) {
var maxVerticesInGroup = extensions.get( 'OES_element_index_uint' ) ? 4294967296 : 65535;
var groupHash, hash_map = {};
var numMorphTargets = geometry.morphTargets.length;
var numMorphNormals = geometry.morphNormals.length;
var group;
var groups = {};
var groupsList = [];
for ( var f = 0, fl = geometry.faces.length; f < fl; f ++ ) {
var face = geometry.faces[ f ];
var materialIndex = usesFaceMaterial ? face.materialIndex : 0;
if ( ! ( materialIndex in hash_map ) ) {
hash_map[ materialIndex ] = { hash: materialIndex, counter: 0 };
}
groupHash = hash_map[ materialIndex ].hash + '_' + hash_map[ materialIndex ].counter;
if ( ! ( groupHash in groups ) ) {
group = {
id: geometryGroupCounter ++,
faces3: [],
materialIndex: materialIndex,
vertices: 0,
numMorphTargets: numMorphTargets,
numMorphNormals: numMorphNormals
};
groups[ groupHash ] = group;
groupsList.push( group );
}
if ( groups[ groupHash ].vertices + 3 > maxVerticesInGroup ) {
hash_map[ materialIndex ].counter += 1;
groupHash = hash_map[ materialIndex ].hash + '_' + hash_map[ materialIndex ].counter;
if ( ! ( groupHash in groups ) ) {
group = {
id: geometryGroupCounter ++,
faces3: [],
materialIndex: materialIndex,
vertices: 0,
numMorphTargets: numMorphTargets,
numMorphNormals: numMorphNormals
};
groups[ groupHash ] = group;
groupsList.push( group );
}
}
groups[ groupHash ].faces3.push( f );
groups[ groupHash ].vertices += 3;
}
return groupsList;
}
function initGeometryGroups( object, geometry ) {
var material = object.material, addBuffers = false;
if ( geometryGroups[ geometry.id ] === undefined || geometry.groupsNeedUpdate === true ) {
delete _webglObjects[ object.id ];
geometryGroups[ geometry.id ] = makeGroups( geometry, material instanceof THREE.MeshFaceMaterial );
geometry.groupsNeedUpdate = false;
}
var geometryGroupsList = geometryGroups[ geometry.id ];
// create separate VBOs per geometry chunk
for ( var i = 0, il = geometryGroupsList.length; i < il; i ++ ) {
var geometryGroup = geometryGroupsList[ i ];
// initialise VBO on the first access
if ( geometryGroup.__webglVertexBuffer === undefined ) {
buffers.initMeshBuffers( geometryGroup, object );
geometry.verticesNeedUpdate = true;
geometry.morphTargetsNeedUpdate = true;
geometry.elementsNeedUpdate = true;
geometry.uvsNeedUpdate = true;
geometry.normalsNeedUpdate = true;
geometry.tangentsNeedUpdate = true;
geometry.colorsNeedUpdate = true;
addBuffers = true;
} else {
addBuffers = false;
}
if ( addBuffers || object.__webglActive === undefined ) {
addBuffer( _webglObjects, geometryGroup, object );
}
}
object.__webglActive = true;
}
function addBuffer( objlist, buffer, object ) {
var id = object.id;
objlist[id] = objlist[id] || [];
objlist[id].push(
{
id: id,
buffer: buffer,
object: object,
material: null,
z: 0
}
);
};
function addBufferImmediate( objlist, object ) {
objlist.push(
{
id: null,
object: object,
opaque: null,
transparent: null,
z: 0
}
);
};
// Objects updates
function updateObject( object ) {
var geometry = object.geometry;
if ( geometry instanceof THREE.BufferGeometry ) {
var attributes = geometry.attributes;
var attributesKeys = geometry.attributesKeys;
for ( var i = 0, l = attributesKeys.length; i < l; i ++ ) {
var key = attributesKeys[ i ];
var attribute = attributes[ key ];
var bufferType = ( key === 'index' ) ? _gl.ELEMENT_ARRAY_BUFFER : _gl.ARRAY_BUFFER;
var data = ( attribute instanceof THREE.InterleavedBufferAttribute ) ? attribute.data : attribute;
if ( data.buffer === undefined ) {
data.buffer = _gl.createBuffer();
_gl.bindBuffer( bufferType, data.buffer );
var usage = _gl.STATIC_DRAW;
if ( data instanceof THREE.DynamicBufferAttribute
|| ( data instanceof THREE.InstancedBufferAttribute && data.dynamic === true )
|| ( data instanceof THREE.InterleavedBuffer && data.dynamic === true ) ) {
usage = _gl.DYNAMIC_DRAW;
}
_gl.bufferData( bufferType, data.array, usage );
data.needsUpdate = false;
} else if ( data.needsUpdate === true ) {
_gl.bindBuffer( bufferType, data.buffer );
if ( data.updateRange === undefined || data.updateRange.count === -1 ) { // Not using update ranges
_gl.bufferSubData( bufferType, 0, data.array );
} else if ( data.updateRange.count === 0 ) {
THREE.error( 'THREE.WebGLRenderer.updateObject: using updateRange for THREE.DynamicBufferAttribute and marked as needsUpdate but count is 0, ensure you are using set methods or updating manually.' );
} else {
_gl.bufferSubData( bufferType, data.updateRange.offset * data.array.BYTES_PER_ELEMENT,
data.array.subarray( data.updateRange.offset, data.updateRange.offset + data.updateRange.count ) );
data.updateRange.count = 0; // reset range
}
data.needsUpdate = false;
}
}
} else if ( object instanceof THREE.Mesh ) {
// check all geometry groups
if ( geometry.groupsNeedUpdate === true ) {
initGeometryGroups( object, geometry );
}
var geometryGroupsList = geometryGroups[ geometry.id ];
for ( var i = 0, il = geometryGroupsList.length; i < il; i ++ ) {
var geometryGroup = geometryGroupsList[ i ];
var material = getBufferMaterial( object, geometryGroup );
var customAttributesDirty = material.attributes && areCustomAttributesDirty( material );
if ( geometry.verticesNeedUpdate || geometry.morphTargetsNeedUpdate || geometry.elementsNeedUpdate ||
geometry.uvsNeedUpdate || geometry.normalsNeedUpdate ||
geometry.colorsNeedUpdate || geometry.tangentsNeedUpdate || customAttributesDirty ) {
buffers.setMeshBuffers( geometryGroup, object, _gl.DYNAMIC_DRAW, ! geometry.dynamic, material );
}
}
geometry.verticesNeedUpdate = false;
geometry.morphTargetsNeedUpdate = false;
geometry.elementsNeedUpdate = false;
geometry.uvsNeedUpdate = false;
geometry.normalsNeedUpdate = false;
geometry.colorsNeedUpdate = false;
geometry.tangentsNeedUpdate = false;
material.attributes && clearCustomAttributes( material );
} else if ( object instanceof THREE.Line ) {
var material = getBufferMaterial( object, geometry );
var customAttributesDirty = material.attributes && areCustomAttributesDirty( material );
if ( geometry.verticesNeedUpdate || geometry.colorsNeedUpdate || geometry.lineDistancesNeedUpdate || customAttributesDirty ) {
buffers.setLineBuffers( geometry, _gl.DYNAMIC_DRAW );
}
geometry.verticesNeedUpdate = false;
geometry.colorsNeedUpdate = false;
geometry.lineDistancesNeedUpdate = false;
material.attributes && clearCustomAttributes( material );
} else if ( object instanceof THREE.PointCloud ) {
var material = getBufferMaterial( object, geometry );
var customAttributesDirty = material.attributes && areCustomAttributesDirty( material );
if ( geometry.verticesNeedUpdate || geometry.colorsNeedUpdate || customAttributesDirty ) {
buffers.setPointCloudBuffers( geometry, _gl.DYNAMIC_DRAW, object );
}
geometry.verticesNeedUpdate = false;
geometry.colorsNeedUpdate = false;
material.attributes && clearCustomAttributes( material );
}
}
// Objects updates - custom attributes check
function areCustomAttributesDirty( material ) {
for ( var name in material.attributes ) {
if ( material.attributes[ name ].needsUpdate ) return true;
}
return false;
}
function clearCustomAttributes( material ) {
for ( var name in material.attributes ) {
material.attributes[ name ].needsUpdate = false;
}
}
// Objects removal
function removeObject( object ) {
if ( object instanceof THREE.Mesh ||
object instanceof THREE.PointCloud ||
object instanceof THREE.Line ) {
delete _webglObjects[ object.id ];
} else if ( object instanceof THREE.ImmediateRenderObject || object.immediateRenderCallback ) {
removeInstances( _webglObjectsImmediate, object );
}
delete object.__webglInit;
delete object._modelViewMatrix;
delete object._normalMatrix;
delete object.__webglActive;
}
function removeInstances( objlist, object ) {
for ( var o = objlist.length - 1; o >= 0; o -- ) {
if ( objlist[ o ].object === object ) {
objlist.splice( o, 1 );
}
}
}
// Materials
var shaderIDs = {
......
/**
* @author mrdoob / http://mrdoob.com/
*/
THREE.WebGLObjects = function ( gl, info, extensions, getBufferMaterial ) {
var buffers = new THREE.WebGLBuffers( gl, info, extensions, getBufferMaterial );
var objects = {};
var objectsImmediate = [];
var geometryGroups = {};
var geometryGroupCounter = 0;
function makeGroups( geometry, usesFaceMaterial ) {
var maxVerticesInGroup = extensions.get( 'OES_element_index_uint' ) ? 4294967296 : 65535;
var groupHash, hash_map = {};
var numMorphTargets = geometry.morphTargets.length;
var numMorphNormals = geometry.morphNormals.length;
var group;
var groups = {};
var groupsList = [];
for ( var f = 0, fl = geometry.faces.length; f < fl; f ++ ) {
var face = geometry.faces[ f ];
var materialIndex = usesFaceMaterial ? face.materialIndex : 0;
if ( ! ( materialIndex in hash_map ) ) {
hash_map[ materialIndex ] = { hash: materialIndex, counter: 0 };
}
groupHash = hash_map[ materialIndex ].hash + '_' + hash_map[ materialIndex ].counter;
if ( ! ( groupHash in groups ) ) {
group = {
id: geometryGroupCounter ++,
faces3: [],
materialIndex: materialIndex,
vertices: 0,
numMorphTargets: numMorphTargets,
numMorphNormals: numMorphNormals
};
groups[ groupHash ] = group;
groupsList.push( group );
}
if ( groups[ groupHash ].vertices + 3 > maxVerticesInGroup ) {
hash_map[ materialIndex ].counter += 1;
groupHash = hash_map[ materialIndex ].hash + '_' + hash_map[ materialIndex ].counter;
if ( ! ( groupHash in groups ) ) {
group = {
id: geometryGroupCounter ++,
faces3: [],
materialIndex: materialIndex,
vertices: 0,
numMorphTargets: numMorphTargets,
numMorphNormals: numMorphNormals
};
groups[ groupHash ] = group;
groupsList.push( group );
}
}
groups[ groupHash ].faces3.push( f );
groups[ groupHash ].vertices += 3;
}
return groupsList;
}
function initGeometryGroups( object, geometry ) {
var material = object.material, addBuffers = false;
if ( geometryGroups[ geometry.id ] === undefined || geometry.groupsNeedUpdate === true ) {
delete objects[ object.id ];
geometryGroups[ geometry.id ] = makeGroups( geometry, material instanceof THREE.MeshFaceMaterial );
geometry.groupsNeedUpdate = false;
}
var geometryGroupsList = geometryGroups[ geometry.id ];
// create separate VBOs per geometry chunk
for ( var i = 0, il = geometryGroupsList.length; i < il; i ++ ) {
var geometryGroup = geometryGroupsList[ i ];
// initialise VBO on the first access
if ( geometryGroup.__webglVertexBuffer === undefined ) {
buffers.initMeshBuffers( geometryGroup, object );
geometry.verticesNeedUpdate = true;
geometry.morphTargetsNeedUpdate = true;
geometry.elementsNeedUpdate = true;
geometry.uvsNeedUpdate = true;
geometry.normalsNeedUpdate = true;
geometry.tangentsNeedUpdate = true;
geometry.colorsNeedUpdate = true;
addBuffers = true;
} else {
addBuffers = false;
}
if ( addBuffers || object.__webglActive === undefined ) {
addBuffer( objects, geometryGroup, object );
}
}
object.__webglActive = true;
}
function addBuffer( objlist, buffer, object ) {
var id = object.id;
objlist[id] = objlist[id] || [];
objlist[id].push(
{
id: id,
buffer: buffer,
object: object,
material: null,
z: 0
}
);
};
function addBufferImmediate( objlist, object ) {
objlist.push(
{
id: null,
object: object,
opaque: null,
transparent: null,
z: 0
}
);
};
//
// Objects updates - custom attributes check
function areCustomAttributesDirty( material ) {
for ( var name in material.attributes ) {
if ( material.attributes[ name ].needsUpdate ) return true;
}
return false;
}
function clearCustomAttributes( material ) {
for ( var name in material.attributes ) {
material.attributes[ name ].needsUpdate = false;
}
}
//
function onObjectRemoved ( event ) {
var object = event.target;
object.traverse( function ( child ) {
child.removeEventListener( 'remove', onObjectRemoved );
removeObject( child );
} );
};
function removeObject( object ) {
if ( object instanceof THREE.Mesh ||
object instanceof THREE.PointCloud ||
object instanceof THREE.Line ) {
delete objects[ object.id ];
} else if ( object instanceof THREE.ImmediateRenderObject || object.immediateRenderCallback ) {
removeInstances( objectsImmediate, object );
}
delete object.__webglInit;
delete object._modelViewMatrix;
delete object._normalMatrix;
delete object.__webglActive;
}
function removeInstances( objlist, object ) {
for ( var o = objlist.length - 1; o >= 0; o -- ) {
if ( objlist[ o ].object === object ) {
objlist.splice( o, 1 );
}
}
}
//
function onGeometryDispose ( event ) {
var geometry = event.target;
geometry.removeEventListener( 'dispose', onGeometryDispose );
deallocateGeometry( geometry );
};
function deallocateGeometry ( geometry ) {
delete geometry.__webglInit;
if ( geometry instanceof THREE.BufferGeometry ) {
for ( var name in geometry.attributes ) {
var attribute = geometry.attributes[ name ];
if ( attribute.buffer !== undefined ) {
gl.deleteBuffer( attribute.buffer );
delete attribute.buffer;
}
}
info.memory.geometries --;
} else {
var geometryGroupsList = geometryGroups[ geometry.id ];
if ( geometryGroupsList !== undefined ) {
for ( var i = 0, l = geometryGroupsList.length; i < l; i ++ ) {
var geometryGroup = geometryGroupsList[ i ];
if ( geometryGroup.numMorphTargets !== undefined ) {
for ( var m = 0, ml = geometryGroup.numMorphTargets; m < ml; m ++ ) {
gl.deleteBuffer( geometryGroup.__webglMorphTargetsBuffers[ m ] );
}
delete geometryGroup.__webglMorphTargetsBuffers;
}
if ( geometryGroup.numMorphNormals !== undefined ) {
for ( var m = 0, ml = geometryGroup.numMorphNormals; m < ml; m ++ ) {
gl.deleteBuffer( geometryGroup.__webglMorphNormalsBuffers[ m ] );
}
delete geometryGroup.__webglMorphNormalsBuffers;
}
buffers.delete( geometryGroup );
}
delete geometryGroups[ geometry.id ];
} else {
buffers.delete( geometry );
}
}
// TOFIX: Workaround for deleted geometry being currently bound
_currentGeometryProgram = '';
};
//
this.objects = objects;
this.objectsImmediate = objectsImmediate;
this.init = function ( object ) {
if ( object.__webglInit === undefined ) {
object.__webglInit = true;
object._modelViewMatrix = new THREE.Matrix4();
object._normalMatrix = new THREE.Matrix3();
object.addEventListener( 'removed', onObjectRemoved );
}
var geometry = object.geometry;
if ( geometry === undefined ) {
// ImmediateRenderObject
} else if ( geometry.__webglInit === undefined ) {
geometry.__webglInit = true;
geometry.addEventListener( 'dispose', onGeometryDispose );
if ( geometry instanceof THREE.BufferGeometry ) {
info.memory.geometries ++;
} else if ( object instanceof THREE.Mesh ) {
initGeometryGroups( object, geometry );
} else if ( object instanceof THREE.Line ) {
buffers.initLineBuffers( geometry, object );
} else if ( object instanceof THREE.PointCloud ) {
buffers.initPointCloudBuffers( geometry, object );
}
}
if ( object.__webglActive === undefined) {
object.__webglActive = true;
if ( object instanceof THREE.Mesh ) {
if ( geometry instanceof THREE.BufferGeometry ) {
addBuffer( objects, geometry, object );
} else if ( geometry instanceof THREE.Geometry ) {
var geometryGroupsList = geometryGroups[ geometry.id ];
for ( var i = 0,l = geometryGroupsList.length; i < l; i ++ ) {
addBuffer( objects, geometryGroupsList[ i ], object );
}
}
} else if ( object instanceof THREE.Line || object instanceof THREE.PointCloud ) {
addBuffer( objects, geometry, object );
} else if ( object instanceof THREE.ImmediateRenderObject || object.immediateRenderCallback ) {
addBufferImmediate( objectsImmediate, object );
}
}
};
this.update = function ( object ) {
var geometry = object.geometry;
if ( geometry instanceof THREE.BufferGeometry ) {
var attributes = geometry.attributes;
var attributesKeys = geometry.attributesKeys;
for ( var i = 0, l = attributesKeys.length; i < l; i ++ ) {
var key = attributesKeys[ i ];
var attribute = attributes[ key ];
var bufferType = ( key === 'index' ) ? gl.ELEMENT_ARRAY_BUFFER : gl.ARRAY_BUFFER;
var data = ( attribute instanceof THREE.InterleavedBufferAttribute ) ? attribute.data : attribute;
if ( data.buffer === undefined ) {
data.buffer = gl.createBuffer();
gl.bindBuffer( bufferType, data.buffer );
var usage = gl.STATIC_DRAW;
if ( data instanceof THREE.DynamicBufferAttribute
|| ( data instanceof THREE.InstancedBufferAttribute && data.dynamic === true )
|| ( data instanceof THREE.InterleavedBuffer && data.dynamic === true ) ) {
usage = gl.DYNAMIC_DRAW;
}
gl.bufferData( bufferType, data.array, usage );
data.needsUpdate = false;
} else if ( data.needsUpdate === true ) {
gl.bindBuffer( bufferType, data.buffer );
if ( data.updateRange === undefined || data.updateRange.count === -1 ) { // Not using update ranges
gl.bufferSubData( bufferType, 0, data.array );
} else if ( data.updateRange.count === 0 ) {
THREE.error( 'THREE.WebGLRenderer.updateObject: using updateRange for THREE.DynamicBufferAttribute and marked as needsUpdate but count is 0, ensure you are using set methods or updating manually.' );
} else {
gl.bufferSubData( bufferType, data.updateRange.offset * data.array.BYTES_PER_ELEMENT,
data.array.subarray( data.updateRange.offset, data.updateRange.offset + data.updateRange.count ) );
data.updateRange.count = 0; // reset range
}
data.needsUpdate = false;
}
}
} else if ( object instanceof THREE.Mesh ) {
// check all geometry groups
if ( geometry.groupsNeedUpdate === true ) {
initGeometryGroups( object, geometry );
}
var geometryGroupsList = geometryGroups[ geometry.id ];
for ( var i = 0, il = geometryGroupsList.length; i < il; i ++ ) {
var geometryGroup = geometryGroupsList[ i ];
var material = getBufferMaterial( object, geometryGroup );
var customAttributesDirty = material.attributes && areCustomAttributesDirty( material );
if ( geometry.verticesNeedUpdate || geometry.morphTargetsNeedUpdate || geometry.elementsNeedUpdate ||
geometry.uvsNeedUpdate || geometry.normalsNeedUpdate ||
geometry.colorsNeedUpdate || geometry.tangentsNeedUpdate || customAttributesDirty ) {
buffers.setMeshBuffers( geometryGroup, object, gl.DYNAMIC_DRAW, ! geometry.dynamic, material );
}
}
geometry.verticesNeedUpdate = false;
geometry.morphTargetsNeedUpdate = false;
geometry.elementsNeedUpdate = false;
geometry.uvsNeedUpdate = false;
geometry.normalsNeedUpdate = false;
geometry.colorsNeedUpdate = false;
geometry.tangentsNeedUpdate = false;
material.attributes && clearCustomAttributes( material );
} else if ( object instanceof THREE.Line ) {
var material = getBufferMaterial( object, geometry );
var customAttributesDirty = material.attributes && areCustomAttributesDirty( material );
if ( geometry.verticesNeedUpdate || geometry.colorsNeedUpdate || geometry.lineDistancesNeedUpdate || customAttributesDirty ) {
buffers.setLineBuffers( geometry, gl.DYNAMIC_DRAW );
}
geometry.verticesNeedUpdate = false;
geometry.colorsNeedUpdate = false;
geometry.lineDistancesNeedUpdate = false;
material.attributes && clearCustomAttributes( material );
} else if ( object instanceof THREE.PointCloud ) {
var material = getBufferMaterial( object, geometry );
var customAttributesDirty = material.attributes && areCustomAttributesDirty( material );
if ( geometry.verticesNeedUpdate || geometry.colorsNeedUpdate || customAttributesDirty ) {
buffers.setPointCloudBuffers( geometry, gl.DYNAMIC_DRAW, object );
}
geometry.verticesNeedUpdate = false;
geometry.colorsNeedUpdate = false;
material.attributes && clearCustomAttributes( material );
}
};
};
......@@ -3,7 +3,7 @@
* @author mrdoob / http://mrdoob.com/
*/
THREE.WebGLShadowMap = function ( _renderer, _lights, _webglObjects, _webglObjectsImmediate ) {
THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) {
var _gl = _renderer.context,
_frustum = new THREE.Frustum(),
......@@ -12,6 +12,9 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _webglObjects, _webglObjec
_min = new THREE.Vector3(),
_max = new THREE.Vector3(),
_webglObjects = _objects.objects,
_webglObjectsImmediate = _objects.objectsImmediate,
_matrixPosition = new THREE.Vector3(),
_renderList = [];
......
......@@ -154,6 +154,7 @@
"src/renderers/WebGLRenderTargetCube.js",
"src/renderers/webgl/WebGLBuffers.js",
"src/renderers/webgl/WebGLExtensions.js",
"src/renderers/webgl/WebGLObjects.js",
"src/renderers/webgl/WebGLProgram.js",
"src/renderers/webgl/WebGLShader.js",
"src/renderers/webgl/WebGLShadowMap.js",
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册