2012-03-26 2 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를 얻습니다. 이것은 상단의 컬링 (culling) 방법이 여전히 화면에서 물건을 그리는 것으로 생각하고, 그래픽을 전환하는 것이 문제라고 생각하게합니다. – Cyral

+0

아마도 프로파일 러를 사용하여 느리게 진행되는 원인을 정확히 찾아 낼 수 있어야합니다. 예 : SlimTune; http://code.google.com/p/slimtune/ –

답변

1

SpriteBatch.Begin을 변경하여 모든 타일을 하나의 텍스처로 결합 해보십시오.

지연을 가장 가능성이 가장 빠른 옵션 인 이유에 대한 정보는 GameDev 질문 this을 참조하십시오.

또한 새로운 텍스처를 그릴 때마다 GPU에서 이전 텍스처를 가져 와서 새 텍스처를 넣어야한다는 것을 알고 있습니다.이 프로세스를 텍스처 교환이라고하며 일반적으로 문제는 아니지만 텍스처를 바꿔 쓰고 있습니다 성능에 눈에 띄게 영향을 줄 수있는 타일 당 두 번.

하나의 텍스처에 여러 개의 스프라이트를 결합하고 소스 사각형 인수를 사용하여 수정할 수 있습니다. 이렇게하면 텍스처 스왑없이 여러 스프라이트를 그릴 수 있습니다. 이를위한 몇 가지 OSS 라이브러리가 있습니다. Sprite Sheet Packer는 제 개인적인 즐겨 찾기입니다.

유감스럽게도 프로젝트 및 프로필러가 없으면 나는 단지 추측하고 있습니다. 그러나 이것들은 내가 아는 타일 맵을 렌더링하는 데있어 가장 큰 두 가지 결함이 있습니다. 나는 여기서 잘못된 것을 볼 수 없다. 아래는 타일 맵을 그릴 때 사용하는 코드이며, 매우 비슷합니다.

다른 모든 것이 실패 할 경우 프로파일 러를 사용하여 어떤 비트가 느리게 실행되는지 파악하는 것이 좋습니다.

 //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을 구현할 예정입니다.하지만 다른 텍스처 대신 하나의 텍스처 만 사용해 보았습니다. 겨우 몇 프레임에 불과했기 때문에 주된 이유는 아닙니다. – Cyral

+1

좋은 지적입니다. SpriteSortMode.Texture를 제안하지 않았습니다. 객체 또는 풍경이있는 경우 "균일하지 않은 스프라이트를 겹치지 않게 그리는 경우 성능이 향상 될 수 있습니다"는 사실이 없기 때문에 SpriteSortMode.Texture를 제안하지 않았습니다. 타일 ​​맵 렌더링 시간에 도움이되는 타일을 렌더링하는 데 별도의 스프라이트 배치를 사용해야하지만 NPC 및 풍경을 고려한 후 전반적인 fps가 손상됩니다. – ClassicThunder