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, ¤tCmdList );
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