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: 28317 $
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 namespace nn {
52 namespace font {
53 namespace CTR {
54
55 struct DispStringBuffer;
56 class CharWriter;
57
58 //---------------------------------------------------------------------------
59 //! @brief 文字を描画するクラスです。
60 //---------------------------------------------------------------------------
61 class RectDrawer
62 {
63 public:
64 enum
65 {
66 DONT_USE_SETUP_COMMAND = 0x1
67 };
68
69 //! @brief RectDrawerが必要な頂点バッファ・コマンドバッファのサイズを取得します。
70 //!
71 //! @param[in] shaderBinary シェーダバイナリ。
72 //! @param[in] size シェーダバイナリのサイズ。
73 //!
74 //! @return 頂点バッファ・コマンドバッファのメモリサイズを返します。
75 //!
76 static u32 GetVertexBufferCommandBufferSize(
77 const void* shaderBinary,
78 u32 size);
79
80 //! @brief RectDrawerが使用する頂点バッファのデータを取得します。
81 //!
82 //! @return 頂点バッファのデータを返します。
83 //!
84 static void* GetVertexBufferData();
85
86 //! @brief RectDrawerが必要な頂点バッファのサイズを取得します。
87 //!
88 //! @return 頂点バッファのメモリサイズを返します。
89 //!
90 static u32 GetVertexBufferSize();
91
92 //! @brief RectDrawerが必要なコマンドバッファのサイズを取得します。
93 //!
94 //! @param[in] shaderBinary シェーダバイナリ。
95 //! @param[in] size シェーダバイナリのサイズ。
96 //!
97 //! @return コマンドバッファのメモリサイズを返します。
98 //!
99 static u32 GetCommandBufferSize(
100 const void* shaderBinary,
101 u32 size);
102
103 //! @name コンストラクタ/デストラクタ
104 //@{
105
106 //! コンストラクタです。
107 RectDrawer();
108
109 //! @brief デストラクタです。
110 //!
111 //! @details Finalize() を呼び出します。
112 //!
113 //! @sa Finalize
114 //!
115 //! @since 2010/06/02 初版。
116 //!
117 virtual ~RectDrawer();
118
119 //@}
120
121 //! @name 初期化/後処理
122 //@{
123
124 //! @brief 初期化を行います。
125 //!
126 //! @param[in] vtxBufCmdBuf 頂点用バッファ・コマンドバッファ。
127 //! @param[in] shaderBinary シェーダバイナリ。
128 //! @param[in] size シェーダバイナリのサイズ。
129 //!
130 //! @sa Finalize
131 //!
132 //! @since 2010/07/29 引数を変更。
133 //! @since 2010/06/02 初版。
134 //!
135 void Initialize(
136 void* vtxBufCmdBuf,
137 const void* shaderBinary,
138 u32 size);
139
140 //! @brief 初期化を行います。
141 //!
142 //! @param[in] vertexBuffer 頂点用バッファ。
143 //! @param[in] commandBuffer コマンドバッファ。
144 //! @param[in] shaderBinary シェーダバイナリ。
145 //! @param[in] size シェーダバイナリのサイズ。
146 //!
147 //! @sa Finalize
148 //!
149 //! @since 2010/07/29 引数を変更。
150 //! @since 2010/06/02 初版。
151 //!
152 void Initialize(
153 void* vertexBuffer,
154 void* commandBuffer,
155 const void* shaderBinary,
156 u32 size);
157
158 //! @brief 終了処理を行います。
159 //!
160 //! @sa Initialize
161 //!
162 //! @since 2010/06/02 初版。
163 //!
164 virtual void Finalize();
165
166 //@}
167
168 //! @brief 描画を開始します。
169 //!
170 //! @param[in] flag 描画を制御するフラグ。
171 //!
172 //! @sa DrawEnd
173 //!
174 //! @since 2010/06/28 初版。
175 //!
176 virtual void DrawBegin(u32 flag = 0);
177
178 //! @brief 描画を終了します。
179 //!
180 //! @param[in] flag 描画を制御するフラグ。
181 //!
182 //! @sa DrawBegin
183 //!
184 //! @since 2010/06/28 初版。
185 //!
186 virtual void DrawEnd(u32 flag = 0);
187
188 //! @brief 射影行列を設定します。
189 //!
190 //! @param[in] mtx 射影行列
191 //!
192 void SetProjectionMtx(const nn::math::MTX44& mtx);
193
194 //! @brief テキスト用のビュー行列を設定します。
195 //!
196 //! @param[in] mtx ビュー行列
197 //!
198 void SetViewMtxForText(const nn::math::MTX34& mtx);
199
200 //! @brief 視差のパラメータを設定します。
201 //!
202 //! @param[in] parallax 視差。
203 //! @param[in] dLevel カメラから基準面までの距離。
204 //! @param[in] addDist カメラとの距離に追加する値。
205 //!
206 void SetParallax(
207 f32 parallax,
208 f32 dLevel,
209 f32 addDist = 0.0f
210 );
211
212 //! @brief 文字列用の描画コマンドを作成します。
213 //!
214 //! @param[in] pCharWriter CharWriter オブジェクトへのポインタ。
215 //!
216 void BuildTextCommand(CharWriter* pCharWriter);
217
218 //! @details :private
219 void UniformAndDrawText(DispStringBuffer* pDispStringBuffer);
220
221 //! @details :private
222 void UseBeginCommand();
223
224 //! @details :private
225 void UseEndCommand();
226
227 protected:
228
229 //! @details :private
SetUniformCommand(u32 * buffer,u32 num)230 static u32 SetUniformCommand(
231 u32* buffer,
232 u32 num
233 )
234 {
235 #if defined(NN_PLATFORM_CTR)
236 buffer[2] = buffer[3];
237 buffer[3] = PICA_CMD_HEADER_VS_F32(num);
238 #else
239 NN_ASSERT(false);
240 (void)buffer;
241 #endif
242 return sizeof(u32) * (4 + 4 * num);
243 }
244
245 //! @details :private
246 void DisableTextures();
247
248 //! @details :private
249 void AddUniformMtx();
250
251 #if defined(NN_FONT_RECTDRAWER_USE_DRAW_ARRAYS)
252 //! @details :private
253 u32 GetVertexIndexAddressOffset(u32 vtxNum) const;
254 #endif
255
256 //! @details :private
257 const u32* GetDrawCommands() const;
258
259 //! @details :private
260 u32 GetDrawCommandSize() const;
261
262 private:
263 static void InitializeStatic();
264
265 void InitializeCMD(
266 void* vertexBuffer,
267 void* commandBuffer,
268 const void* shaderBinary,
269 u32 size,
270 bool initVertexBuffer);
271
272 void InitUniformBuffer(
273 u32* __restrict buf,
274 u32 addr);
275
276 void AddTextColor(
277 math::VEC4* __restrict dst,
278 const util::Color8* __restrict src,
279 int mode);
280
281 protected:
282 ////////////////////////////// Vertex Shader Info
283
284 //! @details :private
285 enum
286 {
287 UNIFORM_MTX_USE_MAX = 3 /* mtx row */ + 4 /* vtx color */,
288 UNIFORM_DATA_USE_MAX = 1 /* rect */ + 3/* TexMapMax */ * 2,
289
290 UNIFORM_TEXT_MTX_MAX = 3, // mtx34 row
291
292 UNIFORM_PROJ_NUM = 4, // mtx44 row
293
294 UNIFORM_PROJ_START = 0,
295 UNIFORM_ULCDDATA_START = UNIFORM_PROJ_START + UNIFORM_PROJ_NUM,
296 UNIFORM_CONST_START,
297 UNIFORM_ADDR_START,
298 UNIFORM_MTX_START = 32,
299 UNIFORM_DATA_START = 64,
300
301 UNIFORM_TEXTCOLOR_START = UNIFORM_MTX_START + UNIFORM_TEXT_MTX_MAX,
302
303 UNIFORM_MAX = 96
304 };
305
306 //! @details :private
307 enum
308 {
309 #ifdef NN_FONT_RECTDRAWER_USE_DRAW_BUFFER
310
311 UNIFORM_ADDR_NUM = UNIFORM_MTX_START - UNIFORM_ADDR_START,
312 UNIFORM_MTX_NUM = UNIFORM_DATA_START - UNIFORM_MTX_START,
313 UNIFORM_DATA_NUM = UNIFORM_MAX - UNIFORM_DATA_START,
314
315 UNIFORM_TEXTCOLOR_NUM = (UNIFORM_DATA_START - UNIFORM_TEXTCOLOR_START) & ~((1 << 2) - 1),
316 #else
317
318 UNIFORM_RESISTER_ADDR = 5,
319
320 // まとめて描かないなら、最大8レジスタ
321 UNIFORM_DATA_NUM = 8,
322
323 UNIFORM_ADDR_NUM = UNIFORM_DATA_NUM - UNIFORM_RESISTER_ADDR,
324 #endif
325
326 DRAW_VTX_NUM = 6,
327 BIND_ATTRIB_LOCATION = 0
328 };
329
330
331 ////////////////////////////// Command
332
333 //! @details :private
334 CmdCache m_CmdCacheDrawBegin;
335
336 //! @details :private
337 CmdCache m_CmdCacheDrawEnd;
338
339 //! @details :private
340 u8 m_UniformAddrIndex;
341
342 //! @details :private
343 u8 m_UniformMtxIndex;
344
345 //! @details :private
346 u8 m_UniformDataIndex;
347
348 //! @details :private
349 u8 m_UniformTextColorIndex;
350
351 //! @details :private
352 u32 m_UniformProjBuffer[ 4 + 4 * (UNIFORM_PROJ_NUM + 1) ];
353
354 //! @details :private
355 u32 m_UniformAddrBuffer[ 4 + 4 * UNIFORM_ADDR_NUM ];
356
357 //! @details :private
358 union
359 {
360 //! @details :private
361 u32 buffer[ 4 + 4 * UNIFORM_MTX_NUM ];
362
363 //! @details :private
364 struct
365 {
366
367 //! @details :private
368 u32 mtx [ 4 + 4 * UNIFORM_TEXT_MTX_MAX ];
369
370 //! @details :private
371 u32 color[ 4 + 4 * UNIFORM_TEXTCOLOR_NUM ];
372 } text;
373 } m_UniformMtxBuffer;
374
375 //! @details :private
376 u32 m_UniformDataBuffer[ 4 + 4 * UNIFORM_DATA_NUM ];
377
378 //! @details :private
379 struct UniformAddress
380 {
381 //! @details :private
UniformAddressUniformAddress382 UniformAddress()
383 : addrMtx(0.f),
384 addrSizeAndVtx(0.f),
385 addrTexCoord(0.f),
386 addrColor(0.f)
387 {}
388
389 //! @details :private
390 f32 addrMtx;
391
392 //! @details :private
393 f32 addrSizeAndVtx;
394
395 //! @details :private
396 f32 addrTexCoord;
397
398 //! @details :private
399 f32 addrColor;
400 };
401
402 //! @details :private
403 UniformAddress m_UniformAddress;
404
405 //! @details :private
406 UniformAddress *const
407 m_UniformAddr;
408
409 //! @details :private
410 math::VEC4 *const m_UniformMtx;
411
412 //! @details :private
413 math::VEC4 *const m_UniformData;
414
415 //! @details :private
416 math::VEC4 *const m_UniformTextColor;
417
418 //! @details :private
419 void* m_CommandBuffer;
420
421 ////////////////////////////// Vertex Buufer Object
422
423 //! @details :private
424 void* m_VertexBufferArray;
425
426 ////////////////////////////// Uniform
427
428 #if defined(NN_FONT_RECTDRAWER_USE_DRAW_ARRAYS)
429 //! @details :private
430 u32 m_VertexBufferBaseAddr;
431 #endif
432
433 //! :private
434 //! @brief 色が変更されているかどうか
435 bool m_IsColorDirty;
436 NN_PADDING3;
437
438 private:
439 struct VertexBuffer
440 {
441 #if defined(NN_FONT_RECTDRAWER_USE_DRAW_ARRAYS)
442 f32 position[UNIFORM_ADDR_NUM][DRAW_VTX_NUM][4];
443 #else
444 f32 position[UNIFORM_ADDR_NUM][VERTEX_MAX][4];
445 u16 indexes[UNIFORM_ADDR_NUM][DRAW_VTX_NUM];
446 #endif
447 };
448
449 static bool s_StaticInitialized;
450 static VertexBuffer s_VertexBuffer;
451 };
452
453 inline
454 u32
GetVertexBufferSize()455 RectDrawer::GetVertexBufferSize()
456 {
457 return sizeof(s_VertexBuffer);
458 }
459
460
461 #if defined(NN_PLATFORM_CTR)
462 inline
463 u32*
SetVertexNumCmd(u32 ** pCmdPtr,u32 addrOffset,u32 vtxNum)464 SetVertexNumCmd(
465 u32** pCmdPtr,
466 u32 addrOffset,
467 u32 vtxNum
468 )
469 {
470 #if defined(NN_FONT_RECTDRAWER_USE_DRAW_ARRAYS)
471 // 頂点インデックスのアドレス/型
472 // 0x227
473 NN_FONT_ADD_SINGLE_COMMAND_PTR(
474 *pCmdPtr,
475 PICA_CMD_HEADER_SINGLE( PICA_REG_INDEX_ARRAY_ADDR_OFFSET ),
476 PICA_CMD_DATA_INDEX_ARRAY_ADDR_OFFSET( addrOffset, 1 /* type */ ));
477 #else
478 (void)addrOffset;
479 #endif
480
481 // 描画頂点数
482 // 0x228
483 NN_FONT_ADD_SINGLE_COMMAND_PTR(
484 *pCmdPtr,
485 PICA_CMD_HEADER_SINGLE( PICA_REG_DRAW_VERTEX_NUM ),
486 PICA_CMD_DATA_DRAW_VERTEX_NUM( vtxNum ));
487
488 return *pCmdPtr;
489 }
490 #endif
491
492 } // namespace CTR
493 } // namespace font
494 } // namespace nn
495
496 #endif // NN_FONT_CTR_FONT_RECT_DRAWER_H_
497