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