2008/05/19(月)Direct3D Sprite の罠

はてブ数 2008/05/19 00:35 計算機な日記::ソフト作りつーさ

この間のDirectSoundといい、DirectXには罠がいっぱい。

回転とか拡大縮小とか簡単にやりたいなーと思ってDraw2Dを使ってみるもどうも直感的じゃない(個人的に)。
そう、これ描画先座標が拡縮回転前指定なんですよね。
つまり、平行移動、拡大縮小、回転 の順番。
どっちかと言えば、2倍に拡大したものをどこどこへって指定したいけど、↑だと描画先に1/2しなきゃいけないし。その上、Viewport+Transformで原点自由に変えられてこりゃいいやーとか思ってたら、ちょっとちょっと、Draw2DたんはTransform弄っちゃうじゃないですか!
Draw2Dはつかえねー……。とゆーかかなり使いにくい。こりゃもー自前でTransformするしかないよねー。
でも行列って計算コスト高いしなぁ……、そもそも、どこを描画時のパラメータにしてどこを描画前に予め与えておくのよ。前が見えなくて先週一週間ずっと胃を痛めていた。とか

今日あらためて、結局やらないかんことって何? と整理してみる。
チップ単位での 拡大縮小・回転・平行移動。そしてViewport+原点弄くるための、平行移動……
あれ、これローカル座標系とワールド座標系の行列計算してるだけじゃーん! ってことに気づく。
ついでに、計算コストの高い行列同士の計算は、予め手計算してみたら案外すっきり。

というわけで、今日やったこと。
拡縮→回転→平行移動 の順番で噛ました行列を作って返してくれるメソッドを作った。
えおなゆ様にすぺしゃるさんくす!
今回は、前回のQoFで避けていた地雷をどんどこ踏みつつ、いろんな人にお世話になりまくっているなぁ!

/// 省略
public Matrix CreateTransformMatrix2D(
    float scaleX, float scaleY, int degree, float transX, float transY)
{
    Matrix m = new Matrix();
    m.M11 = cosineTable[degree % cosineTable.Length] * scaleX;
    m.M12 = sineTable[degree % sineTable.Length] * scaleX;
    m.M21 = sineTable[degree % sineTable.Length] * -scaleY;
    m.M22 = cosineTable[degree % cosineTable.Length] * scaleY;
    m.M41 = transX;
    m.M42 = transY;
    m.M44 = 1f;
    return m;
}

/// 省略
public void SetGlobalTransform(
    float scaleX, float scaleY, int degree, float transX, float transY)
{
    device.Transform.World = 
        CreateTransformMatrix2D(scaleX, scaleY, degree, transX, transY);
}
/// 省略
public void SetLocalTransform(
    float scaleX, float scaleY, int degree, float transX, float transY)
{
    sprite.Transform = 
        CreateTransformMatrix2D(scaleX, scaleY, degree, transX, transY);
}

あぁ、これで便利に使えそう。+αな補足としては、
Sprite.Begin~End間にdevice.Transform弄るのはいいけど、
SpriteさんはBeginするとき、device.Transformの逆行列(のよーなもの?)をTransformにセットして描画位置を戻してる(?)みたいなので、
Begin時のdevice.Transformによっては、変な行列が入っちゃって(?)弄りよーにも弄りにくい。
ので、Sprite.Beginするとき、必ず device.Transform.World = Matrix.Identity; しとくといいかなー。
と言ったところ。

ああ、いろいろと自分でやろうと思ったらお節介すぎるのねー。
これでキャラごとの回転ができる。弾幕も作れるネ!
まだまだ作りかけ。やらなきゃいけないことが多すぎる。
でも、今週は応用確率論の中間があるので、続きはそれ以降になりそう。
今年はQoFとはまた違った意味で、QoF以上の修羅場になりそう。
あぁ、怖いなぁ……