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