2011-01-29 34 views
6

XNA kullanarak pixel-pixel ekranını çizmeye çalışıyorum, ancak kaynaklarla ilgili sorun yaşıyorum. Her çerçeveyi güncelleyen 1 dokuya sahip olmanın en iyi yolunun olacağını düşündüm, ancak güncellemede sorun yaşıyorum. Burada sadece bir test olarak, bugüne kadar bu var: Draw() ikinci kez denir XNA'da 2D piksel piksel nasıl çizilir?

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); 
    } 

, aşağıdaki hatayı alıyorum

.

"işlemi iptal edildi Şunları yapamazsınız Bir cihazda ayarlanmış bir kaynağı veya bir döşeme braketinde kullanıldığında değiştiriniz. "

Draw() uygulamasında yeni bir Texture2D oluşturmaya çalışırsam, hızlı bir şekilde bellek yetersizliği alırım. Bu Windows Phone için. Yanlış şekilde yapmaya çalışıyorum gibi görünüyor, çalışmasını sağlamak için başka seçeneklerim var mı?

+0

Cevabı bilemedim, bu yüzden "xna usulü doku" (bende bu tür bir şey denilen şey). Bunu yapmak için basit, yerleşik bir yol yok gibi görünüyor. En az üç ortak öneri var (arabellek, GPU doku komutları, bunu gölgelendiricide yapıyor). Sonuncusu açıkça en uygun olanıdır, ancak gölgelendirici programlama bilgisi gerektirir. Aynı aramayı yapmak ve orada olanlara göz atmak isteyebilirsiniz. – Tergiver

cevap

5

SetData'yı çağırmadan önce GraphicsDevice.Textures[0] = null ayarlamayı deneyin. Sonradan daha etkili bir yöntem olabileceğine bağlı olarak Silverlights WriteableBitmap'ı da düşünebilirsiniz.

Düzenleme: Bu benim emülatörü test kod şudur:

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 çalışmıyor. – Curyous

+0

Çok teşekkürler, senin örneğinden çalıştım. İlk kez denediğimi düşünüyorum, Draw() 'da bir Texture2D'yi yeniliyor olabilirim. – Curyous

3
Temelde bu istisna içinde sorar olarak yapmanız gereken

:

doku grafik üzerinde ayarlı değil emin olmak için ,

GraphicsDevice.Textures[0] = null; 

bir döşeme parantez içine çizim olmadığından emin olmak için içeride SetData kullanmayın: cihaz, Draw sonunda bu koymak Draw'un hepsi. Aramayı SetData numaralı telefona Update'a taşıyın.


Bonus bilgi: Eğer azalıyor bilmiyor böylece, Texture2D ayırır (çöp toplayıcı onları izleyemez yönetilmeyen kaynakları serbest değildir çünkü dışı hafızasında hatadır bellek). Doku üzerinde Dispose numaralı telefonu aramanız gerekiyor. Ancak yeni bir doku oluşturmak her bir çerçeve için kötü bir fikirdir (bunun neden olduğu performans ve bellek parçalanması sorunlarından kaçınmanın bir yolu yoktur).