卒制の作品のタイトル画面製作中にビルボードとかZソートのことを忘れてて詰まった。先生に聞いて思い出した時めっちゃ恥ずかしいという領域を越したので戒めとしてここでもう一度Zソートについて再確認する意味も含め記載。
※まず『なんでZソートがいるんじゃFu◎k!!』ということについて
Zソートがいる理由としてはもう直結に言うと描画順番の関係があるから。
透過されていないオブジェクトであれば手前にあり、それに隠れている奥のオブジェクトは描画しなくてもいい。(見えている部分のピクセルだけ取り出せばいいから。)
だ が し か し
透過されている場合は別。
人間が透過指定してようがパソコン上ではオブジェクトはオブジェクト。要するに障害物。その為、先に透過していないオブジェクトを配置し、その手前に透過処理しているオブジェクトを置くと手前の透過処理済みオブジェクトの部分のピクセルを取り出してレンダリングしてしまうので奥にあるオブジェクトは透過しているしていないに関わらず、透過処理した手前のオブジェクトに隠されてしまう。(透過したオブジェクト同士だったら加算合成の設定してれば問題ない。)
(上記については図もあったほうが分かりやすいので先生が書いてくれた絵を家に帰ったら画像として貼る)
結論から言うと透過処理したものは一番最後に、『一番最後に』描画する必要がある。(非常に大事なことなので2回言いました。)
それを解決するのがZソート。要するに描画する順番を決めようぜ!ていうこと。まぁ、カメラやオブジェクトが一切動かないのであれば一つ一つ手作業で描画順番決めるのも手だけど。
じゃぁどうやって描画順番決めんの?
答えは簡単。一個一個カメラと対象のオブジェクトの距離見て並べ替える。その計算と処理を『プログラマがすること』それがZソート。
計算は苦手なので割愛(カメラ座標とオブジェクトの距離をベクトルでウンタラカンタラだったと思う。確か。)
ただ、ポリゴンもメッシュもいちいち座標引っ張りだして計算なんてやってられない。そこで継承とかポインタとかが出てくる。
※楽をしようぜ(最初以外)
画面に描画されるオブジェクトの座標を引っ張りだすのはめんどくさい。そんなあなたにおすすめなのは描画に関わるオブジェクト全てに座標と描画用の仮想関数を書いたスーパークラス作ってかたっぱしから継承させること。(DoD:DIAMOND OF DEATHには気をつけろよ)
全オブジェクトをスーパークラスのポインタ配列で管理し、Zソートするクラスを作っちまえばいい。
//スーパークラス。描画する必要が有るものは『すべて』こいつを継承させる(DOD注意)
class Super{
public: //ホントはメンバ変数は全部private化したいけどめんどくさいんでpublicで済ます。
D3DXVECTOR3 m_WldPos;
virtual Draw();
};
class Sub : public Super{
public:
CLVer m_LVerPolygon; //3次元空間に描画するポリゴン
void Draw(); //オーバー・・・ロードだっけ?ライドだっけ?まぁアレした関数。
};
class ZsortManager{
vector m_SortContainer; //←描画される可能性のあるオブジェクトのポインタを全部突っ込むコンテナ
vector::iterator m_SortIterator; //ソート用のイテレーター
//ソートしたりする関数(描画機能もあればなおよし←俺的には)
};
//ちなみにコンテナじゃなく配列でしたいんだったらこんなかんじで処理することになる
Super* Arr[];
//片っ端から配列に突っ込む
//ソート時↓
Arr[]->m_WldPos //座標引っ張りだしてあとは人力でソート。
追記:ISLe さんにご指摘いただいたので一部間違った記述を修正しました。本当にご迷惑おかけして申し訳ありません。