Before a Urho3D application can enter its main loop, the Engine subsystem object must be created and initialized by calling its Initialize() function. Parameters sent in a VariantMap can be used to direct how the Engine initializes itself and the subsystems. One way to configure the parameters is to parse them from the command line like the Urho3DPlayer application does: this is accomplished by the helper function ParseParameters().

在urho3d引擎在执行主循环之前,引擎子系统实体必须被创建并且被初始化,初始化方法为调用Initialize(),初始化所需要的参数被封装于VariantMap类去说明引擎如何初始化自己和子系统,通过配置此参数(在项目属性中以命令行的方式)在引擎中解析,就像Urho3DPlayer那样做的一样,这个解析过程是由函数ParseParameters去负责的 (经验:配置参数格式为 -x= -y= ) 下面将有详细的描述

The full list of supported parameters, their datatypes and default values:

Headless (bool) Headless mode enable. Default false. LogLevel (int) Log verbosity level. Default LOG_INFO in release builds and LOG_DEBUG in debug builds. LogQuiet (bool) Log quiet mode, ie. to not write warning/info/debug log entries into standard output. Default false. LogName (string) Log filename. Default “Urho3D.log”. FrameLimiter (bool) Whether to cap maximum framerate to 200 (desktop) or 60 (Android/iOS.) Default true. WorkerThreads (bool) Whether to create worker threads for the WorkQueue subsystem according to available CPU cores. Default true. ResourcePaths (string) A semicolon-separated list of resource paths to use. If corresponding packages (ie. Data.pak for Data directory) exist they will be used instead. Default “Data;CoreData”. ResourcePackages (string) A semicolon-separated list of resource packages to use. Default empty. AutoloadPaths (string) A semicolon-separated list of autoload paths to use. Any resource packages and subdirectories inside an autoload path will be added to the resource system. Default “Extra”. ForceSM2 (bool) Whether to force Shader Model 2, effective in Direct3D9 mode only. Default false. ExternalWindow (void ptr) External window handle to use instead of creating an application window. Default null. WindowIcon (string) Window icon image resource name. Default empty (use application default icon.) WindowTitle (string) Window title. Default “Urho3D”. WindowWidth (int) Window horizontal dimension. Default 0 (use desktop resolution, or 1024 in windowed mode.) WindowHeight (int) Window vertical dimension. Default 0 (use desktop resolution, or 768 in windowed mode.) WindowPositionX (int) Window horizontal position. Default center to screen. WindowPositionY (int) Window vertical position. Default center to screen. WindowResizable (bool) Whether window is resizable. Default false. FullScreen (bool) Whether to create a full-screen window. Default true. Borderless (bool) Whether to create the window as borderless. Default false. TripleBuffer (bool) Whether to use triple-buffering. Default false. VSync (bool) Whether to wait for vertical sync when presenting rendering window contents. Default false. FlushGPU (bool) Whether to flush GPU command buffer each frame for less input latency. Effective only on Direct3D9. Default false. Multisample (int) Hardware multisampling level. Default 1 (no multisampling.) Orientations (string) Space-separated list of allowed orientations. Effective only on iOS. All possible values are “LandscapeLeft”, “LandscapeRight”, “Portrait” and “PortraitUpsideDown”. Default “LandscapeLeft LandscapeRight”. DumpShaders (string) Filename to dump used shader variations to for precaching. RenderPath (string) Default renderpath resource name. Default empty, which causes forward rendering (Bin/CoreData/RenderPaths/Forward.xml) to be used. Shadows (bool) Shadow rendering enable. Default true. LowQualityShadows (bool) Low-quality (1 sample) shadow mode. Default false. MaterialQuality (int) Material quality level. Default 2 (high) TextureQuality (int) Texture quality level. Default 2 (high) TextureFilterMode (int) Texture default filter mode. Default 2 (trilinear) TextureAnisotropy (int) Texture anisotropy level. Default 4. This has only effect for anisotropically filtered textures. Sound (bool) Sound enable. Default true. SoundBuffer (int) Sound buffer length in milliseconds. Default 100. SoundMixRate (int) Sound output frequency in Hz. Default 44100. SoundStereo (bool) Stereo sound output mode. Default true. SoundInterpolation (bool) Interpolated sound output mode to improve quality. Default true. TouchEmulation (bool) Touch emulation on desktop platform. Default false. Main loop iteration The main loop iteration (also called a frame) is driven by the Engine. In contrast it is the program’s (for example Urho3DPlayer) responsibility to continuously loop this iteration by calling RunFrame(). This function calls in turn the Time subsystem’s BeginFrame() and EndFrame() functions, and sends various update events in between. The event order is:

E_BEGINFRAME: signals the beginning of the new frame. Input and Network react to this to check for operating system window messages and arrived network packets. E_UPDATE: application-wide logic update event. By default each update-enabled Scene reacts to this and triggers the scene update (more on this below.) E_POSTUPDATE: application-wide logic post-update event. The UI subsystem updates its logic here. E_RENDERUPDATE: Renderer updates its viewports here to prepare for rendering, and the UI generates render commands necessary to render the user interface. E_POSTRENDERUPDATE: by default nothing hooks to this. This can be used to implement logic that requires the rendering views to be up-to-date, for example to do accurate raycasts. Scenes may not be modified at this point; especially scene objects may not be deleted or crashes may occur. E_ENDFRAME: signals the end of the frame. Before this, rendering the frame and measuring the next frame’s timestep will have occurred. The update of each Scene causes further events to be sent:

E_SCENEUPDATE: variable timestep scene update. This is a good place to implement any scene logic that does not need to happen at a fixed step. E_SCENESUBSYSTEMUPDATE: update scene-wide subsystems. Currently only the PhysicsWorld component listens to this, which causes it to step the physics simulation and send the following two events for each simulation step: E_PHYSICSPRESTEP: called before the simulation iteration. Happens at a fixed rate (the physics FPS.) If fixed timestep logic updates are needed, this is a good event to listen to. E_PHYSICSPOSTSTEP: called after the simulation iteration. Happens at the same rate as E_PHYSICSPRESTEP. E_SMOOTHINGUPDATE: update SmoothedTransform components in network client scenes. E_SCENEPOSTUPDATE: variable timestep scene post-update. ParticleEmitter and AnimationController update themselves as a response to this event. Variable timestep logic updates are preferable to fixed timestep, because they are only executed once per frame. In contrast, if the rendering framerate is low, several physics simulation steps will be performed on each frame to keep up the apparent passage of time, and if this also causes a lot of logic code to be executed for each step, the program may bog down further if the CPU can not handle the load. Note that the Engine’s minimum FPS, by default 10, sets a hard cap for the timestep to prevent spiraling down to a complete halt; if exceeded, animation and physics will instead appear to slow down.

Main loop and the application activation state The application window’s state (has input focus, minimized or not) can be queried from the Input subsystem. It can also effect the main loop in the following ways:

Rendering is always skipped when the window is minimized. To avoid spinning the CPU and GPU unnecessarily, it is possible to define a smaller maximum FPS when no input focus. See SetMaxInactiveFps() It is also possible to automatically pause update events and audio when the window is minimized. Use SetPauseMinimized() to control this behaviour. By default it is not enabled on desktop, and enabled on mobile devices (Android and iOS.) For singleplayer games this is recommended to avoid unwanted progression while away from the program. However in a multiplayer game this should not be used, as the missing scene updates would likely desync the client with the server. On mobile devices the window becoming minimized can mean that it will never become maximized again, in case the OS decides it needs to free memory and kills your program. Therefore you should listen for the E_INPUTFOCUS event from the Input subsystem and immediately save your program state as applicable if the program loses input focus or is minimized. On mobile devices it is also unsafe to access or create any graphics resources while the window is minimized (as the graphics context may be destroyed during this time); doing so can crash the program. It is recommended to leave the pause-minimized feature on to ensure you do not have to check for this in your update code. Note that on iOS calling Exit() is a no-op as there is no officially sanctioned way to manually exit your program. On Android it will cause the activity to manually exit.

Application framework The Application class provides a minimal framework for a Urho3D C++ application with a main loop. It has virtual functions Setup(), Start() and Stop() which can be defined by the application subclass. The header file also provides a macro for defining a program entry point, which will instantiate the Context object and then the user-specified application class. A minimal example, which would just display a blank rendering window and exit by pressing ESC:

include “Application.h”

include “Engine.h”

include “InputEvents.h”

class MyApp : public Application { public: MyApp(Context* context) : Application(context) { } virtual void Setup() { // Called before engine initialization. engineParameters_ member variable can be modified here } virtual void Start() { // Called after engine initialization. Setup application & subscribe to events here SubscribeToEvent(E_KEYDOWN, HANDLER(MyApp, HandleKeyDown)); } virtual void Stop() { // Perform optional cleanup after main loop has terminated }

  1. void HandleKeyDown(StringHash eventType, VariantMap& eventData)
  2. {
  3. using namespace KeyDown;
  4. // Check for pressing ESC. Note the engine_ member variable for convenience access to the Engine object
  5. int key = eventData[P_KEY].GetInt();
  6. if (key == KEY_ESC)
  7. engine_->Exit();
  8. }

}; DEFINE_APPLICATION_MAIN(MyApp)