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