Silverlight Toolkit (December 2011)的新功能
原文地址:Silverlight Toolkit (December 2011) for Silverlight 5–What’s new?(http://blogs.msdn.com/b/eternalcoding/archive/2011/12/10/silverlight-toolkit-september-2011-for-silverlight-5-what-s-new.aspx?PageIndex=4)。
用于Silverlight 5的新版本Silverlight Toolkit (December 2011) 已经发布,你可以在http://silverlight.codeplex.com/releases/view/78435下载。
更新:Babylon Engine现在也使用了了Silverlight 5 Toolkit::http://code.msdn.microsoft.com/Babylon-3D-engine-f0404ace。
这篇文章帮助你发现这个Toolkit是如何通过下述功能增强Silverlight 5的:
- 使用Content Pipeline(素材管道)无缝整合3D模型和其他素材。
- 用于的新Visual Studio模板:
- a.创建Silverlight 3D应用程序
- b.Silverlight 3D类库
- c.Silverlight Effect
- 3.演示这些新功能的示例。
与Content Pipeline的无缝整合
这个新Toolkit带来了一个新组件:Microsoft.Xna.Framework.Content.dll。这个组件使你可以加载.xnb格式的素材(这些素材是由Content Pipeline创建的)。
使用新的Visual Studio模板(在后面会提到),你可以将已有的3D项目直接导入到Silverlight 5中!
Microsoft.Xna.Framework.Content.dll在Silverlight 5中添加了以下类:
- ContentManager
- Model
- SpriteFont和SpriteBatch
这个Toolkit还带来了Microsoft.Xna.Framework.Tookit.dll程序集,这个程序集在Silverlight 5中添加了以下类:
- SilverlightEffect
- Mouse, MouseState
- Keyboard,KeyboardState
ContentManager
这个类的文档地址为:
http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.content.contentmanager.aspx。
ContentManager类代表代码中的Content Pipeline,它用来从.xnb文件加载对象。
要创建一个ContentManager执行调用以下代码:
ContentManager contentManager = new ContentManager(null, "Content");
这个类有一些限制:用于Silverlight的ContentManager只支持一个Content项目,RootDirectory必须设置为“Content”。
使用这个类很简单,因为它提供了一个简单的Load方法创建对象:
// 加载字体 hudFont = contentManager.Load<spritefont>("Fonts/Hud"); // 加载纹理 winOverlay = contentManager.Load<Texture2D>("Overlays/you_win"); // 加载音乐 backgroundMusic = contentManager.Load<SoundEffect>("Sounds/Music");
模型Model类
这个类的文档的地址为:
http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.graphics.model.aspx。
Model类使用的API与在XNA 4中是一样的,通过这个类你可以从XNB文件加载并绘制3D模型:
// 绘制模型 Model tankModel = content.Load<Model>("tank"); tankModel.Draw();
如果模型支持bone也可以使用:
Model tankModel = content.Load<Model>("tank"); tankModel.Root.Transform = world; tankModel.CopyAbsoluteBoneTransformsTo(boneTransforms); // 绘制模型 foreach (ModelMesh mesh in tankModel.Meshes) { foreach (BasicEffect effect in mesh.Effects) { effect.World = boneTransforms[mesh.ParentBone.Index]; effect.View = view; effect.Projection = projection; effect.EnableDefaultLighting(); } mesh.Draw(); }
你可以导入.x或.fbx格式的模型:
使用FBX导入器,你也可以导入.3ds, .obj, .dxf和Collada。
SpriteFont和SpriteBatch
这些类的文档的地址为:
http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.graphics.spritebatch.aspx,
http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.graphics.spritefont.aspx。
SpriteBatch类用来在顶层显示2D纹理,用来显示UI或Sprite。
SpriteBatch spriteBatch = new SpriteBatch(graphicsDevice); spriteBatch.Begin(SpriteSortMode.Immediate,BlendState.Opaque); spriteBatch.Draw(texture, new Rectangle(0, 0, width, height),Color.White); spriteBatch.End();
从以上的代码可以看出SpriteBatch只需要指定一个纹理用于显示。
SpriteFont可以使用Sprite显示文字。
SpriteFont hudFont = contentManager.Load<SpriteFont>("Fonts/Hud"); spriteBatch.DrawString(hudFont, value, position + new Vector2(1.0f, 1.0f), Color.Black); spriteBatch.DrawString(hudFont, value, position, color);
SpriteFont的绘制依赖于SpriteBatch,而且需要在ContentManager中定义一个font:
SilverlightEffect
Toolkit还提供了一个叫做SilverlightEffect的新类用于处理.fx文件。
它还支持扩展名为.slfx的shader文件,.slfx和.fx并没有区别,但是因为XNA Effect Processor已经关联了.fx文件,所以Silverlight Content Pipeline只能选择另一个扩展名了。
你可以在Content项目中定义一个完整的effect,使用这个effect绘制模型。
步骤为:
- 创建一个至少包含一个technique的.fx文件
- Shader入口点必须是无参数的
- 定义渲染状态
例如下面是一个简单的.fx文件:
float4x4 WorldViewProjection; float4x4 World; float3 LightPosition; // 着色器输入输出结构 struct VS_INPUT { float4 position : POSITION; float3 normal : NORMAL; float4 color : COLOR0; }; struct VS_OUTPUT { float4 position : POSITION; float3 normalWorld : TEXCOORD0; float3 positionWorld : TEXCOORD1; float4 color : COLOR0; }; // 顶点着色器 VS_OUTPUT mainVS(VS_INPUT In) { VS_OUTPUT Out = (VS_OUTPUT)0; // 坐标转换 Out.position = mul(In.position, WorldViewProjection); // 计算世界空间中的法线 Out.normalWorld = mul(In.normal,(float3x3)WorldViewProjection); // 计算世界空间中的位置 Out.positionWorld = (mul(In.position, World)).xyz; // 直接传递顶点颜色 Out.color = In.color; return Out; } // 像素着色器 float4 mainPS(VS_OUTPUT In) : COLOR { // 光照方程 float3 lightDirectionW = normalize(LightPosition - In.positionWorld); float ndl = max(0, dot(In.normalWorld, lightDirectionW)); // 最终颜色 return float4(In.color.rgb * ndl, 1); } // Technique technique MainTechnique { pass P0 { VertexShader = compile vs_2_0 mainVS(); // 必须无参数 PixelShader = compile ps_2_0 mainPS(); // 必须无参数 } }
Toolkit会在Content Pipeline中添加所需的处理器,为这个effect创建.xnb文件:
要使用这个effect,你必须在代码中实例化一个新SilverlightEffect对象:
mySilverlightEffect = scene.ContentManager.Load<Silverlighteffect>("CustomEffect");
然后你就可以访问effect的参数:
worldViewProjectionParameter = mySilverlightEffect.Parameters["WorldViewProjection"]; worldParameter = mySilverlightEffect.Parameters["World"]; lightPositionParameter = mySilverlightEffect.Parameters["LightPosition"];
使用effect绘制对象的代码与XNA4是一样的:
worldParameter.SetValue(Matrix.CreateTranslation(1, 1, 1)); ProjectionParameter.SetValue(WorldViewProjection); lightPositionParameter.SetValue(LightPosition); foreach (var pass in mySilverlightEffect.CurrentTechnique.Passes) { // Apply pass pass.Apply(); // 设置顶点缓冲和索引缓冲 graphicsDevice.SetVertexBuffer(vertexBuffer); graphicsDevice.Indices = indexBuffer; // 绘制primitives graphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList,0, 0, VerticesCount, 0, FaceCount); }
Texture2D, TextureCube和SoundEffect
Silverlight 5提供了Texture2D、TextureCube和SoundEffect类,使用Toolkit你可以从ContentManager加载这些类:
// 加载2D纹理 winOverlay = contentManager.Load<Texture2d>("Overlays/you_win"); // 音乐 backgroundMusic = contentManager.Load<SoundEffect>("Sounds/Music");
鼠标与键盘
为了更好地输出已经存在的3D项目,Toolkit中还添加了对Microsoft.Xna.Framework.Input命名空间的部分支持。
这样就可以在想要的任何地方调用MouseState和KeyboardState:
public MainPage() { InitializeComponent(); Mouse.RootControl = this; Keyboard.RootControl = this; }
但是与原始的XNA有一点不同:你必须注册提供鼠标和键盘事件的根控件,MouseState位置是相对于这个控件的左上角位置的:
private void myDrawingSurface_Draw(object sender, DrawEventArgs e) { // 绘制场景 scene.Draw(); // 刷新 e.InvalidateSurface(); // 获取鼠标和键盘状态 MouseState mouseState = Mouse.GetState(); KeyboardState keyboardState = Keyboard.GetState(); ... }
MouseState和KeyboardState类似于XNA中的版本:
http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.input.mousestate.aspx,
http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.input.keyboardstate.aspx。
扩展
Silverlight Content Pipeline可以使用与XNA Content相同的方式进行扩展。你可以提供自己的实现方式实现从其他地方加载素材,而默认情况是加载内嵌的.xnb文件。
例如,你可以写一个类从网络加载.xnb文件流,要实现以上功能,你必须从inherit继承,提供自己的OpenStream实现:
public class MyContentManager : ContentManager { public MyContentManager() : base(null) { } protected override System.IO.Stream OpenStream(string assetName) { return base.OpenStream(assetName); } }
你也可以编写自己的type reader,以下代码是用于SilverlightEffect的自定义type reader:
/// <summary> /// 读取SilverlightEffect. /// </summary> public class SilverlightEffectReader : ContentTypeReader<Silverlighteffect> { /// <summary> /// 读取并创建一个SilverlightEffect /// </summary> protected override SilverlightEffect Read(ContentReader input, SilverlightEffect existingInstance) { int techniquesCount = input.ReadInt32(); EffectTechnique[] techniques = new EffectTechnique[techniquesCount]; for (int techniqueIndex = 0; techniqueIndex < techniquesCount; techniqueIndex++) { int passesCount = input.ReadInt32(); EffectPass[] passes = new EffectPass[passesCount]; for (int passIndex = 0; passIndex < passesCount;passIndex++) { string passName = input.ReadString(); // 顶点着色器 int vertexShaderByteCodeLength = input.ReadInt32(); byte[] vertexShaderByteCode = input.ReadBytes(vertexShaderByteCodeLength); int vertexShaderParametersLength = input.ReadInt32(); byte[] vertexShaderParameters = input.ReadBytes(vertexShaderParametersLength); // 像素着色器 int pixelShaderByteCodeLength = input.ReadInt32(); byte[] pixelShaderByteCode = input.ReadBytes(pixelShaderByteCodeLength); int pixelShaderParametersLength = input.ReadInt32(); byte[] pixelShaderParameters = input.ReadBytes(pixelShaderParametersLength); MemoryStream vertexShaderCodeStream = new MemoryStream(vertexShaderByteCode); MemoryStream pixelShaderCodeStream = new MemoryStream(pixelShaderByteCode); MemoryStream vertexShaderParametersStream = new MemoryStream(vertexShaderParameters); MemoryStream pixelShaderParametersStream = new MemoryStream(pixelShaderParameters); // 实例化pass SilverlightEffectPass currentPass = new SilverlightEffectPass(passName, Manager.Current.GraphicsDevice,vertexShaderCodeStream, pixelShaderCodeStream, vertexShaderParametersStream, pixelShaderParametersStream); passes[passIndex] = currentPass; vertexShaderCodeStream.Dispose(); pixelShaderCodeStream.Dispose(); vertexShaderParametersStream.Dispose(); pixelShaderParametersStream.Dispose(); // 渲染状态 int renderStatesCount = input.ReadInt32(); for (int renderStateIndex = 0; renderStateIndex < renderStatesCount; renderStateIndex++) { currentPass.AppendState(input.ReadString(),input.ReadString()); } } // 实例化technique techniques[techniqueIndex] = new EffectTechnique(passes); } return new SilverlightEffect(techniques); } }
新的Visual Studio模板
Toolkit会安装两个新的项目模板和一个新item模板:
Silverlight3DApp
这个模板会创建一个完整的可工作的Silverlight 3D应用程序。
这个新解决方案由四个项目组成:
- Silverlight3Dapp:主项目
- Silverlight3DappContent:关联到主项目的content项目
- Silverlight3Dweb:显示主项目的网站
- Silverlight3DwebContent:关联到网站的content项目,当你想不使用内嵌的.xnb素材而是从网站读取.xnb文件流时需要用到这个项目,这样做可以让你发布一个较小的.xap文件。
主项目(Silverlight3Dapp)创建了两个对象:
- 一个scene对象用于
- 创建ContentManager
- 处理DrawingSurface的Draw事件
- 一个cube对象用于
- 创建一个顶点缓冲和索引缓冲
- 使用ContentManager从content项目读取SilverlightEffect(Customeffect.slfx)
- 配置并使用SilverlightEffect进行绘制
Silverlight3DLib
这个模板创建一个不包含content但包含Microsoft.Xna.Framework引用的Silverlight库:
项目的结构如下图所示:
SilverlightEffect
这个item模板在Content项目中使用,它可以添加一个自定义的.slfx文件,与SilverlightEffect类协同工作:
文件的内容如下:
float4x4 World; float4x4 View; float4x4 Projection; // TODO: add effect parameters here. struct VertexShaderInput { float4 Position : POSITION0; // TODO: add input channels such as texture // coordinates and vertex colors here. }; struct VertexShaderOutput { float4 Position : POSITION0; // TODO: add vertex shader outputs such as colors and texture // coordinates here. These values will automatically be interpolated // over the triangle, and provided as input to your pixel shader. }; VertexShaderOutput VertexShaderFunction(VertexShaderInput input) { VertexShaderOutput output; float4 worldPosition = mul(input.Position, World); float4 viewPosition = mul(worldPosition,View); output.Position = mul(viewPosition, Projection); // TODO: add your vertex shader code here. return output; } float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0 { // TODO: add your pixel shader code here. return float4(1, 0, 0, 1); } technique Technique1 { pass Pass1 { // TODO: set renderstates here. VertexShader = compile vs_2_0 VertexShaderFunction(); PixelShader = compile ps_2_0 PixelShaderFunction(); } }
演示新功能的新示例
最后,为了帮你学习这些新功能,我们添加了一些很酷的示例:
Bloom
这个示例介绍了如何使用sprite实现“bloom”后期处理效果,它还使用了Content Pipeline从一个.fbx文件导入了一个坦克模型。
CustomModelEffect(自定义模型Effect)
这个示例介绍了如何使用Content Pipeline 在模型上施加自定义effect。
Generated geometry(生成几何体)
这个示例介绍了如何在Content Pipeline生成过程中使用代码创建3D模型。
Particles(粒子)
这个示例介绍了粒子系统的概念,如何使用SpriteBatch绘制粒子效果。示例中有两个粒子效果:爆炸和烟雾:
Primitives3D(3D图元)
这个例子介绍了如何重用代码绘制基本几何图元:
Platformer(平台游戏)
这个例子介绍了一个具有3个关卡的完整游戏(你也可以很容易地添加自己的关卡)。展示了在一个平台游戏中的SpriteBatch,SpriteFont和SoundEffect的用法,还使用了键盘类控制玩家。
SimpleAnimation(简单动画)
这个示例介绍了如何在一个3D模型上实现刚体动画:
Skinning(蒙皮动画模型)
这个例子介绍了如何使用Content Pipeline处理并绘制一个蒙皮动画模型。
文件下载(已下载 7298 次)
发布时间:2012/1/5 下午4:29:41 阅读次数:11902