zoukankan      html  css  js  c++  java
  • Away3D 的实体收集器流程1

    View3D 顾名思义 它就是一个3D视口,视口的默认值是无穷大的,即相当于“窗口”是无限大的,我们看到的将是外面的所有景物
    即flash尺寸是视口的有效视域.传统电视的高宽比为4:3,现在的高清电视的高宽比为16:9,你也可以如此这般地去设置。
    它是一个Sprite 的子类。主要用于创建 3D场景 相机 及渲染。相信很多人都和我一样在想
    View3D 它究竟做了什么?很多人估计想都不用想可以回答这个问题 “渲染”!那么它是如何渲染的?除了渲染它还干了什么?
    带着这些问题打开 Away3d 源码 View3D.as 寻找真相。
    源码打开乍眼一看几百行代码晕了。无从下手!学java 和C 的程序员都知道要运行程序先得找到main函数。同样先找找主入口吧,既然都知道它是做渲染的先看看render()函数。
    下面从render()函数下手逐步分析。
    以下是render()函数源码:

    public function render() : void
    {
         //if context3D has Disposed by the OS,don't render at this frame
         if (!stage3DProxy.recoverFromDisposal())

       {
            _backBufferInvalid = true;
            return;
         }
       
         // reset or update render settings
         if (_backBufferInvalid)
            updateBackBuffer();
       
         if (_shareContext && _layeredView)
            stage3DProxy.clearDepthBuffer();

         if (!_parentIsStage)

       {
            var globalPos : Point = parent.localToGlobal(_localPos);
            if (_globalPos.x != globalPos.x || _globalPos.y != globalPos.y)

          {
               _globalPos = globalPos;
               _globalPosDirty = true;
            }
         }
       
         if (_globalPosDirty)
            updateGlobalPos();

         updateTime(); //更新本地运行时间

         updateViewSizeData();

         _entityCollector.clear();

         // collect stuff to render 收集的东西呈现
         _scene.traversePartitions(_entityCollector);

         // update picking
         _mouse3DManager.updateCollider(this);

         if (_requireDepthRender)
            renderSceneDepthToTexture(_entityCollector);

         // todo: perform depth prepass after light update and before final render
         if (_depthPrepass)
            renderDepthPrepass(_entityCollector);

         _renderer.clearOnRender = !_depthPrepass;

         if (_filter3DRenderer && _stage3DProxy._context3D)

       {
            _renderer.render(_entityCollector, _filter3DRenderer.getMainInputTexture(_stage3DProxy), _rttBufferManager.renderToTextureRect);
            _filter3DRenderer.render(_stage3DProxy, camera, _depthRender);
         }

       else

       {
            _renderer.shareContext = _shareContext;
           if (_shareContext)

          {
               _renderer.render(_entityCollector, null, _scissorRect);
            }

          else

         {
               _renderer.render(_entityCollector);
           }

         }
       
         if (!_shareContext) {
            stage3DProxy.present();

          // fire collected mouse events
          _mouse3DManager.fireMouseEvents();
         }

         // clean up data for this render
         _entityCollector.cleanUp();
       
         // register that a view has been rendered
         stage3DProxy.bufferClear = false;
      }

    分析:
    if (!stage3DProxy.recoverFromDisposal())
    {
      _backBufferInvalid = true;
      return;
    }
    stage3DProxy 是Away3D提供一个代理类来管理一个Stage3D实例,对Context3D的常用操作进行了封装。
    recoverFromDisposal() 函数对显卡驱动程序的类型进行了检测。
    这个判断意思就是如果你的显卡驱动不是context3D支持的就不在此帧渲染了.

    if (_backBufferInvalid)
        updateBackBuffer();
        
    updateBackBuffer函数用于更新后台缓存区。

    if (!_parentIsStage)
        updateGlobalPos();

    如果当前的View3D所在的父容器不是Stage上那么Away就会调用updateGlobalPos()函数来更新获取全局坐标。

    updateTime();函数是用来统计上一帧所渲染的时间。

    好了其他的就不多废话了大家有兴趣可以去看看源码,下面重点介绍Away3D的一项重要功能实体收集器。

    在updateTime函数下方有一段代码 _entityCollector.clear();表示每次在渲染的前期会清空实体收集器,然后再进行新的一轮收集。

     _scene.traversePartitions(_entityCollector);

    scene 表示是当前渲染的场景。下面就跟着traversePartitions 函数一步步去跟进看看他是如何收集的。

    每一个 Scene3D 在初始化的时候都会创建一个_partitions:Vector.<Partition3D>。Partition3D是一个空间的分区系统的核心。

    它用于将三维场景分级成多个互不重叠的子空间,从而形成一个树型数据结构。

    在Scene3D类中的 traversePartitions 函数可以看见 每次在收集的时候 都会循环_partitions 然后 调用了 Partition3D 类的

    traverse 函数进行收集。到目前为止我们视乎还是没有搞清楚entityCollector到底是如何收集的。细心的朋友可能已经发现了

     traverse 函数里的 _rootNode.acceptTraverser(traverser); 这段代码。那这个_rootNode 到底是啥呢?下一节我再深入的探讨。

  • 相关阅读:
    剑指17.树的子结构
    剑指16.合并两个排序的链表
    剑指15.反转链表
    剑指14.链表中倒数第k个结点
    剑指13.调整数组顺序使奇数位于偶数前面
    剑指12.数值的整数次方
    剑指11.二进制中1的个数
    剑指10.矩形覆盖
    剑指09.变态跳台阶
    JS 中动态创建json,动态为json添加属性、属性值
  • 原文地址:https://www.cnblogs.com/ch06src/p/3874360.html
Copyright © 2011-2022 走看看