スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

効率的 2Dポリゴン描画システムを作ってみた(DirectX)

現在、アーカイブファイル作成とか、3Dモデル読み込みとか、
色んな基盤から作っている訳ですが、

今回、縮退三角形DrawPrimitive関数を用いて、
効率的な2Dポリゴン描画機構を作って見ました。

あ、2Dポリゴンと言うか、
要はスプライト(座標変換済み頂点)の描画ですね。
( 直接 X座標とY座標の位置を指定して画像を描画したい際に、便利。 )

------------------------------------------------
~今回の目次~
1.座標変換済み頂点の問題点
2.問題点の解決方法
3.(今までの)大まかな座標変換済み頂点の描画方法
4.今回作成した描画機構の仕組み

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

1.座標変換済み頂点の問題点
問題点としては、"座標変換済み"なので、
セットした行列が効かない(意味を成さない)
のです。

その為、画像の表示位置を変えたい場合は、
【1】バッファをLock
【2】バッファに書き込み
【3】バッファをUnLock

という手順を行う必要があります。

上記の手順で実装できるならいいじゃん、と思うのですが、
実はLock、UnLock関数というのが曲者で、
呼び出しすぎたら、極端な速度低下を招くのです。

(細かい理由とかは省略。とにかく
   呼び出し過ぎたら駄目、と思ってください。)


2.問題点の解決方法
問題点の解決方法は、実に簡単。
LockとUnLock関数を呼び出す回数を減らせば良いのです。

で、減らす為にはどうすれば良いか?というと、
表示する2Dポリゴン(スプライト)全てを、
1つの巨大なバッファで管理
します。

【参考画像】
splite.jpg

■今までの方法
画像ごとに4つの頂点のバッファを確保している。
描画する際、下記の手順になり、Lock,Unlockが共に4回呼ばれる。
画像AのバッファLock ⇒ 画像Aの座標更新 ⇒ 画像AのバッファUnlock
画像BのバッファLock ⇒ 画像Bの座標更新 ⇒ 画像BのバッファUnlock
画像CのバッファLock ⇒ 画像Cの座標更新 ⇒ 画像CのバッファUnlock
画像DのバッファLock ⇒ 画像Dの座標更新 ⇒ 画像DのバッファUnlock


■今回の新しい方法
(表示させる画像数 × 4つの頂点) + 縮退三角形用の頂点のバッファを確保する。
描画する際は下記の手順になり、
表示させる画像がどんなに増えようと、Lock,Unlockは一回だけ呼び出される。

描画用バッファをLock ⇒
頂点2~5に、画像Aの座標を代入 ⇒
頂点8~11に、画像Bの座標を代入 ⇒
頂点14~17に、画像Cの座標を代入 ⇒
頂点20~23に、画像Dの座標を代入 ⇒ 描画用バッファをUnLock

※スペースの都合上、上の方の画像では、
 頂点20~23は省略しました。




遅くなりました、先にソースコードをUPしておきます。
(記事の一番下)

【実行結果】
SpriteSystem.jpg
※上記の画像は、下記の様に関数を呼び出した際の表示です。
画像の重なり順は、Z座標の値で決まります。
なので、選択肢の画像を一番最後に描画(予約)しても、
ちゃんとZ座標が0.2と、0.3の画像の間に表示されているのが分かると思います。
-----------------------------------------------
PreDrawSprite( 0, 0, 0.5, t_Handle[ 0 ] );
PreDrawSprite( 50, 50, 0.4, t_Handle[ 0 ] );
PreDrawSprite( 100, 100, 0.3, t_Handle[ 0 ] );
PreDrawSprite( 150, 150, 0.2, t_Handle[ 0 ] );
PreDrawSprite( 150, 100, 0.25, t_Handle[ 1 ] ); //選択肢の画像
DrawAllSprite();//スプライトをまとめて全部描画。
-----------------------------------------------



※使い方
【1】LoadTextureで、テクスチャをテクスチャ配列に読み込みます。
【2】GetSpriteHandle関数に、読み込んだテクスチャ配列の添え字を渡し、
   スプライトとしてのハンドルを取得します。
【3】PreDrawSprite関数で、任意のスプライトを描画予約します。(まだ描画されない)
【4】DrawAllSprite関数を呼び出し、PreDrawSprite関数で描画予約をしていたスプライトを
   一気に描画します。

※注意点
・サンプルで作ったので、まともなクラス化は行っておりません。
・読み込んだテクスチャやスプライトの削除機能がありません。
・スプライトの、UV座標、頂点色を変える機能がありません。
・拡大縮小および回転させて表示させる機能がありません。

注意点列挙してみたら、色々と改善点があることに気づいた。
とりあえず、改良版をその内作ってみようかなとか思ってます。


【ソースコード】SpriteSystem.txt
スポンサーサイト

テーマ : ゲーム製作 関連 - ジャンル : ゲーム

コメント

承認待ちコメント

このコメントは管理者の承認待ちです
コメントの投稿
管理者にだけ表示を許可する



上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。