/*---------------------------------------------------------------------------* Project: Horizon File: font_RectDrawer.h Copyright (C)2009-2010 Nintendo Co., Ltd./HAL Laboratory, Inc. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. 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. $Revision: 28317 $ *---------------------------------------------------------------------------*/ #ifndef NN_FONT_CTR_FONT_RECT_DRAWER_H_ #define NN_FONT_CTR_FONT_RECT_DRAWER_H_ //-------------------------------------- // 動作設定 // glDrawArraysで描画する方が速い? #define NN_FONT_RECTDRAWER_USE_DRAW_ARRAYS 1 // Bufferにためられるなら、ためて同時描画 #define NN_FONT_RECTDRAWER_USE_DRAW_BUFFER 1 #include #include #include #if defined(NN_PLATFORM_CTR) #include #endif #include #define NN_FONT_COMMAND_SET_BLEND_FUNC( eq, src, dst ) \ PICA_CMD_DATA_COLOR_OPERATION( \ PICA_DATA_FRAGOP_MODE_DMP, \ PICA_DATA_ENABLE_BLEND ), \ PICA_CMD_HEADER_SINGLE( PICA_REG_COLOR_OPERATION ), \ PICA_CMD_DATA_BLEND_FUNC( eq, src, dst ), \ PICA_CMD_HEADER_SINGLE( PICA_REG_BLEND_FUNC ) #define NN_FONT_COMMAND_SET_BLEND_DEFAULT \ NN_FONT_COMMAND_SET_BLEND_FUNC( \ PICA_DATA_BLEND_EQUATION_ADD, \ PICA_DATA_BLEND_FUNC_SRC_ALPHA, \ PICA_DATA_BLEND_FUNC_ONE_MINUS_SRC_ALPHA ) namespace nn { namespace font { namespace CTR { struct DispStringBuffer; class CharWriter; //--------------------------------------------------------------------------- //! @brief 文字を描画するクラスです。 //--------------------------------------------------------------------------- class RectDrawer { public: enum { DONT_USE_SETUP_COMMAND = 0x1 }; //! @brief RectDrawerが必要な頂点バッファ・コマンドバッファのサイズを取得します。 //! //! @param[in] shaderBinary シェーダバイナリ。 //! @param[in] size シェーダバイナリのサイズ。 //! //! @return 頂点バッファ・コマンドバッファのメモリサイズを返します。 //! static u32 GetVertexBufferCommandBufferSize( const void* shaderBinary, u32 size); //! @brief RectDrawerが使用する頂点バッファのデータを取得します。 //! //! @return 頂点バッファのデータを返します。 //! static void* GetVertexBufferData(); //! @brief RectDrawerが必要な頂点バッファのサイズを取得します。 //! //! @return 頂点バッファのメモリサイズを返します。 //! static u32 GetVertexBufferSize(); //! @brief RectDrawerが必要なコマンドバッファのサイズを取得します。 //! //! @param[in] shaderBinary シェーダバイナリ。 //! @param[in] size シェーダバイナリのサイズ。 //! //! @return コマンドバッファのメモリサイズを返します。 //! static u32 GetCommandBufferSize( const void* shaderBinary, u32 size); //! @name コンストラクタ/デストラクタ //@{ //! コンストラクタです。 RectDrawer(); //! @brief デストラクタです。 //! //! @details Finalize() を呼び出します。 //! //! @sa Finalize //! //! @since 2010/06/02 初版。 //! virtual ~RectDrawer(); //@} //! @name 初期化/後処理 //@{ //! @brief 初期化を行います。 //! //! @param[in] vtxBufCmdBuf 頂点用バッファ・コマンドバッファ。 //! @param[in] shaderBinary シェーダバイナリ。 //! @param[in] size シェーダバイナリのサイズ。 //! //! @sa Finalize //! //! @since 2010/07/29 引数を変更。 //! @since 2010/06/02 初版。 //! void Initialize( void* vtxBufCmdBuf, const void* shaderBinary, u32 size); //! @brief 初期化を行います。 //! //! @param[in] vertexBuffer 頂点用バッファ。 //! @param[in] commandBuffer コマンドバッファ。 //! @param[in] shaderBinary シェーダバイナリ。 //! @param[in] size シェーダバイナリのサイズ。 //! //! @sa Finalize //! //! @since 2010/07/29 引数を変更。 //! @since 2010/06/02 初版。 //! void Initialize( void* vertexBuffer, void* commandBuffer, const void* shaderBinary, u32 size); //! @brief 終了処理を行います。 //! //! @sa Initialize //! //! @since 2010/06/02 初版。 //! virtual void Finalize(); //@} //! @brief 描画を開始します。 //! //! @param[in] flag 描画を制御するフラグ。 //! //! @sa DrawEnd //! //! @since 2010/06/28 初版。 //! virtual void DrawBegin(u32 flag = 0); //! @brief 描画を終了します。 //! //! @param[in] flag 描画を制御するフラグ。 //! //! @sa DrawBegin //! //! @since 2010/06/28 初版。 //! virtual void DrawEnd(u32 flag = 0); //! @brief 射影行列を設定します。 //! //! @param[in] mtx 射影行列 //! void SetProjectionMtx(const nn::math::MTX44& mtx); //! @brief テキスト用のビュー行列を設定します。 //! //! @param[in] mtx ビュー行列 //! void SetViewMtxForText(const nn::math::MTX34& mtx); //! @brief 視差のパラメータを設定します。 //! //! @param[in] parallax 視差。 //! @param[in] dLevel カメラから基準面までの距離。 //! @param[in] addDist カメラとの距離に追加する値。 //! void SetParallax( f32 parallax, f32 dLevel, f32 addDist = 0.0f ); //! @brief 文字列用の描画コマンドを作成します。 //! //! @param[in] pCharWriter CharWriter オブジェクトへのポインタ。 //! void BuildTextCommand(CharWriter* pCharWriter); //! @details :private void UniformAndDrawText(DispStringBuffer* pDispStringBuffer); //! @details :private void UseBeginCommand(); //! @details :private void UseEndCommand(); protected: //! @details :private static u32 SetUniformCommand( u32* buffer, u32 num ) { #if defined(NN_PLATFORM_CTR) buffer[2] = buffer[3]; buffer[3] = PICA_CMD_HEADER_VS_F32(num); #else NN_ASSERT(false); (void)buffer; #endif return sizeof(u32) * (4 + 4 * num); } //! @details :private void DisableTextures(); //! @details :private void AddUniformMtx(); #if defined(NN_FONT_RECTDRAWER_USE_DRAW_ARRAYS) //! @details :private u32 GetVertexIndexAddressOffset(u32 vtxNum) const; #endif //! @details :private const u32* GetDrawCommands() const; //! @details :private u32 GetDrawCommandSize() const; private: static void InitializeStatic(); void InitializeCMD( void* vertexBuffer, void* commandBuffer, const void* shaderBinary, u32 size, bool initVertexBuffer); void InitUniformBuffer( u32* __restrict buf, u32 addr); void AddTextColor( math::VEC4* __restrict dst, const util::Color8* __restrict src, int mode); protected: ////////////////////////////// Vertex Shader Info //! @details :private enum { UNIFORM_MTX_USE_MAX = 3 /* mtx row */ + 4 /* vtx color */, UNIFORM_DATA_USE_MAX = 1 /* rect */ + 3/* TexMapMax */ * 2, UNIFORM_TEXT_MTX_MAX = 3, // mtx34 row UNIFORM_PROJ_NUM = 4, // mtx44 row UNIFORM_PROJ_START = 0, UNIFORM_ULCDDATA_START = UNIFORM_PROJ_START + UNIFORM_PROJ_NUM, UNIFORM_CONST_START, UNIFORM_ADDR_START, UNIFORM_MTX_START = 32, UNIFORM_DATA_START = 64, UNIFORM_TEXTCOLOR_START = UNIFORM_MTX_START + UNIFORM_TEXT_MTX_MAX, UNIFORM_MAX = 96 }; //! @details :private enum { #ifdef NN_FONT_RECTDRAWER_USE_DRAW_BUFFER UNIFORM_ADDR_NUM = UNIFORM_MTX_START - UNIFORM_ADDR_START, UNIFORM_MTX_NUM = UNIFORM_DATA_START - UNIFORM_MTX_START, UNIFORM_DATA_NUM = UNIFORM_MAX - UNIFORM_DATA_START, UNIFORM_TEXTCOLOR_NUM = (UNIFORM_DATA_START - UNIFORM_TEXTCOLOR_START) & ~((1 << 2) - 1), #else UNIFORM_RESISTER_ADDR = 5, // まとめて描かないなら、最大8レジスタ UNIFORM_DATA_NUM = 8, UNIFORM_ADDR_NUM = UNIFORM_DATA_NUM - UNIFORM_RESISTER_ADDR, #endif DRAW_VTX_NUM = 6, BIND_ATTRIB_LOCATION = 0 }; ////////////////////////////// Command //! @details :private CmdCache m_CmdCacheDrawBegin; //! @details :private CmdCache m_CmdCacheDrawEnd; //! @details :private u8 m_UniformAddrIndex; //! @details :private u8 m_UniformMtxIndex; //! @details :private u8 m_UniformDataIndex; //! @details :private u8 m_UniformTextColorIndex; //! @details :private u32 m_UniformProjBuffer[ 4 + 4 * (UNIFORM_PROJ_NUM + 1) ]; //! @details :private u32 m_UniformAddrBuffer[ 4 + 4 * UNIFORM_ADDR_NUM ]; //! @details :private union { //! @details :private u32 buffer[ 4 + 4 * UNIFORM_MTX_NUM ]; //! @details :private struct { //! @details :private u32 mtx [ 4 + 4 * UNIFORM_TEXT_MTX_MAX ]; //! @details :private u32 color[ 4 + 4 * UNIFORM_TEXTCOLOR_NUM ]; } text; } m_UniformMtxBuffer; //! @details :private u32 m_UniformDataBuffer[ 4 + 4 * UNIFORM_DATA_NUM ]; //! @details :private struct UniformAddress { //! @details :private UniformAddress() : addrMtx(0.f), addrSizeAndVtx(0.f), addrTexCoord(0.f), addrColor(0.f) {} //! @details :private f32 addrMtx; //! @details :private f32 addrSizeAndVtx; //! @details :private f32 addrTexCoord; //! @details :private f32 addrColor; }; //! @details :private UniformAddress m_UniformAddress; //! @details :private UniformAddress *const m_UniformAddr; //! @details :private math::VEC4 *const m_UniformMtx; //! @details :private math::VEC4 *const m_UniformData; //! @details :private math::VEC4 *const m_UniformTextColor; //! @details :private void* m_CommandBuffer; ////////////////////////////// Vertex Buufer Object //! @details :private void* m_VertexBufferArray; ////////////////////////////// Uniform #if defined(NN_FONT_RECTDRAWER_USE_DRAW_ARRAYS) //! @details :private u32 m_VertexBufferBaseAddr; #endif //! :private //! @brief 色が変更されているかどうか bool m_IsColorDirty; NN_PADDING3; private: struct VertexBuffer { #if defined(NN_FONT_RECTDRAWER_USE_DRAW_ARRAYS) f32 position[UNIFORM_ADDR_NUM][DRAW_VTX_NUM][4]; #else f32 position[UNIFORM_ADDR_NUM][VERTEX_MAX][4]; u16 indexes[UNIFORM_ADDR_NUM][DRAW_VTX_NUM]; #endif }; static bool s_StaticInitialized; static VertexBuffer s_VertexBuffer; }; inline u32 RectDrawer::GetVertexBufferSize() { return sizeof(s_VertexBuffer); } #if defined(NN_PLATFORM_CTR) inline u32* SetVertexNumCmd( u32** pCmdPtr, u32 addrOffset, u32 vtxNum ) { #if defined(NN_FONT_RECTDRAWER_USE_DRAW_ARRAYS) // 頂点インデックスのアドレス/型 // 0x227 NN_FONT_ADD_SINGLE_COMMAND_PTR( *pCmdPtr, PICA_CMD_HEADER_SINGLE( PICA_REG_INDEX_ARRAY_ADDR_OFFSET ), PICA_CMD_DATA_INDEX_ARRAY_ADDR_OFFSET( addrOffset, 1 /* type */ )); #else (void)addrOffset; #endif // 描画頂点数 // 0x228 NN_FONT_ADD_SINGLE_COMMAND_PTR( *pCmdPtr, PICA_CMD_HEADER_SINGLE( PICA_REG_DRAW_VERTEX_NUM ), PICA_CMD_DATA_DRAW_VERTEX_NUM( vtxNum )); return *pCmdPtr; } #endif } // namespace CTR } // namespace font } // namespace nn #endif // NN_FONT_CTR_FONT_RECT_DRAWER_H_