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: 29908 $ 14 *---------------------------------------------------------------------------*/ 15 16 #include <nn/gr/CTR/gr_FragmentLight.h> 17 18 namespace nn 19 { 20 namespace gr 21 { 22 namespace CTR 23 { 24 MakeCommand(bit32 * command) const25 bit32* FragmentLight::Source::MakeCommand( 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 Source()50 FragmentLight::Source::Source() 51 : id( 0 ), 52 isEnableTwoSideDiffuse( false ), 53 isEnableGeomFactor0( false ), 54 isEnableGeomFactor1( false ), 55 diffuseR( 255 ), 56 diffuseG( 255 ), 57 diffuseB( 255 ), 58 ambientR( 0 ), 59 ambientG( 0 ), 60 ambientB( 0 ), 61 specular0R( 255 ), 62 specular0G( 255 ), 63 specular0B( 255 ), 64 specular1R( 255 ), 65 specular1G( 255 ), 66 specular1B( 255 ), 67 posXY( 0 ), 68 posZ( 0 ), 69 isInfinity( 0 ), 70 distAttnBias( 0 ), 71 distAttnScale( 0 ), 72 spotDirectionXY( 0 ), 73 spotDirectionZ( 0 ) 74 { 75 } 76 77 //------------------------------------------------------------------------------ 78 MakeLutConfigCommand(bit32 * command) const79 bit32* FragmentLight::MakeLutConfigCommand( bit32* command ) const 80 { 81 // 0x1d0 82 *command++ = PICA_CMD_DATA_FRAG_LIGHT_ABSLUTINPUT( 83 lutConfigD0.isAbs, 84 lutConfigD1.isAbs, 85 lutConfigSP.isAbs, 86 lutConfigFR.isAbs, 87 lutConfigRB.isAbs, 88 lutConfigRG.isAbs, 89 lutConfigRR.isAbs ); 90 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_FRAG_LIGHT_ABSLUTINPUT ); 91 92 // 0x1d1 93 *command++ = PICA_CMD_DATA_FRAG_LIGHT_LUTINPUT( 94 lutConfigD0.input, 95 lutConfigD1.input, 96 lutConfigSP.input, 97 lutConfigFR.input, 98 lutConfigRB.input, 99 lutConfigRG.input, 100 lutConfigRR.input ); 101 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_FRAG_LIGHT_LUTINPUT ); 102 103 // 0x1d2 104 *command++ = PICA_CMD_DATA_FRAG_LIGHT_LUTSCALE( 105 lutConfigD0.scale, 106 lutConfigD1.scale, 107 lutConfigSP.scale, 108 lutConfigFR.scale, 109 lutConfigRB.scale, 110 lutConfigRG.scale, 111 lutConfigRR.scale ); 112 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_FRAG_LIGHT_LUTSCALE ); 113 114 return command; 115 } 116 117 //------------------------------------------------------------------------------ 118 MakeLightEnvCommand(bit32 * command,bool isAddDummyCommand) const119 bit32* FragmentLight::MakeLightEnvCommand( bit32* command, bool isAddDummyCommand ) const 120 { 121 bit32 regLightEnable = 0xff00ffff; 122 bit32 regLightEnableEach = 0; 123 s32 count = 0; 124 125 regLightEnable |= PICA_CMD_DATA_FRAG_LIGHT_FUNC_MODE1_LUT( 126 isEnableLutD0, 127 isEnableLutD1, 128 fresnelSelector, 129 isEnableLutRefl ); 130 131 for ( int i = 0; i < LIGHT_SOURCE_MAX; ++i ) 132 { 133 if ( isEnable[ i ] == false ) continue; 134 135 if ( isShadowed[ i ] ) 136 { 137 regLightEnable &= ~( i << i ); 138 } 139 140 if ( isEnableSpot[ i ] ) 141 { 142 regLightEnable &= ~( 1 << ( 8 + i ) ); 143 } 144 145 if ( isEnableDistAttn[ i ] ) 146 { 147 regLightEnable &= ~( 1 << ( 24 + i ) ); 148 } 149 150 regLightEnableEach |= ( i << ( count++ * 4 ) ); 151 } 152 153 // 0x08f の変更の前に、ダミーコマンドを送る 154 if ( isAddDummyCommand ) 155 { 156 *command++ = 0x0; 157 *command++ = PICA_CMD_HEADER_BURST_BE( PICA_REG_TEXTURE_FUNC, 0x3, 0x0 ); 158 *command++ = 0x0; 159 *command++ = 0x0; 160 } 161 162 // 0x08f ライトの有効無効を設定 163 *command++ = PICA_CMD_DATA_FRAG_LIGHT_EN( count ); 164 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_FRAG_LIGHT_EN0 ); 165 166 // 0x1c0 グローバルアンビエントの設定 167 *command++ = globalAmbientB | globalAmbientG << 10 | globalAmbientR << 20; 168 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_FRAG_LIGHT_AMBIENT ); 169 170 // 0x1c2 光源数の設定 171 *command++ = PICA_CMD_DATA_FRAG_LIGHT_NUM( count ); 172 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_FRAG_LIGHT_SRC_NUM ); 173 174 // 0x1c3 175 *command++ = PICA_CMD_DATA_FRAG_LIGHT_FUNC_MODE0( 176 fresnelSelector, 177 layerConfig, 178 isEnableShadowPrimary, 179 isEnableShadowSecondary, 180 isInvertShadow, 181 isEnableShadowAlpha, 182 bumpSelector, 183 shadowSelector, 184 isEnableClampHighLights, 185 bumpMode, 186 isEnableBumpRenorm ); 187 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_FRAG_LIGHT_FUNC_MODE0 ); 188 189 // 0x1c4 190 *command++ = regLightEnable; 191 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_FRAG_LIGHT_FUNC_MODE1 ); 192 193 // 0x1c6 ライトの有効無効を設定 194 *command++ = PICA_CMD_DATA_FRAG_LIGHT_EN_INV( count ); 195 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_FRAG_LIGHT_EN1 ); 196 197 // 0x1d9 198 *command++ = regLightEnableEach; 199 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_FRAG_LIGHT_SRC_EN_ID ); 200 return command; 201 } 202 203 //------------------------------------------------------------------------------ 204 MakeLightSourceCommand(bit32 * command) const205 bit32* FragmentLight::MakeLightSourceCommand( bit32* command ) const 206 { 207 // 各光源ごとの設定 208 for ( int i = 0; i < LIGHT_SOURCE_MAX; ++i ) 209 { 210 if ( isEnable[ i ] == false ) continue; 211 212 command = source[ i ].MakeCommand( command ); 213 } 214 215 return command; 216 } 217 218 //------------------------------------------------------------------------------ 219 MakeAllCommand(bit32 * command,bool isAddDummyCommand) const220 bit32* FragmentLight::MakeAllCommand( bit32* command, bool isAddDummyCommand ) const 221 { 222 #if defined( NN_GR_FRAGMENT_LIGHT_DUMP ) // デバッグ用 223 bit32 * start = command; 224 #endif 225 226 command = MakeLutConfigCommand( command ); 227 228 command = MakeLightEnvCommand( command, isAddDummyCommand ); 229 230 command = MakeLightSourceCommand( command ); 231 232 233 #if defined( NN_GR_FRAGMENT_LIGHT_DUMP ) // デバッグ用 234 static int a = 0; 235 if ( ++a == 10 ) 236 { 237 for ( u32* i = start; i != command; i +=2 ) 238 { 239 NN_LOG( "0x%08x 0x%08x\n", *i, *(i+1) ); 240 } 241 } 242 #endif 243 244 return command; 245 } 246 247 //------------------------------------------------------------------------------ 248 FragmentLight()249 FragmentLight::FragmentLight() 250 : globalAmbientR( 0 ), 251 globalAmbientG( 0 ), 252 globalAmbientB( 0 ), 253 layerConfig( PICA_DATA_FRAG_LIGHT_ENV_LAYER_CONFIG0 ), 254 fresnelSelector( PICA_DATA_FRAG_LIGHT_ENV_NO_FRESNEL ), 255 shadowSelector( PICA_DATA_FRAG_LIGHT_ENV_TEXTURE0 ), 256 bumpMode( PICA_DATA_FRAG_LIGHT_ENV_BUMP_NOT_USED_DMP ), 257 bumpSelector( PICA_DATA_FRAG_LIGHT_ENV_TEXTURE0 ), 258 isEnableShadowPrimary( false ), 259 isEnableShadowSecondary( false ), 260 isEnableShadowAlpha( false ), 261 isInvertShadow( false ), 262 isEnableBumpRenorm( false ), 263 isEnableClampHighLights( true ), 264 isEnableLutD0( false ), 265 isEnableLutD1( false ), 266 isEnableLutRefl( true ) 267 { 268 for ( int i = 0; i < LIGHT_SOURCE_MAX; ++i ) 269 { 270 isEnable[ i ] = false; 271 isEnableSpot[ i ] = false; 272 isEnableDistAttn[ i ] = false; 273 isShadowed[ i ] = false; 274 source[ i ].id = i; 275 } 276 } 277 278 //------------------------------------------------------------------------------ 279 LutConfig()280 FragmentLight::LutConfig::LutConfig() 281 : input( PICA_DATA_FRAG_LIGHT_ENV_NH_DMP ), 282 isAbs( false ), 283 scale( PICA_DATA_FRAG_LIGHT_ENV_LUTSCALE_1_0 ) 284 { 285 } 286 287 } // namespace CTR 288 } // namespace gr 289 } // namespace nn 290