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