

2D描画モジュール表示順についての覚書


-----------------------------------------------------------------------------

[1] 描画順決定の仕組み


 2D 描画モジュールは、各描画チャネルごとに以下のような Ordering Table
 (以下、"OT" と呼称)を持つ。

    1-1)OT概略(1チャネルあたり)-----------

      プライオリティ0
		テクスチャハンドル0
		テクスチャハンドル1

			:

		テクスチャハンドル15
		テクスチャ無し
		

      プライオリティ1
		テクスチャハンドル0
		テクスチャハンドル1

			:

		テクスチャハンドル15
		テクスチャ無し
		
		:
		:

      プライオリティ7
		テクスチャハンドル0
		テクスチャハンドル1

			:

		テクスチャハンドル15
		テクスチャ無し

    --------------------------------------

  描画に際し、2D描画モジュールは、登録されているオブジェクトツリーを走査し、
  プライオリティ値とそのオブジェクトの持つテクスチャが含まれる TRI のハンドル値
  を参照し、対応する上記 OT 列の末尾に追加していく。

  全てのオブジェクトの走査が完了し、OT の内容が整ったら、上記 OT を上から
  順に繋ぎ合わせ、その順番に従って描画する。結果、最終的にはプライオリティ値と
  テクスチャハンドル値によって正しく整理された順序で描画されることになる。

  同じ OT 列において、OT 上での順序は、ツリーを走査した際の順序と前後関係が
  一致する。しかし、オブジェクトのプライオリティ値とテクスチャハンドル値に
  よって、各オブジェクトは異なる OT 列に追加されるため、同じ OT 列に追加
  されるのはプライオリティ値とテクスチャハンドル値が一致する場合のみである。


  これらの作業は、毎フレーム OT を初期化して行われる。このため、常に画面上に
  は最新の情報に基づいた描画が行われる。


-----------------------------------------------------------------------------

[2] 走査順

  オブジェクトの走査順を決定する法則は以下の二つである。

    a) 同じ親を持つ者同士は、登録順の新しいものから古い者にむかって走査する。
    b) 子を持つオブジェクトは、兄弟より子の走査を優先する。

  走査順の例を挙げる。


    2-1) ツリー構造の例 ------------------

       -+- A -+- B
        |     |
        |     +- C -+- D
        |     |     |
        |     |     +- E
        |     |
        |     +- F -+- H
        |           |
        |           +- I
        |
        +- G --- J
       	|
	+- K

    --------------------------------------

  例2-1 におけるオブジェクトツリー構造は、アルファベット順に登録されたもの
  とする。

  この場合、走査順は以下のようになる。しかし、これは *描画順ではない* 。


    2-2) 例 2-1 の走査順 -----------------

	K -> G -> J -> A -> F -> I -> H -> C -> E -> D -> B

    --------------------------------------


  具体的に解説すると、以下のようになる。

	1) まず、ルート直下に登録されているオブジェクトでは、K が最も新しい。
	   法則 a) に従い、K を最初に走査する。

	2) K には子オブジェクトが無いので、次に新しい G に走査対象を移す。

	3) G は J という子オブジェクトを持っている。G には K と A という
	   兄弟がいるが、法則 b) に従い、子である J に走査対象を移す。

	4) J は子も兄弟も持たないので、親の G の走査プロセスに戻るが、
	   G の処理は終っているので、法則 a) に従い、より古い兄弟 A に
	   走査対象を移す。

	5) A には F, C, B という子がいる。法則 b) に従い子の走査に移るが、
	   A の子の中では F が最も新しいため、法則 a) に従い F から走査を
	   行う。

	6) F には子があるので、法則 b) を適用し、兄弟である C より先に
	   子の走査を行う。法則 a) があるので、I -> H の順に走査する。

	7) F とその子の走査が終ったら、法則 a) に従い C を走査する。
	   C には D, E という子がいるので、法則 b), a) と適用し、
	   E -> D と走査する。

	8) C とその子の走査が終ったら、法則 a) に従い B を走査する。


    

-----------------------------------------------------------------------------

[3] 走査と OT 追加の例

  描画順の決定要素として、オブジェクトツリー構造と登録順による走査順列よりも、
  より強力なルールがプライオリティと使用テクスチャである。

  以下のツリー構造の例は、例 2-1 にプライオリティと使用されているテクスチャ
  ハンドルの情報を追加したものである。 
  S(p, t) で記述されており、 p がプライオリティ値、t がテクスチャハンドル値を
  表す。テクスチャを指定していないものは、t の値が nil になっている。


    3-1) プライオリティとテクスチャ情報付ツリー -----

       -+- A(1, 0) -+- B(0, 1)
        |           |
        |           +- C(3, 0) -+- D(3, 1)
        |           |           |
        |           |           +- E(3, 0)
        |           |
        |           +- F(2, 1) -+- H(2, 0)
        |                       |
        |                       +- I(2, 2)
        |
        +- G(0, nil) --- J(4, 2)
       	|
	+- K(2, 1)

    -------------------------------------------------


  ツリー構造自体は、例 2-1 と同じなので、走査順は例 2-2 に準ずる。
  しかし、走査しながらプライオリティ値とテクスチャハンドル値に従って
  * OT への登録を行うことで描画順が決定される* ので、走査終了後の OT の
  内容がどうなるかを把握しておく必要がある。

  例 3-2 は、例3-1 のツリーを走査した後の OT の内容である。
  行頭の "2-1:" などの表記は、プライオリティとテクスチャハンドルを表している。
  "1-0" であれば プライオリティ1, テクスチャ 0 を表す。
       
    3-2) 走査終了後の OT 内容 -----

      0-1: B
      0-n: G
      1-0: A
      2-0: H
      2-1: K -> F
      2-2: I
      3-0: C -> E
      3-1: D
      4-2: J
    
    -------------------------------

  このようにして作成された OT の各行を繋合わせることで、以下の描画順を
  導き出すことができる。

    3-3) OT によって決定された描画順 -----

      B -> G -> A -> H -> K -> F -> I -> C -> E -> D -> J

    --------------------------------------

  例 2-2 の走査順と、例 3-3 の 描画順を比較してみれば、描画順の決定において、
  走査順よりもテクスチャハンドル値、テクスチャハンドル値よりもプライオリティ値
  がより強いルールであることがわかる。

  ただ、プライオリティ値とテクスチャハンドル値が同じ K と F, C と E において
  は、走査順における前後関係がそのまま描画順に反映されている。

  また、テクスチャを持たないオブジェクトである G が、同じプライオリティ値を
  持つ B の後に描画されていることにも注意。テクスチャを持たないオブジェクトは、
  同じプライオリティのテクスチャを持つオブジェクトの描画が終った後で
  描画される。

-----------------------------------------------------------------------------

[4] まとめ: 描画順決定の四大法則


§第一法則: 描画チャネル順は絶対

  MGS2 システムにおいては、5つの描画チャネルがあるが、チャネル間の描画順は
  固定であり、動かすことは出来ない。チャネル番号の大きなものが常に手前に
  描画される。2D 描画モジュールもこの制約の元で設計されている。

  一つの 2D レイアウトは一つの描画チャネル上にしか描画されないため、
  この制限はあまり考えなくて良く、一つのチャネル内における描画順を考えれば
  良い。



§第二法則: プライオリティ値は絶対

  描画順を決定する際において、プライオリティ値のもつ意味は絶対である。
  同一のチャネルに描画されている限り、登録順やテクスチャがどうであれ、
  プライオリティ値の低いものが高いものの手前に描画されることはない。


  描画順: プライオリティ低 → プライオリティ高



§第三法則: 同じ tri を参照するものは近い順番

  テクスチャの転送回数を最小限にとどめるため、同じ TRI を参照するオブジェクト
  は、そのテクスチャを転送した直後に連続して描画される。

  同一のプライオリティ値を持つオブジェクト間では、TRI が異なる場合に、
  そのテクスチャハンドルが若いものから順に描画される。

  Line や Point, Box などや、テクスチャを指定しない Sprite などは、
  同一のプライオリティを持つオブジェクトの間では最後に描画される。


  描画順: テクスチャハンドル低 → テクスチャハンドル高 → テクスチャ無し


  ※テクスチャハンドル

	2D描画モジュールに、使用したい TRI を登録した際、描画モジュールから
	返される値。オブジェクトに対し、TRI に含まれるテクスチャを定義する際、

		*登録済のどの TRI を参照するか* 

	を識別するために使用する。

	通常は登録順に 0, 1, 2…と割当てられるが、必ずしも登録順とハンドル値の
	高低関係が安定であるとは限らない。

	たとえば、A, B, C の3つの TRI を順に登録した直後のハンドル値が以下の
	ようになったとする。

		0: A
		1: B
		2: C

	この状態で、B を破棄し、D という TRI を登録した場合、開放されて
	空きが生じた 1 番が割当てられるため、

		0: A
		1: D
		2: C

	となり、登録順とテクスチャハンドル値の高低関係は必ずしも一致しないと
	いうことになる。



§第四法則: 同じプライオリティ、同じTRI
	    (もしくは同じようにテクスチャ無し)ならば、
	    登録順と親子関係によって描画順が決定される。

  2D描画モジュールはオブジェクトの親子関係のツリーをたどり、プライオリティと
  テクスチャでオブジェクトを分類して OT に登録していく。
  しかし、プライオリティ、テクスチャの双方において同じ条件のオブジェクトは、
  走査して見付けた順番に登録されることになる。

  ここで適用される描画順の法則は、

    1) 「親の登録が終った後は、その兄弟よりも子が先に参照される」
    2) 「同じ親を持つオブジェクトは、新しいものから順に走査される」

  の二つである。この走査の結果、同じプライオリティ、同じテクスチャ条件の
  オブジェクトは、走査が先に行われたものほど先に描画される。つまり、
  画面の奥に描画される。

  注意しなければならないのは、この法則によって描画順が決定されるのは、
  第一～第三法則を適用しても順位が同列になる場合のみである。

  本来、描画順を固定したい場合は、何にもましてプライオリティ値によって
  コントロールすべきである(実装上のポリシー)。


-----------------------------------------------------------------------------

以上。
