Secondlife Viewerのソースを読む
さてコンパイルできたので、今度はソースを読んでみよう。前回に引き続きバージョン1.7.2.0ね。
参考資料
オフィシャルのwikiにいろいろ。
- Viewer source - Second Life Wiki
- プロジェクトの構成
- Viewer Architecture - Second Life Wiki
- ちょっと詳しい解説
- Third Party Libraries - Second Life Wiki
- 使用ライブラリの説明
まずはこのあたりをざっと。
目的
レンダラに細工するため、レンダリング部分を探す。特に視点の設定部分重要。
よむ
コメントも命名規約もしっかりしてるし、なかなか読みやすいソース。とりあえずmainから追っていきましょうかね。
mainはnewview/viewer.cppのなかにある。グローバル変数(大量)を初期化しつつコマンドラインオプション解析しつつ初期化処理。この規模だとオブジェクトの初期化だけでかなりの量。初期化が終わったらmain_loop()呼んでcleanup_app()呼んで終了。
同じくviewer.cpp(このファイル6666行くらいある)内にあるmain_loop()。while(!gQuit)とか書いてあってたいへんわかりやすい。キー/ジョイスティック読んでメッセージポンプしてレンダリングして、あとフレームレート調整とかスレッド管理とか?
//viewer.cpp#1842 // Render scene. if (!gQuit) { display(); LLFloaterSnapshot::update(); // take snapshots if (gbCapturing) { gMovieMaker.Snap(); } }
display()はllviewerdisplay.cppに。LLGL*Defaultというのはglの状態管理するためのクラス。コンストラクタ/デストラクタで状態の設定と復元?前準備が色々あって、レンダリング本体は451行あたりから。この辺で頻出するLLFastTimerというのは、パフォーマンス測定用?のタイマー、だと想像している。
レンダリングに際しては、gFrameStatsおよびgPipelineというオブジェクトが頻出する。gFrameStatsはフレームの状態を(おそらくロギングのために)ためておくオブジェクト。ロギング重要。このへんすごくかっちりつくってある印象。さすが商用アプリ。
そしておそらくレンダリングの親玉がgPipeline(instance of LLPipeline)。レンダリングするオブジェクトをためといてz-orderでソートしたりカリングしたりして描画するようだ。ソートとかやりつつ最終的にLLPipeline::renderGeom(LLCamera& camera)で描画。pipeline.cppの1937行くらいから。コードがスカスカで気持ち悪い C++の宿命か 意味/行数比が低いのだ。
えーと話がそれた。LLDrawPoolのサブクラスが描画するオブジェクトのコンテナとなっているようだ。
どこで視点設定してるのかよくわからないのだが、gCameraなんていうグローバルオブジェクトがあるのでそれが関係してる予感。LLPipeLine::renderGeomにgCameraが渡されて、そこから、はて……?
どうやら描画処理のあちこちで、カメラのパラメータが欲しいときは各自勝手にgCameraを参照してる予感。
雑感
抽象化の漏れは#ifdefでカバー。実用的プログラミングとはこのようなことをいうのだ。
デバッグとかロギングとか、すごく大事にしてきっちり実装してる印象。かっこいい。