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_()89 SmRenderSystem::CreateInternal_()
90 {
91     s_GetGlSystemFlag = true;
92 
93     if (nngxInitialize( smAllocateGraphicsMemory, smDeallocateGraphicsMemory ) == GL_FALSE)
94     {
95         NW_FATAL_ERROR("nngxInitialize failed.\n");
96     }
97 
98     s_GetGlSystemFlag = false;
99 
100     // コマンドリスト生成
101     #define SM_RENDER_SYSTEM_CMD_BUFF_SIZE  0x100000
102     #define SM_RENDER_SYSTEM_CMD_REQ_SIZE   512
103 
104     nngxGenCmdlists(1, &m_CacheCmdListUpper[COMMAND_BUFFER_SIZE_0]);
105     nngxBindCmdlist(m_CacheCmdListUpper[COMMAND_BUFFER_SIZE_0]);
106     nngxCmdlistStorage(SM_RENDER_SYSTEM_CMD_BUFF_SIZE, SM_RENDER_SYSTEM_CMD_REQ_SIZE);
107     nngxSetCmdlistParameteri(NN_GX_CMDLIST_RUN_MODE, NN_GX_CMDLIST_SERIAL_RUN);
108 
109     nngxGenCmdlists(1, &m_CacheCmdListUpper[COMMAND_BUFFER_SIZE_1]);
110     nngxBindCmdlist(m_CacheCmdListUpper[COMMAND_BUFFER_SIZE_1]);
111     nngxCmdlistStorage(SM_RENDER_SYSTEM_CMD_BUFF_SIZE, SM_RENDER_SYSTEM_CMD_REQ_SIZE);
112     nngxSetCmdlistParameteri(NN_GX_CMDLIST_RUN_MODE, NN_GX_CMDLIST_SERIAL_RUN);
113 
114     nngxGenCmdlists(1, &(m_CacheCmdListLower));
115     nngxBindCmdlist(m_CacheCmdListLower);
116     nngxCmdlistStorage(SM_RENDER_SYSTEM_CMD_BUFF_SIZE, SM_RENDER_SYSTEM_CMD_REQ_SIZE);
117     nngxSetCmdlistParameteri(NN_GX_CMDLIST_RUN_MODE, NN_GX_CMDLIST_SERIAL_RUN);
118 
119     nngxRunCmdlist();
120     nngxStartLcdDisplay();
121 }
122 
123 
124 //----------------------------------------
125 // コンストラクタ
SmRenderSystem(const Description & description)126 SmRenderSystem::SmRenderSystem(
127     const Description& description
128 ) : m_RenderContext( NULL ),
129     m_UpperSwapper( NULL ),
130     m_LowerSwapper( NULL ),
131     m_ExtensionSwapper( NULL ),
132     m_CacheCmdListLower( 0 ),
133     m_StereoCamera( NULL )
134 {
135     m_CacheCmdListUpper[COMMAND_BUFFER_SIZE_0] = 0;
136     m_CacheCmdListUpper[COMMAND_BUFFER_SIZE_1] = 0;
137 
138     m_RenderContext = nw::gfx::RenderContext::Builder()
139         .Create( m_Allocator );
140 
141     CreateInternal_();
142 
143     // ディスプレイ初期化
144     {
145         m_UpperSwapper = nw::demo::DisplayBufferSwapper::Builder()
146             .BufferDescription(description.upperScreenDescription)
147             .BufferCount(description.displayBufferCount)
148             .Create(m_Allocator);
149 
150         m_LowerSwapper = nw::demo::DisplayBufferSwapper::Builder()
151             .BufferDescription(description.lowerScreenDescription)
152             .BufferCount(description.displayBufferCount)
153             .Create(m_Allocator);
154 
155         nngxSetDisplayMode(NN_GX_DISPLAYMODE_STEREO);
156 
157         nw::demo::DisplayBufferSwapper::Description extensionScreenDescription;
158         extensionScreenDescription.screenKind = nw::demo::EXTENSION_SCREEN;
159         extensionScreenDescription.width  = description.upperScreenDescription.width;
160         extensionScreenDescription.height = description.upperScreenDescription.height;
161         extensionScreenDescription.bufferCount = description.upperScreenDescription.bufferCount;
162 
163         m_ExtensionSwapper = nw::demo::DisplayBufferSwapper::Builder()
164             .BufferDescription(extensionScreenDescription)
165             .Create( m_Allocator );
166 
167         // ステレオカメラを生成する
168         void* cameraMemory = m_Allocator->Alloc(sizeof(nn::ulcd::CTR::StereoCamera));
169         nn::ulcd::CTR::StereoCamera* stereoCamera = new(cameraMemory) nn::ulcd::CTR::StereoCamera();
170         stereoCamera->Initialize();
171         m_StereoCamera = stereoCamera;
172     }
173 
174     NW_GL_ASSERT();
175 }
176 
177 
178 //----------------------------------------
179 // デストラクタ
~SmRenderSystem()180 SmRenderSystem::~SmRenderSystem()
181 {
182     if (m_StereoCamera)
183     {
184         m_StereoCamera->Finalize();
185         m_Allocator->Free(m_StereoCamera);
186     }
187 
188     nw::gfx::SafeDestroy(m_ExtensionSwapper);
189     nw::gfx::SafeDestroy(m_LowerSwapper);
190     nw::gfx::SafeDestroy(m_UpperSwapper);
191     nw::gfx::SafeDestroy( m_RenderContext);
192 
193     nngxFinalize();
194     NW_GL_ASSERT();
195 }
196 
197 
198 
199 //----------------------------------------
200 // VSync 待ちを行います。
201 void
WaitVSync(s32 screenKind)202 SmRenderSystem::WaitVSync( s32 screenKind )
203 {
204     NW_MAX_ASSERT(screenKind, (int)nw::demo::BOTH_SCREENS);
205 
206     GLenum display;
207     if (screenKind & (nw::demo::UPPER_SCREEN | nw::demo::LOWER_SCREEN)) { display = NN_GX_DISPLAY_BOTH; }
208     else if (screenKind & nw::demo::UPPER_SCREEN) { display = NN_GX_DISPLAY0; }
209     else if (screenKind & nw::demo::LOWER_SCREEN) { display = NN_GX_DISPLAY1; }
210 
211     {
212         nngxWaitVSync(display);
213     }
214 }
215 
216 
217 //----------------------------------------
218 // バッファのスワップを予約します。
219 void
SwapBuffer(s32 screenKind)220 SmRenderSystem::SwapBuffer( s32 screenKind )
221 {
222     GLenum display;
223     if (screenKind & (nw::demo::UPPER_SCREEN | nw::demo::LOWER_SCREEN))
224     {
225         m_UpperSwapper->ActivateBuffer();
226         m_LowerSwapper->ActivateBuffer();
227 
228         if (screenKind & nw::demo::EXTENSION_SCREEN)
229         {
230             m_ExtensionSwapper->ActivateBuffer();
231         }
232 
233         display = NN_GX_DISPLAY_BOTH;
234     }
235     else if (screenKind & nw::demo::UPPER_SCREEN)
236     {
237         m_UpperSwapper->ActivateBuffer();
238 
239         if (screenKind & nw::demo::EXTENSION_SCREEN)
240         {
241             m_ExtensionSwapper->ActivateBuffer();
242         }
243 
244         display = NN_GX_DISPLAY0;
245     }
246     else if (screenKind & nw::demo::LOWER_SCREEN)
247     {
248         m_LowerSwapper->ActivateBuffer();
249 
250         display = NN_GX_DISPLAY1;
251     }
252 
253     nngxSwapBuffers(display);
254     glBindFramebuffer(GL_FRAMEBUFFER, 0);
255 }
256 
257 
258 //----------------------------------------
259 // レンダターゲットを設定します。
260 void
SetRenderTarget(nw::gfx::IRenderTarget * renderTarget)261 SmRenderSystem::SetRenderTarget( nw::gfx::IRenderTarget* renderTarget )
262 {
263     m_RenderContext->SetRenderTarget(renderTarget);
264     m_RenderTarget = renderTarget;
265 }
266 
267 
268 //----------------------------------------
269 // バッファを転送します。
270 void
TransferBuffer(s32 screenKind)271 SmRenderSystem::TransferBuffer( s32 screenKind )
272 {
273     if (screenKind & nw::demo::UPPER_SCREEN)
274     {
275         m_UpperSwapper->MakeTransferBufferCommand(m_RenderContext->GetRenderTarget(), false);
276     }
277 
278     if (screenKind & nw::demo::LOWER_SCREEN)
279     {
280         m_LowerSwapper->MakeTransferBufferCommand(m_RenderContext->GetRenderTarget(), false);
281     }
282 
283     if (screenKind & nw::demo::EXTENSION_SCREEN)
284     {
285         m_ExtensionSwapper->MakeTransferBufferCommand(m_RenderContext->GetRenderTarget(), false);
286     }
287 }
288 
289 
290 //----------------------------------------
291 // コマンドリスト処理の終了待ちを行います。
292 void
WaitCommandList()293 SmRenderSystem::WaitCommandList()
294 {
295 //    nngxSplitDrawCmdlist();
296     nngxWaitCmdlistDone();
297     nngxClearCmdlist();
298 }
299 
300 
301 //----------------------------------------
302 // バッファを消去します。
303 void
ClearBuffer(nw::ut::FloatColor clearColor)304 SmRenderSystem::ClearBuffer( nw::ut::FloatColor clearColor )
305 {
306     m_RenderContext->ClearBuffer(
307         GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,
308         clearColor,
309         1.0f);
310     NW_GL_ASSERT();
311 }
312 
313 //----------------------------------------
314 void
CalcStereoCamera(nw::gfx::Camera * leftCamera,nw::gfx::Camera * rightCamera,nw::gfx::Camera * baseCamera,f32 depthLevel,f32 depthRange)315 SmRenderSystem::CalcStereoCamera(
316     nw::gfx::Camera* leftCamera,
317     nw::gfx::Camera* rightCamera,
318     nw::gfx::Camera* baseCamera,
319     f32 depthLevel,
320     f32 depthRange)
321 {
322     NW_NULL_ASSERT(leftCamera);
323     NW_NULL_ASSERT(rightCamera);
324     NW_NULL_ASSERT(baseCamera);
325     nn::math::MTX44& projOriginal = baseCamera->ProjectionMatrix();
326     nn::math::MTX34& viewOriginal = baseCamera->ViewMatrix();
327     nn::math::MTX44& projL = leftCamera->ProjectionMatrix();
328     nn::math::MTX34& viewL = leftCamera->ViewMatrix();
329     nn::math::MTX44& projR = rightCamera->ProjectionMatrix();
330     nn::math::MTX34& viewR = rightCamera->ViewMatrix();
331 
332     f32 wScale = baseCamera->GetWScale();
333     leftCamera->SetWScale( wScale );
334     rightCamera->SetWScale( wScale );
335 
336     m_StereoCamera->CalculateMatrices(
337         &projL,
338         &viewL,
339         &projR,
340         &viewR,
341         &projOriginal,
342         &viewOriginal,
343         depthLevel,
344         depthRange,
345         false);
346 }
347 
348 
349 } // namespace
350 
351