您當前的位置:首頁 > 舞蹈

Godot Engine 原始碼閱讀筆記:01 引擎的程式執行

作者:由 吳亮弟 發表于 舞蹈時間:2018-11-14

上一篇(Godot Engine 原始碼閱讀筆記:00 程式碼目錄結構)

01 目標

知曉 Godot Engine 的啟動流程

理解遊戲引擎的主迴圈(loop)

對比 Godot Engine 的主迴圈

GO:

知曉 Godot Engine 的啟動流程 (以 X11 平臺為參考)

Godot Engine 以根據不同的平臺(platform),在 /platform 中對應實現了程式的啟動入口,在 /core 中做了 OS 層面的抽象,在各自 platform 中會有對應的實現

在 /platform/x11/godot_x11。cpp 中有很簡單的 main 方法,如下:

int main(int argc, char *argv[]) {

OS_X11 os;

setlocale(LC_CTYPE, “”);

char *cwd = (char *)malloc(PATH_MAX);

char *ret = getcwd(cwd, PATH_MAX);

Error err = Main::setup(argv[0], argc - 1, &argv[1]);

if (err != OK) {

free(cwd);

return 255;

}

if (Main::start())

os。run(); // it is actually the OS that decides how to run

Main::cleanup();

if (ret)

chdir(cwd);

free(cwd);

return os。get_exit_code();

}

OSX11 繼承自 /drivers/unix/osunix。cpp, OSUNIX 繼承自 OS ,並且實現了通用的類 Unix 系統的介面,因此放在了 /drivers 目錄下

/main/main。cpp 中的 Main 類,是 Godot Engine 的生命週期管理物件,setup 對系統進行了引數解析並初始化操作, 包括引擎內部物件的建立,根據引數判斷是需要啟動 “專案管理器”,“編輯器”,“遊戲”,“場景”,“指令碼”等

setup 之後,osx/win/x11 平臺還有 需要執行 Main::setup2 這裡初始化了音訊/ARVR/物理引擎等各 Servers。

Main::start 在 setup 成功後執行,根據不同引數判斷系統所需的 MainLoop 物件

editor 的 MainLoop 為 SceneTree , UI 物件為: EditorNode

project_manager 的 MainLoop 為 SceneTree, UI 物件為:ProjectManager

如果是執行指令碼,則會根據指令碼建立對應的 MainLoop 物件

start 成功後,便呼叫 os。run() 進入引擎主迴圈。

主迴圈退出後,Main::cleanup 做好清場工作。

2。

理解遊戲引擎的主迴圈(loop)

現代遊戲引擎的主迴圈邏輯都大同小異,可參考 (Game Loop · Sequencing Patterns · Game Programming Patterns) , (deWiTTERS Game Loop)

一般遊戲的 MainLoop 做以下事情:

loop:

// 輸入處理

input_event_process()

// 更新遊戲邏輯,包括物理/音效/腳步等模組

update()

// 渲染

render()

FPS(每秒幀數),遊戲要執行流暢,必須要保證一定的 FPS ,所以在遊戲中,就會根據走過的時間來呼叫 loop 中的業務邏輯,通常也會將前後兩幀的時間差(delta) 作為引數傳入到其他模組的 update 中。

3。 對比 Godot Engine 的主迴圈

來到 os。run() 的實現中(OS_X11::run)

void OS_X11::run() {

force_quit = false;

if (!main_loop)

return;

main_loop->init();

//uint64_t last_ticks=get_ticks_usec();

//int frames=0;

//uint64_t frame=0;

while (!force_quit) {

process_xevents(); // get rid of pending events

#ifdef JOYDEV_ENABLED

joypad->process_joypads();

#endif

if (Main::iteration())

break;

};

main_loop->finish();

}

也是很簡潔,除了平臺相關的人機互動介面(滑鼠/鍵盤/觸控/遊戲手柄等)處理外,while 迴圈中,其他業務由 Main::iteration 完成

Main::iteration 和其他引擎的 loop 基本一致

Main::iteration

loop:

計算 fps

物理引擎 update

顯示引擎 draw update

指令碼引擎 frame process

音訊引擎 update

最後在 Main::cleanup 中做了各模組的記憶體清理工作。

標簽: main  Loop  引擎  Godot  Engine