1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     font_RectDrawer.h
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: 25674 $
14  *---------------------------------------------------------------------------*/
15 
16 #ifndef NN_FONT_CTR_FONT_RECT_DRAWER_H_
17 #define NN_FONT_CTR_FONT_RECT_DRAWER_H_
18 
19 //--------------------------------------
20 // 動作設定
21 
22 // glDrawArraysで描画する方が速い?
23 #define NN_FONT_RECTDRAWER_USE_DRAW_ARRAYS 1
24 
25 // Bufferにためられるなら、ためて同時描画
26 #define NN_FONT_RECTDRAWER_USE_DRAW_BUFFER 1
27 
28 
29 #include <nn/assert.h>
30 #include <nn/font/CTR/font_RectDrawerCommand.h>
31 #include <nn/font/CTR/font_CmdCache.h>
32 #if defined(NN_PLATFORM_CTR)
33     #include <nn/gx/CTR/gx_CommandAccess.h>
34 #endif
35 #include <nn/util/util_Color.h>
36 
37 #define NN_FONT_COMMAND_SET_BLEND_FUNC( eq, src, dst ) \
38     PICA_CMD_DATA_COLOR_OPERATION( \
39         PICA_DATA_FRAGOP_MODE_DMP, \
40         PICA_DATA_ENABLE_BLEND ), \
41     PICA_CMD_HEADER_SINGLE( PICA_REG_COLOR_OPERATION ), \
42     PICA_CMD_DATA_BLEND_FUNC( eq, src, dst ), \
43     PICA_CMD_HEADER_SINGLE( PICA_REG_BLEND_FUNC )
44 
45 #define NN_FONT_COMMAND_SET_BLEND_DEFAULT \
46     NN_FONT_COMMAND_SET_BLEND_FUNC( \
47         PICA_DATA_BLEND_EQUATION_ADD, \
48         PICA_DATA_BLEND_FUNC_SRC_ALPHA, \
49         PICA_DATA_BLEND_FUNC_ONE_MINUS_SRC_ALPHA )
50 
51 #if defined(NN_FONT_RECTDRAWER_USE_DRAW_ARRAYS)
52 #define NN_FONT_CMD_SET_VTXNUM( addrOffset, vtxNum )                    \
53     /* 頂点インデックスのアドレス/型 */                                 \
54     /* 0x227 */                                                         \
55     PICA_CMD_DATA_INDEX_ARRAY_ADDR_OFFSET( addrOffset, 1 /* type */ ),  \
56     PICA_CMD_HEADER_SINGLE( PICA_REG_INDEX_ARRAY_ADDR_OFFSET ),         \
57     /* 描画頂点数 */                                                    \
58     /* 0x228 */                                                         \
59     PICA_CMD_DATA_DRAW_VERTEX_NUM( vtxNum ),                            \
60     PICA_CMD_HEADER_SINGLE( PICA_REG_DRAW_VERTEX_NUM )
61 #else
62 #define NN_FONT_CMD_SET_VTXNUM( addrOffset, vtxNum )                    \
63     /* 描画頂点数 */                                                    \
64     /* 0x228 */                                                         \
65     PICA_CMD_DATA_DRAW_VERTEX_NUM( vtxNum ),                            \
66     PICA_CMD_HEADER_SINGLE( PICA_REG_DRAW_VERTEX_NUM )
67 #endif
68 
69 namespace nn {
70 namespace font {
71 namespace CTR {
72 
73 struct DispStringBuffer;
74 class CharWriter;
75 
76 //---------------------------------------------------------------------------
77 //! @brief      描画クラスです。
78 //---------------------------------------------------------------------------
79 class RectDrawer
80 {
81 public:
82     enum
83     {
84         DONT_USE_SETUP_COMMAND = 0x1
85     };
86 
87     //! @brief      DMPGLのプログラムを作成し、初期化します。
88     //!
89     //! @param[in]  shaderBinary  シェーダバイナリ。
90     //! @param[in]  size          シェーダバイナリのサイズ。
91     //!
92     //! @return     プログラムハンドルを返します。
93     //!
94     static GLuint       CreateProgram(
95                             const void* shaderBinary,
96                             u32         size);
97 
98     //! @name コンストラクタ/デストラクタ
99     //@{
100 
101     //! コンストラクタです。
102                         RectDrawer();
103 
104     //! @brief      デストラクタです。
105     //!
106     //! @details    Finalize() を呼び出します。
107     //!
108     //! @sa         Finalize
109     //!
110     //! @since      2010/06/02 初版。
111     //!
112     virtual             ~RectDrawer();
113 
114     //@}
115 
116     //! @name 初期化/後処理
117     //@{
118 
119     //! @brief      初期化を行います。
120     //!
121     //! @details    本関数を実行すると DMPGL ステートが一貫性の無い状態になります。
122     //!             nngxUpdateState(NN_GX_STATE_ALL)を呼び出して一貫性を回復してください。
123     //!
124     //! @param[in]  glProgram GLのプログラムオブジェクト。
125     //!
126     //! @sa         Finalize
127     //!
128     //! @since      2010/06/02 初版。
129     //!
130     void                Initialize(GLuint glProgram);
131 
132     //! @brief      開放を行います。
133     //!
134     //! @sa         Initialize
135     //!
136     //! @since      2010/06/02 初版。
137     //!
138     virtual void        Finalize();
139 
140     //@}
141 
142     //! @brief      描画を開始します。
143     //!
144     //! @param[in]  flag 描画を制御するフラグ。
145     //!
146     //! @sa         DrawEnd
147     //!
148     //! @since      2010/06/28 初版。
149     //!
150     virtual void        DrawBegin(u32 flag = 0);
151 
152     //! @brief      描画を終了します。
153     //!
154     //! @param[in]  flag 描画を制御するフラグ。
155     //!
156     //! @sa         DrawBegin
157     //!
158     //! @since      2010/06/28 初版。
159     //!
160     virtual void        DrawEnd(u32 flag = 0);
161 
162     //! @brief      射影行列を設定します。
163     //!
164     //! @param[in]  mtx  射影行列
165     //!
166     void                SetProjectionMtx(const nn::math::MTX44& mtx);
167 
168     //! @brief      テキスト用のビュー行列を設定します。
169     //!
170     //! @param[in]  mtx  ビュー行列
171     //!
172     void                SetViewMtxForText(const nn::math::MTX34& mtx);
173 
174     //! @brief      視差のパラメータを設定します。
175     //!
176     //! @param[in]  parallax 視差。
177     //! @param[in]  dLevel  カメラから基準面までの距離。
178     //! @param[in]  addDist カメラとの距離に追加する値。
179     //!
180     void                SetParallax(
181                             f32     parallax,
182                             f32     dLevel,
183                             f32     addDist     = 0.0f
184                         );
185 
186     //! @brief      文字列用の描画コマンドを作成します。
187     //!
188     //! @param[in]  pCharWriter CharWriter オブジェクトへのポインタ。
189     //!
190     void                BuildTextCommand(CharWriter* pCharWriter);
191 
192     //! @details :private
193     void                UniformAndDrawText(DispStringBuffer* pDispStringBuffer);
194 
195     //! @details :private
196     void                UseBeginCommand();
197 
198     //! @details :private
199     void                UseEndCommand();
200 
201 protected:
202 
203     //! @details :private
SetUniformCommand(u32 * buffer,u32 num)204     static u32          SetUniformCommand(
205                             u32*    buffer,
206                             u32     num
207                         )
208     {
209 #if defined(NN_PLATFORM_CTR)
210         buffer[2] = buffer[3];
211         buffer[3] = PICA_CMD_HEADER_VS_F32(num);
212 #else
213         NN_ASSERT(false);
214         (void)buffer;
215 #endif
216         return sizeof(u32) * (4 + 4 * num);
217     }
218 
219     //! @details :private
220     void                DisableTextures();
221 
222     //! @details :private
223     void                AddUniformMtx();
224 
225     //! @details :private
226     u32                 GetVertexIndexAddressOffset(u32 vtxNum) const;
227 
228     //! @details :private
229     const u32*          GetDrawCommands() const;
230 
231     //! @details :private
232     u32                 GetDrawCommandSize() const;
233 
234 private:
235     void                InitializeVBO();
236 
237     void                InitializeCMD();
238 
239     void                InitUniformBuffer(
240                             u32* __restrict buf,
241                             u32             addr);
242 
243     void                AddTextColor(
244                             math::VEC4* __restrict          dst,
245                             const util::Color8* __restrict  src,
246                             int                             mode);
247 
248 protected:
249     ////////////////////////////// Vertex Shader Info
250 
251     //! @details :private
252     enum
253     {
254         UNIFORM_MTX_USE_MAX     =  3 /* mtx row */ + 4 /* vtx color */,
255         UNIFORM_DATA_USE_MAX    =  1 /* rect */ + 3/* TexMapMax */ * 2,
256 
257         UNIFORM_TEXT_MTX_MAX    =  3,   // mtx34 row
258 
259         UNIFORM_PROJ_NUM        =  4,   // mtx44 row
260 
261         UNIFORM_PROJ_START      =  0,
262         UNIFORM_ULCDDATA_START  = UNIFORM_PROJ_START + UNIFORM_PROJ_NUM,
263         UNIFORM_CONST_START,
264         UNIFORM_ADDR_START,
265         UNIFORM_MTX_START       = 32,
266         UNIFORM_DATA_START      = 64,
267 
268         UNIFORM_TEXTCOLOR_START = UNIFORM_MTX_START + UNIFORM_TEXT_MTX_MAX,
269 
270         UNIFORM_MAX             = 96
271     };
272 
273     //! @details :private
274     enum
275     {
276 #ifdef NN_FONT_RECTDRAWER_USE_DRAW_BUFFER
277 
278         UNIFORM_ADDR_NUM        = UNIFORM_MTX_START  - UNIFORM_ADDR_START,
279         UNIFORM_MTX_NUM         = UNIFORM_DATA_START - UNIFORM_MTX_START,
280         UNIFORM_DATA_NUM        = UNIFORM_MAX        - UNIFORM_DATA_START,
281 
282         UNIFORM_TEXTCOLOR_NUM   = (UNIFORM_DATA_START - UNIFORM_TEXTCOLOR_START) & ~((1 << 2) - 1),
283 #else
284 
285         UNIFORM_RESISTER_ADDR = 5,
286 
287         // まとめて描かないなら、最大8レジスタ
288         UNIFORM_DATA_NUM  = 8,
289 
290         UNIFORM_ADDR_NUM      = UNIFORM_DATA_NUM - UNIFORM_RESISTER_ADDR,
291 #endif
292 
293         DRAW_VTX_NUM          = 6,
294         BIND_ATTRIB_LOCATION  = 0
295     };
296 
297 
298     ////////////////////////////// Command
299 
300     //! @details :private
301     CmdCache            m_CmdCacheDrawBegin;
302 
303     //! @details :private
304     CmdCache            m_CmdCacheDrawEnd;
305 
306     //! @details :private
307     u8                  m_UniformAddrIndex;
308 
309     //! @details :private
310     u8                  m_UniformMtxIndex;
311 
312     //! @details :private
313     u8                  m_UniformDataIndex;
314 
315     //! @details :private
316     u8                  m_UniformTextColorIndex;
317 
318     //! @details :private
319     u32                 m_UniformProjBuffer[ 4 + 4 * (UNIFORM_PROJ_NUM + 1) ];
320 
321     //! @details :private
322     u32                 m_UniformAddrBuffer[ 4 + 4 * UNIFORM_ADDR_NUM ];
323 
324     //! @details :private
325     union
326     {
327         //! @details :private
328         u32                 buffer[ 4 + 4 * UNIFORM_MTX_NUM  ];
329 
330         //! @details :private
331         struct
332         {
333 
334             //! @details :private
335             u32                 mtx  [ 4 + 4 * UNIFORM_TEXT_MTX_MAX ];
336 
337             //! @details :private
338             u32                 color[ 4 + 4 * UNIFORM_TEXTCOLOR_NUM ];
339         } text;
340     } m_UniformMtxBuffer;
341 
342     //! @details :private
343     u32                 m_UniformDataBuffer[ 4 + 4 * UNIFORM_DATA_NUM ];
344 
345     //! @details :private
346     struct UniformAddress
347     {
348         //! @details :private
UniformAddressUniformAddress349                             UniformAddress()
350                             :   addrMtx(0.f),
351                                 addrSizeAndVtx(0.f),
352                                 addrTexCoord(0.f),
353                                 addrColor(0.f)
354                             {}
355 
356         //! @details :private
357         f32                 addrMtx;
358 
359         //! @details :private
360         f32                 addrSizeAndVtx;
361 
362         //! @details :private
363         f32                 addrTexCoord;
364 
365         //! @details :private
366         f32                 addrColor;
367     };
368 
369     //! @details :private
370     UniformAddress      m_UniformAddress;
371 
372     //! @details :private
373     UniformAddress *const
374                         m_UniformAddr;
375 
376     //! @details :private
377     math::VEC4 *const   m_UniformMtx;
378 
379     //! @details :private
380     math::VEC4 *const   m_UniformData;
381 
382     //! @details :private
383     math::VEC4 *const   m_UniformTextColor;
384 
385     ////////////////////////////// Vertex Buufer Object
386 
387     //! @details :private
388     GLuint              m_GlVboElement;
389 
390     //! @details :private
391     GLuint              m_GlVboArray;
392 
393     ////////////////////////////// Uniform
394 
395     //! @details :private
396     GLuint              m_GlProgram;
397 
398     //! @details :private
399     u32                 m_VBOBaseAddr;
400 
401     //! :private
402     //! @brief      色が変更されているかどうか
403     bool                m_IsColorDirty;
404     NN_PADDING3;
405 
406 #if defined(NN_FONT_RECTDRAWER_USE_DRAW_ARRAYS)
407 private:
408     static bool         s_StaticInitialized;
409     static GLfloat      s_VertexPosition[UNIFORM_ADDR_NUM][DRAW_VTX_NUM][4];
410 #endif
411 };
412 
413 }   // namespace CTR
414 }   // namespace font
415 }   // namespace nn
416 
417 #endif //  NN_FONT_CTR_FONT_RECT_DRAWER_H_
418