cocosエンジンでは、すべてのレンダリングコンポーネントがcc.Sprite、cc.Labelなどのcc.RenderComponentから継承されます。コンポーネントのアセンブラーは、主にコンポーネントデータの更新処理と塗りつぶしを担当します。異なるレンダリングコンポーネントはデータコンテンツと塗りつぶしも異なるため、各レンダリングコンポーネントには独自のAssemblerオブジェクトがあり、すべてのAssemblerオブジェクトが継承されます。 cc.Assembler以降。リソースとしてのマテリアルは主に、使用されるレンダリングコンポーネント、テクスチャ、シェーダーのレンダリング状態を記録します。
まず、最初にアセンブラを分析します。メインコードは次のとおりです。
// renderCompCtorコンポーネントクラス
//アセンブラコンポーネントアセンブリクラス
Assembler.register = 関数(renderCompCtor、アセンブラ){ renderCompCtor .__ assembler__ = アセンブラ; }; Assembler.init = function (renderComp){ let renderCompCtor = renderComp.constructor; let renderrCtor = renderCompCtor .__ assembler__; while(! assemblyrCtor ){ renderCompCtor = renderCompCtor。$ super; if(!renderCompCtor){ cc.warn( ` レンダリングコンポーネントのアセンブラが見つかりません:[$ {cc.js.getClassName(renderComp)}]`); 戻る; } AssemblerCtor = renderCompCtor .__ assembler__; } if (assemblerCtor.getConstructor){ AssemblerCtor = AssemblerCtor.getConstructor(renderComp); } if(!renderComp._assembler || renderComp._assembler.constructor!== AssemblerCtor){ let Assembler = AssemblerPool.get(assemblerCtor); Assembler.init(renderComp); renderComp._assembler = アセンブラ; } };
レンダリングコンポーネントはAssembler.registerを介してエンジンに登録されます。たとえば、グラフィックスレンダリングコンポーネントの登録コードはAssembler.register(cc.Graphics、GraphicsAssembler)、cc.Graphicsはグラフィックスクラス、GraphicsAssemblerはAssemblerクラスから継承し、レンダリングコンポーネントは_assembler,_assembler持有
_renderData,
_renderData
和InputAssembler
都是数据容器,_assembler
是数据操作,_assembler
可以创建和updateRenderData
,更新verts,InputAssembler
是在渲染时用到的,用于组织传入GPU的数据.
v2.xでは、RenderFlowは変換、レンダリング、子などのレンダリングプロセス中の呼び出しの頻度に従って複数のレンダリング状態を分割し、各レンダリング状態は関数に対応します。RenderFlowの初期化プロセス中に、対応するレンダリングブランチがこれらの状態に従って事前に作成され、これらのブランチは対応する状態を順番にリンクします。たとえば、ノードが現在のフレームのマトリックスを更新する必要があり、ノード自体をレンダリングする必要がある場合、このノードはフラグをに更新しnode._renderFlag = RenderFlow.FLAG_TRANSFORM | RenderFlow.FLAG_RENDER
ます。このノードをレンダリングするとき、RenderFlowはノードのnode._renderFlag
状態に応じてtransform => renderブランチに 入ります。追加の状態判断は必要ありません。
cc.rendererオブジェクトは、基本的なレンダリングインターフェイスを提供するレンダラーオブジェクトであるグローバルオブジェクトです。これには、いくつかのレンダリング関連のクラス定義と、デバイス、InputAssembler、Passなどのいくつかのグローバル属性が含まれています。コアは2つの属性で、1つは_froward 1 _フロー_フローRenderFlowのインスタンスを作成し、_flow.init方法を通過し、初期化処理におけるcc.RenderFlowクラスであります
initWebGL(canvas、opts){ require( './webgl/assemblers' ); const ModelBatcher = require( './ webgl / model-batcher' ); this .Texture2D = gfx.Texture2D; this .canvas = canvas; this._flow = cc.RenderFlow; if(CC_JSB && CC_NATIVERENDERER){ // ネイティブコードはデバイスのインスタンスを作成するので、グローバルインスタンスを使用してください。 this .device = gfx.Device.getInstance(); this .scene = new renderer.Scene(); ビルトインてみましょう(= _initBuiltinsthis .device); this ._forward = new renderer.ForwardRenderer(this .device、builtins); let nativeFlow = new renderer.RenderFlow(this .device、this .scene、this ._forward); this ._flow.init(nativeFlow); } else { let Scene = require( '../../ renderer / scene / scene' ); let ForwardRenderer = require( '../../ renderer / renderers / forward-renderer' ); this .device = newgfx.Device(canvas、opts); this .scene = new Scene(); ビルトインしましょう = _initBuiltins(この.device)。 this._forward = new ForwardRenderer(this.device、builtins); this._handle = new ModelBatcher(this.device、this.scene); this._flow.init(this._handle、this ._forward); } config.addStage( 'shadowcast' ); config.addStage( '不透明' ); config.addStage( 'transparent' ); }、
render(ecScene、dt){ this .device.resetDrawCalls(); if (ecScene){ // エンティティコンポーネントシーンをウォークしてモデルを生成する this._flow.render(ecScene、dt); this .drawCalls = this .device.getDrawCalls(); } }、
RenderFlow.render = function(scene、dt){ _batcher.reset(); _batcher.walking = true; RenderFlow.visitRootNode(scene); _batcher.terminate(); _batcher.walking = false; _forward.render(_batcher._renderScene、dt); };