1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     SmRenderSystem.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: 1 $
14  *---------------------------------------------------------------------------*/
15 
16 #include "../include/SmRenderSystem.h"
17 #include <nw/demo/demo_DisplayBufferSwapper.h>
18 
19 
20 
21 nw::demo::GraphicsMemoryAllocator s_GraphicsMemoryAllocator;
22 bool s_GetGlSystemFlag = false;
23 
24 
25 
26 //----------------------------------------
27 //
28 void
SmInitializeGraphicsSystem(nw::demo::DemoAllocator * deviceAllocator)29 SmInitializeGraphicsSystem(nw::demo::DemoAllocator* deviceAllocator)
30 {
31     nn::os::Initialize();
32     nn::fs::Initialize();
33 
34     // メインメモリとデバイスメモリを初期化します。
35     // メインメモリはユーザーが自由にアクセスできる領域となり、
36     // デバイスメモリはGPUがアクセスするFCRAM上の領域となります。
37     nw::demo::InitializeDemoMemory();
38 
39     nw::demo::InitializeDemoAllocator(deviceAllocator, nw::demo::DEMO_MEMORY_SIZE, nn::os::ALLOCATE_OPTION_LINEAR);
40 
41     // デバイスメモリを用いるグラフィックスメモリアロケータを初期化します。
42     s_GraphicsMemoryAllocator.Initialize(deviceAllocator);
43 
44     const int MAX_FILE = 256;
45     const int MAX_DIRECTORY = 16;
46 
47     s32 workingMemorySize = nn::fs::GetRomRequiredMemorySize(MAX_FILE, MAX_DIRECTORY, false);
48     void* workingMemory = nw::demo::Alloc(workingMemorySize);
49     nn::Result result = nn::fs::MountRom(MAX_FILE, MAX_DIRECTORY, workingMemory, workingMemorySize, false);
50     NW_ASSERT(result.IsSuccess());
51 
52 }
53 
54 
55 //----------------------------------------
56 //
57 void
SmFinalizeGraphicsSystem(nw::demo::DemoAllocator * deviceAllocator)58 SmFinalizeGraphicsSystem(nw::demo::DemoAllocator* deviceAllocator)
59 {
60     s_GraphicsMemoryAllocator.Finalize();
61 
62     nw::demo::FinalizeDemoAllocator(deviceAllocator);
63 }
64 
65 
66 
67 //----------------------------------------
smAllocateGraphicsMemory(GLenum area,GLenum aim,GLuint id,GLsizei size)68 void* smAllocateGraphicsMemory(GLenum area, GLenum aim, GLuint id, GLsizei size)
69 {
70     void* buffer = s_GraphicsMemoryAllocator.Allocate(area, aim, id, size);
71 
72     return buffer;
73 }
74 
75 //----------------------------------------
smDeallocateGraphicsMemory(GLenum area,GLenum aim,GLuint id,void * addr)76 void smDeallocateGraphicsMemory(GLenum area, GLenum aim, GLuint id, void* addr)
77 {
78     s_GraphicsMemoryAllocator.Deallocate(area, aim, id, addr);
79 }
80 
81 
82 
83 namespace
84 {
85 
86 
87 //----------------------------------------
88 void
CreateInternal_(const Description & description)89 SmRenderSystem::CreateInternal_(
90     const Description& description
91 )
92 {
93     NW_UNUSED_VARIABLE(description);
94 
95     s_GetGlSystemFlag = true;
96 
97     if (nngxInitialize( smAllocateGraphicsMemory, smDeallocateGraphicsMemory ) == GL_FALSE)
98     {
99         NW_FATAL_ERROR("nngxInitialize failed.\n");
100     }
101 
102     s_GetGlSystemFlag = false;
103 
104 #if 1
105     // コマンドリスト
106 //    if (0 < description.cachingCommandBufferSize  &&
107 //        0 < description.cachingRequestCount)
108     {
109         nngxGenCmdlists(1, &(m_CacheCmdListUpper));
110         nngxBindCmdlist(m_CacheCmdListUpper);
111         nngxCmdlistStorage(0x100000/*description.cachingCommandBufferSize*/, 512/*description.cachingRequestCount*/);
112         nngxSetCmdlistParameteri(NN_GX_CMDLIST_RUN_MODE, NN_GX_CMDLIST_SERIAL_RUN);
113 
114         nngxGenCmdlists(1, &(m_CacheCmdListLower));
115         nngxBindCmdlist(m_CacheCmdListLower);
116         nngxCmdlistStorage(0x100000/*description.cachingCommandBufferSize*/, 512/*description.cachingRequestCount*/);
117         nngxSetCmdlistParameteri(NN_GX_CMDLIST_RUN_MODE, NN_GX_CMDLIST_SERIAL_RUN);
118     }
119 
120     nngxGenCmdlists(1, &(m_CommandList));
121     nngxBindCmdlist(m_CommandList);
122     nngxCmdlistStorage(0x100000/*description.cachingCommandBufferSize*/, 512/*description.cachingRequestCount*/);
123     nngxSetCmdlistParameteri(NN_GX_CMDLIST_RUN_MODE, NN_GX_CMDLIST_SERIAL_RUN);
124 
125 //    nngxSetCommandGenerationMode(NN_GX_CMDGEN_MODE_UNCONDITIONAL);
126 
127 #endif
128 
129     nngxRunCmdlist();
130     nngxStartLcdDisplay();
131 }
132 
133 
134 //----------------------------------------
135 // コンストラクタ
SmRenderSystem(const Description & description)136 SmRenderSystem::SmRenderSystem(
137     const Description& description
138 ) : m_RenderContext( NULL ),
139     m_UpperSwapper( NULL ),
140     m_LowerSwapper( NULL ),
141     m_ExtensionSwapper( NULL ),
142     m_CommandList( 0 ),
143     m_CacheCmdListUpper( 0 ),
144     m_CacheCmdListLower( 0 ),
145     m_StereoCamera( NULL )
146 {
147     m_RenderContext = nw::gfx::RenderContext::Builder()
148         .Create( m_Allocator );
149 
150     CreateInternal_(description);
151 
152     // ディスプレイ初期化
153     {
154         m_UpperSwapper = nw::demo::DisplayBufferSwapper::Builder()
155             .BufferDescription(description.upperScreenDescription)
156             .BufferCount(description.displayBufferCount)
157             .Create(m_Allocator);
158 
159         m_LowerSwapper = nw::demo::DisplayBufferSwapper::Builder()
160             .BufferDescription(description.lowerScreenDescription)
161             .BufferCount(description.displayBufferCount)
162             .Create(m_Allocator);
163 
164         nngxSetDisplayMode(NN_GX_DISPLAYMODE_STEREO);
165 
166         nw::demo::DisplayBufferSwapper::Description extensionScreenDescription;
167         extensionScreenDescription.screenKind = nw::demo::EXTENSION_SCREEN;
168         extensionScreenDescription.width  = description.upperScreenDescription.width;
169         extensionScreenDescription.height = description.upperScreenDescription.height;
170         extensionScreenDescription.bufferCount = description.upperScreenDescription.bufferCount;
171 
172         m_ExtensionSwapper = nw::demo::DisplayBufferSwapper::Builder()
173             .BufferDescription(extensionScreenDescription)
174             .Create( m_Allocator );
175 
176         // ステレオカメラを生成する
177         void* cameraMemory = m_Allocator->Alloc(sizeof(nn::ulcd::CTR::StereoCamera));
178         nn::ulcd::CTR::StereoCamera* stereoCamera = new(cameraMemory) nn::ulcd::CTR::StereoCamera();
179         stereoCamera->Initialize();
180         m_StereoCamera = stereoCamera;
181     }
182 
183     NW_GL_ASSERT();
184 }
185 
186 
187 //----------------------------------------
188 // デストラクタ
~SmRenderSystem()189 SmRenderSystem::~SmRenderSystem()
190 {
191     if (m_StereoCamera)
192     {
193         m_StereoCamera->Finalize();
194         m_Allocator->Free(m_StereoCamera);
195     }
196 
197     nw::gfx::SafeDestroy(m_ExtensionSwapper);
198     nw::gfx::SafeDestroy(m_LowerSwapper);
199     nw::gfx::SafeDestroy(m_UpperSwapper);
200     nw::gfx::SafeDestroy( m_RenderContext);
201 
202     nngxFinalize();
203     NW_GL_ASSERT();
204 }
205 
206 
207 
208 //----------------------------------------
209 // VSync 待ちを行います。
210 void
WaitVSync(s32 screenKind)211 SmRenderSystem::WaitVSync( s32 screenKind )
212 {
213     NW_MAX_ASSERT(screenKind, (int)nw::demo::BOTH_SCREENS);
214 
215     GLenum display;
216     if (screenKind & (nw::demo::UPPER_SCREEN | nw::demo::LOWER_SCREEN)) { display = NN_GX_DISPLAY_BOTH; }
217     else if (screenKind & nw::demo::UPPER_SCREEN) { display = NN_GX_DISPLAY0; }
218     else if (screenKind & nw::demo::LOWER_SCREEN) { display = NN_GX_DISPLAY1; }
219 
220     {
221         nngxWaitVSync(display);
222     }
223 }
224 
225 
226 //----------------------------------------
227 // バッファのスワップを予約します。
228 void
SwapBuffer(s32 screenKind)229 SmRenderSystem::SwapBuffer( s32 screenKind )
230 {
231     GLenum display;
232     if (screenKind & (nw::demo::UPPER_SCREEN | nw::demo::LOWER_SCREEN))
233     {
234         m_UpperSwapper->ActivateBuffer();
235         m_LowerSwapper->ActivateBuffer();
236 
237         if (screenKind & nw::demo::EXTENSION_SCREEN)
238         {
239             m_ExtensionSwapper->ActivateBuffer();
240         }
241 
242         display = NN_GX_DISPLAY_BOTH;
243     }
244     else if (screenKind & nw::demo::UPPER_SCREEN)
245     {
246         m_UpperSwapper->ActivateBuffer();
247 
248         if (screenKind & nw::demo::EXTENSION_SCREEN)
249         {
250             m_ExtensionSwapper->ActivateBuffer();
251         }
252 
253         display = NN_GX_DISPLAY0;
254     }
255     else if (screenKind & nw::demo::LOWER_SCREEN)
256     {
257         m_LowerSwapper->ActivateBuffer();
258 
259         display = NN_GX_DISPLAY1;
260     }
261 
262     nngxSwapBuffers(display);
263     glBindFramebuffer(GL_FRAMEBUFFER, 0);
264 }
265 
266 
267 //----------------------------------------
268 // レンダターゲットを設定します。
269 void
SetRenderTarget(nw::gfx::IRenderTarget * renderTarget)270 SmRenderSystem::SetRenderTarget( nw::gfx::IRenderTarget* renderTarget )
271 {
272     m_RenderContext->SetRenderTarget(renderTarget);
273     m_RenderTarget = renderTarget;
274 }
275 
276 
277 //----------------------------------------
278 // バッファを転送します。
279 void
TransferBuffer(s32 screenKind)280 SmRenderSystem::TransferBuffer( s32 screenKind )
281 {
282     if (screenKind & nw::demo::UPPER_SCREEN)
283     {
284         m_UpperSwapper->MakeTransferBufferCommand(m_RenderContext->GetRenderTarget(), false);
285     }
286 
287     if (screenKind & nw::demo::LOWER_SCREEN)
288     {
289         m_LowerSwapper->MakeTransferBufferCommand(m_RenderContext->GetRenderTarget(), false);
290     }
291 
292     if (screenKind & nw::demo::EXTENSION_SCREEN)
293     {
294         m_ExtensionSwapper->MakeTransferBufferCommand(m_RenderContext->GetRenderTarget(), false);
295     }
296 }
297 
298 
299 //----------------------------------------
300 // コマンドリスト処理の終了待ちを行います。
301 void
WaitCommandList()302 SmRenderSystem::WaitCommandList()
303 {
304 //    nngxSplitDrawCmdlist();
305     nngxWaitCmdlistDone();
306     nngxClearCmdlist();
307 }
308 
309 
310 //----------------------------------------
311 // バッファを消去します。
312 void
ClearBuffer(nw::ut::FloatColor clearColor)313 SmRenderSystem::ClearBuffer( nw::ut::FloatColor clearColor )
314 {
315     m_RenderContext->ClearBuffer(
316         GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,
317         clearColor,
318         1.0f);
319     NW_GL_ASSERT();
320 }
321 
322 //----------------------------------------
323 void
CalcStereoCamera(nw::gfx::Camera * leftCamera,nw::gfx::Camera * rightCamera,nw::gfx::Camera * baseCamera,f32 depthLevel,f32 depthRange)324 SmRenderSystem::CalcStereoCamera(
325     nw::gfx::Camera* leftCamera,
326     nw::gfx::Camera* rightCamera,
327     nw::gfx::Camera* baseCamera,
328     f32 depthLevel,
329     f32 depthRange)
330 {
331     NW_NULL_ASSERT(leftCamera);
332     NW_NULL_ASSERT(rightCamera);
333     NW_NULL_ASSERT(baseCamera);
334     nn::math::MTX44& projOriginal = baseCamera->ProjectionMatrix();
335     nn::math::MTX34& viewOriginal = baseCamera->ViewMatrix();
336     nn::math::MTX44& projL = leftCamera->ProjectionMatrix();
337     nn::math::MTX34& viewL = leftCamera->ViewMatrix();
338     nn::math::MTX44& projR = rightCamera->ProjectionMatrix();
339     nn::math::MTX34& viewR = rightCamera->ViewMatrix();
340 
341     f32 wScale = baseCamera->GetWScale();
342     leftCamera->SetWScale( wScale );
343     rightCamera->SetWScale( wScale );
344 
345     m_StereoCamera->CalculateMatrices(
346         &projL,
347         &viewL,
348         &projR,
349         &viewR,
350         &projOriginal,
351         &viewOriginal,
352         depthLevel,
353         depthRange,
354         false);
355 }
356 
357 
358 } // namespace
359 
360