1

私はXNAを初めて使用し、エンティティを親子階層に編成して、XNA上に軽量の2Dエンジンを開発したいと考えています。子供の位置、回転、縮尺は親に依存するため、子供を描くときはマトリックスを考えます。

を使用するSpriteBatch.Begin()と、長方形を画面に描画できますが、次のように変更すると次のようになります。

        this.DrawingMatrix = Matrix.Identity;
        this.SpriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.LinearClamp, DepthStencilState.None, RasterizerState.CullClockwise, null, this.DrawingMatrix);

もう何も描かれていません。私も試した、new Matrix()または。Matrix.CreateTranslation(0, 0, 0)DrawingMatrix

私の最初の質問は、なぜそれが機能しないのかということです。カメラやビューポートを使用していません。

次に、エンティティを描画する前に、を呼び出してPreDrawマトリックスを変換します(次に、で元の状態にリセットしますPostDraw)。

    protected virtual void PreDraw(Engine pEngine)
    {
        pEngine.DrawingMatrix *=
            Matrix.CreateTranslation(this.X, this.Y, 0) *
            Matrix.CreateScale(this.ScaleX, this.ScaleY, 1) *
            Matrix.CreateRotationZ(this.Rotation);
    }

上記のコードの修正を明確にしてください。そして、私は原点ではなく、でスケーリングする必要がありScaleCenterXますScaleCenterYが、どうすればこれを達成できますか?

追加:これが私のエンジンの描画プロセスの例です:

  1. これらのコードを呼び出します:

        this.DrawingMatrix = Matrix.CreateTranslation(0, 0, 0);
        this.SpriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.LinearClamp, DepthStencilState.None, RasterizerState.CullClockwise, null, this.DrawingMatrix);
    
  2. 呼び出しPreDraw()、次のとおりです。

    protected virtual void PreDraw(Engine pEngine)
    {
        pEngine.DrawingMatrix *=
            Matrix.CreateTranslation(this.X, this.Y, 0) *
            Matrix.CreateScale(this.ScaleX, this.ScaleY, 1) *
            Matrix.CreateRotationZ(this.Rotation);
    }
    
  3. Draw()たとえば、私のRectクラスで電話します。

    protected override void Draw(Engine pEngine)
    {
        pEngine.SpriteBatch.Draw(pEngine.RectangleTexture, new Rectangle(0, 0, (int)this.Width, (int)this.Height), new Rectangle(0, 0, 1, 1), this.Color);
    }
    

上記のBeginコードをに置き換えるとthis.SpriteBatch.Begin()、長方形が正しく描画されるので、マトリックスが原因だと思います。

4

1 に答える 1

4

最初の問題は単純なバグです。デフォルトはですSpriteBatchが、すべてのスプライトをバックフェイスカリングするようにCullCounterClockwise指定しました。デフォルトのレンダリング状態を使用したいだけの場合CullClockwiseは合格できます。明示的に指定する必要はありません。null

(負のスケールを使用した場合は、カリングモードを変更する必要があります。)

2番目の質問に答えるには、「戻る」を変換して、スケーリングの原点(yourScaleCenterXScaleCenterY)をワールドの原点(0,0)に配置する必要があります。変換は常に(0,0)の周りで発生します。したがって、通常の順序は次のとおりです。スプライトの原点をワールドの原点に変換し直し、スケーリング、回転、変換して、スプライトの原点を目的のワールドの位置に配置します。

また、逆変換を適用していないことを願っていますPostDraw(そのように聞こえるようにしました)。それは精度の問題を引き起こす可能性が非常に高いです。代わりに、マトリックスを保存して復元する必要があります。

于 2013-01-09T17:08:31.430 に答える