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