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: 23844 $
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/demo.h>
37 
38 namespace
39 {
40 
41 //---------------------------------------------------------------------------
42 //! @brief      メモリを確保します。
43 //!
44 //! @param[in]  size      確保するメモリのサイズ。
45 //! @param[in]  alignment 確保するメモリのアライメント値。
46 //!
47 //! @return     確保したメモリへのポインタを返します。
48 //---------------------------------------------------------------------------
49 void*
MemAlloc(size_t size,u8 alignment=4)50 MemAlloc(
51     size_t  size,
52     u8      alignment = 4
53 )
54 {
55 #if defined(NW_PLATFORM_CTR)
56     return nw::demo::SimpleApp::Allocate(size, alignment);
57 #else
58     return nw::demo::Alloc(size, alignment);
59 #endif
60 }
61 
62 //---------------------------------------------------------------------------
63 //! @brief      デバイスメモリからメモリを確保します。
64 //!
65 //! @param[in]  size      確保するメモリのサイズ。
66 //! @param[in]  alignment 確保するメモリのアライメント値。
67 //!
68 //! @return     確保したメモリへのポインタを返します。
69 //---------------------------------------------------------------------------
70 void*
DevMemAlloc(size_t size,u8 alignment=4)71 DevMemAlloc(
72     size_t  size,
73     u8      alignment = 4
74 )
75 {
76 #if defined(NW_PLATFORM_CTR)
77     return nw::demo::SimpleApp::AllocateDeviceMemory(size, alignment);
78 #else
79     return nw::demo::Alloc(size, alignment);
80 #endif
81 }
82 
83 //---------------------------------------------------------------------------
84 //! @brief      メモリを解放します。
85 //!
86 //! @param[in]  memory 解放するメモリへのポインタ。
87 //---------------------------------------------------------------------------
88 void
MemFree(void * memory)89 MemFree(void* memory)
90 {
91 #if defined(NW_PLATFORM_CTR)
92     nw::demo::SimpleApp::Free(memory);
93 #else
94     nw::demo::Free(memory);
95 #endif
96 }
97 
98 //---------------------------------------------------------------------------
99 //! @brief      シェーダの初期化を行います。
100 //!
101 //! @param[in,out]  pResource 描画用リソースを管理するオブジェクトへのポインタ。
102 //---------------------------------------------------------------------------
103 void
InitShaders(nw::font::TextWriterResource * pResource)104 InitShaders(nw::font::TextWriterResource* pResource)
105 {
106     const wchar_t* shaders = NW_DEMO_FILE_PATH( NW_FONT_SHADERBINARY );
107     nn::fs::FileReader shaderReader(shaders);
108 
109     const u32 fileSize = (u32)shaderReader.GetSize();
110 
111     void* shaderBinary = MemAlloc(fileSize);
112 
113     s32 read = shaderReader.Read(shaderBinary, fileSize);
114     NN_ASSERT(read == fileSize);
115 
116     pResource->InitResource(shaderBinary, fileSize);
117 
118     MemFree(shaderBinary);
119 }
120 
121 //---------------------------------------------------------------------------
122 //! @brief      描画の初期設定を行います。
123 //---------------------------------------------------------------------------
124 void
InitDraw()125 InitDraw()
126 {
127     glClearColor(0.3f, 0.3f, 0.3f, 1.0f);
128 
129     glDisable(GL_CULL_FACE);            // カリングを無効
130     glDisable(GL_SCISSOR_TEST);         // シザー処理を無効
131     glDisable(GL_POLYGON_OFFSET_FILL);  // ポリゴンオフセットを無効
132 #if defined(NW_PLATFORM_CTR)
133     glDisable(GL_EARLY_DEPTH_TEST_DMP); // アーリーデプステストを無効
134 #endif
135     glDisable(GL_DEPTH_TEST);           // デプステストを無効
136     glDisable(GL_STENCIL_TEST);         // ステンシルテストを無効
137 
138     // カラーバッファの全ての成分を書き込み可
139     glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
140 }
141 
142 //---------------------------------------------------------------------------
143 //! @brief      ResFontを構築します。
144 //!
145 //! @param[out] pFont    構築するフォントへのポインタ。
146 //! @param[in]  filePath ロードするフォントリソースファイル名。
147 //!
148 //! @return     ResFont構築の成否を返します。
149 //---------------------------------------------------------------------------
150 bool
InitFont(nw::font::ResFont * pFont,const wchar_t * filePath)151 InitFont(
152     nw::font::ResFont*  pFont,
153     const wchar_t*      filePath
154 )
155 {
156     // フォントリソースをロードします
157     nn::fs::FileReader fontReader(filePath);
158 
159     s32 fileSize = (s32)fontReader.GetSize();
160     if ( fileSize <= 0 )
161     {
162         return false;
163     }
164 
165     void* buffer = DevMemAlloc(fileSize, nw::font::GlyphDataAlignment);
166     if (buffer == NULL)
167     {
168         return false;
169     }
170 
171     s32 readSize = fontReader.Read(buffer, fileSize);
172     if (readSize != fileSize)
173     {
174         MemFree(buffer);
175         return false;
176     }
177 
178     // フォントリソースをセットします
179     bool bSuccess = pFont->SetResource(buffer);
180     NN_ASSERT(bSuccess);
181 
182     //--- 既にリソースをセット済みであるか,ロード済みであるか、リソースが不正な場合に失敗します。
183     if (! bSuccess)
184     {
185         MemFree(buffer);
186     }
187 
188     // 描画用バッファを設定します。
189     // これを設定しなくても描画は可能ですが、
190     // 処理速度が遅くなります。
191     const u32 drawBufferSize = nw::font::ResFont::GetDrawBufferSize(buffer);
192     void* drawBuffer = MemAlloc(drawBufferSize, 4);
193     pFont->SetDrawBuffer(drawBuffer);
194 
195     return bSuccess;
196 }
197 
198 
199 //---------------------------------------------------------------------------
200 //! @brief      ResFontを破棄します。
201 //!
202 //! @param[in]  pFont           破棄するフォントへのポインタ。
203 //---------------------------------------------------------------------------
204 void
CleanupFont(nw::font::ResFont * pFont)205 CleanupFont(nw::font::ResFont* pFont)
206 {
207     // 描画用バッファの無効化
208     // 描画用バッファがセットされているなら 構築時に SetDrawBuffer に渡したバッファへの
209     // ポインタが返ってきます。
210     void *const drawBuffer = pFont->SetDrawBuffer(NULL);
211     if (drawBuffer != NULL)
212     {
213         MemFree(drawBuffer);
214     }
215 
216     // フォントがセットされているなら SetResource 時に渡したリソースへの
217     // ポインタが返ってきます。
218     void *const resource = pFont->RemoveResource();
219     if (resource != NULL)
220     {
221         MemFree(resource);
222     }
223 
224     // RemoveResource 後は再度 SetResource するまでフォントとして使用できません。
225 }
226 
227 //---------------------------------------------------------------------------
228 //! @brief      文字列表示用にモデルビュー行列と射影行列を設定します。
229 //!
230 //! @param[in]  textWriterResource 描画用リソースを管理するオブジェクトへの参照。
231 //! @param[in]  width              画面の幅。
232 //! @param[in]  height             画面の高さ。
233 //---------------------------------------------------------------------------
234 void
SetupTextCamera(const nw::font::TextWriterResource & textWriterResource,int width,int height)235 SetupTextCamera(
236     const nw::font::TextWriterResource&
237                 textWriterResource,
238     int         width,
239     int         height
240 )
241 {
242 #ifdef NW_PLATFORM_CTRWIN
243     const GLsizei lcdWidth  = width;
244     const GLsizei lcdHeight = height;
245 #else
246     const GLsizei lcdWidth  = height;
247     const GLsizei lcdHeight = width;
248 #endif
249     glViewport(0, 0, lcdWidth, lcdHeight);
250 
251     // 射影行列を正射影に設定
252     {
253         // 左上原点とし、Y軸とZ軸の向きが逆になるように設定します。
254         nn::math::MTX44 proj;
255         f32 znear   =  0.0f;
256         f32 zfar    = -1.0f;
257         f32 t       =  0;
258         f32 b       =  static_cast<f32>(height);
259         f32 l       =  0;
260         f32 r       =  static_cast<f32>(width);
261         nn::math::MTX44OrthoPivot(&proj, l, r, b, t, znear, zfar, nn::math::PIVOT_UPSIDE_TO_TOP);
262         textWriterResource.SetProjectionMtx(proj);
263     }
264 
265     // モデルビュー行列を単位行列に設定
266     {
267         nn::math::MTX34 mv;
268         nn::math::MTX34Identity(&mv);
269         textWriterResource.SetViewMtx(mv);
270     }
271 }
272 
273 //---------------------------------------------------------------------------
274 //! @brief      ASCII文字列を描画します。
275 //!
276 //! @param[in]  pFont               フォントへのポインタ。
277 //! @param[in]  pTextWriterResource 描画用リソースを管理するオブジェクトへのポインタ。
278 //---------------------------------------------------------------------------
279 void
DrawAscii(nw::font::ResFont * pFont,nw::font::TextWriterResource * pTextWriterResource)280 DrawAscii(
281     nw::font::ResFont*              pFont,
282     nw::font::TextWriterResource*   pTextWriterResource
283 )
284 {
285     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
286 
287     nw::font::TextWriter writer;
288     writer.SetFont(pFont);
289     writer.SetTextWriterResource(pTextWriterResource);
290     writer.SetupGX();
291     writer.SetCursor(0, 0);
292 
293     (void)writer.Print("DEMO: ResFont\n");
294     (void)writer.Print("\n");
295 
296     // ASCIIの文字見本を表示
297     (void)writer.Print("All ASCII Character listing:\n");
298     (void)writer.Print("\n");
299     (void)writer.Print(" !\"#$%&'()*+,-./\n");
300     (void)writer.Print("0123456789:;<=>?\n");
301     (void)writer.Print("@ABCDEFGHIJKLMNO\n");
302     (void)writer.Print("PQRSTUVWXYZ[\\]^_\n");
303     (void)writer.Print("`abcdefghijklmno\n");
304     (void)writer.Print("pqrstuvwxyz{|}~\n");
305 
306     glFlush();
307 }
308 
309 }   // namespace
310 
311 //---------------------------------------------------------------------------
312 //! @brief      サンプルのメイン関数です。
313 //---------------------------------------------------------------------------
314 void
nnMain()315 nnMain()
316 {
317     // os の初期化
318     nn::os::Initialize();
319 
320     // fs の初期化
321     nn::fs::Initialize();
322 
323     nw::demo::SimpleApp& demoApp = nw::demo::SimpleApp::GetInstance();
324 
325     demoApp.Initialize();
326 
327     nw::font::ResFont font;
328 
329     // フォントの構築
330     {
331         bool bSuccess = InitFont(&font, NW_DEMO_FILE_PATH(L"tahoma.bcfnt"));
332         NN_ASSERTMSG(bSuccess, "Fail to load ResFont.");
333     }
334 
335     // 描画リソースの構築
336     nw::font::TextWriterResource textWriterResource;
337     InitShaders(&textWriterResource);
338 
339     textWriterResource.ActiveGlProgram();
340 
341     InitDraw();
342 
343     // フォント情報の表示
344     volatile bool loop = true;
345     while (loop)
346     {
347         demoApp.SetRenderingTarget(demoApp.DISPLAY0);
348         {
349             glBindFramebuffer(GL_FRAMEBUFFER, demoApp.GetFrameBufferObject());
350 
351             SetupTextCamera(
352                 textWriterResource,
353                 demoApp.DISPLAY0_WIDTH,
354                 demoApp.DISPLAY0_HEIGHT);
355             DrawAscii(&font, &textWriterResource);
356         }
357 
358         demoApp.SetRenderingTarget(demoApp.DISPLAY1);
359         {
360             glBindFramebuffer(GL_FRAMEBUFFER, demoApp.GetFrameBufferObject());
361 
362             SetupTextCamera(
363                 textWriterResource,
364                 demoApp.DISPLAY1_WIDTH,
365                 demoApp.DISPLAY1_HEIGHT);
366             DrawAscii(&font, &textWriterResource);
367         }
368 
369         demoApp.SwapBuffer(demoApp.DISPLAY_BOTH);
370     }
371 
372     // 描画リソースの破棄
373     textWriterResource.DeleteResource();
374 
375     // フォントの破棄
376     CleanupFont(&font);
377 }
378