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: 26237 $ 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(u32 * command) const25 u32* FragmentLight::Source::MakeCommand( u32* command ) const 26 { 27 u32 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(u32 * command) const79 u32* FragmentLight::MakeLutConfigCommand( u32* 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(u32 * command) const119 u32* FragmentLight::MakeLightEnvCommand( u32* command ) const 120 { 121 u32 regLightEnable = 0xff00ffff; 122 u32 regLightEnableEach = 0; 123 s32 count = 0; 124 125 regLightEnable |= PICA_CMD_DATA_FRAG_LIGHT_FUNC_MODE1_LUT( 126 isEnableLutD0, 127 isEnableLutD1, 128 fresnelSelector, 129 isEnableLutRef1 ); 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 *command++ = PICA_CMD_DATA_FRAG_LIGHT_EN( count ); 155 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_FRAG_LIGHT_EN0 ); 156 157 // 0x1c0 グローバルアンビエントの設定 158 *command++ = globalAmbientB | globalAmbientG << 10 | globalAmbientR << 20; 159 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_FRAG_LIGHT_AMBIENT ); 160 161 // 0x1c2 光源数の設定 162 *command++ = PICA_CMD_DATA_FRAG_LIGHT_NUM( count ); 163 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_FRAG_LIGHT_SRC_NUM ); 164 165 // 0x1c3 166 *command++ = PICA_CMD_DATA_FRAG_LIGHT_FUNC_MODE0( 167 fresnelSelector, 168 layerConfig, 169 isEnableShadowPrimary, 170 isEnableShadowSecondary, 171 isInvertShadow, 172 isEnableShadowAlpha, 173 bumpSelector, 174 shadowSelector, 175 isEnableClampHighLights, 176 bumpMode, 177 isEnableBumpRenorm ); 178 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_FRAG_LIGHT_FUNC_MODE0 ); 179 180 // 0x1c4 181 *command++ = regLightEnable; 182 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_FRAG_LIGHT_FUNC_MODE1 ); 183 184 // 0x1c6 ライトの有効無効を設定 185 *command++ = PICA_CMD_DATA_FRAG_LIGHT_EN_INV( count ); 186 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_FRAG_LIGHT_EN1 ); 187 188 // 0x1d9 189 *command++ = regLightEnableEach; 190 *command++ = PICA_CMD_HEADER_SINGLE( PICA_REG_FRAG_LIGHT_SRC_EN_ID ); 191 return command; 192 } 193 194 //------------------------------------------------------------------------------ 195 MakeLightSourceCommand(u32 * command) const196 u32* FragmentLight::MakeLightSourceCommand( u32* command ) const 197 { 198 // 各光源ごとの設定 199 for ( int i = 0; i < LIGHT_SOURCE_MAX; ++i ) 200 { 201 if ( isEnable[ i ] == false ) continue; 202 203 command = source[ i ].MakeCommand( command ); 204 } 205 206 return command; 207 } 208 209 //------------------------------------------------------------------------------ 210 MakeAllCommand(u32 * command) const211 u32* FragmentLight::MakeAllCommand( u32* command ) const 212 { 213 #if defined( NN_GR_FRAGMENT_LIGHT_DUMP ) // デバッグ用 214 u32 * start = command; 215 #endif 216 217 command = MakeLutConfigCommand( command ); 218 219 command = MakeLightEnvCommand( command ); 220 221 command = MakeLightSourceCommand( command ); 222 223 224 #if defined( NN_GR_FRAGMENT_LIGHT_DUMP ) // デバッグ用 225 static int a = 0; 226 if ( ++a == 10 ) 227 { 228 for ( u32* i = start; i != command; i +=2 ) 229 { 230 NN_LOG( "0x%08x 0x%08x\n", *i, *(i+1) ); 231 } 232 } 233 #endif 234 235 return command; 236 } 237 238 //------------------------------------------------------------------------------ 239 FragmentLight()240 FragmentLight::FragmentLight() 241 : globalAmbientR( 0 ), 242 globalAmbientG( 0 ), 243 globalAmbientB( 0 ), 244 layerConfig( PICA_DATA_FRAG_LIGHT_ENV_LAYER_CONFIG0 ), 245 fresnelSelector( PICA_DATA_FRAG_LIGHT_ENV_NO_FRESNEL ), 246 shadowSelector( PICA_DATA_FRAG_LIGHT_ENV_TEXTURE0 ), 247 bumpMode( PICA_DATA_FRAG_LIGHT_ENV_BUMP_NOT_USED_DMP ), 248 bumpSelector( PICA_DATA_FRAG_LIGHT_ENV_TEXTURE0 ), 249 isEnableShadowPrimary( false ), 250 isEnableShadowSecondary( false ), 251 isEnableShadowAlpha( false ), 252 isInvertShadow( false ), 253 isEnableBumpRenorm( false ), 254 isEnableClampHighLights( true ), 255 isEnableLutD0( false ), 256 isEnableLutD1( false ), 257 isEnableLutRef1( true ) 258 { 259 for ( int i = 0; i < LIGHT_SOURCE_MAX; ++i ) 260 { 261 isEnable[ i ] = false; 262 isEnableSpot[ i ] = false; 263 isEnableDistAttn[ i ] = false; 264 isShadowed[ i ] = false; 265 source[ i ].id = i; 266 } 267 } 268 269 //------------------------------------------------------------------------------ 270 LutConfig()271 FragmentLight::LutConfig::LutConfig() 272 : input( PICA_DATA_FRAG_LIGHT_ENV_NH_DMP ), 273 isAbs( false ), 274 scale( PICA_DATA_FRAG_LIGHT_ENV_LUTSCALE_1_0 ) 275 { 276 } 277 278 } // namespace CTR 279 } // namespace gr 280 } // namespace nn 281