1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     lyt_DrawerGraphics.cpp
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 #include "precompiled.h"
19 #include <nw/lyt/lyt_Drawer.h>
20 #include <nw/lyt/lyt_Layout.h>
21 #include <nw/lyt/lyt_TextBox.h>
22 #include <nw/lyt/lyt_Material.h>
23 #include <nw/lyt/lyt_DrawerCommand.h>
24 #include <nw/lyt/lyt_DrawInfo.h>
25 #include <nw/lyt/lyt_GraphicsResource.h>
26 #include <nw/font/font_DispStringBuffer.h>
27 
28 #ifdef NW_LYT_DRAWER_ENABLE
29 
30 #define TEX_ENV_COLOR_OFFS            3
31 
32 // カラー・デプスバッファクリア(0x100 ~ 0x130 の設定前に一度必要)
33 // 0x111
34 #define ADD_COMMAND_COLOR_DEPTH_BUFFER_CLEAR1(clear) \
35     NW_FONT_RECTDRAWER_ADD_SINGLE_COMMAND( \
36         PICA_REG_COLOR_DEPTH_BUFFER_CLEAR1, \
37         PICA_CMD_DATA_COLOR_DEPTH_BUFFER_CLEAR( clear ) ) \
38 
39 extern unsigned* __cb_current_command_buffer;
40 
41 namespace nw { namespace lyt {
42 
43 void
SetUpTexEnv(const Material * __restrict pMaterial)44 Drawer::SetUpTexEnv( const Material* __restrict pMaterial )
45 {
46 #if ! defined(NW_RELEASE)
47     m_PreviousTexEnvType = m_CurrentTexEnvType;
48 #endif
49 
50     if ( pMaterial->GetTextureOnly() )
51     {
52         switch ( m_CurrentTexEnvType )
53         {
54         case TEX_ENV_TYPE_0_TEX:
55         case TEX_ENV_TYPE_1_TEX:
56             break;
57 
58         default:
59             FlushBuffer();
60             break;
61         }
62 
63         return;
64     }
65 
66     bool bBufferClear = false;
67 
68 #ifdef NW_LYT_DRAWER_ENABLE_ALPHA_TEST
69     // アルファテストの設定
70     if ( pMaterial->IsAlphaCompareCap() )
71     {
72         FlushBuffer();
73         m_AlphaTestEnable = true;
74 
75         // 0x111
76         ADD_COMMAND_COLOR_DEPTH_BUFFER_CLEAR1( true );
77         bBufferClear = true;
78 
79         SetUpAlphaTest( pMaterial );
80     }
81     else if ( m_AlphaTestEnable )
82     {
83         // デフォルト(アルファテストなし)に戻す設定
84         FlushBuffer();
85         m_AlphaTestEnable = false;
86 
87         // 0x111
88         ADD_COMMAND_COLOR_DEPTH_BUFFER_CLEAR1( true );
89         bBufferClear = true;
90 
91         // 0x104
92         NW_FONT_RECTDRAWER_ADD_SINGLE_COMMAND(
93             PICA_REG_FRAGOP_ALPHA_TEST,
94             PICA_CMD_DATA_FRAGOP_ALPHA_TEST_DISABLE() );
95     }
96 #endif
97 
98 #ifdef NW_LYT_DRAWER_ENABLE_BLEND_FUNC
99     // ブレンドモードの設定
100     if ( pMaterial->IsBlendModeCap() )
101     {
102         FlushBuffer();
103         m_IsBlendDefault = false;
104 
105         if (!bBufferClear)
106         {
107             // 0x111
108             ADD_COMMAND_COLOR_DEPTH_BUFFER_CLEAR1( true );
109             bBufferClear = true;
110         }
111 
112         // ブレンドの設定
113         SetUpBlendMode( pMaterial );
114     }
115     else if ( m_IsBlendDefault == false )
116     {
117         // デフォルト(アルファブレンド)に戻す設定
118         FlushBuffer();
119         m_IsBlendDefault = true;
120 
121         if (!bBufferClear)
122         {
123             // 0x111
124             ADD_COMMAND_COLOR_DEPTH_BUFFER_CLEAR1( true );
125             bBufferClear = true;
126         }
127 
128         const u32 command[] =
129         {
130             NW_FONT_COMMAND_SET_BLEND_DEFAULT
131         };
132 
133         NW_FONT_RECTDRAWER_ADD_COMMAND( command, sizeof( command ) );
134     }
135 #endif
136 
137 #ifdef NW_LYT_DRAWER_ENABLE_USER_TEX_ENV
138     //----------------------------------------------------------
139     // ユーザー定義のテクスチャコンバイナの設定
140     if ( pMaterial->GetTevStageNum() > 0 )
141     {
142         FlushBuffer();
143 
144         SetUpGLTexEnvUser( pMaterial );
145 
146         m_CurrentTexEnvType = TEX_ENV_TYPE_USER;
147 
148         return;
149     }
150 #endif
151 
152     //----------------------------------------------------------
153     // プリセットのテクスチャコンバイナの設定
154     switch ( pMaterial->GetTexMapNum() )
155     {
156       case 0:
157         {
158             nw::ut::Color8 white = pMaterial->GetColor( INTERPOLATECOLOR_WHITE );
159 
160             static u32 command[] NW_LYT_DRAWER_ALIGN_32 =
161             {
162                 PICA_CMD_DATA_TEX_ENV_SRC(
163                     PICA_DATA_TEX_ENV_SRC_RGBA_PRIMARY_COLOR,
164                     PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT,
165                     PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT,
166                     PICA_DATA_TEX_ENV_SRC_RGBA_PRIMARY_COLOR,
167                     PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT, PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT ),
168                 PICA_CMD_HEADER_BURSTSEQ( PICA_REG_TEX_ENV5, 5 ),
169                 PICA_CMD_DATA_TEX_ENV_OPERAND(
170                     PICA_DATA_OPE_RGB_SRC_COLOR, PICA_DATA_OPE_RGB_SRC_COLOR, PICA_DATA_OPE_RGB_SRC_COLOR,
171                     PICA_DATA_OPE_ALPHA_SRC_ALPHA, PICA_DATA_OPE_ALPHA_SRC_ALPHA, PICA_DATA_OPE_ALPHA_SRC_ALPHA ),
172                 PICA_CMD_DATA_TEX_ENV_COMBINE(
173                     PICA_DATA_TEX_ENV_COMBINE_MODULATE,
174                     PICA_DATA_TEX_ENV_COMBINE_MODULATE ),
175                 PICA_CMD_DATA_TEX_ENV_BUFFER_COLOR_WHITE,
176                 PICA_CMD_DATA_TEX_ENV_SCALE( PICA_DATA_TEX_ENV_SCALE_1, PICA_DATA_TEX_ENV_SCALE_1 ),
177             };
178 
179             if ( m_CurrentTexEnvType != TEX_ENV_TYPE_0_TEX )
180             {
181                 FlushBuffer();
182 
183                 *reinterpret_cast< nw::ut::Color8* >( &command[ 4 ] ) = white;
184 
185                 NW_FONT_RECTDRAWER_ADD_COMMAND( command, sizeof( command ) );
186 
187                 m_CurrentTexEnvType = TEX_ENV_TYPE_0_TEX;
188             }
189             else if ( *reinterpret_cast< nw::ut::Color8* >( &command[ 4 ] ) != white )
190             {
191                 FlushBuffer();
192 
193                 *reinterpret_cast< nw::ut::Color8* >( &command[ 4 ] ) = white;
194 
195                 NW_FONT_RECTDRAWER_ADD_SINGLE_COMMAND(
196                     PICA_CMD_HEADER_SINGLE( PICA_REG_TEX_ENV5 + TEX_ENV_COLOR_OFFS),
197                     command[ 4 ] );
198             }
199 
200             return;
201         }
202       case 1 :
203         {
204 
205             nw::ut::Color8 white = pMaterial->GetColor( INTERPOLATECOLOR_WHITE );
206             nw::ut::Color8 black = pMaterial->GetColor( INTERPOLATECOLOR_BLACK );
207 
208             static u32 command[] NW_LYT_DRAWER_ALIGN_32 =
209             {
210                 PICA_CMD_DATA_TEX_ENV_SRC(
211                     PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT,
212                     PICA_DATA_TEX_ENV_SRC_RGBA_TEXTURE0,
213                     PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT,
214                     PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT,
215                     PICA_DATA_TEX_ENV_SRC_RGBA_TEXTURE0,
216                     PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT ),
217                 PICA_CMD_HEADER_BURSTSEQ( PICA_REG_TEX_ENV3, 5 ),
218                 PICA_CMD_DATA_TEX_ENV_OPERAND(
219                     PICA_DATA_OPE_RGB_SRC_COLOR, PICA_DATA_OPE_RGB_ONE_MINUS_SRC_COLOR, PICA_DATA_OPE_RGB_SRC_COLOR,
220                     PICA_DATA_OPE_ALPHA_SRC_ALPHA, PICA_DATA_OPE_ALPHA_ONE_MINUS_SRC_ALPHA, PICA_DATA_OPE_ALPHA_SRC_ALPHA ),
221                 PICA_CMD_DATA_TEX_ENV_COMBINE(
222                     PICA_DATA_TEX_ENV_COMBINE_MODULATE,
223                     PICA_DATA_TEX_ENV_COMBINE_MODULATE ),
224                 PICA_CMD_DATA_TEX_ENV_BUFFER_COLOR_BLACK,
225                 PICA_CMD_DATA_TEX_ENV_SCALE( PICA_DATA_TEX_ENV_SCALE_1, PICA_DATA_TEX_ENV_SCALE_1 ),
226 
227                 PICA_CMD_DATA_TEX_ENV_SRC(
228                     PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT,
229                     PICA_DATA_TEX_ENV_SRC_RGBA_TEXTURE0,
230                     PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS,
231                     PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT,
232                     PICA_DATA_TEX_ENV_SRC_RGBA_TEXTURE0,
233                     PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS ),
234                 PICA_CMD_HEADER_BURSTSEQ( PICA_REG_TEX_ENV4, 5 ),
235                 PICA_CMD_DATA_TEX_ENV_OPERAND(
236                     PICA_DATA_OPE_RGB_SRC_COLOR, PICA_DATA_OPE_RGB_SRC_COLOR, PICA_DATA_OPE_RGB_SRC_COLOR,
237                     PICA_DATA_OPE_ALPHA_SRC_ALPHA, PICA_DATA_OPE_ALPHA_SRC_ALPHA, PICA_DATA_OPE_ALPHA_SRC_ALPHA ),
238                 PICA_CMD_DATA_TEX_ENV_COMBINE(
239                     PICA_DATA_TEX_ENV_COMBINE_MULT_ADD_DMP,
240                     PICA_DATA_TEX_ENV_COMBINE_MULT_ADD_DMP ),
241                 PICA_CMD_DATA_TEX_ENV_BUFFER_COLOR_WHITE,
242                 PICA_CMD_DATA_TEX_ENV_SCALE( PICA_DATA_TEX_ENV_SCALE_1, PICA_DATA_TEX_ENV_SCALE_1 ),
243 
244                 PICA_CMD_DATA_TEX_ENV_SRC(
245                     PICA_DATA_TEX_ENV_SRC_RGBA_PRIMARY_COLOR,
246                     PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS,
247                     PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS,
248                     PICA_DATA_TEX_ENV_SRC_RGBA_PRIMARY_COLOR,
249                     PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS,
250                     PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS ),
251                 PICA_CMD_HEADER_BURSTSEQ( PICA_REG_TEX_ENV5, 5 ),
252                 PICA_CMD_DATA_TEX_ENV_OPERAND(
253                     PICA_DATA_OPE_RGB_SRC_COLOR, PICA_DATA_OPE_RGB_SRC_COLOR, PICA_DATA_OPE_RGB_SRC_COLOR,
254                     PICA_DATA_OPE_ALPHA_SRC_ALPHA, PICA_DATA_OPE_ALPHA_SRC_ALPHA, PICA_DATA_OPE_ALPHA_SRC_ALPHA ),
255                 PICA_CMD_DATA_TEX_ENV_COMBINE(
256                     PICA_DATA_TEX_ENV_COMBINE_MODULATE,
257                     PICA_DATA_TEX_ENV_COMBINE_MODULATE ),
258                 PICA_CMD_DATA_TEX_ENV_BUFFER_COLOR_BLACK,
259                 PICA_CMD_DATA_TEX_ENV_SCALE( PICA_DATA_TEX_ENV_SCALE_1, PICA_DATA_TEX_ENV_SCALE_1 ),
260             };
261 
262             if ( m_CurrentTexEnvType != TEX_ENV_TYPE_1_TEX )
263             {
264                 FlushBuffer();
265 
266                 *reinterpret_cast< nw::ut::Color8* >( &command[ 4 ] ) = black;
267                 *reinterpret_cast< nw::ut::Color8* >( &command[ 10 ] ) = white;
268 
269                 NW_FONT_RECTDRAWER_ADD_COMMAND( command, sizeof( command ) );
270 
271                 m_CurrentTexEnvType = TEX_ENV_TYPE_1_TEX;
272             }
273             else if ( *reinterpret_cast< nw::ut::Color8* >( &command[ 4 ] ) != black ||
274                       *reinterpret_cast< nw::ut::Color8* >( &command[ 10 ] ) != white )
275             {
276                 FlushBuffer();
277 
278                 *reinterpret_cast< nw::ut::Color8* >( &command[ 4 ] ) = black;
279                 *reinterpret_cast< nw::ut::Color8* >( &command[ 10 ] ) = white;
280 
281                 NW_FONT_RECTDRAWER_ADD_SINGLE_COMMAND(
282                     PICA_CMD_HEADER_SINGLE( PICA_REG_TEX_ENV3 + TEX_ENV_COLOR_OFFS ),
283                     command[ 4 ] );
284 
285                 NW_FONT_RECTDRAWER_ADD_SINGLE_COMMAND(
286                     PICA_CMD_HEADER_SINGLE( PICA_REG_TEX_ENV4 + TEX_ENV_COLOR_OFFS ),
287                     command[ 10 ] );
288             }
289 
290             return;
291         }
292       case 2 :
293         {
294             FlushBuffer();
295 
296             SetUpTexEnvType2( pMaterial );
297 
298             m_CurrentTexEnvType = TEX_ENV_TYPE_2_TEX;
299 
300             return;
301         }
302       case 3 :
303         {
304             FlushBuffer();
305 
306             SetUpTexEnvType3( pMaterial );
307 
308             m_CurrentTexEnvType = TEX_ENV_TYPE_3_TEX;
309             return;
310         }
311     }
312 }
313 
SetUpTexEnvType2(const Material * __restrict pMaterial)314 void Drawer::SetUpTexEnvType2( const Material* __restrict pMaterial )
315 {
316     static u32 command[] NW_LYT_DRAWER_ALIGN_32 =
317     {
318         // Texture0 と Texture1 をブレンド
319         PICA_CMD_DATA_TEX_ENV_SRC(
320             PICA_DATA_TEX_ENV_SRC_RGBA_TEXTURE0,
321             PICA_DATA_TEX_ENV_SRC_RGBA_TEXTURE1,
322             PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT,
323             PICA_DATA_TEX_ENV_SRC_RGBA_TEXTURE0,
324             PICA_DATA_TEX_ENV_SRC_RGBA_TEXTURE1,
325             PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT ),
326         PICA_CMD_HEADER_BURSTSEQ( PICA_REG_TEX_ENV3, 5 ),
327         PICA_CMD_DATA_TEX_ENV_OPERAND(
328             PICA_DATA_OPE_RGB_SRC_COLOR, PICA_DATA_OPE_RGB_SRC_COLOR, PICA_DATA_OPE_RGB_SRC_ALPHA,
329             PICA_DATA_OPE_ALPHA_SRC_ALPHA, PICA_DATA_OPE_ALPHA_SRC_ALPHA, PICA_DATA_OPE_ALPHA_SRC_ALPHA ),
330         PICA_CMD_DATA_TEX_ENV_COMBINE(
331             PICA_DATA_TEX_ENV_COMBINE_INTERPOLATE,
332             PICA_DATA_TEX_ENV_COMBINE_INTERPOLATE ),
333         // cmdPosBlend
334         PICA_CMD_DATA_TEX_ENV_BUFFER_COLOR_BLACK,
335         PICA_CMD_DATA_TEX_ENV_SCALE( PICA_DATA_TEX_ENV_SCALE_1, PICA_DATA_TEX_ENV_SCALE_1 ),
336 
337         // 白黒カラーをテクスチャでカラー補間
338         PICA_CMD_DATA_TEX_ENV_SRC(
339             PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT,
340             PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS_BUFFER_DMP,
341             PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS,
342             PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT,
343             PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS_BUFFER_DMP,
344             PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS ),
345         PICA_CMD_HEADER_BURSTSEQ( PICA_REG_TEX_ENV4, 5 ),
346         PICA_CMD_DATA_TEX_ENV_OPERAND(
347             PICA_DATA_OPE_RGB_SRC_COLOR, PICA_DATA_OPE_RGB_SRC_COLOR, PICA_DATA_OPE_RGB_SRC_COLOR,
348             PICA_DATA_OPE_ALPHA_SRC_ALPHA, PICA_DATA_OPE_ALPHA_SRC_ALPHA, PICA_DATA_OPE_ALPHA_SRC_ALPHA ),
349         PICA_CMD_DATA_TEX_ENV_COMBINE(
350             PICA_DATA_TEX_ENV_COMBINE_INTERPOLATE,
351             PICA_DATA_TEX_ENV_COMBINE_INTERPOLATE ),
352         // cmdPosWhite
353         PICA_CMD_DATA_TEX_ENV_BUFFER_COLOR_WHITE,
354         PICA_CMD_DATA_TEX_ENV_SCALE( PICA_DATA_TEX_ENV_SCALE_1, PICA_DATA_TEX_ENV_SCALE_1 ),
355 
356         // cmdPosBlack
357         PICA_CMD_DATA_TEX_ENV_BUFFER_COLOR_BLACK,
358         PICA_CMD_HEADER_SINGLE( PICA_REG_TEX_ENV_BUFFER_COLOR ), // 0x0fd
359 
360         // 頂点カラーと掛け算
361         PICA_CMD_DATA_TEX_ENV_SRC(
362             PICA_DATA_TEX_ENV_SRC_RGBA_PRIMARY_COLOR,
363             PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS,
364             PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS,
365             PICA_DATA_TEX_ENV_SRC_RGBA_PRIMARY_COLOR,
366             PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS,
367             PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS ),
368         PICA_CMD_HEADER_BURSTSEQ( PICA_REG_TEX_ENV5, 5 ),
369         PICA_CMD_DATA_TEX_ENV_OPERAND(
370             PICA_DATA_OPE_RGB_SRC_COLOR, PICA_DATA_OPE_RGB_SRC_COLOR, PICA_DATA_OPE_RGB_SRC_COLOR,
371             PICA_DATA_OPE_ALPHA_SRC_ALPHA, PICA_DATA_OPE_ALPHA_SRC_ALPHA, PICA_DATA_OPE_ALPHA_SRC_ALPHA ),
372         PICA_CMD_DATA_TEX_ENV_COMBINE(
373             PICA_DATA_TEX_ENV_COMBINE_MODULATE,
374             PICA_DATA_TEX_ENV_COMBINE_MODULATE ),
375         PICA_CMD_DATA_TEX_ENV_BUFFER_COLOR_BLACK,
376         PICA_CMD_DATA_TEX_ENV_SCALE( PICA_DATA_TEX_ENV_SCALE_1, PICA_DATA_TEX_ENV_SCALE_1 ),
377 
378         NW_LYT_CMD_DATA_TEX_ENV_BUF_INPUT_THROUGH,
379         PICA_CMD_HEADER_SINGLE_BE( PICA_REG_TEX_ENV_BUFFER_INPUT, 0x2 ) // 0x0e0
380     };
381 
382     nw::ut::Color8 blend = pMaterial->GetColor( TEVKONSTSEL_K5 );
383     nw::ut::Color8 white = pMaterial->GetColor( INTERPOLATECOLOR_WHITE );
384     nw::ut::Color8 black = pMaterial->GetColor( INTERPOLATECOLOR_BLACK );
385 
386     const int cmdPosBlend = 4;
387     const int cmdPosWhite = 10;
388     const int cmdPosBlack = 12;
389 
390     if ( m_CurrentTexEnvType != TEX_ENV_TYPE_2_TEX )
391     {
392         *reinterpret_cast< nw::ut::Color8* >( &command[ cmdPosBlend ] ) = blend;
393         *reinterpret_cast< nw::ut::Color8* >( &command[ cmdPosWhite ] ) = white;
394         *reinterpret_cast< nw::ut::Color8* >( &command[ cmdPosBlack ] ) = black;
395 
396         NW_FONT_RECTDRAWER_ADD_COMMAND( command, sizeof( command ) );
397     }
398     else if ( *reinterpret_cast< nw::ut::Color8* >( &command[ cmdPosBlend ] ) != blend ||
399               *reinterpret_cast< nw::ut::Color8* >( &command[ cmdPosWhite ] ) != white ||
400               *reinterpret_cast< nw::ut::Color8* >( &command[ cmdPosBlack ] ) != black )
401     {
402         *reinterpret_cast< nw::ut::Color8* >( &command[ cmdPosBlend ] ) = blend;
403         *reinterpret_cast< nw::ut::Color8* >( &command[ cmdPosWhite ] ) = white;
404         *reinterpret_cast< nw::ut::Color8* >( &command[ cmdPosBlack ] ) = black;
405 
406         NW_FONT_RECTDRAWER_ADD_SINGLE_COMMAND(
407             PICA_CMD_HEADER_SINGLE( PICA_REG_TEX_ENV3 + TEX_ENV_COLOR_OFFS ),
408             command[ cmdPosBlend ] );
409 
410         NW_FONT_RECTDRAWER_ADD_SINGLE_COMMAND(
411             PICA_CMD_HEADER_SINGLE( PICA_REG_TEX_ENV4 + TEX_ENV_COLOR_OFFS ),
412             command[ cmdPosWhite ] );
413 
414         // 0x0fd
415         NW_FONT_RECTDRAWER_ADD_SINGLE_COMMAND(
416             PICA_CMD_HEADER_SINGLE( PICA_REG_TEX_ENV_BUFFER_COLOR ),
417             command[ cmdPosBlack ] );
418     }
419 }
420 
SetUpTexEnvType3(const Material * __restrict pMaterial)421 void Drawer::SetUpTexEnvType3( const Material* __restrict pMaterial )
422 {
423     static u32 command[] NW_LYT_DRAWER_ALIGN_32 =
424     {
425         // Texture0 にブレンド率を乗算
426         PICA_CMD_DATA_TEX_ENV_SRC(
427             PICA_DATA_TEX_ENV_SRC_RGBA_TEXTURE0,
428             PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT,
429             PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT,
430             PICA_DATA_TEX_ENV_SRC_RGBA_TEXTURE0,
431             PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT,
432             PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT ),
433         PICA_CMD_HEADER_BURSTSEQ( PICA_REG_TEX_ENV1, 5 ),
434         PICA_CMD_DATA_TEX_ENV_OPERAND(
435             PICA_DATA_OPE_RGB_SRC_COLOR, PICA_DATA_OPE_RGB_SRC_ALPHA, PICA_DATA_OPE_RGB_SRC_COLOR,
436             PICA_DATA_OPE_ALPHA_SRC_ALPHA, PICA_DATA_OPE_ALPHA_SRC_ALPHA, PICA_DATA_OPE_ALPHA_SRC_ALPHA ),
437         PICA_CMD_DATA_TEX_ENV_COMBINE(
438             PICA_DATA_TEX_ENV_COMBINE_MODULATE,
439             PICA_DATA_TEX_ENV_COMBINE_MODULATE ),
440         // cmdPosBlend0
441         PICA_CMD_DATA_TEX_ENV_BUFFER_COLOR_BLACK,
442         PICA_CMD_DATA_TEX_ENV_SCALE( PICA_DATA_TEX_ENV_SCALE_1, PICA_DATA_TEX_ENV_SCALE_1 ),
443 
444         // Texture1 にブレンド率を乗算
445         PICA_CMD_DATA_TEX_ENV_SRC(
446             PICA_DATA_TEX_ENV_SRC_RGBA_TEXTURE1,
447             PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT,
448             PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS,
449             PICA_DATA_TEX_ENV_SRC_RGBA_TEXTURE1,
450             PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT,
451             PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS ),
452         PICA_CMD_HEADER_BURSTSEQ( PICA_REG_TEX_ENV2, 5 ),
453         PICA_CMD_DATA_TEX_ENV_OPERAND(
454             PICA_DATA_OPE_RGB_SRC_COLOR, PICA_DATA_OPE_RGB_SRC_B_DMP, PICA_DATA_OPE_RGB_SRC_COLOR,
455             PICA_DATA_OPE_ALPHA_SRC_ALPHA, PICA_DATA_OPE_ALPHA_SRC_B_DMP, PICA_DATA_OPE_ALPHA_SRC_ALPHA ),
456         PICA_CMD_DATA_TEX_ENV_COMBINE(
457             PICA_DATA_TEX_ENV_COMBINE_MULT_ADD_DMP,
458             PICA_DATA_TEX_ENV_COMBINE_MULT_ADD_DMP ),
459         // cmdPosBlend1
460         PICA_CMD_DATA_TEX_ENV_BUFFER_COLOR_BLACK,
461         PICA_CMD_DATA_TEX_ENV_SCALE( PICA_DATA_TEX_ENV_SCALE_1, PICA_DATA_TEX_ENV_SCALE_1 ),
462 
463         // Texture2 にブレンド率を乗算
464         PICA_CMD_DATA_TEX_ENV_SRC(
465             PICA_DATA_TEX_ENV_SRC_RGBA_TEXTURE2,
466             PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT,
467             PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS,
468             PICA_DATA_TEX_ENV_SRC_RGBA_TEXTURE2,
469             PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT,
470             PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS ),
471         PICA_CMD_HEADER_BURSTSEQ( PICA_REG_TEX_ENV3, 5 ),
472         PICA_CMD_DATA_TEX_ENV_OPERAND(
473             PICA_DATA_OPE_RGB_SRC_COLOR, PICA_DATA_OPE_RGB_SRC_G_DMP, PICA_DATA_OPE_RGB_SRC_COLOR,
474             PICA_DATA_OPE_ALPHA_SRC_ALPHA, PICA_DATA_OPE_ALPHA_SRC_G_DMP, PICA_DATA_OPE_ALPHA_SRC_ALPHA ),
475         PICA_CMD_DATA_TEX_ENV_COMBINE(
476             PICA_DATA_TEX_ENV_COMBINE_MULT_ADD_DMP,
477             PICA_DATA_TEX_ENV_COMBINE_MULT_ADD_DMP ),
478         // cmdPosBlend2
479         PICA_CMD_DATA_TEX_ENV_BUFFER_COLOR_BLACK,
480         PICA_CMD_DATA_TEX_ENV_SCALE( PICA_DATA_TEX_ENV_SCALE_1, PICA_DATA_TEX_ENV_SCALE_1 ),
481 
482         // 白黒カラーをテクスチャでカラー補間
483         PICA_CMD_DATA_TEX_ENV_SRC(
484             PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT,
485             PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS_BUFFER_DMP,
486             PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS,
487             PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT,
488             PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS_BUFFER_DMP,
489             PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS ),
490         PICA_CMD_HEADER_BURSTSEQ( PICA_REG_TEX_ENV4, 5 ),
491         PICA_CMD_DATA_TEX_ENV_OPERAND(
492             PICA_DATA_OPE_RGB_SRC_COLOR, PICA_DATA_OPE_RGB_SRC_COLOR, PICA_DATA_OPE_RGB_SRC_COLOR,
493             PICA_DATA_OPE_ALPHA_SRC_ALPHA, PICA_DATA_OPE_ALPHA_SRC_ALPHA, PICA_DATA_OPE_ALPHA_SRC_ALPHA ),
494         PICA_CMD_DATA_TEX_ENV_COMBINE(
495             PICA_DATA_TEX_ENV_COMBINE_INTERPOLATE,
496             PICA_DATA_TEX_ENV_COMBINE_INTERPOLATE ),
497         // cmdPosWhite
498         PICA_CMD_DATA_TEX_ENV_BUFFER_COLOR_WHITE,
499         PICA_CMD_DATA_TEX_ENV_SCALE( PICA_DATA_TEX_ENV_SCALE_1, PICA_DATA_TEX_ENV_SCALE_1 ),
500 
501         // cmdPosBlack
502         PICA_CMD_DATA_TEX_ENV_BUFFER_COLOR_BLACK,
503         PICA_CMD_HEADER_SINGLE( PICA_REG_TEX_ENV_BUFFER_COLOR ), // 0x0fd
504 
505         // 頂点カラーと掛け算
506         PICA_CMD_DATA_TEX_ENV_SRC(
507             PICA_DATA_TEX_ENV_SRC_RGBA_PRIMARY_COLOR,
508             PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS,
509             PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS,
510             PICA_DATA_TEX_ENV_SRC_RGBA_PRIMARY_COLOR,
511             PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS,
512             PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS ),
513         PICA_CMD_HEADER_BURSTSEQ( PICA_REG_TEX_ENV5, 5 ),
514         PICA_CMD_DATA_TEX_ENV_OPERAND(
515             PICA_DATA_OPE_RGB_SRC_COLOR, PICA_DATA_OPE_RGB_SRC_COLOR, PICA_DATA_OPE_RGB_SRC_COLOR,
516             PICA_DATA_OPE_ALPHA_SRC_ALPHA, PICA_DATA_OPE_ALPHA_SRC_ALPHA, PICA_DATA_OPE_ALPHA_SRC_ALPHA ),
517         PICA_CMD_DATA_TEX_ENV_COMBINE(
518             PICA_DATA_TEX_ENV_COMBINE_MODULATE,
519             PICA_DATA_TEX_ENV_COMBINE_MODULATE ),
520         PICA_CMD_DATA_TEX_ENV_BUFFER_COLOR_BLACK,
521         PICA_CMD_DATA_TEX_ENV_SCALE( PICA_DATA_TEX_ENV_SCALE_1, PICA_DATA_TEX_ENV_SCALE_1 ),
522 
523         NW_LYT_CMD_DATA_TEX_ENV_BUF_INPUT_THROUGH,
524         PICA_CMD_HEADER_SINGLE_BE( PICA_REG_TEX_ENV_BUFFER_INPUT, 0x2 ) // 0x0e0
525     };
526 
527     nw::ut::Color8 blend = pMaterial->GetColor( TEVKONSTSEL_K5 );
528     nw::ut::Color8 white = pMaterial->GetColor( INTERPOLATECOLOR_WHITE );
529     nw::ut::Color8 black = pMaterial->GetColor( INTERPOLATECOLOR_BLACK );
530 
531     const int cmdPosBlend0 = 4;
532     const int cmdPosBlend1 = 10;
533     const int cmdPosBlend2 = 16;
534     const int cmdPosWhite = 22;
535     const int cmdPosBlack = 24;
536 
537     if ( m_CurrentTexEnvType != TEX_ENV_TYPE_3_TEX )
538     {
539         *reinterpret_cast< nw::ut::Color8* >( &command[ cmdPosBlend0 ] ) = blend;
540         *reinterpret_cast< nw::ut::Color8* >( &command[ cmdPosBlend1 ] ) = blend;
541         *reinterpret_cast< nw::ut::Color8* >( &command[ cmdPosBlend2 ] ) = blend;
542         *reinterpret_cast< nw::ut::Color8* >( &command[ cmdPosWhite ] ) = white;
543         *reinterpret_cast< nw::ut::Color8* >( &command[ cmdPosBlack ] ) = black;
544 
545         NW_FONT_RECTDRAWER_ADD_COMMAND( command, sizeof( command ) );
546     }
547     else if ( *reinterpret_cast< nw::ut::Color8* >( &command[ cmdPosBlend0 ] ) != blend ||
548               *reinterpret_cast< nw::ut::Color8* >( &command[ cmdPosWhite ] ) != white ||
549               *reinterpret_cast< nw::ut::Color8* >( &command[ cmdPosBlack ] ) != black )
550     {
551         *reinterpret_cast< nw::ut::Color8* >( &command[ cmdPosBlend0 ] ) = blend;
552         *reinterpret_cast< nw::ut::Color8* >( &command[ cmdPosBlend1 ] ) = blend;
553         *reinterpret_cast< nw::ut::Color8* >( &command[ cmdPosBlend2 ] ) = blend;
554         *reinterpret_cast< nw::ut::Color8* >( &command[ cmdPosWhite ] ) = white;
555         *reinterpret_cast< nw::ut::Color8* >( &command[ cmdPosBlack ] ) = black;
556 
557         NW_FONT_RECTDRAWER_ADD_SINGLE_COMMAND(
558             PICA_CMD_HEADER_SINGLE( PICA_REG_TEX_ENV1 + TEX_ENV_COLOR_OFFS ),
559             command[ cmdPosBlend0 ] );
560 
561         NW_FONT_RECTDRAWER_ADD_SINGLE_COMMAND(
562             PICA_CMD_HEADER_SINGLE( PICA_REG_TEX_ENV2 + TEX_ENV_COLOR_OFFS ),
563             command[ cmdPosBlend1 ] );
564 
565         NW_FONT_RECTDRAWER_ADD_SINGLE_COMMAND(
566             PICA_CMD_HEADER_SINGLE( PICA_REG_TEX_ENV3 + TEX_ENV_COLOR_OFFS ),
567             command[ cmdPosBlend2 ] );
568 
569         NW_FONT_RECTDRAWER_ADD_SINGLE_COMMAND(
570             PICA_CMD_HEADER_SINGLE( PICA_REG_TEX_ENV4 + TEX_ENV_COLOR_OFFS ),
571             command[ cmdPosWhite ] );
572 
573         // 0x0fd
574         NW_FONT_RECTDRAWER_ADD_SINGLE_COMMAND(
575             PICA_CMD_HEADER_SINGLE( PICA_REG_TEX_ENV_BUFFER_COLOR ),
576             command[ cmdPosBlack ] );
577     }
578 }
579 
SetUpTextures(const Material * __restrict pMaterial,bool addDisableCommand)580 void Drawer::SetUpTextures( const Material* __restrict pMaterial, bool addDisableCommand )
581 {
582     static u32 command[] NW_LYT_DRAWER_ALIGN_32 =
583     {
584         // 0x082
585         PICA_CMD_DATA_ZERO(), PICA_CMD_HEADER_SINGLE( PICA_REG_TEXTURE0_SIZE ),
586         // 0x085
587         PICA_CMD_DATA_ZERO(), PICA_CMD_HEADER_SINGLE( PICA_REG_TEXTURE0_ADDR1 ),
588         // 0x08e
589         PICA_CMD_DATA_ZERO(), PICA_CMD_HEADER_SINGLE( PICA_REG_TEXTURE0_FORMAT ),
590         // 0x083
591         PICA_CMD_DATA_ZERO(), PICA_CMD_HEADER_SINGLE( PICA_REG_TEXTURE0_WRAP_FILTER ),
592 
593         // 0x092
594         PICA_CMD_DATA_ZERO(), PICA_CMD_HEADER_SINGLE( PICA_REG_TEXTURE1_SIZE ),
595         // 0x095
596         PICA_CMD_DATA_ZERO(), PICA_CMD_HEADER_SINGLE( PICA_REG_TEXTURE1_ADDR ),
597         // 0x096
598         PICA_CMD_DATA_ZERO(), PICA_CMD_HEADER_SINGLE( PICA_REG_TEXTURE1_FORMAT ),
599         // 0x093
600         PICA_CMD_DATA_ZERO(), PICA_CMD_HEADER_SINGLE( PICA_REG_TEXTURE1_WRAP_FILTER ),
601 
602         // 0x09a
603         PICA_CMD_DATA_ZERO(), PICA_CMD_HEADER_SINGLE( PICA_REG_TEXTURE2_SIZE ),
604         // 0x09d
605         PICA_CMD_DATA_ZERO(), PICA_CMD_HEADER_SINGLE( PICA_REG_TEXTURE2_ADDR ),
606         // 0x09e
607         PICA_CMD_DATA_ZERO(), PICA_CMD_HEADER_SINGLE( PICA_REG_TEXTURE2_FORMAT ),
608         // 0x09b
609         PICA_CMD_DATA_ZERO(), PICA_CMD_HEADER_SINGLE( PICA_REG_TEXTURE2_WRAP_FILTER ),
610     };
611 
612     enum
613     {
614         idxWidthHeight = 0,
615         idxTextureAddr = 2,
616         idxFormat      = 4,
617         idxWrapFilter  = 6,
618         settingSize    = 8,
619         commandSize    = sizeof( u32 ) * settingSize
620     };
621 
622     if ( pMaterial == NULL )
623     {
624         command[ idxTextureAddr ] = PICA_CMD_DATA_ZERO();
625 
626         #if defined(NW_FONT_RECTDRAWER_USE_DRAW_BUFFER)
627             NW_ASSERT(m_UniformAddrIndex == 0);
628         #endif
629 
630         if (addDisableCommand)
631         {
632             DisableTextures();
633         }
634         return;
635     }
636 
637     bool isTexCoordModified = true;
638     #if defined(NW_FONT_RECTDRAWER_USE_DRAW_BUFFER)
639         if (m_UniformAddrIndex > 0) // フラッシュされていない
640         {
641             NW_ASSERT(
642                     m_PreviousTexEnvType == m_CurrentTexEnvType
643                 &&  (m_CurrentTexEnvType == TEX_ENV_TYPE_0_TEX || m_CurrentTexEnvType == TEX_ENV_TYPE_1_TEX));
644             isTexCoordModified = false;
645         }
646     #endif
647 
648     const u32 num = ut::Min( (u32)pMaterial->GetTexMapNum(), (u32)TexMapMax );
649 
650     bool isTexturesModified = false;
651 
652     int texbit = 0;
653     for ( int i = 0; i < num; ++i )
654     {
655         texbit |= 1 << i;
656 
657         const TexMap& __restrict texMap = pMaterial->GetTexMap( i );
658         u32* __restrict c = &command[ i * settingSize ];
659 
660         if ( c[ idxTextureAddr ] != texMap.GetPhysicalAddress() / 8
661           || c[ idxWrapFilter  ] != texMap.GetU32WrapFilter()
662         )
663         {
664             c[ idxWidthHeight ] = texMap.GetU32WidthHeight();
665             c[ idxTextureAddr ] = texMap.GetPhysicalAddress() / 8;
666             c[ idxFormat      ] = texMap.GetU32Format();
667             c[ idxWrapFilter  ] = texMap.GetU32WrapFilter();
668             isTexturesModified = true;
669         }
670     }
671 
672     if (isTexCoordModified || isTexturesModified)
673     {
674         // バッファを書き出しておく
675         FlushBuffer();
676     }
677 
678     if (isTexCoordModified || isTexturesModified)
679     {
680         // 0x080 x 3 (ダミーコマンド。0x80 ~ 0xbfの前に必要。)
681         static const u32 dummyCommands[] =
682         {
683             0, PICA_CMD_HEADER_BURST_BE( PICA_REG_TEXTURE_FUNC, 3, 0x0), 0, 0,
684         };
685 
686         NW_FONT_RECTDRAWER_ADD_COMMAND( dummyCommands, sizeof(dummyCommands) );
687     }
688 
689     // 0x080
690     const u32 texFuncData =
691         PICA_CMD_DATA_TEXTURE_FUNC(
692             PICA_DATA_TEXTURE0_SAMPLER_TYPE_TEXTURE_FALSE /* texture0SamplerType: texbit */,
693             0 /* texture1SamplerType: texbit */,
694             0 /* texture2SamplerType: texbit */,
695             0 /* texture3Texcoord */,
696             0 /* texture3SamplerType */,
697             0 /* texture2Texcoord */,
698             1 /* clearTextureCache */) | texbit;
699 
700     if (isTexCoordModified)
701     {
702         // テクスチャ座標有効化
703         // 0x06f
704         NW_FONT_RECTDRAWER_ADD_SINGLE_COMMAND(
705             PICA_CMD_HEADER_SINGLE_BE( PICA_REG_VS_OUT_ATTR_CLK, 0x2 ),
706             PICA_CMD_DATA_VS_GS_OUT_ATTR_CLK(
707                 0 /* verZ */,
708                 0 /* col */,
709                 0 /* tex0 : texbit */,
710                 0 /* tex1 : texbit */,
711                 0 /* tex2 : texbit */,
712                 0 /* tex0_w */,
713                 0 /* view_quat */ ) | texbit << 8 );
714 
715         // サンプラータイプ、座標選択
716         // 0x080
717         NW_FONT_RECTDRAWER_ADD_SINGLE_COMMAND(
718             PICA_CMD_HEADER_SINGLE_BE( PICA_REG_TEXTURE_FUNC, 0xB ),
719             texFuncData );
720     }
721 
722     if (isTexCoordModified || isTexturesModified)
723     {
724         // テクスチャキャッシュをクリア
725         // 0x080
726         NW_FONT_RECTDRAWER_ADD_SINGLE_COMMAND(
727             PICA_CMD_HEADER_SINGLE_BE( PICA_REG_TEXTURE_FUNC, 0x4 ),
728             texFuncData );
729     }
730 
731     if (isTexturesModified)
732     {
733         // コマンドリストに積む
734         NW_FONT_RECTDRAWER_ADD_COMMAND( command, commandSize * num );
735     }
736 }
737 
UniformAndDraw()738 void Drawer::UniformAndDraw()
739 {
740     NW_LYT_DRAWER_ASSERT(m_UniformAddrIndex > 0);
741 
742     { // uUniformAddr へのUniform
743     	const u32 size = SetUniformCommand(m_UniformAddrBuffer, m_UniformAddrIndex);
744         NW_FONT_RECTDRAWER_ADD_COMMAND(m_UniformAddrBuffer, size);
745     }
746 
747     if ( m_UniformMtxIndex > 0 )
748     { // uUniformMtx へのUniform
749 
750         Base::AddUniformMtx();
751     }
752 
753     if ( m_UniformDataIndex > 0 )
754     { // uUniformData へのUniform
755         const u32 size = SetUniformCommand(m_UniformDataBuffer, m_UniformDataIndex);
756         NW_FONT_RECTDRAWER_ADD_COMMAND(m_UniformDataBuffer, size);
757         m_UniformDataIndex = 0;
758     }
759 
760     const int vtxNum = DRAW_VTX_NUM * m_UniformAddrIndex;       // 描画頂点数
761 #if defined(NW_FONT_RECTDRAWER_USE_DRAW_ARRAYS)
762     const u32 vtxIdxAddrOffset = GetVertexIndexAddressOffset(vtxNum);
763 #else
764     const u32 vtxIdxAddrOffset = 0;     // dummy
765 #endif
766 
767     // 頂点シェーダーへ、テクスチャ座標の数の設定
768     // 0x2b1
769     NW_FONT_RECTDRAWER_ADD_SINGLE_COMMAND(
770         PICA_CMD_HEADER_SINGLE( PICA_REG_VS_INT0 ),
771         PICA_CMD_DATA_VS_INT( m_TexCoordNum /* x */ , 0 /* y */, 0 /* z */ ));
772 
773     font::internal::SetVertexNumCmd(&__cb_current_command_buffer, vtxIdxAddrOffset, vtxNum);
774 
775     // コマンドリストに積む
776     NW_FONT_RECTDRAWER_ADD_COMMAND( GetDrawCommands(), GetDrawCommandSize() );
777 
778     // インデックスの初期化
779     m_UniformAddrIndex = 0;
780 }
781 
782 
783 void
SetUpTextBox(const TextBox * __restrict pTextBox,const Material * __restrict pMaterial,const DrawInfo & drawInfo)784 Drawer::SetUpTextBox( const TextBox*  __restrict pTextBox,
785                       const Material* __restrict pMaterial,
786                       const DrawInfo& drawInfo )
787 {
788     font::DispStringBuffer* __restrict pStringBuffer = pTextBox->GetDispStringBuffer();
789 
790     // 文字がなければ終了
791     if (pStringBuffer->IsCommandEmpty())
792     {
793         return;
794     }
795 
796     // テキスト描画を設定
797     m_CurrentTexEnvType = TEX_ENV_TYPE_TEXT;
798 
799     // ブレンドはデフォルト
800     m_IsBlendDefault = true;
801 
802     // アルファテストなし
803     m_AlphaTestEnable = false;
804 
805     // 行列情報の設定
806     pTextBox->GetTextGlobalMtx( (nw::math::MTX34*)m_UniformMtx );
807     m_UniformMtxIndex = 3;
808     Base::AddUniformMtx();  // uUniformMtx へのUniform
809 
810     font::WideTextWriter& writer = drawInfo.GetGraphicsResource()->GetTextWriter();
811     writer.SetDispStringBuffer(pStringBuffer);
812 
813     // テキストカラー
814     ut::Color8 topCol = pTextBox->GetTextColor(TEXTCOLOR_TOP);
815     ut::Color8 btmCol = pTextBox->GetTextColor(TEXTCOLOR_BOTTOM);
816     writer.SetGradationMode(
817         topCol != btmCol ?
818             font::CharWriter::GRADMODE_V:
819             font::CharWriter::GRADMODE_NONE);
820     writer.SetTextColor(topCol, btmCol);
821 
822     // 2色補間+アルファ
823     writer.SetColorMapping(
824         pMaterial->GetColor( INTERPOLATECOLOR_BLACK ),
825         pMaterial->GetColor( INTERPOLATECOLOR_WHITE ));
826     writer.SetAlpha(pTextBox->GetGlobalAlpha());
827 
828     // キャッシュからコマンドを追加
829     writer.UseCommandBuffer();
830 
831     writer.SetDispStringBuffer(NULL);
832 
833     // テクスチャの初期化
834     SetUpTextures( NULL );
835 }
836 
837 #ifdef NW_LYT_DRAWER_ENABLE_USER_TEX_ENV
838 void
SetUpGLTexEnvUser(const Material * __restrict pMaterial)839 Drawer::SetUpGLTexEnvUser( const Material* __restrict pMaterial )
840 {
841     // TODO: マテリアルクラスのメンバの時点でコマンド形式で保持するようにする
842     // TODO: ステージ0を使用する必要があるかの判断を事前に行っておく
843 
844     const int tevSrc[] =
845     {
846         PICA_DATA_TEX_ENV_SRC_RGBA_TEXTURE0,
847         PICA_DATA_TEX_ENV_SRC_RGBA_TEXTURE1,
848         PICA_DATA_TEX_ENV_SRC_RGBA_TEXTURE2,
849         PICA_DATA_TEX_ENV_SRC_RGBA_TEXTURE3,
850         PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT,
851         PICA_DATA_TEX_ENV_SRC_RGBA_PRIMARY_COLOR,
852         PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS,
853         PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS_BUFFER_DMP,
854     };
855 
856     const int tevMode[] =
857     {
858         PICA_DATA_TEX_ENV_COMBINE_REPLACE,
859         PICA_DATA_TEX_ENV_COMBINE_MODULATE,
860         PICA_DATA_TEX_ENV_COMBINE_ADD,
861         PICA_DATA_TEX_ENV_COMBINE_ADD_SIGNED,
862         PICA_DATA_TEX_ENV_COMBINE_INTERPOLATE,
863         PICA_DATA_TEX_ENV_COMBINE_SUBTRACT,
864         PICA_DATA_TEX_ENV_COMBINE_ADD_MULT_DMP,
865         PICA_DATA_TEX_ENV_COMBINE_MULT_ADD_DMP,
866     };
867 
868     const int tevOpRgb[] =
869     {
870         PICA_DATA_OPE_RGB_SRC_COLOR,
871         PICA_DATA_OPE_RGB_ONE_MINUS_SRC_COLOR,
872         PICA_DATA_OPE_RGB_SRC_ALPHA,
873         PICA_DATA_OPE_RGB_ONE_MINUS_SRC_ALPHA,
874         PICA_DATA_OPE_RGB_SRC_R_DMP,
875         PICA_DATA_OPE_RGB_ONE_MINUS_SRC_R_DMP,
876         PICA_DATA_OPE_RGB_SRC_G_DMP,
877         PICA_DATA_OPE_RGB_ONE_MINUS_SRC_G_DMP,
878         PICA_DATA_OPE_RGB_SRC_B_DMP,
879         PICA_DATA_OPE_RGB_ONE_MINUS_SRC_B_DMP,
880     };
881 
882     const int tevOpAlp[] =
883     {
884         PICA_DATA_OPE_ALPHA_SRC_ALPHA,
885         PICA_DATA_OPE_ALPHA_ONE_MINUS_SRC_ALPHA,
886         PICA_DATA_OPE_ALPHA_SRC_R_DMP,
887         PICA_DATA_OPE_ALPHA_ONE_MINUS_SRC_R_DMP,
888         PICA_DATA_OPE_ALPHA_SRC_G_DMP,
889         PICA_DATA_OPE_ALPHA_ONE_MINUS_SRC_G_DMP,
890         PICA_DATA_OPE_ALPHA_SRC_B_DMP,
891         PICA_DATA_OPE_ALPHA_ONE_MINUS_SRC_B_DMP,
892     };
893 
894     const u32 scale[] =
895     {
896         PICA_DATA_TEX_ENV_SCALE_1,
897         PICA_DATA_TEX_ENV_SCALE_2,
898         PICA_DATA_TEX_ENV_SCALE_4,
899     };
900 
901     const u32 reg[] =
902     {
903         PICA_REG_TEX_ENV0,
904         PICA_REG_TEX_ENV1,
905         PICA_REG_TEX_ENV2,
906         PICA_REG_TEX_ENV3,
907         PICA_REG_TEX_ENV4,
908         PICA_REG_TEX_ENV5,
909     };
910 
911     u32 bufferInput = NW_LYT_CMD_DATA_TEX_ENV_BUF_INPUT_THROUGH;
912 
913     u32 stageNum = nw::ut::Min( (u32)TEX_ENV_STAGE_NUM, (u32)pMaterial->GetTevStageNum() );
914     for ( int i = 0; i < stageNum; ++i )
915     {
916         const TevStage& tevStage = pMaterial->GetTevStage( i );
917 
918         nw::ut::Color8 rgb = pMaterial->GetColor( tevStage.GetKonstSelRgb() );
919         nw::ut::Color8 alpha = pMaterial->GetColor( tevStage.GetKonstSelAlpha() );
920 
921         int stageNo = i + ( TEX_ENV_STAGE_NUM - stageNum );
922 
923         if (i == 0)
924         {
925             // ステージ0を使わなければならないかチェック
926             if ( ( tevStage.GetSrcRgb0() != TEVSRC_CONSTANT &&
927                    tevStage.GetSrcRgb1() != TEVSRC_CONSTANT &&
928                    tevStage.GetSrcRgb2() != TEVSRC_CONSTANT ) ||
929                  ( tevStage.GetSrcAlpha0() != TEVSRC_CONSTANT &&
930                    tevStage.GetSrcAlpha1() != TEVSRC_CONSTANT &&
931                    tevStage.GetSrcAlpha2() != TEVSRC_CONSTANT ) )
932             {
933                 // スルー設定
934                 for ( int j = 1; j <= stageNo; ++j)
935                 {
936                     // ヘッダ
937                     NW_FONT_RECTDRAWER_ADD_SINGLE_COMMAND(
938                         PICA_CMD_HEADER_BURSTSEQ( reg[ j ], 5 ),
939                         PICA_CMD_DATA_TEX_ENV_SRC(
940                             PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS,
941                             PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT,
942                             PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT,
943                             PICA_DATA_TEX_ENV_SRC_RGBA_PREVIOUS,
944                             PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT,
945                             PICA_DATA_TEX_ENV_SRC_RGBA_CONSTANT ) );
946 
947                     // 続き
948                     static const u32 command[] =
949                     {
950                         PICA_CMD_DATA_TEX_ENV_OPERAND(
951                             PICA_DATA_OPE_RGB_SRC_COLOR,
952                             PICA_DATA_OPE_RGB_SRC_COLOR,
953                             PICA_DATA_OPE_RGB_SRC_COLOR,
954                             PICA_DATA_OPE_ALPHA_SRC_ALPHA,
955                             PICA_DATA_OPE_ALPHA_SRC_ALPHA,
956                             PICA_DATA_OPE_ALPHA_SRC_ALPHA ),
957                         PICA_CMD_DATA_TEX_ENV_COMBINE(
958                             PICA_DATA_TEX_ENV_COMBINE_REPLACE,
959                             PICA_DATA_TEX_ENV_COMBINE_REPLACE ),
960                         PICA_CMD_DATA_TEX_ENV_BUFFER_COLOR_WHITE,
961                         PICA_CMD_DATA_TEX_ENV_SCALE(
962                             PICA_DATA_TEX_ENV_SCALE_1, PICA_DATA_TEX_ENV_SCALE_1 ),
963                     };
964 
965                     NW_FONT_RECTDRAWER_ADD_COMMAND( command, sizeof( command ) );
966                 }
967 
968                 // ステージ0を使用
969                 stageNo = 0;
970             }
971         }
972 
973         if ( 1 <= i && i <= 4 )
974         {
975             bufferInput |= PICA_CMD_DATA_TEX_ENV_BUFFER_INPUT(
976                 stageNo,
977                 ( tevStage.GetSavePrevRgb() ) ?
978                     PICA_DATA_TEX_ENV_BUFFER_INPUT_PREVIOUS :
979                     PICA_DATA_TEX_ENV_BUFFER_INPUT_PREVIOUS_BUFFER_DMP,
980                 ( tevStage.GetSavePrevAlpha() ) ?
981                     PICA_DATA_TEX_ENV_BUFFER_INPUT_PREVIOUS :
982                     PICA_DATA_TEX_ENV_BUFFER_INPUT_PREVIOUS_BUFFER_DMP );
983         }
984 
985         const u32 command[] =
986         {
987             PICA_CMD_DATA_TEX_ENV_SRC(
988                 tevSrc[ tevStage.GetSrcRgb0() ],   tevSrc[ tevStage.GetSrcRgb1() ],  tevSrc[ tevStage.GetSrcRgb2() ],
989                 tevSrc[ tevStage.GetSrcAlpha0() ], tevSrc[ tevStage.GetSrcAlpha1()], tevSrc[ tevStage.GetSrcAlpha2() ] ),
990             PICA_CMD_HEADER_BURSTSEQ( reg[ stageNo ], 5 ),
991             PICA_CMD_DATA_TEX_ENV_OPERAND(
992                 tevOpRgb[ tevStage.GetOperandRgb0() ],   tevOpRgb[ tevStage.GetOperandRgb1() ],   tevOpRgb[ tevStage.GetOperandRgb2() ],
993                 tevOpAlp[ tevStage.GetOperandAlpha0() ], tevOpAlp[ tevStage.GetOperandAlpha1() ], tevOpAlp[ tevStage.GetOperandAlpha2() ] ),
994             PICA_CMD_DATA_TEX_ENV_COMBINE( tevMode[ tevStage.GetCombineRgb() ], tevMode[ tevStage.GetCombineAlpha() ] ),
995             NW_LYT_CMD_DATA_COLOR_ALPHA( rgb, alpha ),
996             PICA_CMD_DATA_TEX_ENV_SCALE( scale[ tevStage.GetScaleRgb() ], scale[ tevStage.GetScaleAlpha() ] ),
997         };
998 
999         // コマンドリストに積む
1000         NW_FONT_RECTDRAWER_ADD_COMMAND( command, sizeof( command ) );
1001     }
1002 
1003     // バッファカラーおよびバッファ入力の設定
1004     {
1005         nw::ut::Color8 black = pMaterial->GetColor( TEVKONSTSEL_BUFFER );
1006 
1007         // 0x0fd
1008         NW_FONT_RECTDRAWER_ADD_SINGLE_COMMAND(
1009             PICA_CMD_HEADER_SINGLE( PICA_REG_TEX_ENV_BUFFER_COLOR ),
1010             NW_LYT_CMD_DATA_COLOR(black) );
1011 
1012         // 0x0e0
1013         NW_FONT_RECTDRAWER_ADD_SINGLE_COMMAND(
1014             PICA_CMD_HEADER_SINGLE_BE( PICA_REG_TEX_ENV_BUFFER_INPUT, 0x2 ),
1015             bufferInput );
1016     }
1017 }
1018 #endif
1019 
1020 #ifdef NW_LYT_DRAWER_ENABLE_ALPHA_TEST
1021 void
SetUpAlphaTest(const Material * __restrict pMaterial)1022 Drawer::SetUpAlphaTest( const Material* __restrict pMaterial )
1023 {
1024     const AlphaCompare& __restrict alphaCompare = pMaterial->GetAlphaCompare();
1025     register f32 refValue = alphaCompare.GetRef() * 255.f + 0.5f;
1026 
1027     const u32 alphaTest[] =
1028     {
1029         PICA_DATA_ALPHA_TEST_NEVER,
1030         PICA_DATA_ALPHA_TEST_LESS,
1031         PICA_DATA_ALPHA_TEST_LEQUAL,
1032         PICA_DATA_ALPHA_TEST_EQUAL,
1033         PICA_DATA_ALPHA_TEST_NOTEQUAL,
1034         PICA_DATA_ALPHA_TEST_GEQUAL,
1035         PICA_DATA_ALPHA_TEST_GREATER,
1036         PICA_DATA_ALPHA_TEST_ALWAYS,
1037     };
1038 
1039     // 0x104
1040     NW_FONT_RECTDRAWER_ADD_SINGLE_COMMAND(
1041         PICA_CMD_HEADER_SINGLE( PICA_REG_FRAGOP_ALPHA_TEST ),
1042         PICA_CMD_DATA_FRAGOP_ALPHA_TEST( true, alphaTest[ alphaCompare.GetFunc() ], (u8)refValue ) );
1043 }
1044 #endif
1045 
1046 #ifdef NW_LYT_DRAWER_ENABLE_BLEND_FUNC
1047 void
SetUpBlendMode(const Material * __restrict pMaterial)1048 Drawer::SetUpBlendMode( const Material* __restrict pMaterial )
1049 {
1050     const BlendMode& blendMode = pMaterial->GetBlendMode();
1051 
1052     if ( blendMode.GetBlendOp() == BLENDOP_DISABLE &&
1053          blendMode.GetLogicOp() == LOGICOP_DISABLE )
1054     {
1055         // ブレンドなしのコマンド
1056         u32 command[] =	{
1057             NW_FONT_COMMAND_SET_BLEND_FUNC(
1058                 PICA_DATA_BLEND_EQUATION_ADD,
1059                 PICA_DATA_BLEND_FUNC_ONE,
1060                 PICA_DATA_BLEND_FUNC_ZERO )
1061         };
1062 
1063         NW_FONT_RECTDRAWER_ADD_COMMAND( command, sizeof( command ) );
1064     }
1065     else if ( blendMode.GetBlendOp() != BLENDOP_DISABLE )
1066     {
1067         // ブレンド設定
1068 
1069         const u32 blendOp[] =
1070         {
1071             0, // DISABLE
1072             PICA_DATA_BLEND_EQUATION_ADD,
1073             PICA_DATA_BLEND_EQUATION_SUBTRACT,
1074             PICA_DATA_BLEND_EQUATION_REVERSE_SUBTRACT,
1075         };
1076 
1077         const u32 srcFactor[] =
1078         {
1079             PICA_DATA_BLEND_FUNC_ZERO,
1080             PICA_DATA_BLEND_FUNC_ONE,
1081             PICA_DATA_BLEND_FUNC_DST_COLOR,
1082             PICA_DATA_BLEND_FUNC_ONE_MINUS_DST_COLOR,
1083             PICA_DATA_BLEND_FUNC_SRC_ALPHA,
1084             PICA_DATA_BLEND_FUNC_ONE_MINUS_SRC_ALPHA,
1085             PICA_DATA_BLEND_FUNC_DST_ALPHA,
1086             PICA_DATA_BLEND_FUNC_ONE_MINUS_DST_ALPHA,
1087         };
1088 
1089         const u32 dstFactor[] =
1090         {
1091             PICA_DATA_BLEND_FUNC_ZERO,
1092             PICA_DATA_BLEND_FUNC_ONE,
1093             PICA_DATA_BLEND_FUNC_SRC_COLOR,
1094             PICA_DATA_BLEND_FUNC_ONE_MINUS_SRC_COLOR,
1095             PICA_DATA_BLEND_FUNC_SRC_ALPHA,
1096             PICA_DATA_BLEND_FUNC_ONE_MINUS_SRC_ALPHA,
1097             PICA_DATA_BLEND_FUNC_DST_ALPHA,
1098             PICA_DATA_BLEND_FUNC_ONE_MINUS_DST_ALPHA,
1099         };
1100 
1101         const u32 command[] =
1102         {
1103             NW_FONT_COMMAND_SET_BLEND_FUNC(
1104                 blendOp[   blendMode.GetBlendOp() ],
1105                 srcFactor[ blendMode.GetSrcFactor() ],
1106                 dstFactor[ blendMode.GetDstFactor() ] ),
1107         };
1108         NW_FONT_RECTDRAWER_ADD_COMMAND( command, sizeof( command ) );
1109     }
1110     else if ( blendMode.GetLogicOp() != LOGICOP_DISABLE )
1111     {
1112         // 論理演算の設定
1113 
1114         const u32 logicOp[] =
1115         {
1116             0 , // DISABLE
1117             PICA_DATA_LOGIC_NOOP,
1118             PICA_DATA_LOGIC_CLEAR,
1119             PICA_DATA_LOGIC_SET,
1120             PICA_DATA_LOGIC_COPY,
1121             PICA_DATA_LOGIC_COPY_INVERTED,
1122             PICA_DATA_LOGIC_INVERT,
1123             PICA_DATA_LOGIC_AND,
1124             PICA_DATA_LOGIC_NAND,
1125             PICA_DATA_LOGIC_OR,
1126             PICA_DATA_LOGIC_NOR,
1127             PICA_DATA_LOGIC_XOR,
1128             PICA_DATA_LOGIC_EQUIV,
1129             PICA_DATA_LOGIC_AND_REVERSE,
1130             PICA_DATA_LOGIC_AND_INVERTED,
1131             PICA_DATA_LOGIC_OR_REVERSE,
1132             PICA_DATA_LOGIC_OR_INVERTED,
1133         };
1134 
1135         const u32 command[] =
1136         {
1137             NW_LYT_COMMAND_SET_LOGIC_OP( logicOp[ blendMode.GetLogicOp() ] ),
1138         };
1139         NW_FONT_RECTDRAWER_ADD_COMMAND( command, sizeof( command ) );
1140     }
1141 }
1142 #endif
1143 
1144 }   // namespace lyt
1145 }   // namespace nw
1146 
1147 #endif // NW_LYT_DRAWER_ENABLE
1148