浅谈Three.js源码-render之WebGLGeometries.js

来源:互联网 发布:java多线程网络编程 编辑:程序博客网 时间:2024/06/05 00:32
/** * @author mrdoob / http://mrdoob.com/ */import { Uint16BufferAttribute, Uint32BufferAttribute } from '../../core/BufferAttribute';import { BufferGeometry } from '../../core/BufferGeometry';import { arrayMax } from '../../utils';function WebGLGeometries( gl, attributes, infoMemory ) {//threejs中管理网格对象的方法   var geometries = {};   var wireframeAttributes = {};   function onGeometryDispose( event ) {//删除几何对象的方法      var geometry = event.target;      var buffergeometry = geometries[ geometry.id ];//得到当前的buffergeometry对象      if ( buffergeometry.index !== null ) {         attributes.remove( buffergeometry.index );      }      for ( var name in buffergeometry.attributes ) {         attributes.remove( buffergeometry.attributes[ name ] );//删除此对象的缓冲区属性         // (比如顶点坐标缓冲、纹理坐标缓冲、顶点索引等)      }      geometry.removeEventListener( 'dispose', onGeometryDispose );//移除删除用的监听方法      delete geometries[ geometry.id ];//释放此对象占用的内存      // TODO Remove duplicate code      //删除几何体在网格模式下的对象,套路(每一个对象分别有正常模式和网格模式下的数据)      var attribute = wireframeAttributes[ geometry.id ];      if ( attribute ) {         attributes.remove( attribute );         delete wireframeAttributes[ geometry.id ];      }      attribute = wireframeAttributes[ buffergeometry.id ];      if ( attribute ) {         attributes.remove( attribute );         delete wireframeAttributes[ buffergeometry.id ];      }      //      infoMemory.geometries --;   }   function get( object, geometry ) {      var buffergeometry = geometries[ geometry.id ];//得到当前的buffergeometry对象      if ( buffergeometry ) return buffergeometry;      geometry.addEventListener( 'dispose', onGeometryDispose );//添加删除几何对象的监听      if ( geometry.isBufferGeometry ) {//geometry分为geometry和BufferGeometry两种类型,         // BufferGeometry占用更少的内存,效率更高         buffergeometry = geometry;      } else if ( geometry.isGeometry ) {         if ( geometry._bufferGeometry === undefined ) {//如果当前对象中 没有BufferGeometry对象            geometry._bufferGeometry = new BufferGeometry().setFromObject( object );//直接从网格对象中进行转换         }         buffergeometry = geometry._bufferGeometry;      }      geometries[ geometry.id ] = buffergeometry;      infoMemory.geometries ++;      return buffergeometry;//从geometry中获取BufferGeometry   }   function update( geometry ) {      var index = geometry.index;      var geometryAttributes = geometry.attributes;      if ( index !== null ) {         attributes.update( index, gl.ELEMENT_ARRAY_BUFFER );//更新几何对象的索引缓冲      }      for ( var name in geometryAttributes ) {         attributes.update( geometryAttributes[ name ], gl.ARRAY_BUFFER );//更新几何对象的其他缓冲      }      // morph targets      var morphAttributes = geometry.morphAttributes;//几何体做变形时的属性      for ( var name in morphAttributes ) {         var array = morphAttributes[ name ];         for ( var i = 0, l = array.length; i < l; i ++ ) {            attributes.update( array[ i ], gl.ARRAY_BUFFER );//更新几何体做变形时的属性         }      }   }   function getWireframeAttribute( geometry ) {//网格状态下,网格对象的棱角直接使用线段进行绘制(平常模式下是三角形),      //所以其索引必须进行适当地变换      var attribute = wireframeAttributes[ geometry.id ];      if ( attribute ) return attribute;      var indices = [];      var geometryIndex = geometry.index;      var geometryAttributes = geometry.attributes;      // console.time( 'wireframe' );      if ( geometryIndex !== null ) {         var array = geometryIndex.array;         for ( var i = 0, l = array.length; i < l; i += 3 ) {            var a = array[ i + 0 ];            var b = array[ i + 1 ];            var c = array[ i + 2 ];            indices.push( a, b, b, c, c, a );         }      } else {         var array = geometryAttributes.position.array;         for ( var i = 0, l = ( array.length / 3 ) - 1; i < l; i += 3 ) {            var a = i + 0;            var b = i + 1;            var c = i + 2;            indices.push( a, b, b, c, c, a );         }      }      // console.timeEnd( 'wireframe' );      attribute = new ( arrayMax( indices ) > 65535 ? Uint32BufferAttribute : Uint16BufferAttribute )( indices, 1 );      attributes.update( attribute, gl.ELEMENT_ARRAY_BUFFER );//更新其索引值      wireframeAttributes[ geometry.id ] = attribute;      return attribute;   }   return {      get: get,      update: update,      getWireframeAttribute: getWireframeAttribute   };}export { WebGLGeometries };
原创粉丝点击