/*---------------------------------------------------------------------------* Project: NintendoWare File: demo_GraphicsSystem.h Copyright (C)2009-2011 Nintendo/HAL Laboratory, Inc. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo and/or its licensed developers and are protected by national and international copyright laws. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. The content herein is highly confidential and should be handled accordingly. $Revision: 31311 $ *---------------------------------------------------------------------------*/ #ifndef NW_DEMO_GRAPHICSSYSTEM_H_ #define NW_DEMO_GRAPHICSSYSTEM_H_ #include #include #include #include #include #include #include #include #include #include #include namespace nw { namespace gfx { class RenderContext; class MeshRenderer; enum RenderColorFormat; class Shader; class SceneNode; class SceneContext; class SceneTraverser; class SceneInitializer; class Camera; } // namespace gfx namespace os { class IAllocator; } // namespace os namespace ut { struct FloatColor; } // namespace ut namespace demo { class RenderSystem; class SceneSystem; class GraphicsDrawing; class DemoAllocator; //--------------------------------------------------------------------------- //! @brief 上画面の表示モードを表す定義です。 //! nngxExtensionMode で指定する引数となります。 //--------------------------------------------------------------------------- enum UpperScreenMode { UPPER_SCREEN_MODE_NORMAL = NN_GX_DISPLAYMODE_NORMAL, //!< 通常モードを表します。 UPPER_SCREEN_MODE_STEREO = NN_GX_DISPLAYMODE_STEREO //!< 3Dモードを表します。 }; //! @brief リソースのセットを表す構造体です。 struct ResourceSet { nw::ut::MoveArray buffer; nw::gfx::ResGraphicsFile resource; }; const int MAX_RESOURCES_COUNT = 128; typedef nw::ut::FixedSizeArray ResourceArray; //--------------------------------------------------------------------------- //! @brief 描画機能をまとめるためのクラスです。 //--------------------------------------------------------------------------- class RenderSystem { public: //--------------------------------------------------------------------------- //! @brief 描画システムの設定内容です。 //--------------------------------------------------------------------------- struct Description { //! @brief 描画を行うスクリーンサイズを表します。 struct ScreenSize { s32 width; //!< スクリーンの横幅を表します。 s32 height; //!< スクリーンの縦幅を表します。 //! @brief コンストラクタです。 ScreenSize(s32 w, s32 h) : width(w), height(h) {} }; //! @brief スクリーンオフセットを表します。 struct ScreenOffset { s32 x; //!< オフセットのX座標を表します。 s32 y; //!< オフセットのY座標を表します。 //! @brief コンストラクタです。 ScreenOffset(s32 x, s32 y) : x(x), y(y) {} }; //! @brief 上画面のディスプレイバッファスワッパの設定内容です。 DisplayBufferSwapper::Description upperScreenDescription; //! @brief 下画面のディスプレイバッファスワッパの設定内容です。 DisplayBufferSwapper::Description lowerScreenDescription; gfx::RenderColorFormat renderColorFormat; //!< スクリーンのカラーフォーマットを表します。 size_t commandBufferSize; //!< コマンドバッファのサイズを現します。 size_t commandRequestCount; //!< コマンドリクエストの上限数を表します。 size_t reusableCommandBufferSize; //!< 再利用コマンドリストのコマンドバッファのサイズを現します。 size_t reusableCommandRequestCount; //!< 再利用コマンドリストのコマンドリクエストの上限数を表します。 UpperScreenMode upperScreenMode; //!< 上画面のモードです。 size_t commandListCount; //!< 生成するコマンドリストの数です。 size_t displayBufferCount; //!< 生成するディスプレイバッファの数です。 size_t maxGpuProfilingEntryCount; //!< コマンドリストの GPU プロファイラエントリの上限数を表します。 //! @brief コンストラクタです。 //! 立体視表示をしない場合のデフォルト値がセットされます。 Description() : renderColorFormat(nw::gfx::RENDER_COLOR_FORMAT_RGBA8), commandBufferSize(0x100000), commandRequestCount(512), reusableCommandBufferSize(0), reusableCommandRequestCount(0), upperScreenMode(UPPER_SCREEN_MODE_NORMAL), commandListCount(2), displayBufferCount(2), maxGpuProfilingEntryCount(8) { upperScreenDescription.screenKind = nw::demo::UPPER_SCREEN; upperScreenDescription.width = NN_GX_DISPLAY0_HEIGHT; upperScreenDescription.height = NN_GX_DISPLAY0_WIDTH; lowerScreenDescription.screenKind = nw::demo::LOWER_SCREEN; lowerScreenDescription.width = NN_GX_DISPLAY1_HEIGHT; lowerScreenDescription.height = NN_GX_DISPLAY1_WIDTH; } }; //--------------------------------------------------------------------------- //! @brief 負荷メーターの内容です。 //--------------------------------------------------------------------------- struct LoadMeterDescription { //! @brief コンストラクタです。 LoadMeterDescription() : startTick(0), loadTime(0.0f), loadGpuTime(0.0f), waitTime(0.0f), transferTime(0.0f), gpuOtherTime(0.0f), cumulativeTime(0.0f), cumulativeGpuTime(0.0f), cumulativeWaitTime(0.0f), drawCommandBufferSize(0), callCount(0) {} s64 startTick; //!< 開始チックです。 float loadTime; //!< 負荷時間です。 float loadGpuTime; //!< GPU負荷時間です。 float waitTime; //!< コマンドリストの終了待ち時間です。 float transferTime; //!< レンダーターゲットからの転送時間です。 float gpuOtherTime; //!< 他のGPU処理の時間です。 float cumulativeTime; //!< 累積時間です。 float cumulativeGpuTime; //!< GPU累積時間です。 float cumulativeWaitTime; //!< 累積コマンドリスト終了待ち時間です。 int drawCommandBufferSize; //!< 描画コマンドのサイズです。 s32 callCount; //!< 呼び出し回数です。 static const float NANO_TO_MILLI; static const float MILLI_TO_RATE; }; //---------------------------------------- //! @name 生成/破棄 //@{ //! @brief 描画関連のクラスを生成します。 //! //! @param[in] allocator アロケータです。 //! @param[in] description 生成するレンダーシステムの設定です。 //! //! @return 生成したレンダーシステムを返します。 //! static RenderSystem* Create( os::IAllocator* allocator, const Description& description ); //! @brief 最遠景に配置するモデルの構築をします。 //! //! 最遠景のモデルは半径1の球を指定します。 //! void LoadSkyModel(const wchar_t* fileName); //! @brief レンダーシステムを破棄します。 void Destroy(); //@} //---------------------------------------- //! @name 取得/設定 //@{ //! @brief 描画を行うターゲットを設定します。 //! //! @param[in] renderTarget 描画を行うターゲットです。 //! void SetRenderTarget(gfx::IRenderTarget* renderTarget); //! @brief レンダーコンテキストを取得します。 //! //! @return レンダーコンテキストです。 //! gfx::RenderContext* GetRenderContext() { return this->m_RenderContext; } //! @brief シーン環境を取得します。 //! //! @return シーン環境です。 //! gfx::SceneEnvironment& GetSceneEnvironment() { NW_NULL_ASSERT(this->m_RenderContext); return this->m_RenderContext->GetSceneEnvironment(); } //! @brief 描画ソートモードを設定します。 //! //! @param[in] renderSortMode 描画ソートモードです。 //! void SetRenderSortMode(gfx::ISceneUpdater::RenderSortMode renderSortMode); //! @brief 描画ソートモードを取得します。 //! //! @return 描画ソートモードです。 //! gfx::ISceneUpdater::RenderSortMode GetRenderSortMode() const { return this->m_RenderSortMode; } //! @brief レンダーキューを取得します。 //! //! @return レンダーキューです。 //! gfx::RenderQueue* GetRenderQueue() const { return this->m_RenderQueue; } //! @brief メッシュレンダラーを取得します。 //! //! @return メッシュレンダラーです。 //! gfx::MeshRenderer* GetMeshRenderer() const { return this->m_MeshRenderer; } //! @brief コマンドリストスワッパーを取得します。 CommandListSwapper* GetCommandListSwapper() const { return this->m_CommandListSwapper; } //! @brief レンダーキューに描画コマンド要素を積みます。 //! //! @param[in] renderCommand コマンドです。 //! @param[in] translucencyKind 透明性の種類です。 //! @param[in] priority メッシュの描画優先度です。 //! @param[in] layerId 描画要素のソート時に最優先に区分される ID です。レイヤーやビューポートの描画を制御するのに用います。 //! void EnqueueRenderCommand( gfx::RenderCommand* renderCommand, gfx::ResMaterial::TranslucencyKind translucencyKind, u8 priority, u8 layerId) { this->m_RenderQueue->EnqueueCommand( renderCommand, translucencyKind, priority, layerId); } //@} //---------------------------------------- //! @name 描画 //@{ //! @brief シーン環境をレンダーコンテキストに設定します。 //! //! @param[in] sceneSystem 描画するシーンコンテンツを含むシーンシステムです。 //! @param[in] sceneEnvironmentSettings 設定するシーン環境です。 //! void SetSceneEnvironmentSettings( SceneSystem* sceneSystem, ut::MoveArray* sceneEnvironmentSettings); //! @brief シーンコンテキストの環境をレンダーコンテキストに設定します。 //! SceneEnvironmentSetting を用いずにライトやフォグを設定するために呼び出します。 //! //! @param[in] sceneSystem 描画するシーンコンテンツを含むシーンシステムです。 //! void SetEnvironment( SceneSystem* sceneSystem); //! @brief レンダーキューにレンダーエレメントを追加します。 //! //! @param[in] sceneSystem 描画するシーンコンテンツを含むシーンシステムです。 //! void SubmitView( SceneSystem* sceneSystem); //! @brief シーンを描画します。 //! //! @param[in] camera このシーンを描画するカメラです。 //! @param[in] screenKind 転送するスクリーンの種類です。 //! @param[in] isCommandCacheDump コマンドキャッシュをログ出力します。 //! void RenderScene( gfx::Camera* camera, s32 screenKind, bool isCommandCacheDump = false); //! @brief ステレオディスプレイに対応したシーンの描画を行います。 //! //! UPPER_SCREEN のみ対応しています。 //! //! @param[in] leftCamera 左目用のカメラです。 //! @param[in] rightCamera 右目用のカメラです。 //! @param[in] isCommandCacheDump コマンドキャッシュをログ出力します。 //! void RenderStereoScene( gfx::Camera* leftCamera, gfx::Camera* rightCamera, bool isCommandCacheDump = false); //! @brief バッファを消去します。 //! //! @param[in] clearColor 設定するクリアカラーです。 //! void ClearBuffer(ut::FloatColor clearColor); //! @brief カメラのパラメータによって最遠景モデルの Translate と Scale の調整を行い描画します。 //! //! @param[in] camera モデルの中心となるカメラです。 //! void ClearBySkyModel(const gfx::Camera* camera); //! @brief バッファを転送します。 //! //! @param[in] screenKind 転送するスクリーンの種類です。 //! void TransferBuffer(s32 screenKind); //! @brief 実行しているコマンドリストの終了待ちを行います。 void WaitCommandList(); //! @brief バインドされているコマンドリストを実行します。 void RunCommandList(); //! @brief コマンドリストをバッファとスワップします。 void SwapCommandList(); //! @brief VSync 待ちを行います。 //! //! @param[in] screenKind VSync待ちを行うスクリーンの種類です。 //! void WaitVSync(s32 screenKind); //! @brief バッファのスワップを予約します。 //! //! @param[in] screenKind スワップを行うスクリーンの種類です。 //! void SwapBuffer(s32 screenKind); //! @brief VSync 待ちとディスプレイバッファの表示、コマンドリストの実行を行います。 //! //! コマンドリストが多重化されている場合は、この関数は次の順序で処理を行います。 @n //! 1. 実行中のコマンドリストの終了待ち @n //! 2. ディスプレイバッファのスワップ予約 @n //! 3. VSync 待ち @n //! 4. 蓄積済みのコマンドリスト非同期実行 @n //! 5. コマンドリストのスワップ //! //! コマンドリストが多重化されていない場合は次の処理を行います。 @n //! 1. 蓄積済みのコマンドリスト同期実行 @n //! 2. ディスプレイバッファのスワップ予約 @n //! 3. VSync 待ち //! //! @param[in] screenKind VSync 待ちとスワップを行うスクリーンの種類です。 void PresentBuffer(s32 screenKind); //! @brief ステレオカメラを計算します。 //! //! @param[out] leftCamera 左目用のカメラです。 //! @param[out] rightCamera 右目用のカメラです。 //! @param[in] baseCamera ベースとなるカメラです。 //! @param[in] depthLevel ベースカメラから基準面までの距離です。 //! @param[in] depthRange 視差の補正値です。 //! void CalcStereoCamera( gfx::Camera* leftCamera, gfx::Camera* rightCamera, gfx::Camera* baseCamera, f32 depthLevel = 1.0f, f32 depthRange = 1.0f); //@} //---------------------------------------- //! @name 負荷メーター //@{ //! @brief 負荷計測を開始します。 void BeginLoadMeter(); //! @brief 負荷計測を終了します。 void EndLoadMeter(); //! @brief 負荷計測結果を計算します。 void CalcLoadMeter(); //! @brief 負荷計測を一時停止します。 void SuspendLoadMeter(); //! @brief 負荷計測を再開します。 void ResumeLoadMeter(); //! @brief 積算負荷をリセットします。 void ResetCumulativeLoadMeter(); //! @brief 負荷メーターの内容を取得します。 const LoadMeterDescription& GetLoadMeter() { return m_LoadMeterDescription; } //! @brief 積算負荷を取得します。 const LoadMeterDescription& GetCumulativeLoadMeter() { return m_CumulativeLoadMeterDescription; } //! @brief ロードメーターで表示する描画コマンドのサイズを追加します。 void AddLoadMeterCommandSize(s32 commandSize) { m_LoadMeterDescription.drawCommandBufferSize += commandSize; } //! @brief 描画と転送の間に呼び出されるシグナルを取得します。 //! 立体視を行う場合は 左目の描画後に呼び出されます。 //! //! @return シグナルを取得します。 //! ut::Signal1* GetPostRenderCallback() const { return this->m_PostRenderCallback; } //! @brief 右目の描画と転送の間に呼び出されるシグナルを取得します。 //! //! @return シグナルを取得します。 //! ut::Signal1* GetPostRightRenderCallback() const { return this->m_PostRightRenderCallback; } //@} private: //! @brief コンストラクタです。 RenderSystem() : m_Allocator(NULL), m_RenderContext(NULL), m_PriorMaterialRenderKeyFactory(NULL), m_RenderQueue(NULL), m_MeshRenderer(NULL), m_RenderSortMode(gfx::ISceneUpdater::ALL_MESH_BASE_SORT), m_UpperSwapper(NULL), m_LowerSwapper(NULL), m_ExtensionSwapper(NULL), m_CommandListSwapper(NULL), m_StereoCamera(NULL), m_SkyModel(NULL), m_PostRenderCallback(NULL), m_PostRightRenderCallback(NULL) { } os::IAllocator* m_Allocator; gfx::RenderContext* m_RenderContext; gfx::RenderKeyFactory* m_PriorMaterialRenderKeyFactory; gfx::RenderKeyFactory* m_PriorDepthRenderKeyFactory; gfx::RenderQueue* m_RenderQueue; gfx::MeshRenderer* m_MeshRenderer; gfx::ISceneUpdater::RenderSortMode m_RenderSortMode; DisplayBufferSwapper* m_UpperSwapper; DisplayBufferSwapper* m_LowerSwapper; DisplayBufferSwapper* m_ExtensionSwapper; CommandListSwapper* m_CommandListSwapper; LoadMeterDescription m_LoadMeterDescription; LoadMeterDescription m_CumulativeLoadMeterDescription; nn::ulcd::CTR::StereoCamera* m_StereoCamera; ResourceArray m_Resources; gfx::Model* m_SkyModel; ut::Signal1* m_PostRenderCallback; ut::Signal1* m_PostRightRenderCallback; }; //--------------------------------------------------------------------------- //! @brief シーン更新機能をまとめるためのクラスです。 //--------------------------------------------------------------------------- class SceneSystem { public: //--------------------------------------------------------------------------- //! @brief シーンシステムの設定内容です。 //--------------------------------------------------------------------------- struct Description { s32 maxSceneNodes; //!< シーンノードの上限数を表します。 s32 maxModels; //!< モデルの上限数を表します。 s32 maxSkeletalModels; //!< スケルタルモデルの上限数を表します。 s32 maxCameras; //!< カメラの上限数を表します。 s32 maxLights; //!< ライトの上限数を表します。 s32 maxFragmentLights; //!< フラグメントライトの上限数を表します。 s32 maxVertexLights; //!< 頂点ライトの上限数を表します。 s32 maxHemiSphereLights; //!< 半球ライトの上限数を表します。 s32 maxAmbientLights; //!< アンビエントライトの上限数を表します。 s32 maxFogs; //!< フォグの上限数を表します。 s32 maxParticleSets; //!< パーティクルセットの上限数を表します。 s32 maxParticleEmitters; //!< パーティクルエミッタの上限数を表します。 s32 maxParticleModels; //!< パーティクルモデルの上限数を表します。 s32 maxBones; //!< スケルトンに含まれるボーンの上限数を表します。 s32 maxMaterials; //!< マテリアルの最大数です。 s32 maxUserRenderNodes; //!< ユーザ定義の描画ノードの最大数です。 bool isFixedSizeMemory; //!< 生成時以外にもメモリを確保するかどうかのフラグを設定します。 //! @brief コンストラクタです。 Description() : maxSceneNodes(gfx::SceneContext::DEFAULT_MAX_SCENE_NODES), maxModels(gfx::SceneContext::DEFAULT_MAX_MODELS), maxSkeletalModels(gfx::SceneContext::DEFAULT_MAX_SKELETAL_MODELS), maxCameras(gfx::SceneContext::DEFAULT_MAX_CAMERAS), maxLights(gfx::SceneContext::DEFAULT_MAX_LIGHTS), maxFragmentLights(gfx::SceneContext::DEFAULT_MAX_FRAGMENT_LIGHTS), maxVertexLights(gfx::SceneContext::DEFAULT_MAX_VERTEX_LIGHTS), maxHemiSphereLights(gfx::SceneContext::DEFAULT_MAX_HEMISPHERE_LIGHTS), maxAmbientLights(gfx::SceneContext::DEFAULT_MAX_AMBIENT_LIGHTS), maxFogs(gfx::SceneContext::DEFAULT_MAX_FOGS), maxParticleSets(gfx::SceneContext::DEFAULT_MAX_PARTICLESETS), maxParticleEmitters(gfx::SceneContext::DEFAULT_MAX_PARTICLEEMITTERS), maxParticleModels(gfx::SceneContext::DEFAULT_MAX_PARTICLEMODELS), maxBones(128), maxMaterials(32), maxUserRenderNodes(gfx::SceneContext::DEFAULT_MAX_USER_RENDER_NODES), isFixedSizeMemory(true) {} }; //---------------------------------------- //! @name 生成/破棄 //@{ //--------------------------------------------------------------------------- //! @brief シーン更新関連のクラスを生成します。 //! //! @param[in] allocator アロケータです。 //! @param[in] description 生成するシーンシステムの設定です。 //! //! @return 生成したシーンシステムです。 //--------------------------------------------------------------------------- static SceneSystem* Create( os::IAllocator* allocator, const Description& description ); //--------------------------------------------------------------------------- //! @brief シーンシステムを破棄します。 //--------------------------------------------------------------------------- void Destroy(); //@} //--------------------------------------------------------------------------- //! @brief シーンを初期化します。 //! //! @param[in] sceneRoot 初期化するシーンのルートノードです。 //--------------------------------------------------------------------------- void InitializeScene(gfx::SceneNode* sceneRoot); //--------------------------------------------------------------------------- //! @brief ルートノードのトラバースを行います。 //! //! @param[in] sceneRoot 対象のルートノードです。 //--------------------------------------------------------------------------- void TraverseScene(gfx::SceneNode* sceneRoot); //--------------------------------------------------------------------------- //! @brief シーンを更新します。 //--------------------------------------------------------------------------- void UpdateScene(); //! シーンコンテキストを取得します。 gfx::SceneContext* GetSceneContext() { return m_SceneContext; } //! シーンアップデータを取得します。 gfx::ISceneUpdater* GetSceneUpdater() { return m_SceneUpdater; } //! カメラ制御クラスを取得します。 nw::demo::CameraController* GetCameraController() { return m_CameraController; } private: SceneSystem() : m_Allocator(NULL), m_SceneContext(NULL), m_SceneTraverser(NULL), m_SceneUpdater(NULL), m_SceneInitializer(NULL), m_CameraController(NULL) {} os::IAllocator* m_Allocator; gfx::SceneContext* m_SceneContext; gfx::SceneTraverser* m_SceneTraverser; gfx::SceneUpdater* m_SceneUpdater; gfx::SceneInitializer* m_SceneInitializer; CameraController* m_CameraController; }; //--------------------------------------------------------------------------- //! @brief グラフィックスシステムに必要な各種初期化を行います。 //! //! @param[in] deviceAllocator デバイスメモリ用のアロケータです。 //--------------------------------------------------------------------------- void InitializeGraphicsSystem(nw::demo::DemoAllocator* deviceAllocator); //--------------------------------------------------------------------------- //! @brief グラフィックスシステムの終了処理を行います。 //--------------------------------------------------------------------------- void FinalizeGraphicsSystem(); //--------------------------------------------------------------------------- //! @brief リソースの後始末をします。 //--------------------------------------------------------------------------- template NW_INLINE void SafeCleanupResources(TArray& resources) { typename TArray::iterator end = resources.end(); for (typename TArray::iterator it = resources.begin(); it != end; ++it) { nw::ut::SafeCleanup(it->resource); } } //--------------------------------------------------------------------------- //! @brief GL や VRAM 用のアロケート関数です。 //! //! @param[in] area 対象エリア情報です。 //! @param[in] aim メモリを要求している対象です。 //! @param[in] id メモリ要求対象の GL オブジェクトIDです。 //! @param[in] size メモリサイズです。 //--------------------------------------------------------------------------- void* AllocateGraphicsMemory(GLenum area, GLenum aim, GLuint id, GLsizei size); //--------------------------------------------------------------------------- //! @brief GL や VRAM 用のでアロケート関数です。 //! //! @param[in] area 対象エリア情報です。 //! @param[in] aim メモリを要求している対象です。 //! @param[in] id メモリ要求対象の GL オブジェクトIDです。 //! @param[in] size メモリサイズです。 //--------------------------------------------------------------------------- void DeallocateGraphicsMemory(GLenum area, GLenum aim, GLuint id, void* addr); } // namespace demo } // namespace nw #endif // NW_DEMO_GRAPHICSSYSTEM_H_