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