/*---------------------------------------------------------------------------* Project: NintendoWare File: main.cpp Copyright (C)2009-2011 Nintendo/HAL Laboratory, Inc. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo and/or its licensed developers and are protected by national and international copyright laws. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. The content herein is highly confidential and should be handled accordingly. $Revision: 31311 $ *---------------------------------------------------------------------------*/ //------------------------------------------------------------------ // デモ: ResFont // // 概要 // nw::font::ResFont の構築と破棄のサンプルです。 // // 操作 // なし。 // //------------------------------------------------------------------ #include #include #include #include #include #include #include #include #include #include namespace { bool s_InitAsciiString = false; u32 s_Counter = 0; u8 s_Color = 0; //--------------------------------------------------------------------------- //! @brief メモリを確保します。 //! //! @param[in] size 確保するメモリのサイズ。 //! @param[in] alignment 確保するメモリのアライメント値。 //! //! @return 確保したメモリへのポインタを返します。 //--------------------------------------------------------------------------- void* MemAlloc( size_t size, u8 alignment = 4 ) { return nw::demo::SimpleApp::Allocate(size, alignment); } //--------------------------------------------------------------------------- //! @brief デバイスメモリからメモリを確保します。 //! //! @param[in] size 確保するメモリのサイズ。 //! @param[in] alignment 確保するメモリのアライメント値。 //! //! @return 確保したメモリへのポインタを返します。 //--------------------------------------------------------------------------- void* DevMemAlloc( size_t size, u8 alignment = 4 ) { return nw::demo::SimpleApp::AllocateDeviceMemory(size, alignment); } //--------------------------------------------------------------------------- //! @brief メモリを解放します。 //! //! @param[in] memory 解放するメモリへのポインタ。 //--------------------------------------------------------------------------- void MemFree(void* memory) { nw::demo::SimpleApp::Free(memory); } //--------------------------------------------------------------------------- //! @brief シェーダの初期化を行います。 //! //! @param[in] pDrawer RectDrawerオブジェクトへのポインタ。 //--------------------------------------------------------------------------- void* InitShaders(nw::font::RectDrawer* pDrawer) { const wchar_t* shaders = NW_DEMO_FILE_PATH( NW_FONT_RECTDRAWER_SHADERBINARY ); nn::fs::FileReader shaderReader(shaders); const u32 fileSize = (u32)shaderReader.GetSize(); void* shaderBinary = MemAlloc(fileSize); NN_NULL_ASSERT(shaderBinary); s32 read = shaderReader.Read(shaderBinary, fileSize); NN_ASSERT(read == fileSize); const u32 vtxBufCmdBufSize = nw::font::RectDrawer::GetVertexBufferCommandBufferSize(shaderBinary, fileSize); void *const vtxBufCmdBuf = DevMemAlloc(vtxBufCmdBufSize); NN_NULL_ASSERT(vtxBufCmdBuf); pDrawer->Initialize(vtxBufCmdBuf, shaderBinary, fileSize); MemFree(shaderBinary); return vtxBufCmdBuf; } //--------------------------------------------------------------------------- //! @brief 描画の初期設定を行います。 //! //! @param[in] width 画面の幅。 //! @param[in] height 画面の高さ。 //--------------------------------------------------------------------------- void InitDraw( int width, int height ) { // カラーバッファ情報 // LCDの向きに合わせて、幅と高さを入れ替えています。 const nw::font::ColorBufferInfo colBufInfo = { height, width, PICA_DATA_DEPTH24_STENCIL8_EXT }; const u32 screenSettingCommands[] = { // ビューポートの設定 NW_FONT_CMD_SET_VIEWPORT( 0, 0, colBufInfo.width, colBufInfo.height ), // シザー処理を無効 NW_FONT_CMD_SET_DISABLE_SCISSOR( colBufInfo ), // wバッファの無効化 // デプスレンジの設定 // ポリゴンオフセットの無効化 NW_FONT_CMD_SET_WBUFFER_DEPTHRANGE_POLYGONOFFSET( 0.0f, // wScale : 0.0 でWバッファが無効 0.0f, // depth range near 1.0f, // depth range far 0, // polygon offset units : 0.0 で ポリゴンオフセットが無効 colBufInfo), }; nngxAdd3DCommand(screenSettingCommands, sizeof(screenSettingCommands), true); static const u32 s_InitCommands[] = { // カリングを無効 NW_FONT_CMD_SET_CULL_FACE( NW_FONT_CMD_CULL_FACE_DISABLE ), // ステンシルテストを無効 NW_FONT_CMD_SET_DISABLE_STENCIL_TEST(), // デプステストを無効 // カラーバッファの全ての成分を書き込み可 NW_FONT_CMD_SET_DEPTH_FUNC_COLOR_MASK( false, // isDepthTestEnabled 0, // depthFunc true, // depthMask true, // red true, // green true, // blue true), // alpha // アーリーデプステストを無効 NW_FONT_CMD_SET_ENABLE_EARLY_DEPTH_TEST( false ), // フレームバッファアクセス制御 NW_FONT_CMD_SET_FBACCESS( true, // colorRead true, // colorWrite false, // depthRead false, // depthWrite false, // stencilRead false), // stencilWrite }; nngxAdd3DCommand(s_InitCommands, sizeof(s_InitCommands), true); } //--------------------------------------------------------------------------- //! @brief ResFontを構築します。 //! //! @param[out] pFont 構築するフォントへのポインタ。 //! @param[in] filePath ロードするフォントリソースファイル名。 //! //! @return ResFont構築の成否を返します。 //--------------------------------------------------------------------------- bool InitFont( nw::font::ResFont* pFont, const wchar_t* filePath ) { // フォントリソースをロードします nn::fs::FileReader fontReader(filePath); s32 fileSize = (s32)fontReader.GetSize(); if ( fileSize <= 0 ) { return false; } void* buffer = DevMemAlloc(fileSize, nw::font::GlyphDataAlignment); if (buffer == NULL) { return false; } s32 readSize = fontReader.Read(buffer, fileSize); if (readSize != fileSize) { MemFree(buffer); return false; } // フォントリソースをセットします bool bSuccess = pFont->SetResource(buffer); NN_ASSERT(bSuccess); //--- 既にリソースをセット済みであるか,ロード済みであるか、リソースが不正な場合に失敗します。 if (! bSuccess) { MemFree(buffer); } // 描画用バッファを設定します。 const u32 drawBufferSize = nw::font::ResFont::GetDrawBufferSize(buffer); void* drawBuffer = MemAlloc(drawBufferSize, 4); NN_NULL_ASSERT(drawBuffer); pFont->SetDrawBuffer(drawBuffer); return bSuccess; } //--------------------------------------------------------------------------- //! @brief ResFontを破棄します。 //! //! @param[in] pFont 破棄するフォントへのポインタ。 //--------------------------------------------------------------------------- void CleanupFont(nw::font::ResFont* pFont) { // 描画用バッファの無効化 // 描画用バッファがセットされているなら 構築時に SetDrawBuffer に渡したバッファへの // ポインタが返ってきます。 void *const drawBuffer = pFont->SetDrawBuffer(NULL); if (drawBuffer != NULL) { MemFree(drawBuffer); } // フォントがセットされているなら SetResource 時に渡したリソースへの // ポインタが返ってきます。 void *const resource = pFont->RemoveResource(); if (resource != NULL) { MemFree(resource); } // RemoveResource 後は再度 SetResource するまでフォントとして使用できません。 } //--------------------------------------------------------------------------- //! @brief 表示文字列用バッファを確保します。 //! //! @param[in] charMax 表示する文字列の最大文字数。 //! //! @return 確保した表示文字列用バッファへのポインタを返します。 //--------------------------------------------------------------------------- nw::font::DispStringBuffer* AllocDispStringBuffer(int charMax) { const u32 DrawBufferSize = nw::font::CharWriter::GetDispStringBufferSize(charMax); void *const bufMem = MemAlloc(DrawBufferSize); NN_NULL_ASSERT(bufMem); return nw::font::CharWriter::InitDispStringBuffer(bufMem, charMax); } //--------------------------------------------------------------------------- //! @brief 文字列表示用にモデルビュー行列と射影行列を設定します。 //! //! @param[in] pDrawer RectDrawerオブジェクトへのポインタ。 //! @param[in] width 画面の幅。 //! @param[in] height 画面の高さ。 //--------------------------------------------------------------------------- void SetupTextCamera( nw::font::RectDrawer* pDrawer, int width, int height ) { // 射影行列を正射影に設定 { // 左上原点とし、Y軸とZ軸の向きが逆になるように設定します。 nn::math::MTX44 proj; f32 znear = 0.0f; f32 zfar = -1.0f; f32 t = 0; f32 b = static_cast(height); f32 l = 0; f32 r = static_cast(width); nn::math::MTX44OrthoPivot(&proj, l, r, b, t, znear, zfar, nn::math::PIVOT_UPSIDE_TO_TOP); pDrawer->SetProjectionMtx(proj); } // モデルビュー行列を単位行列に設定 { nn::math::MTX34 mv; nn::math::MTX34Identity(&mv); pDrawer->SetViewMtxForText(mv); } } //--------------------------------------------------------------------------- //! @brief ASCII文字列を描画します。 //! //! @param[in] pDrawer RectDrawerオブジェクトへのポインタ。 //! @param[in] pDrawStringBuf DispStringBufferオブジェクトへのポインタ。 //! @param[in] pFont フォントへのポインタ。 //! @param[in] width 画面の幅。 //! @param[in] height 画面の高さ。 //--------------------------------------------------------------------------- void DrawAscii( nw::font::RectDrawer* pDrawer, nw::font::DispStringBuffer* pDrawStringBuf, nw::font::ResFont* pFont, int width, int height ) { nw::font::TextWriter writer; writer.SetDispStringBuffer(pDrawStringBuf); writer.SetFont(pFont); writer.SetCursor(0, 0); // 文字列が変更されないので、文字列の描画コマンドを一度だけ作成します。 if (! s_InitAsciiString) { writer.StartPrint(); (void)writer.Print("DEMO: ResFont\n"); (void)writer.Print("\n"); // ASCIIの文字見本を表示 (void)writer.Print("All ASCII Character listing:\n"); (void)writer.Print("\n"); (void)writer.Print(" !\"#$%&'()*+,-./\n"); (void)writer.Print("0123456789:;<=>?\n"); (void)writer.Print("@ABCDEFGHIJKLMNO\n"); (void)writer.Print("PQRSTUVWXYZ[\\]^_\n"); (void)writer.Print("`abcdefghijklmno\n"); (void)writer.Print("pqrstuvwxyz{|}~\n"); writer.EndPrint(); pDrawer->BuildTextCommand(&writer); s_InitAsciiString = true; } // 文字の色は、文字列の描画コマンドを再作成しなくても変更できます。 writer.SetTextColor(nw::ut::Color8(s_Color, 255, s_Color, 255)); s_Color++; pDrawer->DrawBegin(); SetupTextCamera(pDrawer, width, height); writer.UseCommandBuffer(); pDrawer->DrawEnd(); } //--------------------------------------------------------------------------- //! @brief カウンタを描画します。 //! //! @param[in] pDrawer RectDrawerオブジェクトへのポインタ。 //! @param[in] pDrawStringBuf DispStringBufferオブジェクトへのポインタ。 //! @param[in] pFont フォントへのポインタ。 //! @param[in] width 画面の幅。 //! @param[in] height 画面の高さ。 //--------------------------------------------------------------------------- void DrawCounter( nw::font::RectDrawer* pDrawer, nw::font::DispStringBuffer* pDrawStringBuf, nw::font::ResFont* pFont, int width, int height ) { nw::font::TextWriter writer; writer.SetDispStringBuffer(pDrawStringBuf); writer.SetFont(pFont); writer.SetCursor(0, 0); writer.SetFixedWidth(8.0f); writer.EnableFixedWidth(true); pDrawer->DrawBegin(); SetupTextCamera(pDrawer, width, height); // カウンタの描画コマンドをその都度作成して使用します。 writer.StartPrint(); (void)writer.Printf("Counter : %d\n", s_Counter); writer.EndPrint(); pDrawer->BuildTextCommand(&writer); writer.UseCommandBuffer(); // カウンタ1/60の描画コマンドをその都度作成して使用します。 writer.StartPrint(); (void)writer.Printf("Counter 1/60 : %d\n", s_Counter / 60); writer.EndPrint(); pDrawer->BuildTextCommand(&writer); writer.UseCommandBuffer(); pDrawer->DrawEnd(); s_Counter++; } } // namespace //--------------------------------------------------------------------------- //! @brief サンプルのメイン関数です。 //--------------------------------------------------------------------------- void nnMain() { // os の初期化 nn::os::Initialize(); // fs の初期化 nn::fs::Initialize(); nw::demo::SimpleApp& demoApp = nw::demo::SimpleApp::GetInstance(); demoApp.Initialize(); nw::font::ResFont font; // フォントの構築 { bool bSuccess = InitFont(&font, NW_DEMO_FILE_PATH(L"tahoma.bcfnt")); NN_ASSERTMSG(bSuccess, "Fail to load ResFont."); } // 描画リソースの構築 nw::font::RectDrawer drawer; void *const drawerBuf = InitShaders(&drawer); // 描画文字列用バッファの確保 nw::font::DispStringBuffer *const pDrawStringBuf0 = AllocDispStringBuffer(512); nw::font::DispStringBuffer *const pDrawStringBuf1 = AllocDispStringBuffer(128); const nw::ut::FloatColor clearColor(0.3f, 0.3f, 0.3f, 1.0f); const f32 clearDepth = 0.0f; // フォント情報の表示 volatile bool loop = true; while (loop) { demoApp.SetRenderingTarget(demoApp.DISPLAY0); { demoApp.GetFrameBufferObject().ClearBuffer(clearColor, clearDepth); InitDraw(demoApp.DISPLAY0_WIDTH, demoApp.DISPLAY0_HEIGHT); DrawAscii(&drawer, pDrawStringBuf0, &font, demoApp.DISPLAY0_WIDTH, demoApp.DISPLAY0_HEIGHT); } demoApp.SetRenderingTarget(demoApp.DISPLAY1); { demoApp.GetFrameBufferObject().ClearBuffer(clearColor, clearDepth); InitDraw(demoApp.DISPLAY1_WIDTH, demoApp.DISPLAY1_HEIGHT); DrawCounter(&drawer, pDrawStringBuf1, &font, demoApp.DISPLAY1_WIDTH, demoApp.DISPLAY1_HEIGHT); } demoApp.SwapBuffer(demoApp.DISPLAY_BOTH); } // 描画文字列用バッファの解放 MemFree(pDrawStringBuf1); MemFree(pDrawStringBuf0); drawer.Finalize(); MemFree(drawerBuf); // フォントの破棄 CleanupFont(&font); }