Tam XNA GS içermeyen bir makinedeki bir dosyayı dışa aktarmak için XNA ContentPipeline kullanma


9

Oyunum, çalışma zamanında spriteSheet'i yüklemek için Content Pipeline'ı kullanıyor. Oyunun sanatçısı bana değiştirilmiş grafik sayfasını gönderiyor ve makinemde bir yapı yapıyorum ve ona güncellenmiş bir proje gönderiyorum. Bu yüzden tam XNA Oyun stüdyosunu kurmak zorunda kalmadan makinesinde xnb dosyalarını oluşturmanın bir yolunu arıyorum (bu, içerik hattının çıktısıdır).

1) Sanatçımın VS + Xna'yı yüklemesini istemiyorum (VS'nin ücretsiz bir sürümü olduğunu biliyorum, ancak ekibe daha fazla kişi eklediğimizde bu ölçeklenmeyecek). 2) Bu düzenleyiciyi / aracı Xbox'ta çalıştırmakla ilgilenmiyorum, bu yüzden sadece Windows çözümü çalışıyor. 3) MSBuild seçeneklerinin farkındayım ama tam XNA gerektiriyorlar

Ben Shawn blog araştırılmış ve Msbuild kullanma seçeneği bulunan Numune veya vaat görünüyordu XNA 4.0 yeni bir seçenek burada ama aynı kısıtlama var gibi görünüyor: ContentPipeline XNA Redist bir parçası değildir, çünkü tam XNA GS yüklemeniz gerekir.

Herkes bunun için bir çözüm buldu mu?

Yanıtlar:


11

Bunun doğru cevabı ContentPipeline'ı atlamak ve dokuları çalışma zamanında yüklemek için Texture2D.FromStream kullanmaktır. Bu yöntem bir PC'de iyi çalışıyor ve küçük bir performans isabeti olsa da, çıkış tarihine yaklaştıktan sonra optimize edebileceğim bir şey. Şimdilik, hem editör hem de oyun için içeriği dinamik olarak değiştirme yeteneğine sahip olmak tam olarak ihtiyacım olan şey. İçerik donduğunda, bunu ContentPipeline'a giderek optimize edebilirim.

Bu rotayı seçtiğiniz için sizi sadece Texture2D.FromStreamiki nedenden dolayı kullanmak kadar basit olmadığı konusunda uyarmalıyım :

Sorun # 1 - Önceden çarpılmış alfa desteğinin olmaması

XNA4 artık varsayılan olarak renkler ile önceden çarpılmış alfa formatında dokular işliyor. İçerik kanalından bir doku yüklediğinizde, bu işlem sizin için otomatik olarak yapılır. Ne yazık ki Texture2D.FromStreamaynı şeyi yapmaz, bu nedenle bir miktar şeffaflık gerektiren dokular yanlış yüklenir ve işlenir. Aşağıda sorunu göstermek için bir ekran görüntüsü verilmiştir:

resim açıklamasını buraya girin

Bu yüzden doğru sonuçları elde etmek için işlemi kendiniz yapmanız gerekir. Göstereceğim yöntem, işlemi yapmak için GPU'yu kullanır, bu yüzden oldukça hızlıdır. Bu harika makaleye dayanıyordu . Tabii ki SpriteBatcheski NonPremultiplyAlpha modunda da oluşturma talimatı verebilirsiniz ama bunu gerçekten tavsiye etmiyorum.

Sorun # 2 - Desteklenmeyen biçimler

İçerik ardışık düzeninden daha fazla format desteklenir Texture2D.FromStream. Özellikle, Texture2D.FromStreamyalnızca png, jpg ve gif'i destekler. Öte yandan, içerik boru hattı bmp, dds, dib, hdr, jpg, pfm, png, ppm ve tga'yı destekler. Üzerinden usuported bir format yüklemeye çalışırsanız, ek bilgilerle Texture2D.FromStreambir alırsınız InvalidOperationException.

Motorumda gerçekten bmp desteğine ihtiyacım vardı, bu nedenle bu durumda iyi çalışıyor gibi görünen bir geçici çözüm buldum. Diğer formatlardan hiçbirini bilmiyorum. Benim yöntemim ile yakalamak System.Drawing, projenize derleme bir referans eklemeniz gerektiğidir , çünkü Image.FromStreamdaha fazla formatı destekleyen GDI'ları kullanır Texture2D.FromStream.

Eğer bmp'yi desteklemeyi umursamıyorsanız, çözümümün bu kısmını kolayca bırakabilir ve sadece önceden çoğaltılmış alfa işlemini yapabilirsiniz.

Çözüm - Basit Sürüm (Daha Yavaş)

Her şeyden önce, bmp'leri desteklemeyi umursamıyorsanız en basit çözüm. Bu örnekte, işleme aşaması tamamen CPU üzerinde yapılır. Aşağıda göstereceğim alternatiften biraz daha yavaş (her iki çözümü de kıyasladım) ama anlaşılması daha kolay:

public static Texture2D FromStream(GraphicsDevice graphicsDevice, Stream stream)
{
    Texture2D texture = Texture2D.FromStream(graphicsDevice, stream);
    Color[] data = new Color[texture.Width * texture.Height];
    texture.GetData(data);
    for (int i = 0; i != data.Length; ++i)
        data[i] = Color.FromNonPremultiplied(data[i].ToVector4());
    texture.SetData(data);
    return texture;
}

Eğer bmp'leri önemsiyorsanız, yapmanız gereken şey önce görüntüyü GDI ile yüklemek ve daha sonra onu geçmeden önce dahili olarak PNG'ye dönüştürmektir Texture2D.FromStream. İşte bunu yapan kod:

// Load image using GDI because Texture2D.FromStream doesn't support BMP
using (Image image = Image.FromStream(stream))
{
    // Now create a MemoryStream which will be passed to Texture2D after converting to PNG internally
    using (MemoryStream ms = new MemoryStream())
    {
        image.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
        ms.Seek(0, SeekOrigin.Begin);
        texture = Texture2D.FromStream(_graphicsDevice, ms);
    }
}

Çözüm - Karmaşık Sürüm (Daha Hızlı)

Son olarak, projelerimde kullandığım yaklaşım, işlem yapmak için GPU'yu kullanmaktır. Bu yöntemde bir oluşturma hedefi oluşturmanız, bazı karışım durumlarını doğru şekilde ayarlamanız ve görüntüyü bir SpriteBatch ile iki kez çizmeniz gerekir. Sonunda tüm RenderTarget2D üzerinden gidiyorum ve içeriği ayrı bir Texture2D nesnesine klonluyorum çünkü RenderTarget2D uçucudur ve backbuffer boyutunu değiştirmek gibi şeylerden hayatta kalamaz, böylece bir kopya yapmak daha güvenlidir.

Komik olan şey, tüm bunlarla bile, testlerimde bu yaklaşımın CPU yaklaşımından yaklaşık 3 kat daha hızlı gerçekleşmesidir. Bu yüzden, her bir pikselin üzerinden geçip rengi kendiniz hesaplamaktan kesinlikle daha hızlıdır. Kod biraz uzun, bu yüzden bir çöp kutusuna yerleştirilir:

http://pastie.org/3651642

Bu sınıfı projenize eklemeniz ve aşağıdaki kadar basit bir şekilde kullanmanız yeterlidir:

TextureLoader textureLoader = new TextureLoader(GraphicsDevice);
Texture2D texture = textureLoader.FromFile("Content/texture.png");

Not: TextureLoaderTüm oyun için sadece bir örnek oluşturmanız gerekir . Ayrıca BMP düzeltmesini kullanıyorum, ancak bir demet performansa ihtiyacınız yoksa veya sadece needsBmpparametreyi yanlış olarak bırakırsanız çıkarabilirsiniz .


vay, bu harika! Bana çok yardımcı olacak :) Çok teşekkürler David, bunu takdir ediyorum.
Mart'ta krolth

+1 Aslında, FromStreamtıpkı diğer örneğiniz gibi, 32 bit bitmap (png'ye kaydedilmiş) içeren bir bellek akışı ile kullanıyordum , ancak bu yöntem önceden çarpılmış bir doku oluşturmadı. Her rengin açıkça çarpılması hile yaptı, teşekkürler.
Groo

3

Çoğu takımın xnb değişikliklerini (aslında tüm değişiklikler, xnb dahil) svn sunucusuna (ücretsiz olarak kurulabilir) ve başkalarının (sanatçı vb.) Kendi çalışma kopyalarını güncellemesine izin vereceğini düşünüyorum.

Aslında bu, sanatçının orijinal (pre-xnb) sanatı kontrol edebilmesi için iyi bir mekanizma olacaktır. Bu konuda değişiklikler yapar, çalışma kopyasını günceller, oluşturur (işlemde xnb yapar), değişikliklerinizi yapar, çalışmanızın çalışma kopyasını günceller ve herkesin tüm değişiklikleri olur. (En son ham resminiz var, xnb (ler) i var.

Bu da çok iyi ölçekleniyor.


Yani bunun yapılabileceğini düşünmediğini mi söylüyorsun? Öneriniz XNB ve sprite sürüm kontrolü eklemek, bunu zaten yapıyoruz. Ama hoşuma gitmedi çünkü onlar için darboğazım. Animasyonları düzenlemeleri için zaten bir araç yazdım ve oyunda deneyebilirler. Ancak sprite sayfasında değişiklik yaparlarsa, görmeden önce onu inşa etmeyi beklemeliler. Tahmin edebileceğiniz gibi bir hata yaparlarsa tekrar yapmaları gerekir.
krolth

@krolth Sanatçılarınızın VS Express ve XNA'yı bir proje üzerinde çalışmaya hazır hale getirmenin bir parçası olarak alması büyük bir anlaşma mı? Bence bu noktada bir rehber yazma ve insanlara yardımcı olma geleneği, sanatçılar çalışmalarını motorda göremedikleri için şimdi kaybettiğiniz üretkenlikten çok daha ağır basacak. Süreci kolaylaştırmak için onlara bir .BAT dosyası verin ve IDE'yi açmak zorunda kalmadan her şeyi yeniden derlemek için çift tıklatabilirler. Ve eğer sadece OS X kullanıyorlarsa, zor bir bok. Oyun geliştiricisine hoş geldiniz. Spritelarını yapabilir ve bir sonraki taahhütlü XNB'leri bekleyebilirler.
michael.bartnett

o kadar büyük bir şey değil, sadece bir acı. Ama sanırım bunu yapmak zorunda kalacak. Yanıtlarınız / yorumlarınız için herkese teşekkürler!
krolth

1

Bunu araştırmaya devam ettim ve aynı soruya sahip birinin yararına göndereceğim.

Bunun doğru cevabı ContentPipeline'ı atlamak ve dokuları çalışma zamanında yüklemek için Texture2D.FromStream kullanmaktır . Bu yöntem bir bilgisayarda iyi çalışır ve küçük bir performans isabeti olsa da , çıkış tarihine yaklaştığımda optimize edebileceğim bir şey.

Şimdilik, hem editör hem de oyun için içeriği dinamik olarak değiştirme yeteneğine sahip olmak tam olarak ihtiyacım olan şey. İçerik donduğunda, bunu ContentPipeline'a giderek optimize edebilirim.


Bunu doğru bir şekilde test ettiniz mi? Texture2D.FromStreamKendi deneyimlerimden tek başına yeterli değil. Bunun nedeni, sürüm 4 XNA'nın çarpılmış alfa dokuları ile çalıştığı ve içerik boru hattı bu işlemeyi sizin için otomatik olarak hallettiği için, Texture2D.FromStreamşeffaflık ile sprite çizerken muhtemelen sorun yaşamanızdır. İsterseniz çalışan bir çözüm gönderebilirim.
David Gouveia

Ayrıca, içerik kanalı çalışırken dosyaların Texture2D.FromStreamyüklenmesini desteklemez .BMP. Bu, .BMPdaha önce herhangi bir varlık kullandıysanız ve sonra geçtiyseniz muhtemelen sizi attıracak bir şeydir Texture2D.FromStream. Ayrıca bu sınırlama için bir geçici çözüm var. Sadece devam edip postalayacağım.
David Gouveia

0

Bu projeye göz atın .

Sanatçınızın, varsayılan XNA içerik kanalının desteklediği hemen hemen her şeyden XNB oluşturmasına izin verecektir. XNA çerçevesi yeniden dağıtılabilir olsa da, sanatçının Visual Studio'ya ihtiyacı yoktur.


İşaretçi için teşekkürler. Kod bakıldığında, başvuru yaptığım Microsoft örneğinde bir değişiklik gibi görünüyor. Tam XNA Game Studio'nun kurulu olmasına bağlıdır (bkz. ContentBuilder.cs). Neden olmadığını düşünüyorsun?
krolth

Ben öyle düşünmüyorum. İçerik kanalını kullanmak istiyorsanız tam oyun stüdyosuna sahip olmalısınız. Ancak proje sanatçılarınızın Visual Studio'yu kullanmak zorunda kalmasını engelliyor. İçerik hattını yeniden yazmak için diğer alternatifler.
ClassicThunder
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.