1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: main.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: 23847 $
14 *---------------------------------------------------------------------------*/
15
16
17 //------------------------------------------------------------------
18 // デモ: ResFont
19 //
20 // 概要
21 // nw::font::ResFont の構築と破棄のサンプルです。
22 //
23 // 操作
24 // なし。
25 //
26 //------------------------------------------------------------------
27
28 #include <GLES2/gl2.h>
29 #include <GLES2/gl2ext.h>
30 #include <nn.h>
31 #include <nn/math.h>
32 #include <nn/fs.h>
33 #include <nw/sdk.h>
34 #include <nw/font/font_TextWriter.h>
35 #include <nw/font/font_ResFont.h>
36 #include <nw/font/font_RectDrawer.h>
37 #include <nw/demo.h>
38
39 namespace
40 {
41
42 bool s_InitAsciiString = false;
43 u32 s_Counter = 0;
44 u8 s_Color = 0;
45
46 //---------------------------------------------------------------------------
47 //! @brief メモリを確保します。
48 //!
49 //! @param[in] size 確保するメモリのサイズ。
50 //! @param[in] alignment 確保するメモリのアライメント値。
51 //!
52 //! @return 確保したメモリへのポインタを返します。
53 //---------------------------------------------------------------------------
54 void*
MemAlloc(size_t size,u8 alignment=4)55 MemAlloc(
56 size_t size,
57 u8 alignment = 4
58 )
59 {
60 return nw::demo::SimpleApp::Allocate(size, alignment);
61 }
62
63 //---------------------------------------------------------------------------
64 //! @brief デバイスメモリからメモリを確保します。
65 //!
66 //! @param[in] size 確保するメモリのサイズ。
67 //! @param[in] alignment 確保するメモリのアライメント値。
68 //!
69 //! @return 確保したメモリへのポインタを返します。
70 //---------------------------------------------------------------------------
71 void*
DevMemAlloc(size_t size,u8 alignment=4)72 DevMemAlloc(
73 size_t size,
74 u8 alignment = 4
75 )
76 {
77 return nw::demo::SimpleApp::AllocateDeviceMemory(size, alignment);
78 }
79
80 //---------------------------------------------------------------------------
81 //! @brief メモリを解放します。
82 //!
83 //! @param[in] memory 解放するメモリへのポインタ。
84 //---------------------------------------------------------------------------
85 void
MemFree(void * memory)86 MemFree(void* memory)
87 {
88 nw::demo::SimpleApp::Free(memory);
89 }
90
91 //---------------------------------------------------------------------------
92 //! @brief シェーダの初期化を行います。
93 //!
94 //! @param[in] pDrawer RectDrawerオブジェクトへのポインタ。
95 //---------------------------------------------------------------------------
96 void*
InitShaders(nw::font::RectDrawer * pDrawer)97 InitShaders(nw::font::RectDrawer* pDrawer)
98 {
99 const wchar_t* shaders = NW_DEMO_FILE_PATH( NW_FONT_RECTDRAWER_SHADERBINARY );
100 nn::fs::FileReader shaderReader(shaders);
101
102 const u32 fileSize = (u32)shaderReader.GetSize();
103
104 void* shaderBinary = MemAlloc(fileSize);
105 NN_NULL_ASSERT(shaderBinary);
106
107 s32 read = shaderReader.Read(shaderBinary, fileSize);
108 NN_ASSERT(read == fileSize);
109
110 const u32 vtxBufCmdBufSize =
111 nw::font::RectDrawer::GetVertexBufferCommandBufferSize(shaderBinary, fileSize);
112 void *const vtxBufCmdBuf = DevMemAlloc(vtxBufCmdBufSize);
113 NN_NULL_ASSERT(vtxBufCmdBuf);
114 pDrawer->Initialize(vtxBufCmdBuf, shaderBinary, fileSize);
115
116 MemFree(shaderBinary);
117
118 return vtxBufCmdBuf;
119 }
120
121 //---------------------------------------------------------------------------
122 //! @brief 描画の初期設定を行います。
123 //!
124 //! @param[in] width 画面の幅。
125 //! @param[in] height 画面の高さ。
126 //---------------------------------------------------------------------------
127 void
InitDraw(int width,int height)128 InitDraw(
129 int width,
130 int height
131 )
132 {
133 // カラーバッファ情報
134 // LCDの向きに合わせて、幅と高さを入れ替えています。
135 const nw::font::ColorBufferInfo colBufInfo = { height, width, PICA_DATA_DEPTH24_STENCIL8_EXT };
136
137 const u32 screenSettingCommands[] =
138 {
139 // ビューポートの設定
140 NW_FONT_CMD_SET_VIEWPORT( 0, 0, colBufInfo.width, colBufInfo.height ),
141
142 // シザー処理を無効
143 NW_FONT_CMD_SET_DISABLE_SCISSOR( colBufInfo ),
144
145 // wバッファの無効化
146 // デプスレンジの設定
147 // ポリゴンオフセットの無効化
148 NW_FONT_CMD_SET_WBUFFER_DEPTHRANGE_POLYGONOFFSET(
149 0.0f, // wScale : 0.0 でWバッファが無効
150 0.0f, // depth range near
151 1.0f, // depth range far
152 0, // polygon offset units : 0.0 で ポリゴンオフセットが無効
153 colBufInfo),
154 };
155
156 nngxAdd3DCommand(screenSettingCommands, sizeof(screenSettingCommands), true);
157
158 static const u32 s_InitCommands[] =
159 {
160 // カリングを無効
161 NW_FONT_CMD_SET_CULL_FACE( NW_FONT_CMD_CULL_FACE_DISABLE ),
162
163 // ステンシルテストを無効
164 NW_FONT_CMD_SET_DISABLE_STENCIL_TEST(),
165
166 // デプステストを無効
167 // カラーバッファの全ての成分を書き込み可
168 NW_FONT_CMD_SET_DEPTH_FUNC_COLOR_MASK(
169 false, // isDepthTestEnabled
170 0, // depthFunc
171 true, // depthMask
172 true, // red
173 true, // green
174 true, // blue
175 true), // alpha
176
177 // アーリーデプステストを無効
178 NW_FONT_CMD_SET_ENABLE_EARLY_DEPTH_TEST( false ),
179
180 // フレームバッファアクセス制御
181 NW_FONT_CMD_SET_FBACCESS(
182 true, // colorRead
183 true, // colorWrite
184 false, // depthRead
185 false, // depthWrite
186 false, // stencilRead
187 false), // stencilWrite
188 };
189
190 nngxAdd3DCommand(s_InitCommands, sizeof(s_InitCommands), true);
191 }
192
193 //---------------------------------------------------------------------------
194 //! @brief ResFontを構築します。
195 //!
196 //! @param[out] pFont 構築するフォントへのポインタ。
197 //! @param[in] filePath ロードするフォントリソースファイル名。
198 //!
199 //! @return ResFont構築の成否を返します。
200 //---------------------------------------------------------------------------
201 bool
InitFont(nw::font::ResFont * pFont,const wchar_t * filePath)202 InitFont(
203 nw::font::ResFont* pFont,
204 const wchar_t* filePath
205 )
206 {
207 // フォントリソースをロードします
208 nn::fs::FileReader fontReader(filePath);
209
210 s32 fileSize = (s32)fontReader.GetSize();
211 if ( fileSize <= 0 )
212 {
213 return false;
214 }
215
216 void* buffer = DevMemAlloc(fileSize, nw::font::GlyphDataAlignment);
217 if (buffer == NULL)
218 {
219 return false;
220 }
221
222 s32 readSize = fontReader.Read(buffer, fileSize);
223 if (readSize != fileSize)
224 {
225 MemFree(buffer);
226 return false;
227 }
228
229 // フォントリソースをセットします
230 bool bSuccess = pFont->SetResource(buffer);
231 NN_ASSERT(bSuccess);
232
233 //--- 既にリソースをセット済みであるか,ロード済みであるか、リソースが不正な場合に失敗します。
234 if (! bSuccess)
235 {
236 MemFree(buffer);
237 }
238
239 // 描画用バッファを設定します。
240 const u32 drawBufferSize = nw::font::ResFont::GetDrawBufferSize(buffer);
241 void* drawBuffer = MemAlloc(drawBufferSize, 4);
242 NN_NULL_ASSERT(drawBuffer);
243 pFont->SetDrawBuffer(drawBuffer);
244
245 return bSuccess;
246 }
247
248 //---------------------------------------------------------------------------
249 //! @brief ResFontを破棄します。
250 //!
251 //! @param[in] pFont 破棄するフォントへのポインタ。
252 //---------------------------------------------------------------------------
253 void
CleanupFont(nw::font::ResFont * pFont)254 CleanupFont(nw::font::ResFont* pFont)
255 {
256 // 描画用バッファの無効化
257 // 描画用バッファがセットされているなら 構築時に SetDrawBuffer に渡したバッファへの
258 // ポインタが返ってきます。
259 void *const drawBuffer = pFont->SetDrawBuffer(NULL);
260 if (drawBuffer != NULL)
261 {
262 MemFree(drawBuffer);
263 }
264
265 // フォントがセットされているなら SetResource 時に渡したリソースへの
266 // ポインタが返ってきます。
267 void *const resource = pFont->RemoveResource();
268 if (resource != NULL)
269 {
270 MemFree(resource);
271 }
272
273 // RemoveResource 後は再度 SetResource するまでフォントとして使用できません。
274 }
275
276 //---------------------------------------------------------------------------
277 //! @brief 表示文字列用バッファを確保します。
278 //!
279 //! @param[in] charMax 表示する文字列の最大文字数。
280 //!
281 //! @return 確保した表示文字列用バッファへのポインタを返します。
282 //---------------------------------------------------------------------------
283 nw::font::DispStringBuffer*
AllocDispStringBuffer(int charMax)284 AllocDispStringBuffer(int charMax)
285 {
286 const u32 DrawBufferSize = nw::font::CharWriter::GetDispStringBufferSize(charMax);
287 void *const bufMem = MemAlloc(DrawBufferSize);
288 NN_NULL_ASSERT(bufMem);
289
290 return nw::font::CharWriter::InitDispStringBuffer(bufMem, charMax);
291 }
292
293 //---------------------------------------------------------------------------
294 //! @brief 文字列表示用にモデルビュー行列と射影行列を設定します。
295 //!
296 //! @param[in] pDrawer RectDrawerオブジェクトへのポインタ。
297 //! @param[in] width 画面の幅。
298 //! @param[in] height 画面の高さ。
299 //---------------------------------------------------------------------------
300 void
SetupTextCamera(nw::font::RectDrawer * pDrawer,int width,int height)301 SetupTextCamera(
302 nw::font::RectDrawer* pDrawer,
303 int width,
304 int height
305 )
306 {
307 // 射影行列を正射影に設定
308 {
309 // 左上原点とし、Y軸とZ軸の向きが逆になるように設定します。
310 nn::math::MTX44 proj;
311 f32 znear = 0.0f;
312 f32 zfar = -1.0f;
313 f32 t = 0;
314 f32 b = static_cast<f32>(height);
315 f32 l = 0;
316 f32 r = static_cast<f32>(width);
317 nn::math::MTX44OrthoPivot(&proj, l, r, b, t, znear, zfar, nn::math::PIVOT_UPSIDE_TO_TOP);
318 pDrawer->SetProjectionMtx(proj);
319 }
320
321 // モデルビュー行列を単位行列に設定
322 {
323 nn::math::MTX34 mv;
324 nn::math::MTX34Identity(&mv);
325 pDrawer->SetViewMtxForText(mv);
326 }
327 }
328
329 //---------------------------------------------------------------------------
330 //! @brief ASCII文字列を描画します。
331 //!
332 //! @param[in] pDrawer RectDrawerオブジェクトへのポインタ。
333 //! @param[in] pDrawStringBuf DispStringBufferオブジェクトへのポインタ。
334 //! @param[in] pFont フォントへのポインタ。
335 //! @param[in] width 画面の幅。
336 //! @param[in] height 画面の高さ。
337 //---------------------------------------------------------------------------
338 void
DrawAscii(nw::font::RectDrawer * pDrawer,nw::font::DispStringBuffer * pDrawStringBuf,nw::font::ResFont * pFont,int width,int height)339 DrawAscii(
340 nw::font::RectDrawer* pDrawer,
341 nw::font::DispStringBuffer* pDrawStringBuf,
342 nw::font::ResFont* pFont,
343 int width,
344 int height
345 )
346 {
347 nw::font::TextWriter writer;
348 writer.SetDispStringBuffer(pDrawStringBuf);
349 writer.SetFont(pFont);
350
351 writer.SetCursor(0, 0);
352
353 // 文字列が変更されないので、文字列の描画コマンドを一度だけ作成します。
354 if (! s_InitAsciiString)
355 {
356 writer.StartPrint();
357 (void)writer.Print("DEMO: ResFont\n");
358 (void)writer.Print("\n");
359
360 // ASCIIの文字見本を表示
361 (void)writer.Print("All ASCII Character listing:\n");
362 (void)writer.Print("\n");
363 (void)writer.Print(" !\"#$%&'()*+,-./\n");
364 (void)writer.Print("0123456789:;<=>?\n");
365 (void)writer.Print("@ABCDEFGHIJKLMNO\n");
366 (void)writer.Print("PQRSTUVWXYZ[\\]^_\n");
367 (void)writer.Print("`abcdefghijklmno\n");
368 (void)writer.Print("pqrstuvwxyz{|}~\n");
369 writer.EndPrint();
370 pDrawer->BuildTextCommand(&writer);
371
372 s_InitAsciiString = true;
373 }
374
375 // 文字の色は、文字列の描画コマンドを再作成しなくても変更できます。
376 writer.SetTextColor(nw::ut::Color8(s_Color, 255, s_Color, 255));
377 s_Color++;
378
379 pDrawer->DrawBegin();
380
381 SetupTextCamera(pDrawer, width, height);
382 writer.UseCommandBuffer();
383
384 pDrawer->DrawEnd();
385 }
386
387 //---------------------------------------------------------------------------
388 //! @brief カウンタを描画します。
389 //!
390 //! @param[in] pDrawer RectDrawerオブジェクトへのポインタ。
391 //! @param[in] pDrawStringBuf DispStringBufferオブジェクトへのポインタ。
392 //! @param[in] pFont フォントへのポインタ。
393 //! @param[in] width 画面の幅。
394 //! @param[in] height 画面の高さ。
395 //---------------------------------------------------------------------------
396 void
DrawCounter(nw::font::RectDrawer * pDrawer,nw::font::DispStringBuffer * pDrawStringBuf,nw::font::ResFont * pFont,int width,int height)397 DrawCounter(
398 nw::font::RectDrawer* pDrawer,
399 nw::font::DispStringBuffer* pDrawStringBuf,
400 nw::font::ResFont* pFont,
401 int width,
402 int height
403 )
404 {
405 nw::font::TextWriter writer;
406 writer.SetDispStringBuffer(pDrawStringBuf);
407 writer.SetFont(pFont);
408
409 writer.SetCursor(0, 0);
410 writer.SetFixedWidth(8.0f);
411 writer.EnableFixedWidth(true);
412
413 pDrawer->DrawBegin();
414
415 SetupTextCamera(pDrawer, width, height);
416
417 // カウンタの描画コマンドをその都度作成して使用します。
418 writer.StartPrint();
419 (void)writer.Printf("Counter : %d\n", s_Counter);
420 writer.EndPrint();
421 pDrawer->BuildTextCommand(&writer);
422 writer.UseCommandBuffer();
423
424 // カウンタ1/60の描画コマンドをその都度作成して使用します。
425 writer.StartPrint();
426 (void)writer.Printf("Counter 1/60 : %d\n", s_Counter / 60);
427 writer.EndPrint();
428 pDrawer->BuildTextCommand(&writer);
429 writer.UseCommandBuffer();
430
431 pDrawer->DrawEnd();
432
433 s_Counter++;
434 }
435
436 } // namespace
437
438
439 //---------------------------------------------------------------------------
440 //! @brief サンプルのメイン関数です。
441 //---------------------------------------------------------------------------
442 void
nnMain()443 nnMain()
444 {
445 // os の初期化
446 nn::os::Initialize();
447
448 // fs の初期化
449 nn::fs::Initialize();
450
451 nw::demo::SimpleApp& demoApp = nw::demo::SimpleApp::GetInstance();
452
453 demoApp.Initialize();
454
455 nw::font::ResFont font;
456
457 // フォントの構築
458 {
459 bool bSuccess = InitFont(&font, NW_DEMO_FILE_PATH(L"tahoma.bcfnt"));
460 NN_ASSERTMSG(bSuccess, "Fail to load ResFont.");
461 }
462
463 // 描画リソースの構築
464 nw::font::RectDrawer drawer;
465
466 void *const drawerBuf = InitShaders(&drawer);
467
468 // 描画文字列用バッファの確保
469 nw::font::DispStringBuffer *const pDrawStringBuf0 = AllocDispStringBuffer(512);
470 nw::font::DispStringBuffer *const pDrawStringBuf1 = AllocDispStringBuffer(128);
471
472 const nw::ut::FloatColor clearColor(0.3f, 0.3f, 0.3f, 1.0f);
473 const f32 clearDepth = 0.0f;
474
475 // フォント情報の表示
476 volatile bool loop = true;
477 while (loop)
478 {
479 demoApp.SetRenderingTarget(demoApp.DISPLAY0);
480 {
481 demoApp.GetFrameBufferObject().ClearBuffer(clearColor, clearDepth);
482
483 InitDraw(demoApp.DISPLAY0_WIDTH, demoApp.DISPLAY0_HEIGHT);
484
485 DrawAscii(&drawer, pDrawStringBuf0, &font, demoApp.DISPLAY0_WIDTH, demoApp.DISPLAY0_HEIGHT);
486 }
487
488 demoApp.SetRenderingTarget(demoApp.DISPLAY1);
489 {
490 demoApp.GetFrameBufferObject().ClearBuffer(clearColor, clearDepth);
491
492 InitDraw(demoApp.DISPLAY1_WIDTH, demoApp.DISPLAY1_HEIGHT);
493
494 DrawCounter(&drawer, pDrawStringBuf1, &font, demoApp.DISPLAY1_WIDTH, demoApp.DISPLAY1_HEIGHT);
495 }
496
497 demoApp.SwapBuffer(demoApp.DISPLAY_BOTH);
498 }
499
500 // 描画文字列用バッファの解放
501 MemFree(pDrawStringBuf1);
502 MemFree(pDrawStringBuf0);
503
504 drawer.Finalize();
505
506 MemFree(drawerBuf);
507
508 // フォントの破棄
509 CleanupFont(&font);
510 }
511