五月天青色头像情侣网名,国产亚洲av片在线观看18女人,黑人巨茎大战俄罗斯美女,扒下她的小内裤打屁股

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

blender核心源碼部分之一

2023-07-26 11:24 作者:抓住小豬  | 我要投稿

如之前的文章所說,下面三個(gè)部分是blender中最核心的代碼,第一次記錄會(huì)比較零散。

source/blender

source/creator

source/tools



C語言的基礎(chǔ)

????????在閱讀源碼過程中,有大量的宏定義。這一些在代碼預(yù)編譯階段就做了展開,給我們debug增加了難度,但是便于參數(shù)調(diào)節(jié)、增加運(yùn)行效率等等。這一些優(yōu)勢(shì),反正我開始讀的時(shí)候是沒有感覺到的,希望之后可以感覺到。

????????簡(jiǎn)單介紹一下,最常用的宏定義的一些內(nèi)容。

1. 簡(jiǎn)單的可以分為帶參數(shù)、不帶參數(shù)的宏定義兩種。對(duì)于后者,比如

#define?PI?3.1415926

2. 我們把PI作為3.1415926的替代對(duì)象。對(duì)于前者,比如

#define?B(x,y)?x##y

3. 定義了B(x,y),提供類似函數(shù)的功能,但是在預(yù)編譯時(shí)而不是運(yùn)行時(shí),就做到把x和y鏈接起來。常用的有四種特殊符號(hào),#、##、#@、\

????????1.? #:?把#之后的內(nèi)容變成字符串;

????????2.? ##:將前后兩個(gè)對(duì)象拼接在一起,變成一個(gè);

????????3.? #@:將后面一個(gè)內(nèi)容,變成單個(gè)字符,類似于加上單引號(hào);

????????4.? \:?一行不夠,把下面一行內(nèi)容也作為#define的內(nèi)容

????????

????????第一次讀代碼,目前就想到哪里,就寫到哪里了;

????????我在使用中感覺到,需要Visual?Studio?和Visual?Studio?Code?配合,看源碼+調(diào)試會(huì)更方便。

主入口

????????從入口函數(shù)所在模塊開始?source/creator?里面內(nèi)容很少,從Visual?Studio的解決方案中也可以看到。

????????其中,buildinfo.c?這個(gè)文件,是在CMakeLists階段生成的。具體內(nèi)容如下所示,通過VSCode在整個(gè)項(xiàng)目中搜索關(guān)鍵字可以找到,在?build_files\cmake?中,將hash、date等內(nèi)容寫入到這個(gè)特殊c文件中。在編譯階段,這個(gè)c文件中的內(nèi)容就被讀取了。

下圖是cmake中的部分代碼

????????主入口函數(shù)在creator.c?中,這個(gè)文件不大,所以我們從頭開始看。

????????blender在各個(gè)文件都,都做了一些自己操作的封裝,比如像這種存粹是輸出字符串內(nèi)容到標(biāo)準(zhǔn)錯(cuò)誤通道的例子;


????????fflush是為了清buffer,保證之前內(nèi)容先輸出完。否則會(huì)出現(xiàn)多次輸出順序與調(diào)用順序不一致的問題。類似的一些函數(shù),我第一次遇到的就介紹一下,相似的就不做記錄了。


????????隨后遇到的新面孔是一個(gè)在blender中非常常見的結(jié)構(gòu):一個(gè)函數(shù)指針,或者一個(gè)宏定義,加上一個(gè)函數(shù)指針或者宏定義作為參數(shù)。沒有做宏展開或者具體看指針指向的函數(shù)要干嘛之前,這種結(jié)構(gòu)真的是讓源碼讀者很無奈。這邊我第一次遇到,就展開介紹下。

????????MEM_set_error_callback?是一個(gè)函數(shù)指針,指向一個(gè)返回值為void,入?yún)楹瘮?shù)指針的函數(shù)。顯然在blender中,這個(gè)指針直接指向了?MEM_lockfree_set_error_callback?。?而MEM_lockfree_set_error_callback很明顯是在某個(gè)private的地方定義的函數(shù)。

????????搜了一圈看到,MEM_lockfree_set_error_callback?的唯一作用,是把入?yún)⒌暮瘮?shù)指針,傳給一個(gè)內(nèi)部定義的函數(shù)指針。所以轉(zhuǎn)了一圈,經(jīng)過3個(gè)調(diào)用函數(shù),main_callback_setup的作用,就是使得在creator.c中定義的函數(shù)?callback_mem_error,?傳給內(nèi)部的error_callback。

????????乍一看,是肯定會(huì)疑惑就這么一個(gè)操作為什么需要這么多次的函數(shù)調(diào)用呢?可能的理由是,這種多模塊之間的接口調(diào)用,都需要通過模塊之間相互暴露接口、通過接口訪問來實(shí)現(xiàn),所以中間就有這一些步驟,很合理。


????????到了主函數(shù)中,拋開變量的定義,首先做的是注冊(cè)在blender還沒有加載完全時(shí)就退出這種情況下的資源釋放函數(shù)。從我的角度看,BKE_blender_atexit_register?就是做這件事情了。

????????隨后通過 CommandLineToArgvW(GetCommandLineW(),?&argc) 來獲取命令行參數(shù),并提供給argv。

????????這是WIN32的獲取命令行參數(shù)的方式,在其他OS中直接通過argv就可以拿到參數(shù)了。隨后有一些為了特殊模式做的特殊初始化,比如對(duì)于debug模式要做從無鎖分配器到完全保護(hù)分配器的切換(具體意義是什么并不清楚)。對(duì)于日志信息的初始化,也在這部分做,日志信息是目前看到在blender的context初始化之前,最后一個(gè)初始化的內(nèi)容。這個(gè)很合理,畢竟日志模塊需要記錄blender的上下文以及其他模塊的各種日志信息。

????????在blender中,有幾個(gè)特殊的全局變量,上下文context是其中一個(gè)。在整個(gè)源碼中,都用大寫字母C來表示,確實(shí)是很隨意。而在做context內(nèi)存分配時(shí)候,則使用了blender內(nèi)建的MEM_callocN。這個(gè)分配函數(shù)所在的模塊為?blender\intern\guardedalloc?。blender\intern?與?blender\source?同級(jí)。在blender中這種自定義的內(nèi)存分配隨處可見,目的在于做類似單例的實(shí)現(xiàn)。以MEM_callocN為例,入?yún)⒎謩e為待分配字節(jié)數(shù)量,以及一個(gè)靜態(tài)字符串。被分配的內(nèi)存與這個(gè)靜態(tài)字符串綁定。

????????在上下文創(chuàng)建之后,準(zhǔn)備開始做各個(gè)子模塊的初始化了。看起來比較有意思,比如最開始初始化,就首先找到當(dāng)前自己所在完整路徑。這一系列初始化,都使用了blender自定義的內(nèi)存分配函數(shù),構(gòu)建了一堆“內(nèi)存空間”-“靜態(tài)字符串”?的映射。這部分內(nèi)容相對(duì)比較繁雜,也沒有深入看的意義。可以認(rèn)為,幾乎所有與啟動(dòng)相關(guān)的、子系統(tǒng)相關(guān)的初始化,都在這邊執(zhí)行了。需要注意的是,如果是子模塊的初始化函數(shù)的話,子模塊內(nèi)部幾乎都還有一堆初始化要做。這塊我們先跳過。

????????在大量初始化之后,需要注冊(cè)程序退出時(shí)調(diào)用的回調(diào)函數(shù),以及在main最后做了一次是否為background執(zhí)行的判斷。一般的,對(duì)于background執(zhí)行方式,所有計(jì)算,都已經(jīng)在上述初始化之內(nèi),以及CPython中執(zhí)行完畢了,此時(shí)會(huì)直接退出。之所以能直接退出,是因?yàn)樗斜匾K初始化完成之后,background執(zhí)行的python腳本任務(wù),已經(jīng)在同步的CPython的執(zhí)行邏輯中,執(zhí)行完畢了。對(duì)于非后臺(tái)任務(wù)模式,需要以Editor模式來運(yùn)行(Editor模式相關(guān)的源碼,幾乎全部集中在??/source/blender/editors?目錄下,46+個(gè)模塊)。此時(shí)會(huì)進(jìn)入WM_Main(C)。?這個(gè)定義在?source\blender\windowmanager\intern\wm.c?中的函數(shù),才是正常我們看到的blender頁面的渲染循環(huán)的入口。

????????下圖是WM_Main的事件、渲染循環(huán)代碼,其中的邏輯,主要是為了做UI操作的監(jiān)聽,以及監(jiān)聽之后的事件觸發(fā),以及事件通知,渲染繪制更新。Blender的代碼嚴(yán)格遵循MVC模式。具體的,Model為Blender中實(shí)現(xiàn)的各種功能,View就是與用戶交互的界面,Controller就是接受用戶的交互并將需要的操作告訴Model,以及把Model計(jì)算結(jié)果反饋給View來展示給用戶。從循環(huán)中也可以看出來,Model的數(shù)據(jù)更新在前,View的更新在最后。

????????到此處為止,我們已經(jīng)把blender入口以及整個(gè)運(yùn)行tick部分的地方找到了,下面針對(duì)性查詢感興趣的模塊的源碼就行。

通過官方提供的文件夾結(jié)構(gòu)與說明,記錄以下我比較感興趣的一些模塊地址:

  1. Object級(jí)別的修改器;?

    1. /source/blender/modifiers/

    2. /intern/dualcon/

  2. 渲染模塊

    1. 底層渲染

      1. /source/blender/draw/

      2. /source/blender/render/

      3. ?/intern/cycles/

    2. 渲染在editor部分的節(jié)點(diǎn)交互

      1. /source/blender/editors/space_node/

      2. /source/blender/nodes/

    3. 渲染與editor的交互

      1. ?/source/blender/editors/render/

  3. UV Editing部分

    1. ?/source/blender/editors/uvedit/

  4. Mesh級(jí)別的Edit操作

    1. /source/blender/editors/mesh/


blender核心源碼部分之一的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
固阳县| 鞍山市| 抚顺市| 霍林郭勒市| 东乌珠穆沁旗| 扶余县| 伽师县| 云林县| 广丰县| 抚州市| 乌什县| 普安县| 连江县| 陵川县| 牟定县| 平潭县| 玉龙| 田东县| 奉节县| 尤溪县| 庐江县| 香格里拉县| 安乡县| 闽侯县| 苍溪县| 正阳县| 兴义市| 商丘市| 海盐县| 慈利县| 岢岚县| 鹿泉市| 新乐市| 万盛区| 红安县| 沭阳县| 全椒县| 镇坪县| 白水县| 五大连池市| 房产|