|
@@ -215,7 +215,9 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
var state = new THREE.WebGLState( _gl, extensions, paramThreeToGL );
|
|
|
var properties = new THREE.WebGLProperties();
|
|
|
var objects = new THREE.WebGLObjects( _gl, properties, this.info );
|
|
|
- var renderer = new THREE.WebGLBufferRenderer( _gl, extensions, _infoRender );
|
|
|
+
|
|
|
+ var bufferRenderer = new THREE.WebGLBufferRenderer( _gl, extensions, _infoRender );
|
|
|
+ var indexedBufferRenderer = new THREE.WebGLIndexedBufferRenderer( _gl, extensions, _infoRender );
|
|
|
|
|
|
//
|
|
|
|
|
@@ -757,10 +759,6 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
};
|
|
|
|
|
|
- function getDefaultGroups( position ) {
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
this.renderBufferDirect = function ( camera, lights, fog, geometry, material, object ) {
|
|
|
|
|
|
setMaterial( material );
|
|
@@ -840,108 +838,118 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
var groups = geometry.drawcalls;
|
|
|
|
|
|
+ var renderer;
|
|
|
+
|
|
|
if ( index !== undefined ) {
|
|
|
|
|
|
- var type, size;
|
|
|
+ renderer = indexedBufferRenderer;
|
|
|
+ renderer.setIndex( index );
|
|
|
|
|
|
- if ( index.array instanceof Uint32Array && extensions.get( 'OES_element_index_uint' ) ) {
|
|
|
+ setupVertexAttributes( material, program, geometry, 0 );
|
|
|
+ _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, objects.getAttributeBuffer( index ) );
|
|
|
|
|
|
- type = _gl.UNSIGNED_INT;
|
|
|
- size = 4;
|
|
|
+ } else {
|
|
|
|
|
|
- } else {
|
|
|
+ renderer = bufferRenderer;
|
|
|
|
|
|
- type = _gl.UNSIGNED_SHORT;
|
|
|
- size = 2;
|
|
|
+ if ( updateBuffers ) {
|
|
|
|
|
|
- }
|
|
|
+ setupVertexAttributes( material, program, geometry, 0 );
|
|
|
|
|
|
- if ( object instanceof THREE.Mesh ) {
|
|
|
+ }
|
|
|
|
|
|
- renderIndexedMesh( type, size, material, geometry, program, updateBuffers );
|
|
|
+ }
|
|
|
|
|
|
- } else if ( object instanceof THREE.Line ) {
|
|
|
+ if ( updateBuffers ) {
|
|
|
|
|
|
- renderIndexedLine( type, size, material, geometry, object, program, updateBuffers );
|
|
|
+ setupVertexAttributes( material, program, geometry, 0 );
|
|
|
|
|
|
- } else if ( object instanceof THREE.PointCloud ) {
|
|
|
+ if ( index !== undefined ) {
|
|
|
|
|
|
- renderIndexedPoints( type, size, material, geometry, program, updateBuffers );
|
|
|
+ _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, objects.getAttributeBuffer( index ) );
|
|
|
|
|
|
}
|
|
|
|
|
|
- } else {
|
|
|
+ }
|
|
|
|
|
|
- if ( updateBuffers ) {
|
|
|
+ if ( groups.length === 0 ) {
|
|
|
|
|
|
- setupVertexAttributes( material, program, geometry, 0 );
|
|
|
+ var count;
|
|
|
|
|
|
- }
|
|
|
+ if ( index !== undefined ) {
|
|
|
|
|
|
- if ( groups.length === 0 ) {
|
|
|
+ count = index.array.length;
|
|
|
|
|
|
- groups = [ {
|
|
|
- start: 0,
|
|
|
- count: position.array.length / 3,
|
|
|
- index: 0
|
|
|
- } ];
|
|
|
+ } else if ( position instanceof THREE.InterleavedBufferAttribute ) {
|
|
|
|
|
|
- }
|
|
|
+ count = position.data.array.length / 3;
|
|
|
|
|
|
- if ( object instanceof THREE.Mesh ) {
|
|
|
+ } else {
|
|
|
|
|
|
- if ( material.wireframe === true ) {
|
|
|
+ count = position.array.length / 3;
|
|
|
|
|
|
- state.setLineWidth( material.wireframeLinewidth * pixelRatio );
|
|
|
- renderer.setMode( _gl.LINES );
|
|
|
+ }
|
|
|
|
|
|
- } else {
|
|
|
+ groups = [ {
|
|
|
+ start: 0,
|
|
|
+ count: count,
|
|
|
+ index: 0
|
|
|
+ } ];
|
|
|
+
|
|
|
+ }
|
|
|
|
|
|
- renderer.setMode( _gl.TRIANGLES );
|
|
|
+ if ( object instanceof THREE.Mesh ) {
|
|
|
|
|
|
- }
|
|
|
+ if ( material.wireframe === true ) {
|
|
|
|
|
|
- if ( geometry instanceof THREE.InstancedBufferGeometry && geometry.maxInstancedCount > 0 ) {
|
|
|
+ state.setLineWidth( material.wireframeLinewidth * pixelRatio );
|
|
|
+ renderer.setMode( _gl.LINES );
|
|
|
|
|
|
- renderer.renderInstances( geometry );
|
|
|
+ } else {
|
|
|
|
|
|
- } else if ( position instanceof THREE.InterleavedBufferAttribute ) {
|
|
|
+ renderer.setMode( _gl.TRIANGLES );
|
|
|
|
|
|
- renderer.render( 0, position.data.count );
|
|
|
+ }
|
|
|
|
|
|
- } else {
|
|
|
+ if ( geometry instanceof THREE.InstancedBufferGeometry && geometry.maxInstancedCount > 0 ) {
|
|
|
|
|
|
- renderer.renderGroups( groups );
|
|
|
+ renderer.renderInstances( geometry );
|
|
|
|
|
|
- }
|
|
|
+ } else if ( position instanceof THREE.InterleavedBufferAttribute ) {
|
|
|
|
|
|
- } else if ( object instanceof THREE.Line ) {
|
|
|
+ renderer.render( 0, position.data.count );
|
|
|
|
|
|
- var lineWidth = material.linewidth;
|
|
|
+ } else {
|
|
|
|
|
|
- if ( lineWidth === undefined ) lineWidth = 1; // Not using Line*Material
|
|
|
+ renderer.renderGroups( groups );
|
|
|
|
|
|
- state.setLineWidth( lineWidth * pixelRatio );
|
|
|
+ }
|
|
|
|
|
|
- if ( object instanceof THREE.LineSegments ) {
|
|
|
+ } else if ( object instanceof THREE.Line ) {
|
|
|
|
|
|
- renderer.setMode( _gl.LINES );
|
|
|
+ var lineWidth = material.linewidth;
|
|
|
|
|
|
- } else {
|
|
|
+ if ( lineWidth === undefined ) lineWidth = 1; // Not using Line*Material
|
|
|
|
|
|
- renderer.setMode( _gl.LINE_STRIP );
|
|
|
+ state.setLineWidth( lineWidth * pixelRatio );
|
|
|
|
|
|
- }
|
|
|
+ if ( object instanceof THREE.LineSegments ) {
|
|
|
|
|
|
- renderer.renderGroups( groups );
|
|
|
+ renderer.setMode( _gl.LINES );
|
|
|
|
|
|
- } else if ( object instanceof THREE.PointCloud ) {
|
|
|
+ } else {
|
|
|
|
|
|
- renderer.setMode( _gl.POINTS );
|
|
|
- renderer.renderGroups( groups );
|
|
|
+ renderer.setMode( _gl.LINE_STRIP );
|
|
|
|
|
|
}
|
|
|
|
|
|
+ renderer.renderGroups( groups );
|
|
|
+
|
|
|
+ } else if ( object instanceof THREE.PointCloud ) {
|
|
|
+
|
|
|
+ renderer.setMode( _gl.POINTS );
|
|
|
+ renderer.renderGroups( groups );
|
|
|
+
|
|
|
}
|
|
|
|
|
|
};
|
|
@@ -1077,214 +1085,6 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
}
|
|
|
|
|
|
- function renderIndexedMesh( type, size, material, geometry, program, updateBuffers ) {
|
|
|
-
|
|
|
- var mode = _gl.TRIANGLES;
|
|
|
-
|
|
|
- if ( material.wireframe === true ) {
|
|
|
-
|
|
|
- mode = _gl.LINES;
|
|
|
- state.setLineWidth( material.wireframeLinewidth * pixelRatio );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- var index = geometry.attributes.index;
|
|
|
- var indexBuffer = objects.getAttributeBuffer( index );
|
|
|
-
|
|
|
- var drawcall = geometry.drawcalls;
|
|
|
-
|
|
|
- if ( drawcall.length === 0 ) {
|
|
|
-
|
|
|
- if ( updateBuffers ) {
|
|
|
-
|
|
|
- setupVertexAttributes( material, program, geometry, 0 );
|
|
|
- _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, indexBuffer );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- if ( geometry instanceof THREE.InstancedBufferGeometry && geometry.maxInstancedCount > 0 ) {
|
|
|
-
|
|
|
- var extension = extensions.get( 'ANGLE_instanced_arrays' );
|
|
|
-
|
|
|
- if ( extension === null ) {
|
|
|
-
|
|
|
- console.error( 'THREE.WebGLRenderer.renderIndexedMesh: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );
|
|
|
- return;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- extension.drawElementsInstancedANGLE( mode, index.array.length, type, 0, geometry.maxInstancedCount ); // Draw the instanced meshes
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- _gl.drawElements( mode, index.array.length, type, 0 );
|
|
|
-
|
|
|
- }
|
|
|
- _infoRender.calls ++;
|
|
|
- _infoRender.vertices += index.array.length; // not really true, here vertices can be shared
|
|
|
- _infoRender.faces += index.array.length / 3;
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- // if there is more than 1 chunk
|
|
|
- // must set attribute pointers to use new drawcall for each chunk
|
|
|
- // even if geometry and materials didn't change
|
|
|
-
|
|
|
- updateBuffers = true;
|
|
|
-
|
|
|
- for ( var i = 0, il = drawcall.length; i < il; i ++ ) {
|
|
|
-
|
|
|
- var startIndex = drawcall[ i ].index;
|
|
|
-
|
|
|
- if ( updateBuffers ) {
|
|
|
-
|
|
|
- setupVertexAttributes( material, program, geometry, startIndex );
|
|
|
- _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, indexBuffer );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- // render indexed triangles
|
|
|
-
|
|
|
- if ( geometry instanceof THREE.InstancedBufferGeometry && drawcall[ i ].instances > 0 ) {
|
|
|
-
|
|
|
- var extension = extensions.get( 'ANGLE_instanced_arrays' );
|
|
|
-
|
|
|
- if ( extension === null ) {
|
|
|
-
|
|
|
- console.error( 'THREE.WebGLRenderer.renderIndexedMesh: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );
|
|
|
- return;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- extension.drawElementsInstancedANGLE( mode, drawcall[ i ].count, type, drawcall[ i ].start * size, drawcall[ i ].count, type, drawcall[ i ].instances ); // Draw the instanced meshes
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- _gl.drawElements( mode, drawcall[ i ].count, type, drawcall[ i ].start * size );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- _infoRender.calls ++;
|
|
|
- _infoRender.vertices += drawcall[ i ].count; // not really true, here vertices can be shared
|
|
|
- _infoRender.faces += drawcall[ i ].count / 3;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function renderIndexedLine( type, size, material, geometry, object, program, updateBuffers ) {
|
|
|
-
|
|
|
- var mode = object instanceof THREE.LineSegments ? _gl.LINES : _gl.LINE_STRIP;
|
|
|
-
|
|
|
- // In case user is not using Line*Material by mistake
|
|
|
- var lineWidth = material.linewidth !== undefined ? material.linewidth : 1;
|
|
|
-
|
|
|
- state.setLineWidth( lineWidth * pixelRatio );
|
|
|
-
|
|
|
- var index = geometry.attributes.index;
|
|
|
- var indexBuffer = objects.getAttributeBuffer( index );
|
|
|
-
|
|
|
- var drawcall = geometry.drawcalls;
|
|
|
-
|
|
|
- if ( drawcall.length === 0 ) {
|
|
|
-
|
|
|
- if ( updateBuffers ) {
|
|
|
-
|
|
|
- setupVertexAttributes( material, program, geometry, 0 );
|
|
|
- _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, indexBuffer );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- _gl.drawElements( mode, index.array.length, type, 0 ); // 2 bytes per Uint16Array
|
|
|
-
|
|
|
- _infoRender.calls ++;
|
|
|
- _infoRender.vertices += index.array.length; // not really true, here vertices can be shared
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- // if there is more than 1 chunk
|
|
|
- // must set attribute pointers to use new drawcall for each chunk
|
|
|
- // even if geometry and materials didn't change
|
|
|
-
|
|
|
- if ( drawcall.length > 1 ) updateBuffers = true;
|
|
|
-
|
|
|
- for ( var i = 0, il = drawcall.length; i < il; i ++ ) {
|
|
|
-
|
|
|
- var startIndex = drawcall[ i ].index;
|
|
|
-
|
|
|
- if ( updateBuffers ) {
|
|
|
-
|
|
|
- setupVertexAttributes( material, program, geometry, startIndex );
|
|
|
- _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, indexBuffer );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- _gl.drawElements( mode, drawcall[ i ].count, type, drawcall[ i ].start * size ); // 2 bytes per Uint16Array
|
|
|
-
|
|
|
- _infoRender.calls ++;
|
|
|
- _infoRender.vertices += drawcall[ i ].count; // not really true, here vertices can be shared
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- function renderIndexedPoints( type, size, material, geometry, program, updateBuffers ) {
|
|
|
-
|
|
|
- var mode = _gl.POINTS;
|
|
|
-
|
|
|
- var index = geometry.attributes.index;
|
|
|
- var indexBuffer = objects.getAttributeBuffer( index );
|
|
|
-
|
|
|
- var drawcall = geometry.drawcalls;
|
|
|
-
|
|
|
- if ( drawcall.length === 0 ) {
|
|
|
-
|
|
|
- if ( updateBuffers ) {
|
|
|
-
|
|
|
- setupVertexAttributes( material, program, geometry, 0 );
|
|
|
- _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, indexBuffer );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- _gl.drawElements( mode, index.array.length, type, 0 );
|
|
|
-
|
|
|
- _infoRender.calls ++;
|
|
|
- _infoRender.points += index.array.length;
|
|
|
-
|
|
|
- } else {
|
|
|
-
|
|
|
- // if there is more than 1 chunk
|
|
|
- // must set attribute pointers to use new drawcall for each chunk
|
|
|
- // even if geometry and materials didn't change
|
|
|
-
|
|
|
- if ( drawcall.length > 1 ) updateBuffers = true;
|
|
|
-
|
|
|
- for ( var i = 0, il = drawcall.length; i < il; i ++ ) {
|
|
|
-
|
|
|
- var startIndex = drawcall[ i ].index;
|
|
|
-
|
|
|
- if ( updateBuffers ) {
|
|
|
-
|
|
|
- setupVertexAttributes( material, program, geometry, startIndex );
|
|
|
- _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, indexBuffer );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- _gl.drawElements( mode, drawcall[ i ].count, type, drawcall[ i ].start * size );
|
|
|
-
|
|
|
- _infoRender.calls ++;
|
|
|
- _infoRender.points += drawcall[ i ].count;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
// Sorting
|
|
|
|
|
|
function numericalSort ( a, b ) {
|