2013-06-07 5 views
5

MonoGame을 사용하여 Linux로 XNA에서 만든 스크롤 슈팅 게임을 포팅했습니다. 거의 모든 것이 원활하게 진행되었지만 SpriteBatch.Draw()에 대한 호출로 특정 위치에 문제가있어 프레임 속도를 무력화합니다. 대부분의 게임은 딸꾹질없이 잘 돌아갑니다. 그것은 천천히 적의 좋은 수의 총알과 많은 총알을 한 번에 그립니다. 그러나 드롭 된 프레임의 원인이되는 부분은 계층화 된 스크롤 배경입니다. 코드의 관련 섹션은 여기에 있습니다.Monogame XNA 몇몇 Draw() 호출에서 낮은 프레임 수

Level.cs :

은 "scrollingBackground"
public void Draw(SpriteBatch spriteBatch) 
{ 
    foreach (ScrollingBackgroundLayer sbl in scrollingBackground) 
    { 
     sbl.Draw(spriteBatch); 
    } 
} 

위 ScrollingBackgroundLayers의 목록, 관련 부분은 어느 위치 :

ScrollingBackgroundLayers.cs :

Vector2[] scrollingBackgroundImages; 
public float DrawLayer; 

public ScrollingBackgroundLayer(GameScene newScene, Texture2D texture, float scrollSpeed, Color color) 
{ 
    layerColor = color; 
    layerSpeed = scrollSpeed; 
    layerTexture = texture; 
    thisScene = newScene; 

    Initialize(); 
} 

public void Initialize() 
{ 
    scrollingBackgroundImages = new Vector2[2]; 

    for (int i = 0; i < 2; i++) 
    { 
     scrollingBackgroundImages[i] = new Vector2(0, thisScene.ScreenArea.Height - (layerTexture.Height * i)); 
    } 
} 


public void Update(GameTime gameTime) 
{ 
    for (int i = 0; i < scrollingBackgroundImages.Length; i++) 
    { 
     scrollingBackgroundImages[i].Y += (float)gameTime.ElapsedGameTime.TotalSeconds * layerSpeed; 

     if (layerSpeed > 0 && scrollingBackgroundImages[i].Y >= thisScene.ScreenArea.Height) 
     { 
      scrollingBackgroundImages[i] = new Vector2(scrollingBackgroundImages[i].X, (scrollingBackgroundImages[i].Y - layerTexture.Height * 2)); 
     } 
     else if (layerSpeed < 0 && scrollingBackgroundImages[i].Y + layerTexture.Height <= 0) 
     { 
      scrollingBackgroundImages[i] = new Vector2(scrollingBackgroundImages[i].X, (scrollingBackgroundImages[i].Y + layerTexture.Height * 2)); 
     } 
    } 
} 

public void Draw(SpriteBatch spriteBatch) 
{ 
    foreach (Vector2 sb in scrollingBackgroundImages) 
    { 
     spriteBatch.Draw(layerTexture, sb, null, layerColor, 0f, Vector2.Zero, 1f, SpriteEffects.None, DrawLayer); 
    } 
} 

의 모든 ScrollingBackgroundLayer.Draw()에 대한 호출을 주석 처리하자마자 프레임 속도 문제가 사라지므로 문제는 S에서 발생한다는 것을 알 수 있습니다. priteBatch가 스크롤링 레이어를 그려 봅니다. 분명히, 나는 이것이 왜 일어나고 있는지를 알고 싶다. SpriteBatches에서 다른 문제를 조사한 결과 가장 일반적으로 발견 한 점은 텍스처가 변경 될 때마다 새로운 SpriteBatch가 만들어 지지만 SpriteSortMode를 텍스처로 설정해도 개선되지 않았다는 것입니다.

프레임 율의 감소는 설명하기 위해 더 이상 2 배 이하 이렇게해야 700 개 픽셀 폭 900 하이 (각 층 주위에 별도의 감촉을 그리는 각각 7 가지 ScollingBackgroundLayers을 가진 게임의 단계에서 발생 스크롤 효과). 게임에서 때로는 똑같은 과부하를 사용하여 2 ~ 3 백개의 총알을 렌더링하기 때문에 분명히 뭔가를 놓치고 있어야하는 것처럼 느껴지므로 다른 14 개의 통화가 양동이에 드롭되어야합니다. SpriteBatch가 효과적으로 처리하기에 너무 큰 텍스처를 그리는 데 문제가 있습니까? Windows 버전에서는 문제가되지 않으므로 플랫폼에 특정한 해결 방법이 없는지 아니면 MonoGame의 Draw 구현이 비효율적인지 궁금합니다. 모든 의견은 환영받을 것입니다. 관심있는 사람들을위한

전체 소스 :

리눅스 - https://github.com/cmark89/AsteroidRebuttal-Linux
윈도우 - https://github.com/cmark89/AsteroidRebuttal

편집 : 나는 좀 더 그것으로 땜질했습니다. 대상 직사각형이 화면의 드로어 블 영역과 같았 음을 확인하기 위해 Draw()에 대한 호출을 변경했지만 눈에 띄는 변경은 없었습니다. 텍스처를 아주 작은 텍스처로 바꾸어서 지연을 제거했기 때문에 텍스처의 크기와 관련이 있다고 생각합니다.

편집 2 : 좋아, 난 그냥 총알을 물고 (안-게으른 사람의 일종처럼) 내가 사용 된 투명 레이어를 절단 끝났다. 아마도 더 이상 쓸모없는 픽셀을 렌더링 할 필요가 없기 때문에이 문제를 해결할 수는 있지만, 이것이 왜 리눅스에서만 문제가되는지 궁금합니다. 나는 시간이되고 내 문제를 해결했다하더라도, 나는 단지의 경우 사람에 조금이 열린 상태로 두려면려고하면 과감한 성능 차이의 원인이 될 수 있는지에 대한 통찰력을 가지고있다.

이 상황에서
+1

다른 것들에 대한 성능 비용을 기억할 수는 없지만 GPU가 고해상도 텍스처를 많이 사용하도록 강요하는 것은 좋은 생각이 아니며 다른 방식으로 디자인 할 수 있어야합니다. 메모리가 올바르게 작동하면 이러한 텍스쳐는 GPU로 전송 될 때 1024 * 1024 텍스처 (2 요구 사항의 힘 및 런타임 동안 해당 크기로 다시 작성되기 때문에)가 될 것입니다. –

+0

이 경우의 문제는 배경의 각 이미지가 다른 속도로 스크롤되거나 다른 투명도를 갖습니다. 그 중 일부는 확실히 화면의 더 작은 부분을 그리는 레이어를 자르고 만들 수 있지만 그 중 일부 (대부분 투명 레이어)는 그렇게 쉽지 않습니다. 나는 GPU가 어쨌든 2 개의 텍스처가 아닌 힘의 크기가 조정되었음을 알지 못했다. 어쩌면 나는 그것들의 크기를 재조정하고 그것이 무엇인가를 바꿀 것인지 지켜 볼 것입니다. 최적화에 관계없이 제작을 조사 할 것이지만 Windows에서이 문제가 발생하지 않는 이유는 정말로 혼란 스럽습니다. – cmark89

답변

2

, 나는 당신이 이러한 목표를 달성하기 위해, 대신 셰이더를 사용하는 것이 좋습니다 것입니다. 이렇게하면 성과가 급증 할 것입니다.다음에서 살펴 보자 : CPU 사용량을 많이 완화됩니다, 이런 식으로 이렇게

http://www.david-gouveia.com/scrolling-textures-with-zoom-and-rotation/

하고 GPU를 만드는 것은 대부분의 작업을한다.

텍스처를 700x900 대신 2의 배수로 저장할 수도 있습니다. (512x512와 같은 것을하십시오). 그래픽 파이프 라인은 2의 거듭 제곱과 관련된 성능 향상을 제공합니다.

+0

나는 이것을 조사하고 있지만, 내가해야 할 일이 너무 많을 수도있다. 어쩌면 그것은 쉐이더들이 나를 두려워하기 때문일 수도 있습니다. 내가 이걸 시도 할 기회가 생기면 다시 연락 할게. – cmark89

+0

이것은 잔인한 것이 아니라 매우 간단하다는 것을 확신합니다. 이 작업을 수행하기 위해 쉐이더에 대해 알 필요조차 없습니다.) – jgallant

+0

간단한 작업을 사용 했으므로이 작업을 시도하지 않았지만 이것이 유일한 해결책이므로 마킹하고 있습니다. 허용 된대로 이펙트 파일을 작동시킬 수 있다면 정말 좋은 솔루션처럼 보일 것입니다. (사실, MonoGame의 현재 버전에서는 이것이 시도되지 않은 것입니다.) – cmark89