[英]How to draw 2D pixel-by-pixel in XNA?
我正在嘗試使用 XNA 在屏幕上逐個像素地繪制,但是遇到了資源問題。 我認為最好的方法是讓 1 個紋理更新每一幀,但我無法更新它。 這是我到目前為止所得到的,只是作為一個測試:
Texture2D canvas;
Rectangle tracedSize;
UInt32[] pixels;
protected override void Initialize()
{
tracedSize = GraphicsDevice.PresentationParameters.Bounds;
canvas = new Texture2D(GraphicsDevice, tracedSize.Width, tracedSize.Height, false, SurfaceFormat.Color);
pixels = new UInt32[tracedSize.Width * tracedSize.Height];
base.Initialize();
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
pixels[100] = 0xFF00FF00;
canvas.SetData<UInt32>(pixels, 0, tracedSize.Width * tracedSize.Height);
spriteBatch.Begin();
spriteBatch.Draw(canvas, new Rectangle(0, 0, tracedSize.Width, tracedSize.Height), Color.White);
spriteBatch.End();
base.Draw(gameTime);
}
第二次調用 Draw() 時,出現以下錯誤:
“操作已中止。您不能修改已在設備上設置的資源,或在平鋪括號內使用后的資源。”
如果我嘗試在 Draw() 中創建一個新的 Texture2D,我很快就會遇到內存不足的錯誤。 這適用於 Windows Phone。 似乎我正在嘗試以錯誤的方式進行操作,我還需要哪些其他選項才能使其正常工作?
在調用SetData之前,請嘗試設置GraphicsDevice.Textures[0] = null
。 根據您之后可能有更高效的方法的效果,您還可以考慮Silverlight WriteableBitmap。
編輯:這是我在模擬器中測試的代碼:
Texture2D canvas;
Rectangle tracedSize;
UInt32[] pixels;
protected override void Initialize()
{
tracedSize = GraphicsDevice.PresentationParameters.Bounds;
canvas = new Texture2D(GraphicsDevice, tracedSize.Width, tracedSize.Height, false, SurfaceFormat.Color);
pixels = new UInt32[tracedSize.Width * tracedSize.Height];
base.Initialize();
}
Random rnd = new Random();
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
GraphicsDevice.Textures[0] = null;
pixels[rnd.Next(pixels.Length)] = 0xFF00FF00;
canvas.SetData<UInt32>(pixels, 0, tracedSize.Width * tracedSize.Height);
spriteBatch.Begin();
spriteBatch.Draw(canvas, new Rectangle(0, 0, tracedSize.Width, tracedSize.Height), Color.White);
spriteBatch.End();
base.Draw(gameTime);
}
您基本上需要按照異常中的要求執行操作:
要確保未在圖形設備上設置紋理,請將其放在Draw
的末尾:
GraphicsDevice.Textures[0] = null;
為確保您沒有在平鋪括號內Draw
,請不要在Draw
中使用SetData
。 將調用SetData
移動到Update
。
獎勵信息:您的內存不足錯誤是因為您沒有釋放Texture2D
分配的非托管資源(垃圾收集器無法跟蹤它們,因此它不知道您的內存不足)。 您需要在紋理上調用Dispose
。 然而,無論如何在每個幀中創建一個新的紋理是一個壞主意(沒有辦法避免它導致的性能和內存碎片問題)。
永遠不要在Draw()
** 中創建或修改紋理。**
SpriteBatch.Draw() 調用期望 GraphicsDevice 緩沖區包含所有紋理數據(通過擴展到 GPU 緩沖區),此時仍在發生的任何更改(來自 Update 和 IsRunningSlowly == true)將導致渲染時撕裂。
GraphicsDevice.Textures[0] = null;
的解決方法GraphicsDevice.Textures[0] = null;
阻塞 Draw 調用和游戲直到傳輸到 GPU 完成,從而減慢整個游戲循環。
重用在類級別聲明的 Texure2D 對象。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.