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