1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     SimpleDemo.cpp
4 
5   Copyright (C)2009-2010 Nintendo Co., Ltd./HAL Laboratory, Inc.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law.  They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Revision: 18469 $
14  *---------------------------------------------------------------------------*/
15 
16 
17 #define NW_DEBUG_CHECK_MEMORY_LEAK
18 
19 
20 #include <nn/os.h>
21 #include <nn/fs.h>
22 #include <nn/hid/CTR/hid_TouchPanelReader.h>
23 
24 #include <nw/types.h>
25 #include <nw/dev.h>
26 #include <nw/gfx.h>
27 #include <nw/ut.h>
28 #include <nw/lyt.h>
29 
30 #include "../include/SmRenderSystem.h"
31 #include "../include/SmSceneCtrl.h"
32 #include "../include/SmCommandUtility.h"
33 #include "../include/demo.h"
34 #include "../include/framework.h"
35 #include "../include/GfxCtrl.h"
36 #include "../include/LytCtrl.h"
37 #include "../include/SmDef.h"
38 #include "../include/SmPerf.h"
39 #include "../include/SmFile.h"
40 #include "../include/SmPrimitive.h"
41 #include "../include/SmTouchPanelStatus.h"
42 #include "../include/SmPadStatus.h"
43 #include "../include/SmSliderBar.h"
44 #include "../include/SmButton.h"
45 #include "../include/SmCommandUtility.h"
46 
47 
48 namespace
49 {
50 
51 //----------------------------------------
52 // 描画関係
53 const int RENDER_TARGET_COUNT = 2;
54 #define DEMO_UPPER_SCREEN    (0)
55 #define DEMO_LOWER_SCREEN    (1)
56 typedef nw::ut::FixedSizeArray<nw::gfx::IRenderTarget*, RENDER_TARGET_COUNT> RenderTargetArray;
57 RenderTargetArray           s_RenderTargets;
58 
59 SmRenderSystem*             s_RenderSystem = NULL;
60 SmSceneCtrl*                s_GfxSceneCtrl = NULL;
61 
62 //----------------------------------------
63 // メモリ関係
64 nw::demo::DemoAllocator     s_DeviceAllocator;
65 //nw::demo::DemoDeviceMemoryAllocator         s_DeviceAllocator;
66 
67 
68 //----------------------------------------
69 // 各オブジェクト群管理
70 
71 // Gfxオブジェクトの管理
72 GfxCtrl*    s_GfxCtrl       = NULL;
73 
74 // Lytオブジェクトの管理
75 LytCtrl*    s_LytCtrl       = NULL;
76 
77 // デモ
78 Demo*       s_Demo          = NULL;
79 
80 // フレームワークのステータス
81 FrameWorkStatus s_FrameStatus;
82 
83 
84 //----------------------------------------
85 // OpenGL描画関係
86 SmOgl*      s_SmOgl     = NULL;
87 
88 
89 //----------------------------------------
90 // パフォーマンス計測
91 SmCpuPerf*      s_CpuPerf = NULL;
92 SmGpuPerf*      s_GpuPerf = NULL;
93 SmPerfDrawer*   s_PerfDrawer = NULL;
94 
95 
96 //----------------------------------------
97 // 視差カメラ
98 nw::gfx::Camera* s_LeftCamera = NULL;
99 nw::gfx::Camera* s_RightCamera = NULL;
100 
101 
102 //----------------------------------------
103 // 静的なコマンドキャッシュ
104 SmStaticCommandCache* s_StaticCommandCache = NULL;
105 
106 // レイアウト、OpenGL用のコマンドキャッシュ
107 GLuint      s_LytCmdCacheList = 0;
108 GLuint      s_OglCmdCacheList = 0;
109 
110 const s32 s_BaseCameraIndex = 0;
111 const s32 s_PadCameraIndex = 1;
112 
113 
114 /*!--------------------------------------------------------------------------*
115   @brief        グラフィックス関連の初期化を行います。
116  *---------------------------------------------------------------------------*/
117 void
InitializeGraphics()118 InitializeGraphics()
119 {
120     // SmBase にアローケータを設定します。
121     SmBase::SetAllocator( &s_DeviceAllocator, &s_DeviceAllocator );
122 
123     nw::gfx::CommandCacheManager::SetAllocator( &s_DeviceAllocator );
124 
125     // renderDescriptionへの標準的な設定はコンストラクタで行われています。
126     SmRenderSystem::Description renderDescription;
127     {
128         // レンダーシステム生成します。
129         s_RenderSystem = new SmRenderSystem( renderDescription );
130 
131         // レンダターゲットの生成します。
132         s_RenderTargets.push_back(
133             nw::gfx::IRenderTarget::Builder()
134                     .BufferSize(
135                         renderDescription.upperScreenDescription.height,
136                         renderDescription.upperScreenDescription.width
137                     )
138                     .ColorFormat(renderDescription.renderColorFormat)
139                     .Create(&s_DeviceAllocator)
140         );
141         NW_ASSERT(!s_RenderTargets.empty());
142 //        s_RenderSystem->GetRenderContext()->SetRenderTarget(s_RenderTargets.front());
143 
144         s_RenderTargets.push_back(
145             nw::gfx::IRenderTarget::Builder()
146                     .BufferSize(
147                         renderDescription.lowerScreenDescription.height,
148                         renderDescription.lowerScreenDescription.width
149                     )
150                     .ColorFormat(renderDescription.renderColorFormat)
151                     .Create(&s_DeviceAllocator)
152         );
153         NW_ASSERT(!s_RenderTargets.empty());
154     }
155 
156     // SmOgl(OpenGLラッパ) を初期化します。
157     s_SmOgl = SmOgl::InitializeSmOgl( NW_DEMO_FILE_PATH(L"shader.shbin") );
158 
159     // 静的なコマンドキャッシュを生成。
160     s_StaticCommandCache = new SmStaticCommandCache();
161 
162     // レイアウト、OpenGL用のコマンドキャッシュを生成します。
163     GLint currentCmdList;
164     nngxGetCmdlistParameteri( NN_GX_CMDLIST_BINDING, &currentCmdList );
165     {
166         nngxGenCmdlists( 1, &s_LytCmdCacheList );
167         nngxBindCmdlist( s_LytCmdCacheList );
168         nngxCmdlistStorage( 0x40000, 128 );
169         nngxSetCmdlistParameteri(NN_GX_CMDLIST_RUN_MODE, NN_GX_CMDLIST_SERIAL_RUN);
170 
171         nngxGenCmdlists( 1, &s_OglCmdCacheList );
172         nngxBindCmdlist( s_OglCmdCacheList );
173         nngxCmdlistStorage( 0x40000, 128 );
174         nngxSetCmdlistParameteri(NN_GX_CMDLIST_RUN_MODE, NN_GX_CMDLIST_SERIAL_RUN);
175     }
176     nngxBindCmdlist(currentCmdList);
177 
178     NW_GL_ASSERT();
179 }
180 
181 
182 /*!--------------------------------------------------------------------------*
183   @brief        グラフィックス関連の後始末をします。
184  *---------------------------------------------------------------------------*/
185 void
TerminateGraphics()186 TerminateGraphics()
187 {
188     // 静的なコマンドキャッシュを破棄
189     SM_SAFE_DELETE( s_StaticCommandCache );
190 
191     // SmOgl 終了
192     SmOgl::TerminateSmOgl();
193 
194     // レンダーターゲット破棄
195     nw::gfx::SafeDestroyAll(s_RenderTargets);
196 
197     // レンダーシステム破棄
198     SM_SAFE_DELETE( s_RenderSystem );
199 
200     NW_GL_ASSERT();
201 }
202 
203 
204 /*!--------------------------------------------------------------------------*
205   @brief       Gfx関連の初期化を行います。
206  *---------------------------------------------------------------------------*/
207 void
InitializeGfx()208 InitializeGfx()
209 {
210     // SmSceneCtrlの生成
211     s_GfxSceneCtrl = new SmSceneCtrl( s_RenderSystem->GetRenderContext() );
212 
213     // GfxCtrl 生成
214     s_GfxCtrl = new GfxCtrl( s_GfxSceneCtrl );
215     NW_NULL_ASSERT( s_GfxCtrl );
216 
217     // 処理バー関連
218     s_CpuPerf       = new SmCpuPerf();
219     NW_NULL_ASSERT( s_CpuPerf );
220     s_GpuPerf       = new SmGpuPerf();
221     NW_NULL_ASSERT( s_GpuPerf );
222 
223     s_PerfDrawer    = new SmPerfDrawer();
224     NW_NULL_ASSERT( s_PerfDrawer );
225 }
226 
227 
228 /*!--------------------------------------------------------------------------*
229   @brief        Gfx関連のの後始末を行います。
230  *---------------------------------------------------------------------------*/
231 void
TerminateGfx()232 TerminateGfx()
233 {
234     SM_SAFE_DELETE(s_GfxCtrl);
235     SM_SAFE_DELETE(s_CpuPerf);
236     SM_SAFE_DELETE(s_GpuPerf);
237     SM_SAFE_DELETE(s_PerfDrawer);
238 
239     SM_SAFE_DELETE(s_GfxSceneCtrl);
240 }
241 
242 
243 /*!--------------------------------------------------------------------------*
244   @brief       Lyt関連の初期化を行います。
245  *---------------------------------------------------------------------------*/
246 void
InitializeLyt()247 InitializeLyt()
248 {
249     // LytCtrl 生成
250     s_LytCtrl = new LytCtrl();
251     NW_NULL_ASSERT( s_LytCtrl );
252 }
253 
254 
255 /*!--------------------------------------------------------------------------*
256   @brief        Gfx関連のの後始末を行います。
257  *---------------------------------------------------------------------------*/
258 void
TerminateLyt()259 TerminateLyt()
260 {
261     SM_SAFE_DELETE(s_LytCtrl);
262 }
263 
264 
265 /*!--------------------------------------------------------------------------*
266   @brief        ログ出力を行います。
267  *---------------------------------------------------------------------------*/
268 void
OutputLog()269 OutputLog()
270 {
271     f32 cpuCost = 0.f;
272     f32 gpuCost = 0.f;
273 /*
274     NW_DEV_LOG( "\n[COST LOG]\n" );
275     NW_DEV_LOG( "RED   :GFX\n" );
276     NW_DEV_LOG( "BLUE  :SYS\n" );
277     NW_DEV_LOG( "GREEN :LYT\n" );
278     NW_DEV_LOG( "YELLOW:PERFORMANCE METER\n" );
279 */
280     NW_DEV_LOG( "\n[CPU COST LOG]\n" );
281     for ( int i = 0; i < s_CpuPerf->GetCostCount(); i++ )
282     {
283 //        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 );
284         cpuCost += s_CpuPerf->GetCost(i);
285     }
286     NW_DEV_LOG( "CPU COST:%8.4f[%8.4f%%]\n", cpuCost, cpuCost/16.666f*100.f );
287     NW_DEV_LOG( "[GPU COST LOG]\n" );
288     for ( int i = 0; i < s_GpuPerf->GetCostCount(); i++ )
289     {
290 //        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 );
291         gpuCost += s_GpuPerf->GetCost(i);
292     }
293     NW_DEV_LOG( "GPU COST:%8.4f[%8.4f%%]\n\n", gpuCost, gpuCost/16.666f*100.f );
294 }
295 
296 
297 /*!--------------------------------------------------------------------------*
298   @brief        タッチパネルメッセージ処理を行います。
299  *---------------------------------------------------------------------------*/
300 SmMessageType
SendTouchPanelMassage(SmTouchPanelStatus & touchPanelStatus)301 SendTouchPanelMassage( SmTouchPanelStatus& touchPanelStatus )
302 {
303     SmMessageType messageType = SM_MESSAGE_NONE;
304 
305     // タッチパネルメッセージ
306     static u16 touchPanelX = 0;
307     static u16 touchPanelY = 0;
308 
309     // 現状を、press, release, motion に分けて、メッセージを送信します。
310     messageType = SM_MESSAGE_NONE;
311 
312     // Press ?
313     if ( ( touchPanelX == 0 && touchPanelStatus.GetX() != 0 ) || ( touchPanelY == 0 && touchPanelStatus.GetY() != 0 ) )
314     {
315         messageType = SM_MESSAGE_TUCHPANEL_PRESS;
316     }
317     else
318     // Release ?
319     if ( ( touchPanelX != 0 && touchPanelStatus.GetX() == 0 ) || ( touchPanelY != 0 && touchPanelStatus.GetY() == 0 ) )
320     {
321         messageType = SM_MESSAGE_TUCHPANEL_RELEASE;
322     }
323     else
324     // Motion ?
325      if ( ( touchPanelX != touchPanelStatus.GetX() ) || ( touchPanelY != touchPanelStatus.GetY() ) )
326     {
327         messageType = SM_MESSAGE_TUCHPANEL_MOTION;
328     }
329     else
330     if ( touchPanelStatus.IsGrab() )
331     {
332         messageType = SM_MESSAGE_TUCHPANEL_MOTION;      // 掴まれている場合は、MOTIONに
333     }
334 
335     touchPanelX = touchPanelStatus.GetX();
336     touchPanelY = touchPanelStatus.GetY();
337 
338     // デモ対してメッセージを送信
339     if ( messageType != SM_MESSAGE_NONE )
340     {
341         s_Demo->SendMessage( messageType, &touchPanelStatus );
342     }
343 
344     return messageType;
345 }
346 
347 
348 /*!--------------------------------------------------------------------------*
349   @brief        パッドメッセージ処理を行います。
350  *---------------------------------------------------------------------------*/
351 void
SendPadMassage(SmPadStatus & padStatus)352 SendPadMassage( SmPadStatus& padStatus )
353 {
354     // フレームワークのパッド操作
355     if ( padStatus.IsHold( SmPadStatus::SM_BUTTON_R ) )
356     {
357         // ログ出力
358         if ( padStatus.IsTrigger( SmPadStatus::SM_BUTTON_A ) )
359         {
360             OutputLog();
361         }
362 
363         // コマンドダブルバッファ有効/無効
364         if ( padStatus.IsTrigger( SmPadStatus::SM_BUTTON_B ) )
365         {
366             s_FrameStatus.SwapCommandBufferMode();
367         }
368 
369         // レイアウトの有効/無効
370         if ( padStatus.IsTrigger( SmPadStatus::SM_BUTTON_Y ) )
371         {
372             s_FrameStatus.SwapLayoutVisible();
373         }
374 
375         // CpuMeterの有効/無効
376         if ( padStatus.IsTrigger( SmPadStatus::SM_BUTTON_X ) )
377         {
378             s_FrameStatus.SwapCpuMeterVisible();
379         }
380     }
381     else
382     {
383         // 再生開始/停止
384         if ( padStatus.IsTrigger( SmPadStatus::SM_BUTTON_A ) )
385         {
386             s_FrameStatus.SwapPlay();
387         }
388 
389         // こま送り
390         if ( padStatus.IsTrigger( SmPadStatus::SM_BUTTON_X ) )
391         {
392             s_FrameStatus.SetAddFrame();
393         }
394 
395         // 巻き戻し
396         if ( padStatus.IsTrigger( SmPadStatus::SM_BUTTON_B ) )
397         {
398             s_FrameStatus.SetFrame( 0.f );
399             s_Demo->Reset();
400             NW_DEV_LOG( "[DEMO] Demo Reset\n\n" );
401         }
402 
403         // 隠しログ出力
404         if ( padStatus.IsTrigger( SmPadStatus::SM_BUTTON_L ) )
405         {
406             NW_DEV_LOG( "[DEMO] FRAME_END - START:%8.4f[%8.4f%%]\n", s_FrameStatus.GetAllTime(), s_FrameStatus.GetAllTime()/16.666f );
407             NW_DEV_LOG( "[DEMO] WAIT GPU         :%8.4f[%8.4f%%]\n", s_FrameStatus.GetGpuWaitTime(), s_FrameStatus.GetGpuWaitTime()/16.666f );
408             NW_DEV_LOG( "[DEMO] COMMNAD REQ COUNT      :%d\n", s_FrameStatus.GetUsedReqCount() );
409             NW_DEV_LOG( "[DEMO] STEREO PARAM LEVEL     :%f\n", s_Demo->GetStereoLevel() );
410             NW_DEV_LOG( "[DEMO] STEREO PARAM RANGE     :%f\n", s_Demo->GetStereoRange() );
411             s_GfxCtrl->OutputLog();
412             NW_DEV_LOG( "\n" );
413         }
414     }
415 
416     // デモ対してメッセージを送信
417     s_Demo->SendMessage( SM_MESSAGE_PAD_UPDATE, &padStatus );
418 }
419 
420 
421 /*!--------------------------------------------------------------------------*
422   @brief        処理計測マクロ。
423  *---------------------------------------------------------------------------*/
424 
425 #define _SET_PERF_CPU_BEGIN( costName, costColor ) \
426     s_CpuPerf->Begin( costName, costColor ); \
427 
428 #define _SET_PERF_CPU_END() \
429     s_CpuPerf->End(); \
430 
431 #define _SET_PERF_GPU_BEGIN( costName, costColor ) \
432     s_GpuPerf->Begin( costName, costColor ); \
433 
434 #define _SET_PERF_GPU_END() \
435     s_GpuPerf->End(); \
436 
437 
438 /*!--------------------------------------------------------------------------*
439   @brief        Gfx(上画面)のコマンドキャッシュを生成します。
440  *---------------------------------------------------------------------------*/
441 void
CreateGfxCache(SmCommandReuser & CmdReuser,s32 CameraIndex,nw::gfx::Camera * CurrentCamera,SmRenderSystem::CommandBufferSide side)442 CreateGfxCache( SmCommandReuser& CmdReuser, s32 CameraIndex, nw::gfx::Camera* CurrentCamera, SmRenderSystem::CommandBufferSide side )
443 {
444    // シーン更新します。
445     _SET_PERF_CPU_BEGIN( "GFX :Update Scene               ", nw::ut::Color8::RED );
446     {
447         bool bUpdate = true;
448 
449         // レンダコンテキストをリセットします。
450         nw::gfx::RenderContext* renderContext = s_RenderSystem->GetRenderContext();
451         renderContext->ResetState();
452 
453         // デモコンテンツの処理を行います。
454         // 60fpsを切るようであれば、加算するフレーム数を2.f~3.fに変更します。
455          if ( s_FrameStatus.IsPlaying() )
456         {
457             if ( s_FrameStatus.GetAllTime() > 33.33f )
458             {
459                 s_FrameStatus.AddFrame( 3.f );
460             }
461             else
462             if ( s_FrameStatus.GetAllTime() > 16.66f )
463             {
464                 s_FrameStatus.AddFrame( 2.f );
465             }
466             else
467             {
468                  s_FrameStatus.AddFrame( 1.f );
469             }
470         }
471         else
472         {
473             if ( s_FrameStatus.GetAddFrame() )
474             {
475                 s_FrameStatus.AddFrame( 1.f );
476             }
477             else
478             {
479                 bUpdate = false;
480             }
481         }
482 
483         // デモに現在のフレームを設定します。
484         s_Demo->Exec( s_FrameStatus.GetFrame() );
485 
486         // フレームが未更新であれば更新処理を行いません。
487         if ( bUpdate )
488         {
489             // シーンの更新を行います。
490             s_GfxSceneCtrl->UpdateScene();
491 
492             // Smシーンのアップデートを行います。
493             s_GfxCtrl->Update();
494         }
495 
496         // ライト等の描画環境をセットします。
497 //        s_GfxSceneCtrl->SetEnvironment(CameraIndex);
498         renderContext->SetActiveCamera(CameraIndex);
499 
500         // カメラ・フォグ更新、描画ソートなどの処理を行います。
501         s_GfxSceneCtrl->SubmitView(CurrentCamera);
502     }
503     _SET_PERF_CPU_END();
504 
505      // コマンドキャッシュを生成します
506     _SET_PERF_CPU_BEGIN( "GFX :Create Command Cache       ", nw::ut::Color8::RED );
507     {
508         CmdReuser.StartCaching( s_RenderSystem->GetCacheCmdListUpper(side) );
509         {
510             s_GfxSceneCtrl->Render();
511         }
512         CmdReuser.EndCaching();
513     }
514     _SET_PERF_CPU_END();
515 /*
516     u32 uframe = s_FrameStatus.GetFrame();
517     if (uframe % 200 == 0)
518     {
519         NW_DEV_LOG( "CMD BUFF SIZE:%d\n", CmdReuser.GetCacheSize() );
520     }
521 */
522 }
523 
524 
525 /*!--------------------------------------------------------------------------*
526   @brief        レイアウトのコマンドキャッシュを生成する。
527  *---------------------------------------------------------------------------*/
528 void
CreateLayoutCache(SmCommandReuser & CmdReuser)529 CreateLayoutCache( SmCommandReuser& CmdReuser )
530 {
531     CmdReuser.StartCaching( s_LytCmdCacheList );
532     {
533         s_LytCtrl->Render();
534     }
535     CmdReuser.EndCaching();
536 }
537 
538 
539 /*!--------------------------------------------------------------------------*
540   @brief        シーンをデモンストレーションします。
541  *---------------------------------------------------------------------------*/
542 void
DemoScene()543 DemoScene()
544 {
545     NW_ASSERT(!s_RenderTargets.empty());
546 
547     nw::gfx::Camera* currentCamera = NULL;
548 
549     nw::gfx::RenderContext* renderContext = s_RenderSystem->GetRenderContext();
550 
551     InitializeGfx();
552     InitializeLyt();
553 
554     // デモクラス再生クラスを生成
555     // デモクラスでは、Gfxオブジェクトやレイアウトの管理を行います。
556     {
557         s_Demo  = new Demo( s_GfxCtrl, s_LytCtrl );
558         s_Demo->InitializeScene();
559     }
560 
561     // シーンの初期化と更新をします。
562     s_GfxSceneCtrl->InitializeScene( s_GfxCtrl->GetSceneRoot());
563     s_GfxSceneCtrl->UpdateScene();
564 
565     // シーン環境の参照解決を行い設定します。
566     s_GfxSceneCtrl->SetSceneEnvironmentSetting(s_GfxCtrl->GetSceneEnvSetting());
567 
568     // カメラを設定します。
569     SmCamera* pSmCamera = s_GfxCtrl->GetSmCamera();
570     nw::gfx::SceneEnvironment& sceneEnvironment = renderContext->GetSceneEnvironment();
571     sceneEnvironment.SetCamera(s_BaseCameraIndex, pSmCamera->GetBaseCamera());
572     sceneEnvironment.SetCamera(s_PadCameraIndex, pSmCamera->GetPadCamera());
573 
574     // カメラのアスペクト比をセット
575     nw::demo::Utility::SetCameraAspectRatio(s_GfxCtrl->GetCamera(), s_RenderTargets[0]);
576 
577     // ステレオ用のカメラを生成
578     {
579         s_LeftCamera =
580             nw::gfx::Camera::DynamicBuilder()
581             .MaxChildren(0)
582             .MaxCallbacks(0)
583             .Create(&s_DeviceAllocator);
584 
585         s_RightCamera =
586             nw::gfx::Camera::DynamicBuilder()
587             .MaxChildren(0)
588             .MaxCallbacks(0)
589             .Create(&s_DeviceAllocator);
590     }
591 
592     // コマンド
593     SmCommandReuser                 CmdReuser;
594     SmCommandReuser                 CmdReuserLyt;
595     SmCommandReuser                 CmdReuserOgl;
596 
597     bool                            firstLoop = true;
598     bool                            preMassageType = SM_MESSAGE_NONE;
599 
600     SmRenderSystem::CommandBufferSide commandBuffSide = SmRenderSystem::COMMAND_BUFFER_SIZE_0;
601 
602     SmTouchPanelStatus              touchPanelStatus;
603     SmPadStatus                     padStatus;
604 
605     nn::hid::CTR::PadReader         padReader;
606     nn::hid::CTR::TouchPanelReader  touchPanelReader;
607 
608 
609     #define TRANSPARENCY_COLOR  (0)
610 
611     // 操作説明をログ出力します。
612     {
613         NW_DEV_LOG( "[DEMO] PAD_A:PLAY/STOP\n" );
614         NW_DEV_LOG( "[DEMO] PAD_X:ADD FRAME\n" );
615         NW_DEV_LOG( "[DEMO] PAD_R+A:OUTPUT LOG\n" );
616         NW_DEV_LOG( "[DEMO] PAD_R+B:COMMAND BUFFER DOUBLE/SINGLE SWAP\n" );
617         NW_DEV_LOG( "[DEMO] PAD_R+Y:LAYOUT DRAW ON/OFF\n" );
618         NW_DEV_LOG( "[DEMO] PAD_R+X:CPU METER DRAW ON/OFF\n" );
619         NW_DEV_LOG( "\n" );
620     }
621 
622     /*
623         [メインループ]
624 
625         ・シングルバッファモードの場合は、以下の順番で処理が行われます。
626 
627           Gfxシーン更新、コマンドキャッシュ生成 → ステレオ描画 → レイアウト → 処理メータ(OpenGL)
628 
629         ・ダブルバッファモードの場合は、以下の順番で処理が行われます。
630 
631           ステレオ描画 → レイアウト → 処理メータ(OpenGL) → Gfxシーン更新、コマンドキャッシュ生成
632 
633         ・バッファクリア等の処理は、ステージ描画で行っています。
634 
635         ・レイアウトのコマンドキャッシュはユーザー操作等で変更があった場合のみ行っています。
636 
637         ・デモ内で生成されるクラスはSmMessageクラスから派生されており、
638          タッチパネルやパッド、UI操作からのメッセージなどの処理を行っています。
639     */
640     while ( ! nw::demo::Utility::IsTerminating() )
641     {
642         // 処理計測をリセット
643         s_CpuPerf->Reset();
644         s_GpuPerf->Reset();
645 
646         // フレームの先頭タイムを記録します。
647         s_FrameStatus.SetTimerStart();
648 
649         // タッチパネルメッセージ処理を行います。
650         touchPanelReader.ReadLatest( touchPanelStatus.GetHidTouchPanelStatus() );
651         SmMessageType touchPanelMessageType = SendTouchPanelMassage( touchPanelStatus );
652 
653         // パッドメッセージ処理を行います。
654         padReader.ReadLatest( padStatus.GetHidPadStatus() );
655         SendPadMassage( padStatus );
656 
657         // カレントのカメラを取得します。
658         currentCamera = s_GfxCtrl->GetCamera();
659         NW_NULL_ASSERT( currentCamera );
660 
661         // カメラのアスペクト比をセットします。
662         nw::demo::Utility::SetCameraAspectRatio(currentCamera, s_RenderTargets[0]);
663 
664         // 上画面へ切り替え
665         {
666             s_RenderSystem->SetRenderTarget(s_RenderTargets[DEMO_UPPER_SCREEN]);
667             nngxValidateState(NN_GX_STATE_FRAMEBUFFER, GL_TRUE);
668         }
669 
670         // シングルバッファの場合は、CPU待ち時間を考慮をメータに記録します。
671         if ( !s_FrameStatus.IsCommandBufferDouble() )
672         {
673             _SET_PERF_GPU_BEGIN( "CPU WAIT                        ", nw::ut::Color8::RED );
674         }
675 
676         // コマンドのシングルバッファモードの場合は、
677         // このタイミングでコマンドキャッシュの生成を行います。
678         if ( !s_FrameStatus.IsCommandBufferDouble() )
679         {
680             if( pSmCamera->IsPadCamera() )
681             {
682                 CreateGfxCache( CmdReuser, s_PadCameraIndex, currentCamera, commandBuffSide );
683             }
684             else
685             {
686                 CreateGfxCache( CmdReuser, s_BaseCameraIndex, currentCamera, commandBuffSide );
687             }
688         }
689 
690         // シングルバッファの場合は、CPU待ち時間を考慮をメータに記録します。
691         if ( !s_FrameStatus.IsCommandBufferDouble() )
692         {
693             _SET_PERF_GPU_END();
694         }
695 
696         // GPU処理計測開始します。
697         _SET_PERF_GPU_BEGIN( "GPU_ALL_COST                    ", nw::ut::Color8::BLUE );
698 
699         // キャッシュ(CreateGfxCache)したコマンドを利用して
700         // 左右のスクリーンを描画します。
701         _SET_PERF_CPU_BEGIN( "GFX :CommandCache Copy          ", nw::ut::Color8::RED );
702         if ( CmdReuser.IsCache() )
703         {
704             // 視差計算を行います。
705             {
706                 nw::gfx::ResCameraProjectionUpdater resProjectionUpdater = currentCamera->GetProjectionUpdater()->GetResource();
707                 NW_ASSERT(resProjectionUpdater.IsValid());
708 
709                 // UIからの視差パラメータ入力
710                 f32 flevel = s_Demo->GetStereoLevel() * (resProjectionUpdater.GetFar() - resProjectionUpdater.GetNear()) + resProjectionUpdater.GetNear();
711                 f32 frange = s_Demo->GetStereoRange();
712                 s_RenderSystem->CalcStereoCamera( s_LeftCamera, s_RightCamera, currentCamera, flevel, frange);
713             }
714 
715             // 左目の映像を描画します。
716             renderContext->SetCameraMatrix( s_LeftCamera );
717             CmdReuser.UseCommand(true); // 1スプリット追加
718             s_RenderSystem->TransferBuffer(nw::demo::UPPER_SCREEN);
719 
720             // ステレオ描画モードの場合は、描画を行います。
721              if ( s_Demo->IsStereoEnable() )
722             {
723                 renderContext->SetCameraMatrix( s_RightCamera );
724                 CmdReuser.UseCommand(true); // 1スプリット追加されます。
725                 s_RenderSystem->TransferBuffer(nw::demo::EXTENSION_SCREEN);
726             }
727         }
728         _SET_PERF_CPU_END();
729 
730 
731         // 下画面へ切り替えます。
732         _SET_PERF_CPU_BEGIN( "SYS :RenderTarget Change        ", nw::ut::Color8::BLUE );
733         {
734             s_RenderSystem->SetRenderTarget(s_RenderTargets[DEMO_LOWER_SCREEN]);
735             nngxValidateState(NN_GX_STATE_FRAMEBUFFER, GL_TRUE);
736 
737             glBindFramebuffer(GL_FRAMEBUFFER, s_RenderSystem->GetRenderContext()->GetRenderTarget()->GetBufferObject());
738         }
739         _SET_PERF_CPU_END();
740 
741 
742         // レイアウトを描画しないのであれば処理をスキップします。
743         if ( !s_FrameStatus.IsLayoutVisible() ) goto layout_end;
744 
745         // メッセージが存在する場合のみコマンドキャッシュを生成します。
746         // タッチパネルが操作された場合やデモ内でレイアウトが更新された場合等のみ
747         // コマンドキャッシュの生成を行います。
748         _SET_PERF_CPU_BEGIN( "LYT :Calc                       ", nw::ut::Color8::GREEN );
749         if ( firstLoop ||
750              touchPanelMessageType != SM_MESSAGE_NONE ||
751              preMassageType != SM_MESSAGE_NONE ||
752              s_Demo->IsLytUpdate() )
753         {
754             CreateLayoutCache( CmdReuserLyt );
755         }
756         _SET_PERF_CPU_END();
757 
758         // キャッシュしたコマンドを利用してレイアウトの描画を行います。
759         _SET_PERF_CPU_BEGIN( "LYT :CommandCache Copy          ", nw::ut::Color8::GREEN );
760         {
761             if ( CmdReuserLyt.IsCache() )
762             {
763                 CmdReuserLyt.UseCommand(true);
764             }
765         }
766         _SET_PERF_CPU_END();
767 
768 layout_end:
769 
770 
771         // Cpuメータ(OpenGL描画部分)を処理しないのであれば処理をスキップします。
772         if ( !s_FrameStatus.IsCpuMeterVisible() ) goto cpumeter_end;
773 
774         // Cpuメータでの描画を行います。
775         _SET_PERF_CPU_BEGIN( "PERF:Performance Meter          ", nw::ut::Color8::YELLOW );
776         {
777             {
778                 //glBindFramebuffer(GL_FRAMEBUFFER, s_RenderSystem->GetRenderContext()->GetRenderTarget()->GetBufferObject());
779 
780                 nngxUpdateState(NN_GX_STATE_ALL);
781                 s_SmOgl->SetBegin2D();
782                 s_PerfDrawer->Render( s_CpuPerf, s_GpuPerf );
783             }
784         }
785         _SET_PERF_CPU_END();
786 
787 cpumeter_end:
788 
789 
790         _SET_PERF_CPU_BEGIN( "SYS :Transfer BUffer            ", nw::ut::Color8::BLUE );
791         {
792             s_RenderSystem->TransferBuffer(nw::demo::LOWER_SCREEN);
793         }
794         _SET_PERF_CPU_END();
795 
796 
797         // ダブルバッファモードの場合、このタイミングでコマンドキャッシュを生成します。
798         if ( s_FrameStatus.IsCommandBufferDouble() )
799         {
800             // Gfxコマンド生成
801             if( pSmCamera->IsPadCamera() )
802             {
803                 CreateGfxCache( CmdReuser, s_PadCameraIndex, currentCamera, commandBuffSide );
804             }
805             else
806             {
807                 CreateGfxCache( CmdReuser, s_BaseCameraIndex, currentCamera, commandBuffSide );
808             }
809 
810             // コマンドバッファのスワップ(ダブルの場合のみ)
811             if (commandBuffSide == SmRenderSystem::COMMAND_BUFFER_SIZE_0)
812             {
813                 commandBuffSide = SmRenderSystem::COMMAND_BUFFER_SIZE_1;
814             }
815             else
816             {
817                 commandBuffSide = SmRenderSystem::COMMAND_BUFFER_SIZE_0;
818             }
819         }
820 
821         // 総コマンドリクエストカウントを取得します。
822         s_FrameStatus.UpdateUsedReqCount();
823 
824         // GPU実行待ち
825         s_FrameStatus.SetGpuWaitStart();
826         {
827             s_RenderSystem->WaitCommandList();
828             s_RenderSystem->SwapBuffer(nw::demo::UPPER_SCREEN | nw::demo::LOWER_SCREEN | nw::demo::EXTENSION_SCREEN);
829         }
830         s_FrameStatus.SetGpuWaitEnd();
831 
832         // GPU処理計測はここまで。
833         _SET_PERF_GPU_END();
834 
835         // 1フレームにかかった全ての時間を計算します。
836         s_FrameStatus.SetTimerEnd();
837 /*
838         // todo:nngxValidateStateのタイミングでは、OpenGLの描画がずれてしまう。
839         // 上画面へ切り替え
840         {
841             s_RenderSystem->SetRenderTarget(s_RenderTargets[DEMO_UPPER_SCREEN]);
842             nngxValidateState(NN_GX_STATE_FRAMEBUFFER, GL_TRUE);
843         }
844 */
845         // Sync待ち
846         s_RenderSystem->WaitVSync(nw::demo::UPPER_SCREEN | nw::demo::LOWER_SCREEN | nw::demo::EXTENSION_SCREEN);
847 
848         // 各種、フレーム終了処理を行います。
849         firstLoop = false;
850         preMassageType = touchPanelMessageType;
851     }
852 
853     // ステレオ用カメラを破棄します。
854     nw::gfx::SafeDestroy(s_LeftCamera);
855     nw::gfx::SafeDestroy(s_RightCamera);
856 
857     SM_SAFE_DELETE( s_Demo );
858 
859     TerminateGfx();
860     TerminateLyt();
861 }
862 
863 } // namespace
864 
865 
866 /*!--------------------------------------------------------------------------*
867   @brief        メイン関数です。
868  *---------------------------------------------------------------------------*/
869 void
nnMain()870 nnMain()
871 {
872     // グラフィックシステムの初期化
873     SmInitializeGraphicsSystem( &s_DeviceAllocator );
874 
875     // レイアウトライブラリの初期化。
876     nw::lyt::Initialize(&s_DeviceAllocator, &s_DeviceAllocator);
877 
878     // タッチパネル初期化します。
879     nn::hid::CTR::Initialize();
880 
881     {
882         InitializeGraphics();
883         nw::demo::PadFactory::Initialize(&s_DeviceAllocator);
884 
885         {
886             DemoScene();
887         }
888 
889         nw::demo::PadFactory::Finalize();
890         TerminateGraphics();
891     }
892 
893     // グラフィックシステムの終了
894     SmFinalizeGraphicsSystem( &s_DeviceAllocator );
895 }
896 
897 
898