2012-03-26 7 views
1

私のタイルを描画するこのメソッドは非常に遅いようですが、私は正確に何が間違っているのかわからない、私のカリングメソッドがうまく動作せず、オフスクリーンのものを描画しています。ここでは、次のとおりです。XNA - カリングパフォーマンスの問題

 // Calculate the visible range of tiles. 
     int left = (int)Math.Floor(cameraPosition.X/16); 
     int right = left + spriteBatch.GraphicsDevice.Viewport.Width/16; 
     right = Math.Min(right, Width) + 1; // Width -1 originally - didn't look good as tiles drawn on screen 
     if (right > tiles.GetUpperBound(0)) 
      right = tiles.GetUpperBound(0) + 1; // adding 1 to get the last right tile drawn 

     int top = (int)Math.Floor(cameraPosition.Y/16); 
     int bottom = left + spriteBatch.GraphicsDevice.Viewport.Height/ 16; 
     bottom = Math.Min(bottom, Height) + 1; // Height -1 originally - didn't look good as tiles drawn on screen 
     if (bottom > tiles.GetUpperBound(1)) 
      bottom = tiles.GetUpperBound(1) + 1; // adding 1 to get the last bottom tile drawn 

     // For each tile position 
     for (int y = top; y < bottom; ++y) 
     { 
      for (int x = left; x < right; ++x) 
      { 
       // If there is a visible tile in that position, draw it 
       if (tiles[x, y].BlockType.Name != "Blank") 
       { 
        Texture2D texture = tileContent["DirtBlock_" + getTileSetType(tiles,x,y)]; 
        spriteBatch.Draw(texture, new Vector2(x * 16, y * 16), Color.White); 
        if (isMinimap) 
        spriteBatch.Draw(pixel, new Vector2(30+x, 30+y), Color.White); 
       } 

      } 
     } 

GetTileSetTypes

などDirtBlock_North、DirtBlock_Center、同様に、異なるテクスチャのために、

その周りにあるものをタイルを取得するための機能であるタイルコンテンツが私のブロックのテクスチャを持つだけのクラスです。

+0

どのようにこれが遅いコードであると判断しましたか?フレームあたりのタイル数はどれくらいですか?どこでSpriteBatch.Beginと.Endを呼び出しますか? –

+0

それは間違いなくSpriteBatchの問題ですが、タイルの図面をスキップするだけですが、ロードの衝突などでは30fpsが得られます。これは、私が、上のカリング方法がまだスクリーンから外れていると思って、グラフィックを切り替えることが問題であると考えさせる。 – Cyral

+0

おそらくプロファイラを使用して、何が遅くなっているのかを正確に突き止めることができます。例:SlimTune; http://code.google.com/p/slimtune/ –

答えて

1

SpriteBatch.Beginを変更して、すべてのタイルを1つのテクスチャに結合して組み合わせるようにしてください。

GameDevの質問を参照してください。なぜ、あなたは最も遅い可能性が最も高いのでしょうか。

また、新しいテクスチャを描画するたびに、古いものをGPUから取り出して新しいものを入れなければならないことに気付きます。このプロセスはテクスチャスワッピングと呼ばれ、通常は問題はありませんが、テクスチャ性能に著しい影響を与える可能性のある1タイルにつき2回です。

これは、1つのテクスチャに複数のスプライトを組み合わせ、ソース矩形引数を使用することで修正できます。これにより、テクスチャスワップなしで複数のスプライトを描画することができます。これにはいくつかのOSSライブラリがあります。 Sprite Sheet Packerは私の個人的なお気に入りです。

残念ながらプロジェクトとプロファイラがなければ私はただ推測しています。しかし、これらは私が知っているタイルマップをレンダリングするための2つの大きな問題点です。私は本当にここから間違って何かを見ることができません。以下は私のタイルマップを描画するために使用するコードであり、あなたのものと非常によく似ています。

それ以外の場合は、プロファイラを使用して、どのビットがゆっくりと実行されているかを知ることをお勧めします。

 //Init the holder 
     _holder = new Rectangle(0, 0, TileWidth, TileHeight); 

     //Figure out the min and max tile indices to draw 
     var minX = Math.Max((int)Math.Floor((float)worldArea.Left/TileWidth), 0); 
     var maxX = Math.Min((int)Math.Ceiling((float)worldArea.Right/TileWidth), Width); 

     var minY = Math.Max((int)Math.Floor((float)worldArea.Top/TileHeight), 0); 
     var maxY = Math.Min((int)Math.Ceiling((float)worldArea.Bottom/TileHeight), Height); 

     for (var y = minY; y < maxY; y++) { 
      for (var x = minX; x < maxX; x++) { 

       _holder.X = x * TileWidth; 
       _holder.Y = y * TileHeight; 

       var t = tileLayer[y * Width + x]; 
       spriteBatch.Draw(
        t.Texture, 
        _holder, 
        t.SourceRectangle, 
        Color.White, 
        0, 
        Vector2.Zero, 
        t.SpriteEffects, 
        0); 
      } 
     } 
+0

スプライトシートが最も可能性が高い方法ですが、OPは単に遅延させるのではなく、SpriteSortMode.Textureを試すことができます。これは、テクスチャの切り替えを最小限に抑えるテクスチャによってすべてをソートします。 http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.graphics.spritesortmode.aspx –

+0

すぐにSpriteSheetsを実装しようとしていますが、別のものではなく1つのテクスチャで試してみました。ほんの数fpsだったので、私はそれが主な理由ではないことを知っています。 – Cyral

+1

ありがとうございます。SpriteSortMode.Textureを提案したことはお断りしています。オブジェクトや風景がある場合は、「オーバーラップしないスプライトを一様な深さで描画するときのパフォーマンスが向上します」が当てはまりません。タイルマップのレンダリングに役立つタイルをレンダリングするために別のスプライトバッチを使用するように強制しますが、NPCや風景を考慮して全体のフレームレートを損なうことになります。 – ClassicThunder

関連する問題