2011-01-29 81 views
6

我想使用XNA在屏幕上逐個像素繪製,但是我遇到了資源問題。我認爲最好的辦法是有1個紋理更新每一幀,但我無法更新它。這裏就是我這麼遠,只是作爲一個測試:如何在XNA中繪製2D像素?

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()中創建一個新的Texture2D,我很快就會發現內存不足的錯誤。這是用於Windows Phone的。看來我試圖以錯誤的方式去做,還有什麼其他選擇可以讓它發揮作用?

+0

我不知道答案,所以我搜索了「xna程序紋理」(這就是所謂的這種東西)。似乎沒有一種簡單的內置方式可以做到這一點。至少有三種常見建議(緩衝,GPU紋理命令,在着色器中執行)。最後一個顯然是最優的,但需要着色器編程知識。您可能想要執行相同的搜索並瀏覽那裏的內容。 – Tergiver 2011-01-29 15:45:25

回答

5

在調用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); 
} 
+0

GraphicsDevice.Textures [0] = null不起作用。 – Curyous 2011-01-30 04:57:33

3

你基本上需要做的,因爲它要求的例外:

爲了確保紋理沒有被設置在顯卡裝置,把這個在Draw末:

GraphicsDevice.Textures[0] = null; 

爲了確保你沒有鋪磚括號內畫,不要使用SetDataDraw。將呼叫轉移到SetDataUpdate


獎金信息:內存不足,你的錯誤是因爲你沒有釋放該Texture2D分配(垃圾收集器無法跟蹤他們的非託管資源,所以它不知道你在運行的記憶)。您需要在紋理上調用Dispose。然而,無論如何,創建新紋理每幀都是一個壞主意(無法避免它引起的性能和內存碎片問題)。