## UE游戏、渲染线程

· ☕ 3 分钟 · 👻 Victor

# 游戏线程 & 渲染线程

## UE4游戏线程启动

Lauch.cpp定义了一个全局的变量FEngineLoop GEngineLoop;

  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145  /** * Implements the main engine loop. */ class FEngineLoop #if WITH_ENGINE : public IEngineLoop #endif { public: /** Default constructor. */ FEngineLoop(); virtual ~FEngineLoop() { } public: /** * Pre-Initialize the main loop, and generates the commandline from standard ArgC/ArgV from main(). * * @param ArgC The number of strings in ArgV. * @param ArgV The command line parameters (ArgV[0] is expected to be the executable name). * @param AdditionalCommandLine Optional string to append to the command line (after ArgV is put together). * @return Returns the error level, 0 if successful and > 0 if there were errors. */ int32 PreInit(int32 ArgC, TCHAR* ArgV[], const TCHAR* AdditionalCommandline = nullptr); /** * Pre-Initialize the main loop - parse command line, sets up GIsEditor, etc. * * @param CmdLine The command line. * @return The error level; 0 if successful, > 0 if there were errors. */ int32 PreInit(const TCHAR* CmdLine); /** First part of PreInit. */ int32 PreInitPreStartupScreen(const TCHAR* CmdLine); /** Second part of PreInit. */ int32 PreInitPostStartupScreen(const TCHAR* CmdLine); /** Load all modules needed before Init. */ void LoadPreInitModules(); /** Load core modules. */ bool LoadCoreModules(); /** Clean up PreInit context. */ void CleanupPreInitContext(); #if WITH_ENGINE /** Load all core modules needed at startup time. */ bool LoadStartupCoreModules(); /** Load all modules needed at startup time. */ bool LoadStartupModules(); /** * Initialize the main loop (the rest of the initialization). * * @return The error level; 0 if successful, > 0 if there were errors. */ virtual int32 Init() override; /** Initialize the timing options from the command line. */ void InitTime(); /** Performs shut down. */ void Exit(); /** Whether the engine should operate in an idle mode that uses no CPU or GPU time. */ bool ShouldUseIdleMode() const; // Advances the main loop.推进主循环 virtual void Tick() override; /** Removes references to any objects pending cleanup by deleting them. */ virtual void ClearPendingCleanupObjects() override; #endif // WITH_ENGINE /** RHI post-init initialization */ static void PostInitRHI(); /** Pre-init HMD device (if necessary). */ static void PreInitHMDDevice(); public: /** Initializes the application. */ static bool AppInit(); /** * Prepares the application for shutdown. * * This function is called from within guarded exit code, only during non-error exits. */ static void AppPreExit(); /** * Shuts down the application. * * This function called outside guarded exit code, during all exits (including error exits). */ static void AppExit(); private: /** Utility function that processes Slate operations. */ void ProcessLocalPlayerSlateOperations() const; protected: /** Holds a dynamically expanding array of frame times in milliseconds (if FApp::IsBenchmarking() is set). */ TArray FrameTimes; /** Holds the total time spent ticking engine. */ double TotalTickTime; /** Holds the maximum number of seconds engine should be ticked. */ double MaxTickTime; /** Holds the maximum number of frames to render in benchmarking mode. */ uint64 MaxFrameCounter; /** Holds the number of cycles in the last frame. */ uint32 LastFrameCycles; #if WITH_ENGINE /** Holds the objects which need to be cleaned up when the rendering thread finishes the previous frame. */ FPendingCleanupObjects* PendingCleanupObjects; #endif //WITH_ENGINE private: #if WITH_ENGINE /** Holds the engine service. */ FEngineService* EngineService; /** Holds the application session service. */ TSharedPtr SessionService; #endif // WITH_ENGINE FPreInitContext PreInitContext; }; 

 1 2 3 4 5 6 7 8 9  /** Public interface to FEngineLoop so we can call it from editor or editor code */ class IEngineLoop { public: virtual int32 Init() = 0; virtual void Tick() = 0; /** Removes references to any objects pending cleanup by deleting them. */ virtual void ClearPendingCleanupObjects() = 0; }; 

 1 2 3 4 5 6  /* Inits the engine loop */ int32 EngineInit() { int32 ErrorLevel = GEngineLoop.Init(); return( ErrorLevel ); } 

GEngineLoop.Init()函数：

  1 2 3 4 5 6 7 8 9 10  /** * Shuts down the engine */ void EngineExit( void ) { // Make sure this is set RequestEngineExit(TEXT("EngineExit() was called")); GEngineLoop.Exit(); } 

Launch.cpp中的函数多次使用GEngine这个外部变量，这个变量在上面的初始化函数会自定设置为相应的引擎，即Game引擎或者Editor引擎：

FEngineLoop::Tick()函数会调用GEngine的Tick函数：

Victor
Full Stack