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