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