• UE4 源码解析----引擎初始化流程


       在研究UE4的源码过程中着实不理解的地方有很多,今天给大家分享一下UE4引擎的初始化流程。

    一、引擎的函数入口

    C++的函数入口都是Main() 函数入口,UE4也是一样,Engine\Source\Runtime\Launch\Private

    Windows函数入口

     引擎入口函数为:GuardedMain

     二、引擎初始化的三个阶段

    UE4所有相关的代码都在游戏循环函数中,在Launch.cpp中,写了四个函数PreInit(),Init(),以及Tick(),实际的函数现是在GEngineLoop中FEngineLoop::PreInit(),FEngineLoop::Init(),以及FEngineLoop::Tick()。引擎先执行预初始化工作,在执行初始化工作,在执行Tick()函数,初始化一些渲染UI游戏逻辑等内容。

    1. int32 EnginePreInit( const TCHAR* CmdLine )
    2. {
    3. int32 ErrorLevel = GEngineLoop.PreInit( CmdLine );
    4. return( ErrorLevel );
    5. }
    6. /**
    7. * Inits the engine loop
    8. */
    9. int32 EngineInit()
    10. {
    11. int32 ErrorLevel = GEngineLoop.Init();
    12. return( ErrorLevel );
    13. }
    14. /**
    15. * Ticks the engine loop
    16. */
    17. void EngineTick( void )
    18. {
    19. GEngineLoop.Tick();
    20. }
    21. void EngineExit( void )
    22. {
    23. // Make sure this is set
    24. RequestEngineExit(TEXT("EngineExit() was called"));
    25. GEngineLoop.Exit();
    26. }

    引擎初始化过程 

    1. #if WITH_EDITOR
    2. if (GIsEditor)
    3. {
    4. ErrorLevel = EditorInit(GEngineLoop);
    5. }
    6. else
    7. #endif
    8. {
    9. ErrorLevel = EngineInit();
    10. }
    11. }
    12. double EngineInitializationTime = FPlatformTime::Seconds() - GStartTime;
    13. UE_LOG(LogLoad, Log, TEXT("(Engine Initialization) Total time: %.2f seconds"), EngineInitializationTime);
    14. #if WITH_EDITOR
    15. UE_LOG(LogLoad, Log, TEXT("(Engine Initialization) Total Blueprint compile time: %.2f seconds"), BlueprintCompileAndLoadTimerData.GetTime());
    16. #endif
    17. ACCUM_LOADTIME(TEXT("EngineInitialization"), EngineInitializationTime);
    18. BootTimingPoint("Tick loop starting");
    19. DumpBootTiming();
    20. while( !IsEngineExitRequested() )
    21. {
    22. EngineTick();
    23. }

     三、FEngineLoop::PreInit()函数

    PreInit有着大量的初始化工作:日志功能的启动,线程池的启动,加载了预初始相关的模块,应用程序层面的初始化(ini配置的缓冲的加载,TaskGraph的启动),RHI初始化,异步IO系统初始化,平台特征模块初始化,游戏物理的初始化,流管理初始化,Slate应用程序的创建,启动渲染线程,加载启动模块。

     四、FEngineLoop::Init()函数

    引擎的对象的构造,引擎的命令行控制字处理,时间初始化,引擎的具体初始化。它先会创建GEngine,然后创建GameInstance,然后创建WorldContext及UWorld,最后会创建游戏使用的viewport。

     五、FEngineLoop::Tick()函数

    开始帧(请求渲染线程的BeginFrame命令、更新时间以及处理最大更新率、更新FPS图表),重启延迟更新(请求渲染线程的ResetDeferredUpdates、消息泵,引擎的具体循环、Shader的异步编译处理),结束帧(请求渲染线程的EndFrame命令)

    逻辑线程先通过ENQUEUE_RENDER_COMMAND(UpdateScenePrimitives)函数调用渲染线程更新渲染数据。

    然后通过GEngine->Tick()更新游戏逻辑,其中也会更新物理相关的内容。

    然后调用RedrawViewports()函数进行上一帧的场景渲染,生成渲染命令。

    然后调用FSlateApplication::Get().Tick()函数更新UI相关内容。

    最后通过FrameEndSync.Sync函数阻塞逻辑线程直到上一帧的渲染线程执行完毕。也就是说逻辑线程和渲染线程是并行执行的,只不过它们之间相差一帧的内容。

  • 相关阅读:
    2014软专算法题T1
    学习appium必备的避坑指南
    OSI体系结构和TCP/IP体系结构
    uni-app:对数组对象进行以具体某一项的分类处理
    (五)JPA - 原生SQL实现增删改查
    Redis原理篇——内存回收
    Java之线程相关应用实现
    sklearn快速入门教程:处理连续型特征
    ESP32---logging库
    异常处理 android.os.NetworkOnMainThreadException
  • 原文地址:https://blog.csdn.net/qq_43021038/article/details/126661766