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系统中无法运行!