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

/**
 * @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 };
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值