Axiom3D程序的基本渲染流程
1 #region Namespace Declarations
2
3 using System; 4 using System.Linq; 5 using Axiom.Core; 6 using Axiom.Framework.Configuration; 7 using Axiom.Graphics; 8 using Vector3 = Axiom.Math.Vector3; 9
10 #endregion Namespace Declarations
11
12 namespace Axiom.Framework 13 { 14 public abstract class Game : IDisposable, IWindowEventListener 15 { 16 protected Root Engine; 17 protected IConfigurationManager ConfigurationManager; 18 protected ResourceGroupManager Content; 19 protected SceneManager SceneManager; 20 protected Camera Camera; 21 protected Viewport Viewport; 22 protected RenderWindow Window; 23 protected Axiom.Graphics.RenderSystem RenderSystem; 24 protected SharpInputSystem.InputManager InputManager; 25 protected SharpInputSystem.Mouse mouse; 26 protected SharpInputSystem.Keyboard keyboard; 27
28 public virtual void Run() 29 { 30 PreInitialize(); 31 LoadConfiguration(); 32 Initialize(); 33 CreateRenderSystem(); 34 CreateRenderWindow(); 35 LoadContent(); 36 CreateSceneManager(); 37 CreateCamera(); 38 CreateViewports(); 39 CreateInput(); 40 CreateScene(); 41 this.Engine.StartRendering(); 42 } 43
44 private void PreInitialize() 45 { 46 this.ConfigurationManager = new DefaultConfigurationManager(); 47
48 // instantiate the Root singleton
49 this.Engine = new Root( this.ConfigurationManager.LogFilename ); 50
51 // add event handlers for frame events
52 this.Engine.FrameStarted += Engine_FrameRenderingQueued; 53 } 54
55 public virtual void LoadConfiguration() 56 { 57 this.ConfigurationManager.RestoreConfiguration( this.Engine ); 58 } 59
60
61 private void Engine_FrameRenderingQueued( object source, FrameEventArgs e ) 62 { 63 Update( e.TimeSinceLastFrame ); 64 } 65
66 public virtual void Initialize() 67 { 68 } 69
70 public virtual void CreateRenderSystem() 71 { 72 if ( this.Engine.RenderSystem == null ) 73 { 74 this.RenderSystem = this.Engine.RenderSystem = this.Engine.RenderSystems.First().Value; 75 } 76 else
77 { 78 this.RenderSystem = this.Engine.RenderSystem; 79 } 80 } 81
82 public virtual void CreateRenderWindow() 83 { 84 this.Window = Root.Instance.Initialize( true, "Axiom Framework Window" ); 85
86 WindowEventMonitor.Instance.RegisterListener( this.Window, this ); 87 } 88
89 public virtual void LoadContent() 90 { 91 ResourceGroupManager.Instance.InitializeAllResourceGroups(); 92 } 93
94 public virtual void CreateSceneManager() 95 { 96 // Get the SceneManager, a generic one by default
97 this.SceneManager = this.Engine.CreateSceneManager( "DefaultSceneManager", "GameSMInstance" ); 98 this.SceneManager.ClearScene(); 99 } 100
101 public virtual void CreateCamera() 102 { 103 // create a camera and initialize its position
104 this.Camera = this.SceneManager.CreateCamera( "MainCamera" ); 105 this.Camera.Position = new Vector3( 0, 0, 500 ); 106 this.Camera.LookAt( new Vector3( 0, 0, -300 ) ); 107
108 // set the near clipping plane to be very close
109 this.Camera.Near = 5; 110
111 this.Camera.AutoAspectRatio = true; 112 } 113
114 public virtual void CreateViewports() 115 { 116 // create a new viewport and set it's background color
117 this.Viewport = this.Window.AddViewport( this.Camera, 0, 0, 1.0f, 1.0f, 100 ); 118 this.Viewport.BackgroundColor = ColorEx.SteelBlue; 119 } 120
121 public virtual void CreateInput() 122 { 123 var pl = new SharpInputSystem.ParameterList(); 124 pl.Add( new SharpInputSystem.Parameter( "WINDOW", this.Window[ "WINDOW" ] ) ); 125
126 if ( this.RenderSystem.Name.Contains( "DirectX" ) ) 127 { 128 //Default mode is foreground exclusive..but, we want to show mouse - so nonexclusive
129 pl.Add( new SharpInputSystem.Parameter( "w32_mouse", "CLF_BACKGROUND" ) ); 130 pl.Add( new SharpInputSystem.Parameter( "w32_mouse", "CLF_NONEXCLUSIVE" ) ); 131 } 132
133 //This never returns null.. it will raise an exception on errors
134 this.InputManager = SharpInputSystem.InputManager.CreateInputSystem( pl ); 135 //mouse = InputManager.CreateInputObject<SharpInputSystem.Mouse>( true, "" ); 136 //keyboard = InputManager.CreateInputObject<SharpInputSystem.Keyboard>( true, "" );
137 } 138
139 public abstract void CreateScene(); 140
141 public virtual void Update( float timeSinceLastFrame ) 142 { 143 } 144
145 #region IDisposable Implementation
146
147 #region IsDisposed Property
148
149 /// <summary>
150 /// Determines if this instance has been disposed of already. 151 /// </summary>
152 public bool IsDisposed { get; set; } 153
154 #endregion IsDisposed Property
155
156 /// <summary>
157 /// Class level dispose method 158 /// </summary>
159 /// <remarks>
160 /// When implementing this method in an inherited class the following template should be used; 161 /// protected override void dispose( bool disposeManagedResources ) 162 /// { 163 /// if ( !IsDisposed ) 164 /// { 165 /// if ( disposeManagedResources ) 166 /// { 167 /// // Dispose managed resources. 168 /// } 169 ///
170 /// // If there are unmanaged resources to release, 171 /// // they need to be released here. 172 /// } 173 ///
174 /// // If it is available, make the call to the 175 /// // base class's Dispose(Boolean) method 176 /// base.dispose( disposeManagedResources ); 177 /// } 178 /// </remarks>
179 /// <param name="disposeManagedResources">True if Unmanaged resources should be released.</param>
180 protected virtual void dispose( bool disposeManagedResources ) 181 { 182 if ( !IsDisposed ) 183 { 184 if ( disposeManagedResources ) 185 { 186 if ( this.Engine != null ) 187 { 188 // remove event handlers
189 this.Engine.FrameStarted -= Engine_FrameRenderingQueued; 190 } 191 if ( this.SceneManager != null ) 192 { 193 this.SceneManager.RemoveAllCameras(); 194 } 195 this.Camera = null; 196 if ( Root.Instance != null ) 197 { 198 Root.Instance.RenderSystem.DetachRenderTarget( this.Window ); 199 } 200 if ( this.Window != null ) 201 { 202 WindowEventMonitor.Instance.UnregisterWindow( this.Window ); 203 this.Window.Dispose(); 204 } 205 if ( this.Engine != null ) 206 { 207 this.Engine.Dispose(); 208 } 209 } 210
211 // There are no unmanaged resources to release, but 212 // if we add them, they need to be released here.
213 } 214 IsDisposed = true; 215 } 216
217 /// <summary>
218 /// Call to when class is no longer needed 219 /// </summary>
220 public void Dispose() 221 { 222 dispose( true ); 223 GC.SuppressFinalize( this ); 224 } 225
226 ~Game() 227 { 228 dispose( false ); 229 } 230
231 #endregion IDisposable Implementation
232
233 #region IWindowEventListener Implementation
234
235 /// <summary>
236 /// Window has moved position 237 /// </summary>
238 /// <param name="rw">The RenderWindow which created this event</param>
239 public void WindowMoved( RenderWindow rw ) 240 { 241 } 242
243 /// <summary>
244 /// Window has resized 245 /// </summary>
246 /// <param name="rw">The RenderWindow which created this event</param>
247 public void WindowResized( RenderWindow rw ) 248 { 249 } 250
251 /// <summary>
252 /// Window has closed 253 /// </summary>
254 /// <param name="rw">The RenderWindow which created this event</param>
255 public void WindowClosed( RenderWindow rw ) 256 { 257 // Only do this for the Main Window
258 if ( rw == this.Window ) 259 { 260 Root.Instance.QueueEndRendering(); 261 } 262 } 263
264 /// <summary>
265 /// Window lost/regained the focus 266 /// </summary>
267 /// <param name="rw">The RenderWindow which created this event</param>
268 public void WindowFocusChange( RenderWindow rw ) 269 { 270 } 271
272 #endregion
273 } 274 }
查看Run()方法。
public virtual void Run()
{
PreInitialize();
LoadConfiguration();//加载配置
Initialize();
CreateRenderSystem();//创建渲染系统
CreateRenderWindow();//创建渲染窗体
LoadContent();
CreateSceneManager();//创建场景管理器
CreateCamera();//设置相机
CreateViewports();//设置视口
CreateInput();
CreateScene();//构建场景
this.Engine.StartRendering();//开始渲染
}
基本流程:实例化Root,加载配置文件,创建渲染系统,创建渲染窗体,创建场景管理器,设置相机,设置视口,构建场景,开始渲染流程。
新建C#项目,命名为AppAxiom,添加引用Axiom.Engine。
新建类MyGame,继承自Game,编写代码如下:
1 public class myGame : Game 2 { 3 public override void CreateScene() 4 { 5 6 SceneManager.SetSkyDome(true, "Examples/CloudySky", 5, 8); 7 SceneManager.AmbientLight = new ColorEx(0.3f, 0.3f, 0.3f); 8 SceneManager.CreateLight("ParticleSampleLight").Position = new Vector3(20, 80, 50); 9 10 Entity ogreHead = SceneManager.CreateEntity("OgreHead", "ogrehead.mesh"); 11 // Load muiltiple heads for box select and demonstrating single select with stacked objects 12 // create a scene node for each entity and attach the entity 13 SceneNode ogreHead1Node; 14 ogreHead1Node = SceneManager.RootSceneNode.CreateChildSceneNode("OgreHeadNode", Vector3.Zero, Quaternion.Identity); 15 ogreHead1Node.AttachObject(ogreHead); 16 17 SceneNode ogreHead2Node; 18 Entity ogreHead2 = SceneManager.CreateEntity("OgreHead2", "ogrehead.mesh"); 19 ogreHead2Node = SceneManager.RootSceneNode.CreateChildSceneNode("OgreHead2Node", new Vector3(-100, 0, 0), 20 Quaternion.Identity); 21 ogreHead2Node.AttachObject(ogreHead2); 22 23 SceneNode ogreHead3Node; 24 Entity ogreHead3 = SceneManager.CreateEntity("OgreHead3", "ogrehead.mesh"); 25 ogreHead3Node = SceneManager.RootSceneNode.CreateChildSceneNode("OgreHead3Node", new Vector3(+100, 0, 0), 26 Quaternion.Identity); 27 ogreHead3Node.AttachObject(ogreHead3); 28 29 } 30 public override void CreateCamera() 31 { 32 // create a camera and initialize its position 33 this.Camera = this.SceneManager.CreateCamera("MainCamera"); 34 this.Camera.Position = new Vector3(0, 0, 500); 35 this.Camera.LookAt(new Vector3(0, 0, 0)); 36 37 // set the near clipping plane to be very close 38 this.Camera.Near = 5; 39 this.Camera.AutoAspectRatio = true; 40 } 41 }
添加项目配置文件App.Config,内容如下:
1 <?xml version="1.0"?> 2 3 <configuration> 4 <configSections> 5 <section name="axiom" type="Axiom.Framework.Configuration.AxiomConfigurationSection, Axiom.Framework" /> 6 </configSections> 7 <startup useLegacyV2RuntimeActivationPolicy="true"> 8 <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0,Profile=Client" /> 9 </startup> 10 <axiom xmlns="http://www.axiom3d.net/schemas/configuration/v1.0"> 11 <resourceLocations> 12 <!-- Resource Group : Essential --> 13 <resourceLocation type="ZipFile" group="Essential" path="../../media/archives/SdkTrays.zip" recurse="false" /> 14 <resourceLocation type="Folder" group="Essential" path="../../media/thumbnails" recurse="false" /> 15 <resourceLocation type="Folder" group="Essential" path="../../media/icons" recurse="false" /> 16 17 <!-- Resource Group : Popular --> 18 <resourceLocation type="ZipFile" group="Popular" path="../../media/archives/cubemap.zip" recurse="false" /> 19 <resourceLocation type="ZipFile" group="Popular" path="../../media/archives/cubemapsjs.zip" recurse="false" /> 20 <!-- resourceLocation type="ZipFile" group="Popular" path="../../media/archives/dragon.zip" recurse="false" /--> 21 <!-- resourceLocation type="ZipFile" group="Popular" path="../../media/archives/fresneldemo.zip" recurse="false" /--> 22 <!-- resourceLocation type="ZipFile" group="Popular" path="../../media/archives/ogretestmap.zip" recurse="false" /--> 23 <resourceLocation type="ZipFile" group="Popular" path="../../media/archives/skybox.zip" recurse="false" /> 24 <resourceLocation type="ZipFile" group="Popular" path="../../media/archives/sinbad.zip" recurse="false" /> 25 <resourceLocation type="Folder" group="Popular" path="../../media/fonts" recurse="false" /> 26 <resourceLocation type="Folder" group="Popular" path="../../media/programs" recurse="false" /> 27 <resourceLocation type="Folder" group="Popular" path="../../media/materials" recurse="false" /> 28 <resourceLocation type="Folder" group="Popular" path="../../media/particles" recurse="false" /> 29 <resourceLocation type="Folder" group="Popular" path="../../media/textures" recurse="false" /> 30 <resourceLocation type="Folder" group="Popular" path="../../media/meshes" recurse="false" /> 31 <!-- resourceLocation type="Folder" group="Popular" path="../../media/deferredshadingmedia" recurse="false" / --> 32 <!-- resourceLocation type="Folder" group="Popular" path="../../media/pczappmedia" recurse="false" / --> 33 </resourceLocations> 34 <renderSystems> 35 <renderSystem name="Xna"> 36 <options> 37 <option name="Video Mode" value="1280 x 720 @ 32-bit color" /> 38 <option name="Full Screen" value="Yes" /> 39 <option name="VSync" value="No" /> 40 <option name="Anti aliasing" value="None" /> 41 <option name="Floating-point mode" value="Fastest" /> 42 <option name="Allow NVPerfHUD" value="No" /> 43 <option name="Save Generated Shaders" value="No" /> 44 <option name="Use Content Pipeline" value="No" /> 45 </options> 46 </renderSystem> 47 <renderSystem name="DirectX9"> 48 <options> 49 <option name="Video Mode" value="800 x 600 @ 32-bit colour" /> 50 <option name="Full Screen" value="No" /> 51 <option name="VSync" value="No" /> 52 <option name="Anti aliasing" value="None" /> 53 <option name="Floating-point mode" value="Fastest" /> 54 <option name="Allow NVPerfHUD" value="No" /> 55 </options> 56 </renderSystem> 57 <renderSystem name="OpenGL"> 58 <options> 59 <option name="Video Mode" value="1280 x 720" /> 60 <option name="Color Depth" value="32" /> 61 <option name="Display Frequency" value="N/A" /> 62 <option name="Full Screen" value="Yes" /> 63 <option name="FSAA" value="0" /> 64 <option name="VSync" value="No" /> 65 <option name="RTT Preferred Mode" value="FBO" /> 66 </options> 67 </renderSystem> 68 </renderSystems> 69 </axiom> 70 </configuration>
在Main方法下添加代码:
1 static void Main() 2 { 3 myGame my = new myGame(); 4 my.Run(); 5 }
将材质文件Material放在debug同一级目录下,将dll放在Debug目录下,运行效果如下。
奇怪的是同样的D3D、Vs配置在XP系统中无法运行!