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