花了兩個月陸陸續續地把這本書讀完,覺得總體上是一本很不錯的書。作者以前參與過cocos引擎的開發,因此是以自己的角度講解cocos引擎,不同於市面上很多單純羅列cocos api和代碼的書,而是結合OpenGL ES和圖形學,對於cocos的講解深入到引擎實現層面。看完之後,對於cocos引擎的各方面:渲染、紋理、事件分發、物理引擎等都有比較深入的瞭解。
另外也有一些不足之處:部分章節編排顯得散亂,正如作者所寫,他的寫作方法是先把相關資料都蒐羅在一起,然後再整理目錄結構。在講解渲染的時候,作者本意是想融合OpenGL ES和圖形學的知識,但是有的地方講解不甚清楚,跳躍性較強,需要較好的圖形學功底才容易理解。另外,最後幾章的結束顯得略微草率。
- cocos2d-x 3.x的幾項重大改動:新的渲染系統、統一的事件系統、深度集成的物理系統、C++的命名風格
- 基於RenderCommand 的新渲染系統
- 可組合(自動批處理),減少繪製次數,提升性能
- 可排序:globalZOder > localZOrder > orderOfArrival
- Sprite的自動剔除
- 統一的事件分發器EventDispatcher,將事件關聯到UI元素
- cocos 3.x新的數據結構:Vector<T>和Map<K, V>,push時retain, popBack時release
- cocos的內存管理機制:
- 繼承Ref類的對象都可以被管理,每一幀都會把引用計數爲0的對象釋放
- retain會讓計數加1,release會減1
- addChild會自動調用retain
- create會自動調用autoRelease
- C++風格:隨着與cocos-iPhone的分離,從OC風格轉成C++,CCSprite -> Sprite
- cocos引擎的主要組成:渲染系統、物理系統、事件系統、動畫及紋理系統、內存管理及調度器
- 內存管理詳解:
- new會讓引用計數加1
- create = new + autorelease(添加到AutoreleasePool)
- 每一幀對Pool中每個對象,做release(引用計數減1,若減到0則釋放)
- 對於想提前釋放的Ref對象,可以使用自定義AutoreleasePool來即時清理
- anchorPoint和position共同決定了元素的位置
- UI樹和繪製順序
- localZOrder:將UI樹結構和繪製順序綁定
- globalZOrder:更靈活
- 具體繪製流程
- 對globalZOrder不爲0的元素按值排序
- 對其餘元素,按localZOrder。對每個元素做中序遍歷:
- 遍歷左邊子節點(所有localZOrder小於0的直接子節點,且按升序排列)
- 遍歷當前元素
- 遍歷右邊子節點(所有localZOrder大於0的直接子節點,且按升序排列)
- autorelease本質是延遲釋放,將Pool中所有不在UI樹中的元素釋放;addChild/removeFromParent -> Vector的push/popBack -> retain/release
- Application的子類AppDelegate定義了遊戲生命週期各個階段的處理:啓動後,切後臺,切前臺
- 設計分辨率和實際分辨率
- pushScene和replaceScene
- 遊戲循環詳細過程:用戶輸入 -> 動畫 -> 物理模擬 -> 邏輯更新(與物理模擬順序不一定) -> UI樹遍歷 -> 渲染 -> 交換緩衝區 -> 自動釋放
- Scheduler的兩種方式:
- scheduleUpdate: 可指定priority,性能更好
- schedule:可指定interval,repeat,delay
- Scheduler的priority根據邏輯而不是對象:
- ActionManager:永遠最低
- PhysicsWorld:0
- CustomLogic:自定義
- 避免在每幀做複雜的查找或者迭代運算,以免影響性能
- Cocos2d-x是一個單線程的引擎,許多異步處理的結果須在主線程完成;如異步紋理加載,回調addImageAsyncCallBack每一幀處理一個紋理,上傳到GL內存中(GL命令耗時且必須在主線程中執行)
- GPU vs CPU: 並行 vs 串行;衡量GPU性能參數:pps
- OpenGL ES渲染管線:
- 頂點數組:所有圖元primitive的頂點信息
- 頂點着色器:計算頂點的座標、顏色、光照等;頂點座標變換;提供易變變量
- 圖元組裝:視錐體相關的一些座標變換
- 光柵化:圖元轉成片段fragment(像素),計算插值
- 片段着色器:計算每個片段(像素)的顏色值,實現特殊效果(陰影、描邊、閃光
- 片段測試:深度測試、模板測試、混合
- 幀緩衝:每個像素點的最終信息(顏色、深度、模板值),雙buffer切換
- 新的繪製系統的特點:
- UI樹遍歷和繪製分離
- 自動批處理和自動裁剪
- 自定義繪製命令
- 繪製流程
- 遍歷UI樹並生成RenderCommand(根據localZOrder:遍歷順序)
- 排序(根據globalZOrder:繪製順序)
- 執行繪製(自動批處理)
- RenderCommand分類:
- QuadCommand:Sprite和ParticleSystem;自動批處理:相鄰的QuadCommand使用同樣的紋理
- BatchCommand:TextureAtlas,性能更好,但不能參與自動批繪製
- GroupCommand:ClippingNode和RenderTexture,包裝多個RenderCommand且不參與全局排序
- CustomCommand:自定義
- 自定義RenderCommand例子:新手教程實現其餘區域半透明
- 多重採樣:抗鋸齒
- 紋理:通過TextImage2D命令定義的像素矩形;紋素
- 紋理 + 光柵化採樣 -> 片段着色器
- 紋理座標:uv型(紋理寬高)和st型(最大是1)
- 解包:客戶端(format和type定義格式的像素數據) -> GL服務端(浮點型RGBA像素值);打包:GL服務端 -> 客戶端
- PNG、JPG等格式在使用時需先轉成cocos支持的指定格式(如RGBA8888)
- 紋理縮放
- 縮小:多個紋素 -> 一個像素
- 放大:一個紋素 -> 多個像素
- 多級紋理:通過圖像金字塔適配不同分辨率
- 紋理壓縮:
- ios:PVRTC
- android:ETC
- 紋理對象的管理:
- TextureCache
- 自己封裝ResourceManager
- 紋理所佔內存的計算 result = width * height * bpp / 8
- 紋理使用優化:
- 引擎商和硬件商合作定製優化
- 提前加載資源
- 即使清除不用的資源
- 合圖
- 多級紋理:
- 減少內存:只上傳所需級別的紋理
- 減少計算量:無需加載時再計算
- 選擇適當的資源格式(RGBA8888,RGBA4444)
- 使用壓縮紋理
- 精靈:遊戲中的元素,紋理的一部分(關聯到Texture2D對象)
- 使用精靈的好處:
- 自動批繪製
- 在一組元素中使用精靈,單個的屬性(位置、顏色、縮放等)控制比較靈活
- RGBA
- R、G、B:三基色通道,0-255,值越大越亮,0表示黑色,255表示最亮,都爲255時爲白色。
- A:Alpha通道,不透明度,0-1,值越大越不透明
- 顏色混合:多個圖層之間的混合
- 混合規則:定義RGBA各向量的加成規則
- 深度測試會將較遠的位於非透明圖元之後的部分丟棄
- 顏色疊加:將一個顏色作用在當前圖層,如角色受攻擊後閃動紅色
- 顏色疊加可以沿UI樹遞歸傳遞
- 每個Node擁有displayColor = realColor * parentColor / 255
- Alpha預乘:
- 對於顏色混合的計算:(Rs, Gs, Bs) * As + (Rd, Gd, Bd) * (1 - As),提前乘好Alpha通道的值
- 優點:減少計算量,提高性能;缺點:預乘減小了顏色精度
- 精靈表:合圖,將多個精靈合併在一張圖上,通過配置文件(plist)表示每個精靈的位置
- frameCache:addSpriteFrames(.plist) 通過plist將spriteFrame加入spriteFrameCache
- 同時會將對應的紋理加入textureCache
- 精靈動畫:都通過配置文件來定義
- 幀動畫:每幀間隔、關鍵幀的spriteFrame、來自精靈表
- 骨骼動畫:
- 使用SpriteBatchNode的批繪製
- 多個Sprite需放在同一個SpriteBatchNode下
- 使用不便,不如自動批繪製
- 部分拉伸:Scale9Sprite,底層使用SpriteBatchNode
- 自動批繪製的條件(同一次繪製)
- 同一張紋理
- 相同的BlendFunc設置
- 相同的Shader程序
- 順序上相鄰
- OpenGL ES着色語言可以用來編寫着色器程序
- 存儲限定符
- attribute:應用程序傳給頂點着色器
- uniform:應用程序傳給頂點着色器和片段着色器
- varying:頂點着色器傳給片段着色器,經過插值的易變量
- 頂點緩衝對象,頂點數組對象(VAO)
- cocos着色器子系統:Node 多<->一 GLProgramState 多<->一 GLProgram
- 着色器編輯工具
- GroupCommand <-> RenderTexture <-> 幀緩衝
- 幀緩衝的邏輯緩衝區:
- 顏色
- 深度
- 模板
- 片段操作和測試:從片段着色器到幀緩衝
- 像素所有權測試
- 裁剪測試
- 模板測試:裁剪、光照陰影
- 深度測試:遮擋
- 資源分辨率,設計分辨率,應用分辨率
- 5種縮放策略:
- EXACT_FIT(非等比)
- NO_BORDER
- SHOW_ALL
- FIXED_HEIGHT
- FIXED_WIDTH
- 不要寫死絕對座標,而是根據visibleSize自適應
- 設置資源縮放因子,程序中提供一套不同分辨率的資源,使用不同的搜索路徑
- 事件分發模型:訂閱者模式,事件分發者,訂閱者,好處:解耦合
- 訂閱時可指定關聯Node或優先級,對於多個訂閱者,分發的順序:
- 優先級小於0的訂閱者
- Node繪製的順序
- 優先級大於0的訂閱者
- 多點觸摸 EventListenerTouchAllAtOnce 單點觸摸 EventListenerTouchOneByOne
- 飛機移動例子:指定關聯到fighter,再實現began和move事件的處理函數
- setSwallowTouches可以阻止一個觸摸點向後面的訂閱者繼續分發
- 輪廓字的發展:PostScript(Adobe) -> Type 1(Adobe) -> TrueType(Apple, MS) -> FreeType(iOS, Android,cocos支持)
- Label的創建
- createWithTTF:輪廓字,效率稍低
- createWithBMFont:點陣字,通過紋理生成,效率高,但不支持所有中文
- Label的特效:陰影,描邊,發光
- 動畫系統基於線性插值
- Action,MoveTo, Sequence, Spwan, Repeat
- 加速是通過dt * speed(基於時間片而不是幀率)
- 收到傷害時閃白的實現:在動畫開始時使用自定義的着色器
- Box2D和Chipmunk2D(cocos使用)
- 碰撞檢測基於剛體,剛體有自己的範圍
- Entity Component System:以屬性爲中心的架構風格
- 代表:genius-x,cocos creator
- lua使用虛擬棧和C傳遞值
- cocos 3.0使用bindings-generator來生成綁定代碼,基於tolua++,比原來的tolua更方便