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