1 /*---------------------------------------------------------------------------* 2 Project: Horizon 3 File: gr_FragmentLight.cpp 4 5 Copyright (C)2010 Nintendo Co., Ltd. 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 $Rev: 33699 $ 14 *---------------------------------------------------------------------------*/ 15 16 #include <nn/gr/CTR/gr_FragmentLight.h> 17 18 namespace nn 19 { 20 namespace gr 21 { 22 namespace CTR 23 { 24 MakeAllCommand(bit32 * command) const25 bit32* FragmentLight::Source::MakeAllCommand( bit32* command ) const 26 { 27 bit32 reg = PICA_REG_FRAG_LIGHT_START + id * PICA_FRAG_LIGHT_STRIDE; 28 29 *command++ = specular0B | specular0G << 10 | specular0R << 20; // specular0 30 *command++ = PICA_CMD_HEADER_BURSTSEQ( reg, 12 ); // header 31 *command++ = specular1B | specular1G << 10 | specular1R << 20; // specular1 32 *command++ = diffuseB | diffuseG << 10 | diffuseR << 20; // diffuse 33 *command++ = ambientB | ambientG << 10 | ambientR << 20; // ambient 34 *command++ = posXY; 35 *command++ = posZ; 36 *command++ = spotDirectionXY; 37 *command++ = spotDirectionZ; 38 *command++ = 0; 39 *command++ = isInfinity | ( isEnableTwoSideDiffuse ? 1 : 0 ) << 1 | 40 ( isEnableGeomFactor0 ? 1 : 0 ) << 2 | ( isEnableGeomFactor1 ? 1 : 0 ) << 3; 41 *command++ = distAttnBias; 42 *command++ = distAttnScale; 43 *command++ = 0; 44 45 return command; 46 } 47 48 //------------------------------------------------------------------------------ 49 MakeCommand(bit32 * command) const50 bit32* FragmentLight::Source::MakeCommand( bit32* command ) const 51 { 52 return MakeAllCommand( command ); 53 } 54 55 //------------------------------------------------------------------------------ 56 MakeColorCommand(bit32 * command) const57 bit32* FragmentLight::Source::MakeColorCommand( bit32* command ) const 58 { 59 bit32 reg = PICA_REG_FRAG_LIGHT_START + id * PICA_FRAG_LIGHT_STRIDE; 60 61 *command++ = specular0B | specular0G << 10 | specular0R << 20; // specular0 62 *command++ = PICA_CMD_HEADER_BURSTSEQ( reg, 4 ); // header 63 64 *command++ = specular1B | specular1G << 10 | specular1R << 20; // specular1 65 *command++ = diffuseB | diffuseG << 10 | diffuseR << 20; // diffuse 66 67 *command++ = ambientB | ambientG << 10 | ambientR << 20; // ambient 68 *command++ = 0; 69 70 return command; 71 } 72 73 //------------------------------------------------------------------------------ 74 MakeGeometryCommand(bit32 * command) const75 bit32* FragmentLight::Source::MakeGeometryCommand( bit32* command ) const 76 { 77 bit32 reg = PICA_REG_FRAG_LIGHT_START + id * PICA_FRAG_LIGHT_STRIDE + 0x4; 78 79 *command++ = posXY; 80 *command++ = PICA_CMD_HEADER_BURSTSEQ( reg, 8 ); 81 82 *command++ = posZ; 83 *command++ = spotDirectionXY; 84 85 *command++ = spotDirectionZ; 86 *command++ = 0; 87 88 *command++ = isInfinity | 89 ( isEnableTwoSideDiffuse ? 1 : 0 ) << 1 | 90 ( isEnableGeomFactor0 ? 1 : 0 ) << 2 | 91 ( isEnableGeomFactor1 ? 1 : 0 ) << 3; 92 *command++ = distAttnBias; 93 94 *command++ = distAttnScale; 95 *command++ = 0; 96 97 return command; 98 } 99 100 //------------------------------------------------------------------------------ 101 Source()102 FragmentLight::Source::Source() 103 : id( 0 ), 104 isEnableTwoSideDiffuse( false ), 105 isEnableGeomFactor0( false ), 106 isEnableGeomFactor1( false ), 107 diffuseR( 255 ), 108 diffuseG( 255 ), 109 diffuseB( 255 ), 110 ambientR( 0 ), 111 ambientG( 0 ), 112 ambientB( 0 ), 113 specular0R( 255 ), 114 specular0G( 255 ), 115 specular0B( 255 ), 116 specular1R( 255 ), 117 specular1G( 255 ), 118 specular1B( 255 ), 119 posXY( 0 ), 120 posZ( 0 ), 121 isInfinity( 0 ), 122 distAttnBias( 0 ), 123 distAttnScale( 0 ), 124 spotDirectionXY( 0 ), 125 spotDirectionZ( 0 ) 126 { 127 } 128 129 //------------------------------------------------------------------------------ 130 MakeLutConfigCommand(bit32 * command) const131 bit32* FragmentLight::MakeLutConfigCommand( bit32* command ) const 132 { 133 // 0x1d0 134 *command++ = PICA_CMD_DATA_FRAG_LIGHT_ABSLUTINPUT( 135 lutConfigD0.isAbs, 136 lutConfigD1.isAbs, 137 lutConfigSP.isAbs, 138 lutConfigFR.isAbs, 139 lutConfigRB.isAbs, 140 lutConfigRG.isAbs, 141 lutConfigRR.isAbs ); 142 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_FRAG_LIGHT_ABSLUTINPUT ); 143 144 // 0x1d1 145 *command++ = PICA_CMD_DATA_FRAG_LIGHT_LUTINPUT( 146 lutConfigD0.input, 147 lutConfigD1.input, 148 lutConfigSP.input, 149 lutConfigFR.input, 150 lutConfigRB.input, 151 lutConfigRG.input, 152 lutConfigRR.input ); 153 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_FRAG_LIGHT_LUTINPUT ); 154 155 // 0x1d2 156 *command++ = PICA_CMD_DATA_FRAG_LIGHT_LUTSCALE( 157 lutConfigD0.scale, 158 lutConfigD1.scale, 159 lutConfigSP.scale, 160 lutConfigFR.scale, 161 lutConfigRB.scale, 162 lutConfigRG.scale, 163 lutConfigRR.scale ); 164 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_FRAG_LIGHT_LUTSCALE ); 165 166 return command; 167 } 168 169 //------------------------------------------------------------------------------ 170 MakeLightEnvCommand(bit32 * command,bool isAddDummyCommand) const171 bit32* FragmentLight::MakeLightEnvCommand( bit32* command, bool isAddDummyCommand ) const 172 { 173 bit32 regLightEnable = 0xff00ffff; 174 bit32 regLightEnableEach = 0; 175 s32 count = 0; 176 177 regLightEnable |= PICA_CMD_DATA_FRAG_LIGHT_FUNC_MODE1_LUT( 178 isEnableLutD0, 179 isEnableLutD1, 180 fresnelSelector, 181 isEnableLutRefl ); 182 183 for ( int i = 0; i < LIGHT_SOURCE_MAX; ++i ) 184 { 185 if ( isEnable[ i ] == false ) 186 { 187 continue; 188 } 189 190 if ( isShadowed[ i ] ) 191 { 192 regLightEnable &= ~( 1 << i ); 193 } 194 195 if ( isEnableSpot[ i ] ) 196 { 197 regLightEnable &= ~( 1 << ( 8 + i ) ); 198 } 199 200 if ( isEnableDistAttn[ i ] ) 201 { 202 regLightEnable &= ~( 1 << ( 24 + i ) ); 203 } 204 205 regLightEnableEach |= ( i << ( count++ * 4 ) ); 206 } 207 208 // 0x08f の変更の前に、ダミーコマンドを送る 209 if ( isAddDummyCommand ) 210 { 211 *command++ = 0x0; 212 *command++ = PICA_CMD_HEADER_BURST_BE( PICA_REG_TEXTURE_FUNC, 0x3, 0x0 ); 213 *command++ = 0x0; 214 *command++ = 0x0; 215 } 216 217 // 0x08f ライトの有効無効を設定 218 *command++ = PICA_CMD_DATA_FRAG_LIGHT_EN( count ); 219 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_FRAG_LIGHT_EN0 ); 220 221 // 0x1c0 グローバルアンビエントの設定 222 *command++ = globalAmbientB | globalAmbientG << 10 | globalAmbientR << 20; 223 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_FRAG_LIGHT_AMBIENT ); 224 225 // 0x1c2 光源数の設定 226 *command++ = PICA_CMD_DATA_FRAG_LIGHT_NUM( count ); 227 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_FRAG_LIGHT_SRC_NUM ); 228 229 // 0x1c3 230 *command++ = PICA_CMD_DATA_FRAG_LIGHT_FUNC_MODE0( 231 fresnelSelector, 232 layerConfig, 233 isEnableShadowPrimary, 234 isEnableShadowSecondary, 235 isInvertShadow, 236 isEnableShadowAlpha, 237 bumpSelector, 238 shadowSelector, 239 isEnableClampHighLights, 240 bumpMode, 241 isEnableBumpRenorm ); 242 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_FRAG_LIGHT_FUNC_MODE0 ); 243 244 // 0x1c4 245 *command++ = regLightEnable; 246 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_FRAG_LIGHT_FUNC_MODE1 ); 247 248 // 0x1c6 ライトの有効無効を設定 249 *command++ = PICA_CMD_DATA_FRAG_LIGHT_EN_INV( count ); 250 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_FRAG_LIGHT_EN1 ); 251 252 // 0x1d9 253 *command++ = regLightEnableEach; 254 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_FRAG_LIGHT_SRC_EN_ID ); 255 return command; 256 } 257 258 //------------------------------------------------------------------------------ 259 MakeLightSourceCommand(bit32 * command) const260 bit32* FragmentLight::MakeLightSourceCommand( bit32* command ) const 261 { 262 // 各光源ごとの設定 263 for ( int i = 0; i < LIGHT_SOURCE_MAX; ++i ) 264 { 265 if ( isEnable[ i ] == false ) continue; 266 267 command = source[ i ].MakeCommand( command ); 268 } 269 270 return command; 271 } 272 273 //------------------------------------------------------------------------------ 274 MakeAllCommand(bit32 * command,bool isAddDummyCommand) const275 bit32* FragmentLight::MakeAllCommand( bit32* command, bool isAddDummyCommand ) const 276 { 277 #if defined( NN_GR_FRAGMENT_LIGHT_DUMP ) // デバッグ用 278 bit32 * start = command; 279 #endif 280 281 command = MakeLutConfigCommand( command ); 282 283 command = MakeLightEnvCommand( command, isAddDummyCommand ); 284 285 command = MakeLightSourceCommand( command ); 286 287 288 #if defined( NN_GR_FRAGMENT_LIGHT_DUMP ) // デバッグ用 289 static int a = 0; 290 if ( ++a == 10 ) 291 { 292 for ( u32* i = start; i != command; i +=2 ) 293 { 294 NN_LOG( "0x%08x 0x%08x\n", *i, *(i+1) ); 295 } 296 } 297 #endif 298 299 return command; 300 } 301 302 //------------------------------------------------------------------------------ 303 MakeDisableCommand(bit32 * command,bool isAddDummyCommand)304 bit32* FragmentLight::MakeDisableCommand( bit32* command, bool isAddDummyCommand ) 305 { 306 // 0x08f の変更の前に、ダミーコマンドを送る 307 if ( isAddDummyCommand ) 308 { 309 *command++ = 0x0; 310 *command++ = PICA_CMD_HEADER_BURST_BE( PICA_REG_TEXTURE_FUNC, 0x3, 0x0 ); 311 312 *command++ = 0x0; 313 *command++ = 0x0; 314 } 315 316 // 0x08f ライト無効を設定 317 *command++ = 0; 318 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_FRAG_LIGHT_EN0 ); 319 320 // 0x1c6 ライト無効を設定 321 *command++ = 0; 322 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_FRAG_LIGHT_EN1 ); 323 324 // 0x1c2 光源の数を 0 に設定 325 *command++ = 0; 326 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_FRAG_LIGHT_SRC_NUM ); 327 328 return command; 329 } 330 331 //------------------------------------------------------------------------------ 332 FragmentLight()333 FragmentLight::FragmentLight() 334 : globalAmbientR( 0 ), 335 globalAmbientG( 0 ), 336 globalAmbientB( 0 ), 337 layerConfig( PICA_DATA_FRAG_LIGHT_ENV_LAYER_CONFIG0 ), 338 fresnelSelector( PICA_DATA_FRAG_LIGHT_ENV_NO_FRESNEL ), 339 shadowSelector( PICA_DATA_FRAG_LIGHT_ENV_TEXTURE0 ), 340 bumpMode( PICA_DATA_FRAG_LIGHT_ENV_BUMP_NOT_USED_DMP ), 341 bumpSelector( PICA_DATA_FRAG_LIGHT_ENV_TEXTURE0 ), 342 isEnableShadowPrimary( false ), 343 isEnableShadowSecondary( false ), 344 isEnableShadowAlpha( false ), 345 isInvertShadow( false ), 346 isEnableBumpRenorm( false ), 347 isEnableClampHighLights( true ), 348 isEnableLutD0( false ), 349 isEnableLutD1( false ), 350 isEnableLutRefl( true ) 351 { 352 for ( int i = 0; i < LIGHT_SOURCE_MAX; ++i ) 353 { 354 isEnable[ i ] = false; 355 isEnableSpot[ i ] = false; 356 isEnableDistAttn[ i ] = false; 357 isShadowed[ i ] = false; 358 source[ i ].id = i; 359 } 360 } 361 362 //------------------------------------------------------------------------------ 363 LutConfig()364 FragmentLight::LutConfig::LutConfig() 365 : input( PICA_DATA_FRAG_LIGHT_ENV_NH_DMP ), 366 isAbs( false ), 367 scale( PICA_DATA_FRAG_LIGHT_ENV_LUTSCALE_1_0 ) 368 { 369 } 370 371 } // namespace CTR 372 } // namespace gr 373 } // namespace nn 374