/*---------------------------------------------------------------------------* Project: NintendoWare File: main.cpp 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: $ *---------------------------------------------------------------------------*/ #define NW_DEBUG_CHECK_MEMORY_LEAK #include #include #include #include #include #include #include #include #include "../include/SmRenderSystem.h" #include "../include/SmSceneCtrl.h" #include "../include/SmCommandUtility.h" #include "../include/demo.h" #include "../include/framework.h" #include "../include/GfxCtrl.h" #include "../include/LytCtrl.h" #include "../include/SmDef.h" #include "../include/SmPerf.h" #include "../include/SmFile.h" #include "../include/SmPrimitive.h" #include "../include/SmTouchPanelStatus.h" #include "../include/SmPadStatus.h" #include "../include/SmSliderBar.h" #include "../include/SmButton.h" #include "../include/SmCommandUtility.h" namespace { //---------------------------------------- // 描画関係 const int RENDER_TARGET_COUNT = 2; #define DEMO_UPPER_SCREEN (0) #define DEMO_LOWER_SCREEN (1) typedef nw::ut::FixedSizeArray RenderTargetArray; RenderTargetArray s_RenderTargets; SmRenderSystem* s_RenderSystem = NULL; SmSceneCtrl* s_GfxSceneCtrl = NULL; //---------------------------------------- // メモリ関係 nw::demo::DemoAllocator s_DeviceAllocator; //nw::demo::DemoDeviceMemoryAllocator s_DeviceAllocator; //---------------------------------------- // 各オブジェクト群管理 // Gfxオブジェクトの管理 GfxCtrl* s_GfxCtrl = NULL; // Lytオブジェクトの管理 LytCtrl* s_LytCtrl = NULL; // デモ Demo* s_Demo = NULL; // フレームワークのステータス FrameWorkStatus s_FrameStatus; //---------------------------------------- // OpenGL描画関係 SmOgl* s_SmOgl = NULL; //---------------------------------------- // パフォーマンス計測 SmCpuPerf* s_CpuPerf = NULL; SmGpuPerf* s_GpuPerf = NULL; SmPerfDrawer* s_PerfDrawer = NULL; //---------------------------------------- // 視差カメラ nw::gfx::Camera* s_LeftCamera = NULL; nw::gfx::Camera* s_RightCamera = NULL; //---------------------------------------- // 静的なコマンドキャッシュ SmStaticCommandCache* s_StaticCommandCache = NULL; // レイアウト、OpenGL用のコマンドキャッシュ GLuint s_LytCmdCacheList = 0; GLuint s_OglCmdCacheList = 0; const s32 s_BaseCameraIndex = 0; const s32 s_PadCameraIndex = 1; /*!--------------------------------------------------------------------------* @brief グラフィックス関連の初期化を行います。 *---------------------------------------------------------------------------*/ void InitializeGraphics() { // SmBase にアローケータを設定します。 SmBase::SetAllocator( &s_DeviceAllocator, &s_DeviceAllocator ); nw::gfx::CommandCacheManager::SetAllocator( &s_DeviceAllocator ); // renderDescriptionへの標準的な設定はコンストラクタで行われています。 SmRenderSystem::Description renderDescription; { // レンダーシステム生成します。 s_RenderSystem = new SmRenderSystem( renderDescription ); // レンダターゲットの生成します。 s_RenderTargets.push_back( nw::gfx::IRenderTarget::Builder() .BufferSize( renderDescription.upperScreenDescription.height, renderDescription.upperScreenDescription.width ) .ColorFormat(renderDescription.renderColorFormat) .Create(&s_DeviceAllocator) ); NW_ASSERT(!s_RenderTargets.empty()); // s_RenderSystem->GetRenderContext()->SetRenderTarget(s_RenderTargets.front()); s_RenderTargets.push_back( nw::gfx::IRenderTarget::Builder() .BufferSize( renderDescription.lowerScreenDescription.height, renderDescription.lowerScreenDescription.width ) .ColorFormat(renderDescription.renderColorFormat) .Create(&s_DeviceAllocator) ); NW_ASSERT(!s_RenderTargets.empty()); } // SmOgl(OpenGLラッパ) を初期化します。 s_SmOgl = SmOgl::InitializeSmOgl( NW_DEMO_FILE_PATH(L"shader.shbin") ); // 静的なコマンドキャッシュを生成。 s_StaticCommandCache = new SmStaticCommandCache(); // レイアウト、OpenGL用のコマンドキャッシュを生成します。 GLint currentCmdList; nngxGetCmdlistParameteri( NN_GX_CMDLIST_BINDING, ¤tCmdList ); { nngxGenCmdlists( 1, &s_LytCmdCacheList ); nngxBindCmdlist( s_LytCmdCacheList ); nngxCmdlistStorage( 0x40000, 128 ); nngxSetCmdlistParameteri(NN_GX_CMDLIST_RUN_MODE, NN_GX_CMDLIST_SERIAL_RUN); nngxGenCmdlists( 1, &s_OglCmdCacheList ); nngxBindCmdlist( s_OglCmdCacheList ); nngxCmdlistStorage( 0x40000, 128 ); nngxSetCmdlistParameteri(NN_GX_CMDLIST_RUN_MODE, NN_GX_CMDLIST_SERIAL_RUN); } nngxBindCmdlist(currentCmdList); NW_GL_ASSERT(); } /*!--------------------------------------------------------------------------* @brief グラフィックス関連の後始末をします。 *---------------------------------------------------------------------------*/ void TerminateGraphics() { // 静的なコマンドキャッシュを破棄 SM_SAFE_DELETE( s_StaticCommandCache ); // SmOgl 終了 SmOgl::TerminateSmOgl(); // レンダーターゲット破棄 nw::gfx::SafeDestroyAll(s_RenderTargets); // レンダーシステム破棄 SM_SAFE_DELETE( s_RenderSystem ); NW_GL_ASSERT(); } /*!--------------------------------------------------------------------------* @brief Gfx関連の初期化を行います。 *---------------------------------------------------------------------------*/ void InitializeGfx() { // SmSceneCtrlの生成 s_GfxSceneCtrl = new SmSceneCtrl( s_RenderSystem->GetRenderContext() ); // GfxCtrl 生成 s_GfxCtrl = new GfxCtrl( s_GfxSceneCtrl ); NW_NULL_ASSERT( s_GfxCtrl ); // 処理バー関連 s_CpuPerf = new SmCpuPerf(); NW_NULL_ASSERT( s_CpuPerf ); s_GpuPerf = new SmGpuPerf(); NW_NULL_ASSERT( s_GpuPerf ); s_PerfDrawer = new SmPerfDrawer(); NW_NULL_ASSERT( s_PerfDrawer ); } /*!--------------------------------------------------------------------------* @brief Gfx関連のの後始末を行います。 *---------------------------------------------------------------------------*/ void TerminateGfx() { SM_SAFE_DELETE(s_GfxCtrl); SM_SAFE_DELETE(s_CpuPerf); SM_SAFE_DELETE(s_GpuPerf); SM_SAFE_DELETE(s_PerfDrawer); SM_SAFE_DELETE(s_GfxSceneCtrl); } /*!--------------------------------------------------------------------------* @brief Lyt関連の初期化を行います。 *---------------------------------------------------------------------------*/ void InitializeLyt() { // LytCtrl 生成 s_LytCtrl = new LytCtrl(); NW_NULL_ASSERT( s_LytCtrl ); } /*!--------------------------------------------------------------------------* @brief Gfx関連のの後始末を行います。 *---------------------------------------------------------------------------*/ void TerminateLyt() { SM_SAFE_DELETE(s_LytCtrl); } /*!--------------------------------------------------------------------------* @brief ログ出力を行います。 *---------------------------------------------------------------------------*/ void OutputLog() { f32 cpuCost = 0.f; f32 gpuCost = 0.f; /* NW_DEV_LOG( "\n[COST LOG]\n" ); NW_DEV_LOG( "RED :GFX\n" ); NW_DEV_LOG( "BLUE :SYS\n" ); NW_DEV_LOG( "GREEN :LYT\n" ); NW_DEV_LOG( "YELLOW:PERFORMANCE METER\n" ); */ NW_DEV_LOG( "\n[CPU COST LOG]\n" ); for ( int i = 0; i < s_CpuPerf->GetCostCount(); i++ ) { // NW_DEV_LOG( "%s:%8.4f[%8.4f%%]\n", s_CpuPerf->GetCostName(i), s_CpuPerf->GetCost(i), s_CpuPerf->GetCost(i)/16.666f*100.f ); cpuCost += s_CpuPerf->GetCost(i); } NW_DEV_LOG( "CPU COST:%8.4f[%8.4f%%]\n", cpuCost, cpuCost/16.666f*100.f ); NW_DEV_LOG( "[GPU COST LOG]\n" ); for ( int i = 0; i < s_GpuPerf->GetCostCount(); i++ ) { // NW_DEV_LOG( "%s:%8.4f[%8.4f%%]\n", s_GpuPerf->GetCostName(i), s_GpuPerf->GetCost(i), s_GpuPerf->GetCost(i)/16.666f*100.f ); gpuCost += s_GpuPerf->GetCost(i); } NW_DEV_LOG( "GPU COST:%8.4f[%8.4f%%]\n\n", gpuCost, gpuCost/16.666f*100.f ); } /*!--------------------------------------------------------------------------* @brief タッチパネルメッセージ処理を行います。 *---------------------------------------------------------------------------*/ SmMessageType SendTouchPanelMassage( SmTouchPanelStatus& touchPanelStatus ) { SmMessageType messageType = SM_MESSAGE_NONE; // タッチパネルメッセージ static u16 touchPanelX = 0; static u16 touchPanelY = 0; // 現状を、press, release, motion に分けて、メッセージを送信します。 messageType = SM_MESSAGE_NONE; // Press ? if ( ( touchPanelX == 0 && touchPanelStatus.GetX() != 0 ) || ( touchPanelY == 0 && touchPanelStatus.GetY() != 0 ) ) { messageType = SM_MESSAGE_TUCHPANEL_PRESS; } else // Release ? if ( ( touchPanelX != 0 && touchPanelStatus.GetX() == 0 ) || ( touchPanelY != 0 && touchPanelStatus.GetY() == 0 ) ) { messageType = SM_MESSAGE_TUCHPANEL_RELEASE; } else // Motion ? if ( ( touchPanelX != touchPanelStatus.GetX() ) || ( touchPanelY != touchPanelStatus.GetY() ) ) { messageType = SM_MESSAGE_TUCHPANEL_MOTION; } else if ( touchPanelStatus.IsGrab() ) { messageType = SM_MESSAGE_TUCHPANEL_MOTION; // 掴まれている場合は、MOTIONに } touchPanelX = touchPanelStatus.GetX(); touchPanelY = touchPanelStatus.GetY(); // デモ対してメッセージを送信 if ( messageType != SM_MESSAGE_NONE ) { s_Demo->SendMessage( messageType, &touchPanelStatus ); } return messageType; } /*!--------------------------------------------------------------------------* @brief パッドメッセージ処理を行います。 *---------------------------------------------------------------------------*/ void SendPadMassage( SmPadStatus& padStatus ) { // フレームワークのパッド操作 if ( padStatus.IsHold( SmPadStatus::SM_BUTTON_R ) ) { // ログ出力 if ( padStatus.IsTrigger( SmPadStatus::SM_BUTTON_A ) ) { OutputLog(); } // コマンドダブルバッファ有効/無効 if ( padStatus.IsTrigger( SmPadStatus::SM_BUTTON_B ) ) { s_FrameStatus.SwapCommandBufferMode(); } // レイアウトの有効/無効 if ( padStatus.IsTrigger( SmPadStatus::SM_BUTTON_Y ) ) { s_FrameStatus.SwapLayoutVisible(); } // CpuMeterの有効/無効 if ( padStatus.IsTrigger( SmPadStatus::SM_BUTTON_X ) ) { s_FrameStatus.SwapCpuMeterVisible(); } } else { // 再生開始/停止 if ( padStatus.IsTrigger( SmPadStatus::SM_BUTTON_A ) ) { s_FrameStatus.SwapPlay(); } // こま送り if ( padStatus.IsTrigger( SmPadStatus::SM_BUTTON_X ) ) { s_FrameStatus.SetAddFrame(); } // 巻き戻し if ( padStatus.IsTrigger( SmPadStatus::SM_BUTTON_B ) ) { s_FrameStatus.SetFrame( 0.f ); s_Demo->Reset(); NW_DEV_LOG( "[DEMO] Demo Reset\n\n" ); } // 隠しログ出力 if ( padStatus.IsTrigger( SmPadStatus::SM_BUTTON_L ) ) { NW_DEV_LOG( "[DEMO] FRAME_END - START:%8.4f[%8.4f%%]\n", s_FrameStatus.GetAllTime(), s_FrameStatus.GetAllTime()/16.666f ); NW_DEV_LOG( "[DEMO] WAIT GPU :%8.4f[%8.4f%%]\n", s_FrameStatus.GetGpuWaitTime(), s_FrameStatus.GetGpuWaitTime()/16.666f ); NW_DEV_LOG( "[DEMO] COMMNAD REQ COUNT :%d\n", s_FrameStatus.GetUsedReqCount() ); NW_DEV_LOG( "[DEMO] STEREO PARAM LEVEL :%f\n", s_Demo->GetStereoLevel() ); NW_DEV_LOG( "[DEMO] STEREO PARAM RANGE :%f\n", s_Demo->GetStereoRange() ); s_GfxCtrl->OutputLog(); NW_DEV_LOG( "\n" ); } } // デモ対してメッセージを送信 s_Demo->SendMessage( SM_MESSAGE_PAD_UPDATE, &padStatus ); } /*!--------------------------------------------------------------------------* @brief 処理計測マクロ。 *---------------------------------------------------------------------------*/ #define _SET_PERF_CPU_BEGIN( costName, costColor ) \ s_CpuPerf->Begin( costName, costColor ); \ #define _SET_PERF_CPU_END() \ s_CpuPerf->End(); \ #define _SET_PERF_GPU_BEGIN( costName, costColor ) \ s_GpuPerf->Begin( costName, costColor ); \ #define _SET_PERF_GPU_END() \ s_GpuPerf->End(); \ /*!--------------------------------------------------------------------------* @brief Gfx(上画面)のコマンドキャッシュを生成します。 *---------------------------------------------------------------------------*/ void CreateGfxCache( SmCommandReuser& CmdReuser, s32 CameraIndex, nw::gfx::Camera* CurrentCamera, SmRenderSystem::CommandBufferSide side ) { // シーン更新します。 _SET_PERF_CPU_BEGIN( "GFX :Update Scene ", nw::ut::Color8::RED ); { bool bUpdate = true; // レンダコンテキストをリセットします。 nw::gfx::RenderContext* renderContext = s_RenderSystem->GetRenderContext(); renderContext->ResetState(); // デモコンテンツの処理を行います。 // 60fpsを切るようであれば、加算するフレーム数を2.f~3.fに変更します。 if ( s_FrameStatus.IsPlaying() ) { if ( s_FrameStatus.GetAllTime() > 33.33f ) { s_FrameStatus.AddFrame( 3.f ); } else if ( s_FrameStatus.GetAllTime() > 16.66f ) { s_FrameStatus.AddFrame( 2.f ); } else { s_FrameStatus.AddFrame( 1.f ); } } else { if ( s_FrameStatus.GetAddFrame() ) { s_FrameStatus.AddFrame( 1.f ); } else { bUpdate = false; } } // デモに現在のフレームを設定します。 s_Demo->Exec( s_FrameStatus.GetFrame() ); // フレームが未更新であれば更新処理を行いません。 if ( bUpdate ) { // シーンの更新を行います。 s_GfxSceneCtrl->UpdateScene(); // Smシーンのアップデートを行います。 s_GfxCtrl->Update(); } // ライト等の描画環境をセットします。 // s_GfxSceneCtrl->SetEnvironment(CameraIndex); renderContext->SetActiveCamera(CameraIndex); // カメラ・フォグ更新、描画ソートなどの処理を行います。 s_GfxSceneCtrl->SubmitView(CurrentCamera); } _SET_PERF_CPU_END(); // コマンドキャッシュを生成します _SET_PERF_CPU_BEGIN( "GFX :Create Command Cache ", nw::ut::Color8::RED ); { CmdReuser.StartCaching( s_RenderSystem->GetCacheCmdListUpper(side) ); { s_GfxSceneCtrl->Render(); } CmdReuser.EndCaching(); } _SET_PERF_CPU_END(); /* u32 uframe = s_FrameStatus.GetFrame(); if (uframe % 200 == 0) { NW_DEV_LOG( "CMD BUFF SIZE:%d\n", CmdReuser.GetCacheSize() ); } */ } /*!--------------------------------------------------------------------------* @brief レイアウトのコマンドキャッシュを生成する。 *---------------------------------------------------------------------------*/ void CreateLayoutCache( SmCommandReuser& CmdReuser ) { CmdReuser.StartCaching( s_LytCmdCacheList ); { s_LytCtrl->Render(); } CmdReuser.EndCaching(); } /*!--------------------------------------------------------------------------* @brief シーンをデモンストレーションします。 *---------------------------------------------------------------------------*/ void DemoScene() { NW_ASSERT(!s_RenderTargets.empty()); nw::gfx::Camera* currentCamera = NULL; nw::gfx::RenderContext* renderContext = s_RenderSystem->GetRenderContext(); InitializeGfx(); InitializeLyt(); // デモクラス再生クラスを生成 // デモクラスでは、Gfxオブジェクトやレイアウトの管理を行います。 { s_Demo = new Demo( s_GfxCtrl, s_LytCtrl ); s_Demo->InitializeScene(); } // シーンの初期化と更新をします。 s_GfxSceneCtrl->InitializeScene( s_GfxCtrl->GetSceneRoot()); s_GfxSceneCtrl->UpdateScene(); // シーン環境の参照解決を行い設定します。 s_GfxSceneCtrl->SetSceneEnvironmentSetting(s_GfxCtrl->GetSceneEnvSetting()); // カメラを設定します。 SmCamera* pSmCamera = s_GfxCtrl->GetSmCamera(); nw::gfx::SceneEnvironment& sceneEnvironment = renderContext->GetSceneEnvironment(); sceneEnvironment.SetCamera(s_BaseCameraIndex, pSmCamera->GetBaseCamera()); sceneEnvironment.SetCamera(s_PadCameraIndex, pSmCamera->GetPadCamera()); // カメラのアスペクト比をセット nw::demo::Utility::SetCameraAspectRatio(s_GfxCtrl->GetCamera(), s_RenderTargets[0]); // ステレオ用のカメラを生成 { s_LeftCamera = nw::gfx::Camera::DynamicBuilder() .MaxChildren(0) .MaxCallbacks(0) .Create(&s_DeviceAllocator); s_RightCamera = nw::gfx::Camera::DynamicBuilder() .MaxChildren(0) .MaxCallbacks(0) .Create(&s_DeviceAllocator); } // コマンド SmCommandReuser CmdReuser; SmCommandReuser CmdReuserLyt; SmCommandReuser CmdReuserOgl; bool firstLoop = true; bool preMassageType = SM_MESSAGE_NONE; SmRenderSystem::CommandBufferSide commandBuffSide = SmRenderSystem::COMMAND_BUFFER_SIZE_0; SmTouchPanelStatus touchPanelStatus; SmPadStatus padStatus; nn::hid::CTR::PadReader padReader; nn::hid::CTR::TouchPanelReader touchPanelReader; #define TRANSPARENCY_COLOR (0) // 操作説明をログ出力します。 { NW_DEV_LOG( "[DEMO] PAD_A:PLAY/STOP\n" ); NW_DEV_LOG( "[DEMO] PAD_X:ADD FRAME\n" ); NW_DEV_LOG( "[DEMO] PAD_R+A:OUTPUT LOG\n" ); NW_DEV_LOG( "[DEMO] PAD_R+B:COMMAND BUFFER DOUBLE/SINGLE SWAP\n" ); NW_DEV_LOG( "[DEMO] PAD_R+Y:LAYOUT DRAW ON/OFF\n" ); NW_DEV_LOG( "[DEMO] PAD_R+X:CPU METER DRAW ON/OFF\n" ); NW_DEV_LOG( "\n" ); } /* [メインループ] ・シングルバッファモードの場合は、以下の順番で処理が行われます。   Gfxシーン更新、コマンドキャッシュ生成 → ステレオ描画 → レイアウト → 処理メータ(OpenGL) ・ダブルバッファモードの場合は、以下の順番で処理が行われます。   ステレオ描画 → レイアウト → 処理メータ(OpenGL) → Gfxシーン更新、コマンドキャッシュ生成 ・バッファクリア等の処理は、ステージ描画で行っています。 ・レイアウトのコマンドキャッシュはユーザー操作等で変更があった場合のみ行っています。 ・デモ内で生成されるクラスはSmMessageクラスから派生されており、  タッチパネルやパッド、UI操作からのメッセージなどの処理を行っています。 */ while ( ! nw::demo::Utility::IsTerminating() ) { // 処理計測をリセット s_CpuPerf->Reset(); s_GpuPerf->Reset(); // フレームの先頭タイムを記録します。 s_FrameStatus.SetTimerStart(); // タッチパネルメッセージ処理を行います。 touchPanelReader.ReadLatest( touchPanelStatus.GetHidTouchPanelStatus() ); SmMessageType touchPanelMessageType = SendTouchPanelMassage( touchPanelStatus ); // パッドメッセージ処理を行います。 padReader.ReadLatest( padStatus.GetHidPadStatus() ); SendPadMassage( padStatus ); // カレントのカメラを取得します。 currentCamera = s_GfxCtrl->GetCamera(); NW_NULL_ASSERT( currentCamera ); // カメラのアスペクト比をセットします。 nw::demo::Utility::SetCameraAspectRatio(currentCamera, s_RenderTargets[0]); // 上画面へ切り替え { s_RenderSystem->SetRenderTarget(s_RenderTargets[DEMO_UPPER_SCREEN]); nngxValidateState(NN_GX_STATE_FRAMEBUFFER, GL_TRUE); } // シングルバッファの場合は、CPU待ち時間を考慮をメータに記録します。 if ( !s_FrameStatus.IsCommandBufferDouble() ) { _SET_PERF_GPU_BEGIN( "CPU WAIT ", nw::ut::Color8::RED ); } // コマンドのシングルバッファモードの場合は、 // このタイミングでコマンドキャッシュの生成を行います。 if ( !s_FrameStatus.IsCommandBufferDouble() ) { if( pSmCamera->IsPadCamera() ) { CreateGfxCache( CmdReuser, s_PadCameraIndex, currentCamera, commandBuffSide ); } else { CreateGfxCache( CmdReuser, s_BaseCameraIndex, currentCamera, commandBuffSide ); } } // シングルバッファの場合は、CPU待ち時間を考慮をメータに記録します。 if ( !s_FrameStatus.IsCommandBufferDouble() ) { _SET_PERF_GPU_END(); } // GPU処理計測開始します。 _SET_PERF_GPU_BEGIN( "GPU_ALL_COST ", nw::ut::Color8::BLUE ); // キャッシュ(CreateGfxCache)したコマンドを利用して // 左右のスクリーンを描画します。 _SET_PERF_CPU_BEGIN( "GFX :CommandCache Copy ", nw::ut::Color8::RED ); if ( CmdReuser.IsCache() ) { // 視差計算を行います。 { nw::gfx::ResCameraProjectionUpdater resProjectionUpdater = currentCamera->GetProjectionUpdater()->GetResource(); NW_ASSERT(resProjectionUpdater.IsValid()); // UIからの視差パラメータ入力 f32 flevel = s_Demo->GetStereoLevel() * (resProjectionUpdater.GetFar() - resProjectionUpdater.GetNear()) + resProjectionUpdater.GetNear(); f32 frange = s_Demo->GetStereoRange(); s_RenderSystem->CalcStereoCamera( s_LeftCamera, s_RightCamera, currentCamera, flevel, frange); } // 左目の映像を描画します。 renderContext->SetCameraMatrix( s_LeftCamera ); CmdReuser.UseCommand(true); // 1スプリット追加 s_RenderSystem->TransferBuffer(nw::demo::UPPER_SCREEN); // ステレオ描画モードの場合は、描画を行います。 if ( s_Demo->IsStereoEnable() ) { renderContext->SetCameraMatrix( s_RightCamera ); CmdReuser.UseCommand(true); // 1スプリット追加されます。 s_RenderSystem->TransferBuffer(nw::demo::EXTENSION_SCREEN); } } _SET_PERF_CPU_END(); // 下画面へ切り替えます。 _SET_PERF_CPU_BEGIN( "SYS :RenderTarget Change ", nw::ut::Color8::BLUE ); { s_RenderSystem->SetRenderTarget(s_RenderTargets[DEMO_LOWER_SCREEN]); nngxValidateState(NN_GX_STATE_FRAMEBUFFER, GL_TRUE); glBindFramebuffer(GL_FRAMEBUFFER, s_RenderSystem->GetRenderContext()->GetRenderTarget()->GetBufferObject()); } _SET_PERF_CPU_END(); // レイアウトを描画しないのであれば処理をスキップします。 if ( !s_FrameStatus.IsLayoutVisible() ) goto layout_end; // メッセージが存在する場合のみコマンドキャッシュを生成します。 // タッチパネルが操作された場合やデモ内でレイアウトが更新された場合等のみ // コマンドキャッシュの生成を行います。 _SET_PERF_CPU_BEGIN( "LYT :Calc ", nw::ut::Color8::GREEN ); if ( firstLoop || touchPanelMessageType != SM_MESSAGE_NONE || preMassageType != SM_MESSAGE_NONE || s_Demo->IsLytUpdate() ) { CreateLayoutCache( CmdReuserLyt ); } _SET_PERF_CPU_END(); // キャッシュしたコマンドを利用してレイアウトの描画を行います。 _SET_PERF_CPU_BEGIN( "LYT :CommandCache Copy ", nw::ut::Color8::GREEN ); { if ( CmdReuserLyt.IsCache() ) { CmdReuserLyt.UseCommand(true); } } _SET_PERF_CPU_END(); layout_end: // Cpuメータ(OpenGL描画部分)を処理しないのであれば処理をスキップします。 if ( !s_FrameStatus.IsCpuMeterVisible() ) goto cpumeter_end; // Cpuメータでの描画を行います。 _SET_PERF_CPU_BEGIN( "PERF:Performance Meter ", nw::ut::Color8::YELLOW ); { { //glBindFramebuffer(GL_FRAMEBUFFER, s_RenderSystem->GetRenderContext()->GetRenderTarget()->GetBufferObject()); nngxUpdateState(NN_GX_STATE_ALL); s_SmOgl->SetBegin2D(); s_PerfDrawer->Render( s_CpuPerf, s_GpuPerf ); } } _SET_PERF_CPU_END(); cpumeter_end: _SET_PERF_CPU_BEGIN( "SYS :Transfer BUffer ", nw::ut::Color8::BLUE ); { s_RenderSystem->TransferBuffer(nw::demo::LOWER_SCREEN); } _SET_PERF_CPU_END(); // ダブルバッファモードの場合、このタイミングでコマンドキャッシュを生成します。 if ( s_FrameStatus.IsCommandBufferDouble() ) { // Gfxコマンド生成 if( pSmCamera->IsPadCamera() ) { CreateGfxCache( CmdReuser, s_PadCameraIndex, currentCamera, commandBuffSide ); } else { CreateGfxCache( CmdReuser, s_BaseCameraIndex, currentCamera, commandBuffSide ); } // コマンドバッファのスワップ(ダブルの場合のみ) if (commandBuffSide == SmRenderSystem::COMMAND_BUFFER_SIZE_0) { commandBuffSide = SmRenderSystem::COMMAND_BUFFER_SIZE_1; } else { commandBuffSide = SmRenderSystem::COMMAND_BUFFER_SIZE_0; } } // 総コマンドリクエストカウントを取得します。 s_FrameStatus.UpdateUsedReqCount(); // GPU実行待ち s_FrameStatus.SetGpuWaitStart(); { s_RenderSystem->WaitCommandList(); s_RenderSystem->SwapBuffer(nw::demo::UPPER_SCREEN | nw::demo::LOWER_SCREEN | nw::demo::EXTENSION_SCREEN); } s_FrameStatus.SetGpuWaitEnd(); // GPU処理計測はここまで。 _SET_PERF_GPU_END(); // 1フレームにかかった全ての時間を計算します。 s_FrameStatus.SetTimerEnd(); /* // todo:nngxValidateStateのタイミングでは、OpenGLの描画がずれてしまう。 // 上画面へ切り替え { s_RenderSystem->SetRenderTarget(s_RenderTargets[DEMO_UPPER_SCREEN]); nngxValidateState(NN_GX_STATE_FRAMEBUFFER, GL_TRUE); } */ // Sync待ち s_RenderSystem->WaitVSync(nw::demo::UPPER_SCREEN | nw::demo::LOWER_SCREEN | nw::demo::EXTENSION_SCREEN); // 各種、フレーム終了処理を行います。 firstLoop = false; preMassageType = touchPanelMessageType; } // ステレオ用カメラを破棄します。 nw::gfx::SafeDestroy(s_LeftCamera); nw::gfx::SafeDestroy(s_RightCamera); SM_SAFE_DELETE( s_Demo ); TerminateGfx(); TerminateLyt(); } } // namespace /*!--------------------------------------------------------------------------* @brief メイン関数です。 *---------------------------------------------------------------------------*/ void nnMain() { // グラフィックシステムの初期化 SmInitializeGraphicsSystem( &s_DeviceAllocator ); // レイアウトライブラリの初期化。 nw::lyt::Initialize(&s_DeviceAllocator, &s_DeviceAllocator); // タッチパネル初期化します。 nn::hid::CTR::Initialize(); { InitializeGraphics(); nw::demo::PadFactory::Initialize(&s_DeviceAllocator); { DemoScene(); } nw::demo::PadFactory::Finalize(); TerminateGraphics(); } // グラフィックシステムの終了 SmFinalizeGraphicsSystem( &s_DeviceAllocator ); }