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 : 좋아, 난 그냥 총알을 물고 (안-게으른 사람의 일종처럼) 내가 사용 된 투명 레이어를 절단 끝났다. 아마도 더 이상 쓸모없는 픽셀을 렌더링 할 필요가 없기 때문에이 문제를 해결할 수는 있지만, 이것이 왜 리눅스에서만 문제가되는지 궁금합니다. 나는 시간이되고 내 문제를 해결했다하더라도, 나는 단지의 경우 사람에 조금이 열린 상태로 두려면려고하면 과감한 성능 차이의 원인이 될 수 있는지에 대한 통찰력을 가지고있다.
이 상황에서
다른 것들에 대한 성능 비용을 기억할 수는 없지만 GPU가 고해상도 텍스처를 많이 사용하도록 강요하는 것은 좋은 생각이 아니며 다른 방식으로 디자인 할 수 있어야합니다. 메모리가 올바르게 작동하면 이러한 텍스쳐는 GPU로 전송 될 때 1024 * 1024 텍스처 (2 요구 사항의 힘 및 런타임 동안 해당 크기로 다시 작성되기 때문에)가 될 것입니다. –
이 경우의 문제는 배경의 각 이미지가 다른 속도로 스크롤되거나 다른 투명도를 갖습니다. 그 중 일부는 확실히 화면의 더 작은 부분을 그리는 레이어를 자르고 만들 수 있지만 그 중 일부 (대부분 투명 레이어)는 그렇게 쉽지 않습니다. 나는 GPU가 어쨌든 2 개의 텍스처가 아닌 힘의 크기가 조정되었음을 알지 못했다. 어쩌면 나는 그것들의 크기를 재조정하고 그것이 무엇인가를 바꿀 것인지 지켜 볼 것입니다. 최적화에 관계없이 제작을 조사 할 것이지만 Windows에서이 문제가 발생하지 않는 이유는 정말로 혼란 스럽습니다. – cmark89