/// <summary> /// Runs the application. /// </summary> /// <param name="platform">Render system platform</param> /// <param name="pp">Parameters for backbuffer/window creation</param> public void Run(RenderSystemPlatform platform, PresentationParameters pp) { Init(platform, pp); //Create the timer for interpolation during Update() calls _timer = new GameTimer(); //Set the timer to the engine's data value map, so we can access Time,TimePerFrame,and PerFrame engine values for our shaders Engine.ValueMap.Timer = _timer; _timer.Start(); //Create and run the host _host.Idle += new Heartbeat(Loop); _host.Run(); }
/// <summary> /// Creates a host to run our application in and executes the "game loop" /// </summary> public void Run(RenderSystemPlatform platform, PresentationParameters pp) { //Tesla's core functionality is serviced based. A service is a module that provides access //to concrete implementation of engine objects. Common services are the render system, windowing, and input. They are //managed by the static "Engine" class, which serves as the primary point in the codebase to bring together all services. //The only service that is actually is needed to "Initialize" the engine is a render system, all others are optional. // //Since service providers are interfaces, you effectively de-couple their implementations from other services or code //that relies on them. Other than allowing for code to be cleanly separated into modules, this allows for the developer to mix-and-match //services. For example, if you're developing a Windows application, then you can use the SWFWindowProvider, WindowsKeyboardProvider, //and WindowsMouseProvider (which we use below) for your windowing/input needs. Then, different render systems such as OpenGL, D3D10, //or XNA can be used without any modification. // //This modularity allows the engine to expand in the future, to include new implementations for new platforms or allow //the developer to create their own specific implementations. Additionally, new services can be created such as joystick or //gamepad support, either as a third-party addition or integrated directly into the engine core. //The render system is the central service for the graphics engine. Initializing //the engine will create default graphics content/objects (such as the standard render states) Engine.Initialize(new Tesla.Direct3D10.Graphics.D3D10RenderSystemProvider()); //A window service provider allows us to setup native windows + the means to host them as an application. Engine.Services.AddService(typeof(IWindowProvider), new Tesla.Windows.Core.SWFWindowProvider()); //Input providers should be obvious (in this case, by registering a service provider we can use the Keyboard/Mouse static classes) Engine.Services.AddService(typeof(IKeyboardProvider), new Tesla.Windows.Input.WindowsKeyboardProvider()); Engine.Services.AddService(typeof(IMouseProvider), new Tesla.Windows.Input.WindowsMouseProvider()); //Get the renderer so we don't have to keep querying the render system (there is only ever one renderer, similar //to how there's only ever one Device in Direct3D) _renderer = Engine.Services.GetService <IRenderSystemProvider>().Renderer; //Setup your game window. Since it's set to primary window, a form will be created. Non-primary creates //a control that can be added to a a windows form app (e.g. editor and such) _window = new Window(pp, true); _window.AllowUserResizing = true; _window.IsMouseVisible = true; _window.Title = "Minimal Sample"; //Create a camera - if you resize the window, make sure you update your camera's viewport and projection! Camera camera = new Camera(new Viewport(0, 0, pp.BackBufferWidth, pp.BackBufferHeight)); camera.Position = new Vector3(0, 0, 100f); camera.SetProjection(45.0f, 1.0f, 30000.0f); camera.Update(); //Set the camera onto the renderer. This can be considered the "active" camera, which would //be used if you draw the scene graph (first there is a culling pass). Setting the current camera //also sets the viewport onto the device _renderer.CurrentCamera = camera; //To resize the camera we can add an event handler to the window. If we shrink/grow the window, //we need to reset the camera's viewport and projection too. _window.ClientSizeChanged += new EventHandler(delegate(Object sender, EventArgs args) { Rectangle rect = _window.ClientBounds; camera.Viewport = new Viewport(0, 0, rect.Width, rect.Height); camera.SetProjection(45.0f, 1.0f, 30000.0f); camera.Update(); //Set the viewport onto the renderer - if we set the renderer.CurrentCamera property, this would be taken care of too. _renderer.Viewport = camera.Viewport; }); //Create a content manager - this allows us to load & cache assets. Very similar to XNA's way of doing content loading. //Every renderer has a manager for default content (currently the shader library), for platform-specific content. //Content managers only have the binary/material loaders registered, and all others (image, model loaders) must be registered. //You can also use content managers to divide up your assets into logical groups, _content = new ContentManager(); //Load content LoadContent(); //Create and start the timer we'll use for update calls _timer = new GameTimer(); //Engine values are common properties such as the World-View-Projection matrices, the Camera, or the timer. You can //tell the material to query these values, which it will automatically every frame. The value map only needs 3 inputs: // // 1. World Matrix - Set your world matrix to it before calling properties that may require it (such as a World-View-Projection) // 2. Timer - Set your timer before calling timing properties (time per frame, fps, etc) // 3. Camera - Set your current camera before calling any camera related properties (such as World-View-Projection) // //When you set the camera to the renderer (renderer.CurrentCamera), #3 is automatically taken care of. The scenegraph takes //care of #1. When you setup your application, you have to set #2 yourself (as we do here). If you create your own mesh classes/scene graph, //be aware of #1. Engine.ValueMap.Timer = _timer; _timer.Start(); //Create a host for the window (only for primary windows), if you're familiar with Application.Run(), our SWF host is effectively that! _host = Engine.Services.GetService <IWindowProvider>().CreateWindowHost(_window); //The "game loop", which is called when the application is idle _host.Idle += new Heartbeat(Loop); //Run the app _host.Run(); //Ensure we dismiss the services and clean up the resources created, when we fall out of our loop. Engine.CleanUpResources(); }