N3的情境管理最為核心的一個類是GrphicsServer, 它包含一些"stage"和"View".
Stage把圖形實體(模型, 攝像機, 燈光)進行分類渲染. 它的主要工作是在串連的圖形實體間加速可見度查詢. 不同的可見度查詢由不同的Stage子類來實現. N3會提供了一些不同用途的Stage子類, 但你也可以根據程式需要自己來實現可見度查詢機制.
可見度查詢適用於這些實體:
- Camera->Light: 尋找對於指定攝像機可見的所有燈光
- Camera->Model: 尋找對於指定攝像機可見的所有模型
- Light->MOdel: 尋找被指定光源照射到的所有模型
這些可見度查詢在圖形實體間建立了一些所謂的"可見度連結", 再利用低級的渲染子系統來加速渲染.
要渲染一個Stage的內容, 需要至少一個View對象. 一個View對象通過綁定一個攝像機實體把Stage渲染到一個render target. 可以並存任意數目的View, 也可能都被綁定到任意Stage. 此外, View對象之間可能存在依賴關係(結果就是一個View對象會在渲染自身時首先請求它所依賴的View對象).
圖形實體表示了可以被串連到Stage的一個最小繪圖物件, 它分為以下三種:
- ModelEntity: 一個可見的模型執行個體
- LightEntity: 一個光源
- CameraEntity: 一個攝像機
可見度查詢使圖形實體間形成一種雙向的連結關係. 一個CameraEntity連結到所有對於這個攝像機來說可見的ModelEntity和LightEntity. 因為可見度連結是雙向的, 所以ModelEntity和LightEntity也知道它們對於哪個攝像機可見. LightEntity有它們影響到的ModelEntity的連結, ModelEntity也知道它們被哪個光源照亮.
==========================================================
N3 畫個東西真簡單, 想畫個模型, 建立出來設定一下位置扔給Stage就好了
this->model = ModelEntity::Create();<br /> this->model->SetTransform(matrix44::translation(0.0f, 3.0f, 0.0f));<br /> this->model->SetResourceId(ResourceId("mdl:examples/eagle.n2"));<br /> this->stage->AttachEntity(this->model.upcast<GraphicsEntity>());<br />
模型是黑的? 再往情境裡扔個燈就好了:
// attach a light entity<br /> matrix44 lightTransform = matrix44::multiply(matrix44::scaling(100.0f, 100.0f, 100.0f), matrix44::lookatrh(point(20.0f, 20.0f, 20.0f), point::origin(), vector::upvec()));<br /> this->lightEntity = SpotLightEntity::Create();<br /> this->lightEntity->SetCastShadows(true);<br /> this->lightEntity->SetTransform(lightTransform);<br /> this->lightEntity->SetColor(float4(4.0f, 2.0f, 1.0f, 1.0f));<br /> this->stage->AttachEntity(this->lightEntity.upcast<GraphicsEntity>());<br />
想控制的話, 再扔個攝像機進去就OK了.......
GraphicsServer* gfxServer = GraphicsServer::Instance();</p><p> // setup the camera util object<br /> this->mayaCameraUtil.Setup(point(0.0f, 0.0f, 0.0f), point(0.0f, 0.0f, 10.0f), vector(0.0f, 1.0f, 0.0f));</p><p> // setup a stage<br /> this->stage = gfxServer->CreateStage(StringAtom("DefaultStage"), SimpleStageBuilder::Create());</p><p> // attach a camera to the stage<br /> this->cameraEntity = CameraEntity::Create();<br /> cameraEntity->SetTransform(this->mayaCameraUtil.GetCameraTransform());<br /> this->stage->AttachEntity(cameraEntity.upcast<GraphicsEntity>());</p><p> // setup a default view<br /> this->view = gfxServer->CreateView(View::RTTI, StringAtom("DefaultView"), true);<br /> this->view->SetStage(this->stage);<br /> this->view->SetFrameShader(FrameServer::Instance()->GetFrameShaderByName(ResourceId(DEFAULT_FRAMESHADER_NAME)));<br /> this->view->SetCameraEntity(cameraEntity);<br />
別忘了處理輸入事件:
可以參考ViewerApplication::OnProcessInput().