原文出處:http://blogs.msdn.com/shawnhar/archive/2006/11/07/build-it-ahead-of-time.aspx
One of the biggest differences between the XNA content pipeline and the way many people are used to loading their game assets is that with the content pipeline, games no longer read directly from standard asset formats like .X, .BMP, and .FX. Instead, we process those files into a specialized binary format at the same time as compiling your game code.
The idea of processing assets during the build will be familiar to anyone who has worked on a console game, but may come as a surprise to people from a Windows background. There are actually several reasons why this is a good idea:
- Windows has a very rich programming environment with many helper programs and libraries that can be useful for loading and converting asset files. Most of these libraries are not available on Xbox, so the only way to get access to them is to pre-process the assets on a Windows machine.
- Game consoles only have limited amounts of RAM, and no virtual memory. Asset processing can need a lot of temporary memory, so it makes sense to run this on Windows during the build process.
- Converting game assets into a format that is ready to render can take a long time. If we did this work while loading the asset, it would slow down load times for everyone who plays the game. By moving processing operations to the build process, the developer only has to process the content once, after which it can be loaded nice and quickly for everyone who plays the game.
- By processing assets during the build, we can throw away any data that is not actually required by the game. This minimizes the size of the final game distributable.
- The more processing work is done during the build, the more errors can be reported up front, rather than only being spotted as a runtime crash when you later try to load that content.
But what if you need to convert content yourself, outside of XNA Game Studio Express? For instance what if you want to use the content pipeline in a level editor, or to convert user provided assets so that modders can extend your game?
You're in luck, because all the content pipeline build functionality is exposed as an MSBuild task. I won't go into details about MSBuild here (you can find more about it on MSDN, or using Google), other than to explain that MSBuild runs tasks as described by XML project files. In fact the .csproj files that you load into Game Studio Express are just a special kind of MSBuild project.
So to manually build content, you simply have to generate an MSBuild project that invokes the content pipeline, run it using MSBuild, and then load in the compiled .xnb files that will have been created for you.
Here is an example MSBuild project that uses the content pipeline to build a single file called MyTexture.tga:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<UsingTask TaskName="BuildContent" AssemblyName="Microsoft.Xna.Framework.Content.Pipeline, Version=1.0.0.0, Culture=neutral, PublicKeyToken=6d5c3888ef60e27d" />
<PropertyGroup>
<XnaInstall>C:/Program Files/Microsoft XNA/XNA Game Studio Express/v1.0/References/Windows/x86</XnaInstall>
</PropertyGroup>
<ItemGroup>
<PipelineAssembly Include="$(XnaInstall)/Microsoft.Xna.Framework.Content.Pipeline.TextureImporter.dll" />
</ItemGroup>
<ItemGroup>
<Content Include="MyTexture.tga">
<Importer>TextureImporter</Importer>
<Processor>SpriteTextureProcessor</Processor>
</Content>
</ItemGroup>
<Target Name="Build">
<BuildContent SourceAssets="@(Content)" PipelineAssemblies="@(PipelineAssembly)" TargetPlatform="Windows" />
</Target>
</Project>
If you save this XML into a file called test.proj, you can then run this from the commandline by invoking "msbuild test.proj".
XNA資源管線中同大多數人載入遊戲資源的方法有一個重要的差異:在資源管線中,遊戲不再直接從不同格式的資源檔如.x,.BMP,.fx直接讀取。相反,我們編譯遊戲代碼的同時就將各種資源檔編譯成特定的二進位格式。
這種產生期處理資源的做法對於任何有過控制台遊戲開發經驗的人來說都是很熟悉的,但是Windows背景的同志們可能會感到驚訝。這樣做的好處主要有:1.Windows具有豐富的編程環境,許多工具軟體和庫,可以方便地載入和轉換資源檔。而大多數這些庫在XBOX上都是沒有的,因此使用它們的唯一的辦法是在Windows系統上預先處理好。
2.遊戲控制台具有相對小的記憶體,並且沒有虛擬記憶體。資源處理往往需要大量的臨時記憶體消耗,因此最好先在Windows系統上建立好。
3.將遊戲資源轉換到用於渲染的資源的過程可能需要很長的時間,如果我們在載入資源時做這樣的轉換,將使得每個玩家的遊戲載入速度變慢。通過將處理操作轉移到產生時,只需要開發人員一次性處理,每個玩家都可以很快地載入這些資源。
4.通過產生時處理資源,我們可以丟棄任何遊戲中實際不需要的資料。因此可以最小化發布包。
5.提前處理意味著提前發現錯誤,可以盡量減少運行時載入資源發生的故障。然而,如果你確實需要在XNAGameStudio之外自己來轉換格式該怎麼辦呢?比如你需要在關卡設計器中使用XNA資源管線,或者需要載入使用者自訂資源時?
你的運氣不錯,因為所有的資源管線產生功能都被暴露為一個MSBuild任務。這裡我就不詳細介紹MSBuild了(詳情請詢問MSDN,或者Google)。只需要知道,MSBuild運行通過XML工程檔案描述的任務。
實際上,你載入到GameStudioExpress中的.csproj檔案就是一種MSBuild工程。
因此,為了手動產生資源,你只需要建立一個調用資源管線的MSBuild工程檔案,運行MSBuild建立出.xnb,然後載入這個檔案。這裡有個MSBuild工程檔案的例子,它使用資源管線載入一個檔案ZhengTuLogin.bmp:<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<UsingTask TaskName="BuildContent" AssemblyName="Microsoft.Xna.Framework.Content.Pipeline, Version=當前Xna版本號碼, Culture=neutral, PublicKeyToken=6d5c3888ef60e27d" />
<PropertyGroup>
<XnaInstall>Xna開發包安裝路徑</XnaInstall>
</PropertyGroup>
<ItemGroup>
<PipelineAssembly Include="$(XnaInstall)/Microsoft.Xna.Framework.Content.Pipeline.TextureImporter.dll" />
</ItemGroup>
<ItemGroup>
<Content Include="ZhengTuLogin.bmp"(使用時換成你的檔案名稱)>
<Importer>TextureImporter</Importer>
<Processor>SpriteTextureProcessor</Processor>
</Content>
</ItemGroup>
<Target Name="Build">
<BuildContent SourceAssets="@(Content)" PipelineAssemblies="@(PipelineAssembly)" TargetPlatform="Windows" />
</Target>
</Project>
這段XML儲存成test.proj檔案,就可以通過命令列調用"msbuild test.proj"來運行它。使用時需要稍微注意一下msbuild工具的路徑問題,一般預設路徑為 系統硬碟:/WINDOWS/Microsoft.NET/Framework/(某個版本) ,需要事先cd到這個路徑下,系統才可以識別msbuild指令。如下為運行:ZhengTuLogin.bmp編譯之後的ZhengTuLogin%0.xnb會自動產生到相對的bin目錄下,而無需藉助事先構建好的Xna工程項目。