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