4.3RenderState及其更新

主要的 Render State 分为 global state lights effects

一,抽象基类 GlobalState

    该类为一个抽象基类,所有的全局状态类型如 alpha blending triangle culling material polygon offset stenciling wireframe depth buffering 等都要基于该类创建。 Node Geometry 均有相关接口用于 global state 的存储,加载和移除。

   这些派生类有两个共同点:( 1 )都要重载虚函数 GetStateType

                          2 )都要在 program initialization 时创建默认对象,在 program termination 时销毁对象。

 

 

二, Lights

Lights 的作用结果与 material 密切相关。

经过多次更改和权衡( p261-p263 ),作者最终决定将 Light 类写成一个通用类,其中包含了所有类型的光源所需的信息,并定义了枚举类 LightType ,以标识对象的光源模型。接口略。

 

三, effects 。详见 chapter3.4

 

四, RenderState 的更新。

当下列事件发生时, RenderState 需要更新:( 1 attach/detach global states  2 attach/detach lights  3 attach/detach effects    (4) 场景图的拓扑结构改变。

   RenderState 更新的顶层接口相对于 geometry state 要简单,只有一个 :UpdateRS()( spatial 中)当上述情况发生时,调用 UpdateRS ()即可。注意,如果仅仅是 RenderState 的某个数据成员发生改变,则没有必要调用 UpdateRS ,因为场景图中每个节点存储的是 RenderState 的智能指针,而不是 RenderState 本身,因此,一旦 RenderState 的内容发生改变,所有共享该类的节点会马上感应到这一点,从而在 draw 的时候体现出来。

 

下面给出 UpdateRS 的函数调用图:

说明: N1 RenderState 更新的触发点。

N1                       UpdateRS ()

             声明 Gstack Lstack

             PropagateStateFromRoot                     parent--- à PropagateStateFromRoot(), 向上

                                              PushState ,向上递归结束。

  UpdateState      

             销毁 Gstack Lstack (递归的终点)

 

 

N 不是触发点:

               PushState

                        UpdateState                对每一个 chilid

  N                                     Child- à UpdateRS(), (向下递归开始。)

               PopState (向下递归结束

                 (node)                     

 

 

UpdateState Geometry -- à 将栈中 RenderState 复制到本地。

向上递归的目的是在栈中加入触发节点之前所有父节点的 RenderState ,以便传给子节点。

向下递归的目的是将当前节点的所有 RenderState 传给子节点(本质是覆盖子节点的本地 RenderState )。

 

 

  读者可能会有此种想法:不用当前节点的 RenderState 覆盖 子节点的 RenderState ,而是通过修正,即当前节点中没有的不做任何动作,多出来的就添加进去,这样就可以免去覆盖,从而省略了 PropagateStateFromRoot 这一步。这是错误的 。例如,某子节点被一个新的子节点替换,这是如果没有 PropagateStateFromRoot (),就无法获得新子节点的全部 RenderState

   当然了,添加 PropagateStateFromRootr ()的缺点是对于原有节点来说,这一步是多余的。

 

 

   一点说明: Gstack Lstack 并不仅是一个栈,而是栈数组,每种类型的 RenderState 拥有一个栈,这是因为可能出现多个同类型的 RenderState 连接到一个节点的情况。

猜你喜欢

转载自blog.csdn.net/huazai434/article/details/5970377
4.3