一般情況下,做三維展示系統,模型都是在3DMax這樣的軟體中提前做好,然後再載入到系統中展示。XNA支援很多格式的模型,但和3Dmax對接的是FBX檔案。
XNA的底層的D3D,所以模型的渲染本質也是D3D的渲染。在比較新的D3D版本中就已經出現了類似於C語言道德GPU語言,當然這主要還是歸功於顯卡技術的發展。
現在GPU語言主要有三種一個是支援openGL的GLSL,還有一種是英偉達的CG語言,最後一種是微軟的基於D3D的HLSL語言。其中cg語言和HLSL本是一家,是英偉達和微軟合作的產物,但最後由於某種原因分道揚鑣。英偉達的就是cg了,微軟的就是HLSL,但兩者的用法和文法都很類似,甚至很多代碼都能運行。
如果我們使用的XNA的話,和微軟的其他技術一樣,支援HLSL比較好。我到現在還沒有找到XNA支援GC的例子,我想應該不支援吧。因為我看過一篇文章對比這三種GPU語言,說他沒有任何理由讓自己不用GC,cg語言是同時支援OpenGL和D3D的,既然GC那麼好的話,我看過的那麼多的XNA代碼都是用HLSL,這可能說明XNA是不支援GC的。
D3D渲染的本質就選渲染一個個的三角面,越來越多的三角面就組成了三角體,立方體,圓柱,圓球以及更複雜的地形,樹木,人,動物等。而渲染的的最終代碼就是GPU代碼,然後再選擇這些三角面時做了一些像光照,紋理等效果,最終呈現出惟妙惟肖的三維情境。
XNA提供了Model類和普通的三維渲染類。三維渲染類封裝了GPU代碼,讓開發人員可以快速方便的去渲染模型,而不是去寫GPU代碼。但XNA提供的這個類功能有限,如果要實現折射、反射、高光照射等效果,還的需要自己去單獨寫GPU代碼。
下面,我們就先看一下XNA中的定義吧。
代碼如下:
Model myModel = this.Content.Load<Model>(@"Content/Models/tank");
foreach (ModelMesh myMesh in myModel.Meshes)
{
Matrix myWorld = myMesh.ParentBone.Transform * Matrix.CreateScale (0.01f);
foreach (ModelMeshPart myModelMeshPart in myMesh.MeshParts)
{
BasicEffect myBasicEffect = myModelMeshPart.Effect as BasicEffect;
myBasicEffect.World = myWorld;
myBasicEffect.View = this.ActiveSence .Camera.View;
myBasicEffect.Projection = this.ActiveSence .Camera.Projection;
myBasicEffect.TextureEnabled = true;
myBasicEffect.CurrentTechnique.Passes[0].Apply();
this.GraphicsDevice.Indices = myModelMeshPart.IndexBuffer;
this.GraphicsDevice.SetVertexBuffer(myModelMeshPart.VertexBuffer);
this.GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList
, myModelMeshPart.VertexOffset, 0, myModelMeshPart.NumVertices
, myModelMeshPart.StartIndex, myModelMeshPart.PrimitiveCount);
}
}
其中Model就XNA中針對模型定義的類。BasicEffect是XNA中自訂的渲染類,對一般的GPU渲染進行了封裝。
運行效果如下: