/*---------------------------------------------------------------------------* Project: NintendoWare File: gfx_ResLight.h Copyright (C)2009-2010 Nintendo Co., Ltd./HAL Laboratory, Inc. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. $Revision: 19456 $ *---------------------------------------------------------------------------*/ #ifndef NW_GFX_RESLIGHT_H_ #define NW_GFX_RESLIGHT_H_ #include #include #include #include #include #include namespace nw { namespace gfx { namespace res { class ResGraphicsFile; //! @details :private struct ResLightData : public ResTransformNodeData { nw::ut::ResBool m_IsLightEnabled; u8 padding_[3]; }; //! @details :private struct ResFragmentLightData : public ResLightData { enum Flag { FLAG_TWO_SIDE_DIFFUSE_ENABLED_SHIFT = ResTransformNode::FLAG_SHIFT_MAX, FLAG_DISTANCE_ATTENUATION_ENABLED_SHIFT, FLAG_INHERITING_DIRECTION_ROTATE_SHIFT, FLAG_SHIFT_MAX, FLAG_TWO_SIDE_DIFFUSE_ENABLED = 0x1 << FLAG_TWO_SIDE_DIFFUSE_ENABLED_SHIFT, FLAG_DISTANCE_ATTENUATION_ENABLED = 0x1 << FLAG_DISTANCE_ATTENUATION_ENABLED_SHIFT, FLAG_IS_INHERITING_DIRECTION_ROTATE = 0x1 << FLAG_INHERITING_DIRECTION_ROTATE_SHIFT }; nw::ut::ResS32 m_LightKind; nw::ut::ResFloatColor m_Ambient; nw::ut::ResFloatColor m_Diffuse; nw::ut::ResFloatColor m_Specular0; nw::ut::ResFloatColor m_Specular1; nw::ut::ResU32 m_AmbientU32; nw::ut::ResU32 m_DiffuseU32; nw::ut::ResU32 m_Specular0U32; nw::ut::ResU32 m_Specular1U32; nw::ut::ResVec3 m_Direction; nw::ut::Offset toDistanceSampler; nw::ut::Offset toAngleSampler; nw::ut::ResF32 m_DistanceAttenuationStart; // アニメーション書き込み用バッファ nw::ut::ResF32 m_DistanceAttenuationEnd; // アニメーション書き込み用バッファ nw::ut::ResU32 m_DistanceAttenuationScale; nw::ut::ResU32 m_DistanceAttenuationBias; nw::ut::ResBool m_IsDirty; u8 padding_[3]; }; //! @details :private struct ResAmbientLightData : public ResLightData { nw::ut::ResFloatColor m_Ambient; nw::ut::ResU32 m_AmbientU32; nw::ut::ResBool m_IsDirty; u8 padding_[3]; }; //! @details :private struct ResVertexLightData : public ResLightData { enum Flag { FLAG_INHERITING_DIRECTION_ROTATE_SHIFT = ResTransformNode::FLAG_SHIFT_MAX, FLAG_SHIFT_MAX, FLAG_IS_INHERITING_DIRECTION_ROTATE = 0x1 << FLAG_INHERITING_DIRECTION_ROTATE_SHIFT }; nw::ut::ResS32 m_LightKind; nw::ut::ResFloatColor m_Ambient; nw::ut::ResFloatColor m_Diffuse; nw::ut::ResVec3 m_Direction; nw::ut::ResVec3 m_DistanceAttenuation; nw::ut::ResF32 m_IsDistanceAttenuationEnabled; nw::ut::ResVec2 m_SpotFactor; }; //! @details :private struct ResHemiSphereLightData : public ResLightData { enum Flag { FLAG_INHERITING_DIRECTION_ROTATE_SHIFT = ResTransformNode::FLAG_SHIFT_MAX, FLAG_SHIFT_MAX, FLAG_IS_INHERITING_DIRECTION_ROTATE = 0x1 << FLAG_INHERITING_DIRECTION_ROTATE_SHIFT }; nw::ut::ResFloatColor m_GroundColor; nw::ut::ResFloatColor m_SkyColor; nw::ut::ResVec3 m_Direction; nw::ut::ResF32 m_LerpFactor; }; //-------------------------------------------------------------------------- //! @brief ライトを表すバイナリリソースの基底クラスです。 //--------------------------------------------------------------------------- class ResLight : public ResTransformNode { public: enum { BINARY_REVISION = REVISION_RES_LIGHT }; //! @brief ライトの光源の種類です。 enum Kind { KIND_DIRECTIONAL, //!< ディレクショナルライトです。 KIND_POINT, //!< ポイントライトです。 KIND_SPOT, //!< スポットライトです。 KIND_UNUSED, //!< 光源の種類を考慮しないライトです。 KIND_COUNT //!< enum の最大値です。 }; NW_RES_CTOR_INHERIT( ResLight, ResTransformNode ) //--------------------------------------------------------------------------- //! @fn void SetLightEnabled(bool value) //! @brief ライトの有効フラグを設定します。 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //! @fn bool IsLightEnabled() const //! @brief ライトの有効フラグを取得します。 //--------------------------------------------------------------------------- NW_RES_FIELD_BOOL_PRIMITIVE_DECL( LightEnabled ) // IsLightEnabled(), SetLightEnabled() //--------------------------------------------------------------------------- //! @brief リビジョンを取得します。 //! //! @return リソースのリビジョン情報です。 //--------------------------------------------------------------------------- u32 GetRevision() const { return this->GetHeader().revision; } //--------------------------------------------------------------------------- //! @brief リソースのセットアップをおこないます。 //! //! @param[in] allocator アロケータです。 //! @param[in] graphicsFile グラフィックスリソースです。 //--------------------------------------------------------------------------- Result Setup(os::IAllocator* allocator, ResGraphicsFile graphicsFile); //--------------------------------------------------------------------------- //! @brief リソースの後始末をおこないます。 //--------------------------------------------------------------------------- void Cleanup(); }; typedef nw::ut::ResArrayPatricia::type ResLightArray; //-------------------------------------------------------------------------- //! @brief フラグメントライトを表すバイナリリソースクラスです。 //--------------------------------------------------------------------------- class ResFragmentLight : public ResLight { public: enum { TYPE_INFO = NW_GFX_RES_TYPE_INFO(ResFragmentLight) }; enum { SIGNATURE = NW_RES_SIGNATURE32('CFLT') }; NW_RES_CTOR_INHERIT( ResFragmentLight, ResLight ) //--------------------------------------------------------------------------- //! @fn void SetSpecular1(f32 r, f32 g, f32 b) //! @brief ライトのスペキュラカラー1を設定します。 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //! @fn void SetSpecular0(f32 r, f32 g, f32 b) //! @brief ライトのスペキュラカラー0を設定します。 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //! @fn void SetLightKind(s32 value) //! @brief 光源の種類を設定します。 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //! @fn void SetDirty(bool value) //! @brief ライトの内容が更新されているかどうかのフラグを設定します。 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //! @fn void SetDirection(f32 x, f32 y, f32 z) //! @brief ライトの方向を設定します。 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //! @fn void SetDiffuse(f32 r, f32 g, f32 b) //! @brief ライトのディフューズカラーを設定します。 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //! @fn void SetAmbient(f32 r, f32 g, f32 b) //! @brief ライトのアンビエントカラーを設定します。 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //! @fn bool IsDirty() const //! @brief ライトの内容が更新されているかどうかのフラグを取得します。 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //! @fn u32 GetSpecular1U32() const //! @brief ライトのスペキュラカラー1を RGBA8 の32bitフォーマットで取得します。 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //! @fn const nw::ut::FloatColor & GetSpecular1() const //! @brief ライトのスペキュラカラー1を取得します。 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //! @fn u32 GetSpecular0U32() const //! @brief ライトのスペキュラカラー0を RGBA8 の32bitフォーマットで取得します。 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //! @fn const nw::ut::FloatColor & GetSpecular0() const //! @brief ライトのスペキュラカラー0を取得します。 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //! @fn s32 GetLightKind() const //! @brief 光源の種類を取得します。 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //! @fn ResLookupTable GetDistanceSampler() //! @brief 距離減衰用のルックアップテーブルを取得します。 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //! @fn const nw::math::VEC3 & GetDirection() const //! @brief ライトの方向を取得します。 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //! @fn u32 GetDiffuseU32() const //! @brief ライトのディフューズカラーを RGBA8 の32bitフォーマットで取得します。 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //! @fn const nw::ut::FloatColor & GetDiffuse() const //! @brief ライトのディフューズカラーを取得します。 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //! @fn ResLightingLookupTable GetAngleSampler() //! @brief 角度減衰用のルックアップテーブルを取得します。 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //! @fn u32 GetAmbientU32() const //! @brief ライトのアンビエントカラーを RGBA8 の32bitフォーマットで取得します。 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //! @fn const nw::ut::FloatColor & GetAmbient() const //! @brief ライトのアンビエントカラーを取得します。 //--------------------------------------------------------------------------- NW_RES_FIELD_PRIMITIVE_DECL( s32, LightKind ) // GetLightKind(), SetLightKind() NW_RES_FIELD_FLOAT_U32_COLOR_DECL( nw::ut::FloatColor, Ambient ) // const FloatColor& GetAmbient() NW_RES_FIELD_FLOAT_U32_COLOR_DECL( nw::ut::FloatColor, Diffuse ) // const FloatColor& GetDiffuse() NW_RES_FIELD_FLOAT_U32_COLOR_DECL( nw::ut::FloatColor, Specular0 ) // const FloatColor& GetSpecular0() NW_RES_FIELD_FLOAT_U32_COLOR_DECL( nw::ut::FloatColor, Specular1 ) // const FloatColor& GetSpecular1() NW_RES_FIELD_VECTOR3_DECL( nw::math::VEC3, Direction ) // VEC3& GetDirection() NW_RES_FIELD_CLASS_DECL( ResLookupTable, DistanceSampler ) // GetDistanceSampler() NW_RES_FIELD_CLASS_DECL( ResLightingLookupTable, AngleSampler ) // GetAngleSampler() //--------------------------------------------------------------------------- //! @brief 参照テーブルを設定します。 //! 参照先に設定しますのでリソースの解放はされません。 //! //! @param[in] 参照テーブルです。 //--------------------------------------------------------------------------- void SetDistanceSampler(ResImageLookupTable lookupTable) { NW_ASSERT(lookupTable.IsValid()); ResReferenceLookupTable referenceLut = ResStaticCast(GetDistanceSampler()); referenceLut.ref().toTargetLut.set_ptr(lookupTable.ptr()); } //-------------------------------------------------------------------------- //! @brief 距離減衰の開始距離を取得します。 //! //! @return 距離減衰の開始距離設定です。 //--------------------------------------------------------------------------- f32 GetDistanceAttenuationStart() const { return ref().m_DistanceAttenuationStart; } //-------------------------------------------------------------------------- //! @brief 距離減衰の終了距離を取得します。 //! //! @return 距離減衰の終了距離設定です。 //--------------------------------------------------------------------------- f32 GetDistanceAttenuationEnd() const { return ref().m_DistanceAttenuationEnd; } //-------------------------------------------------------------------------- //! @brief 距離減衰の開始距離を設定します。 //--------------------------------------------------------------------------- void SetDistanceAttenuationStart(f32 start) { ref().m_DistanceAttenuationStart = start; SetDistanceAttenuation(ref().m_DistanceAttenuationStart, ref().m_DistanceAttenuationEnd); } //-------------------------------------------------------------------------- //! @brief 距離減衰の終了距離を設定します。 //--------------------------------------------------------------------------- void SetDistanceAttenuationEnd(f32 end) { ref().m_DistanceAttenuationEnd = end; SetDistanceAttenuation(ref().m_DistanceAttenuationStart, ref().m_DistanceAttenuationEnd); } //-------------------------------------------------------------------------- //! @brief 距離減衰の開始、終了パラメータを設定します。 //! //! @param[in] start 減衰開始距離です。 //! @param[in] end 減衰終了距離です。 //--------------------------------------------------------------------------- void SetDistanceAttenuation(f32 start, f32 end) { f32 diff = end - start; f32 minimumDistance = 0.01f; if (math::FAbs(diff) < minimumDistance) { diff = minimumDistance; } ref().m_DistanceAttenuationScale = ut::Float20::Float32ToBits20(1.0f / diff); ref().m_DistanceAttenuationBias = ut::Float20::Float32ToBits20(-start / diff); } NW_RES_FIELD_BOOL_PRIMITIVE_DECL( Dirty ) // IsDirty(), SetDirty() }; //-------------------------------------------------------------------------- //! @brief グローバルアンビエントライトを表すバイナリリソースクラスです。 //--------------------------------------------------------------------------- class ResAmbientLight : public ResLight { public: enum { TYPE_INFO = NW_GFX_RES_TYPE_INFO(ResAmbientLight) }; enum { SIGNATURE = NW_RES_SIGNATURE32('CALT') }; NW_RES_CTOR_INHERIT( ResAmbientLight, ResLight ) //--------------------------------------------------------------------------- //! @fn void SetAmbient(f32 r, f32 g, f32 b) //! @brief ライトのアンビエントカラーを設定します。 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //! @fn u32 GetAmbientU32() const //! @brief ライトのアンビエントカラーを RGBA8 の32bitフォーマットで取得します。 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //! @fn const nw::ut::FloatColor & GetAmbient() const //! @brief ライトのアンビエントカラーを取得します。 //--------------------------------------------------------------------------- NW_RES_FIELD_FLOAT_U32_COLOR_DECL( nw::ut::FloatColor, Ambient ) // FloatColor& GetAmbient() }; //-------------------------------------------------------------------------- //! @brief 頂点ライトを表すバイナリリソースクラスです。 //--------------------------------------------------------------------------- class ResVertexLight : public ResLight { public: enum { TYPE_INFO = NW_GFX_RES_TYPE_INFO(ResVertexLight) }; enum { SIGNATURE = NW_RES_SIGNATURE32('CVLT') }; NW_RES_CTOR_INHERIT( ResVertexLight, ResLight ) //--------------------------------------------------------------------------- //! @fn void SetSpotFactor(f32 x, f32 y) //! @brief スポットライトの角度減衰係数を設定します。 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //! @fn void SetLightKind(s32 value) //! @brief 光源の種類を設定します。 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //! @fn void SetDistanceAttenuation(f32 x, f32 y, f32 z) //! @brief 距離減衰のパラメータを設定します。 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //! @fn void SetDirection(f32 x, f32 y, f32 z) //! @brief ライトの方向を設定します。 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //! @fn void SetDiffuse(f32 r, f32 g, f32 b) //! @brief ライトのディフューズカラーを設定します。 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //! @fn void SetAmbient(f32 r, f32 g, f32 b) //! @brief ライトのアンビエントカラーを設定します。 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //! @fn const nw::math::VEC2 & GetSpotFactor() const //! @brief スポットライトの角度減衰係数を取得します。 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //! @fn s32 GetLightKind() const //! @brief 光源の種類を取得します。 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //! @fn const nw::math::VEC3 & GetDistanceAttenuation() const //! @brief 距離減衰のパラメータを取得します。 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //! @fn const nw::math::VEC3 & GetDirection() const //! @brief ライトの方向を取得します。 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //! @fn const nw::ut::FloatColor & GetDiffuse() const //! @brief ライトのディフューズカラーを取得します。 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //! @fn const nw::ut::FloatColor & GetAmbient() const //! @brief ライトのアンビエントカラーを取得します。 //--------------------------------------------------------------------------- NW_RES_FIELD_PRIMITIVE_DECL( s32, LightKind ) // GetLightLind(), SetLightKind() NW_RES_FIELD_FLOAT_COLOR_DECL( nw::ut::FloatColor, Ambient ) // const FloatColor& GetAmbient() NW_RES_FIELD_FLOAT_COLOR_DECL( nw::ut::FloatColor, Diffuse ) // const FloatColor& GetDiffuse() NW_RES_FIELD_VECTOR3_DECL( nw::math::VEC3, Direction ) // VEC3& GetDirection() NW_RES_FIELD_VECTOR3_DECL( nw::math::VEC3, DistanceAttenuation ) // VEC3& GetDistanceAttenuation() NW_RES_FIELD_VECTOR2_DECL( nw::math::VEC2, SpotFactor ) // VEC2& GetSpotFactor() //--------------------------------------------------------------------------- //! @brief 距離減衰が有効かどうかを取得します。 //! //! @return 距離減衰が有効であれば true を返します。 //--------------------------------------------------------------------------- bool IsDistanceAttenuationEnabled() const { return ref().m_IsDistanceAttenuationEnabled != 0.0f; } //--------------------------------------------------------------------------- //! @brief 距離減衰が有効かどうかを設定します。 //! //! @param[in] enable 距離減衰を有効にするためには true を指定します。 //--------------------------------------------------------------------------- void SetDistanceAttenuationEnabled(bool enable) { ref().m_IsDistanceAttenuationEnabled = enable ? 1.0f : 0.0f; } //--------------------------------------------------------------------------- //! @brief DistanceAttenuation と IsDistanceAttenuationEnabled を VEC4 として取得します。 //! //! @return w 値に IsDistanceAttenuationEnabled が格納された 4 要素のベクトルです。 //--------------------------------------------------------------------------- math::VEC4& GetDistanceAttenuationAndEnabled() { return reinterpret_cast( ref().m_DistanceAttenuation ); } //--------------------------------------------------------------------------- //! @brief Direction と IsDistanceAttenuationEnabled を VEC4 として取得します。 //! //! @return w 値に IsDistanceAttenuationEnabled が格納された 4 要素のベクトルです。 //--------------------------------------------------------------------------- const math::VEC4& GetDistanceAttenuationAndEnabled() const { return reinterpret_cast( ref().m_DistanceAttenuation ); } }; //-------------------------------------------------------------------------- //! @brief 半球ライトを表すバイナリリソースクラスです。 //--------------------------------------------------------------------------- class ResHemiSphereLight : public ResLight { public: enum { TYPE_INFO = NW_GFX_RES_TYPE_INFO(ResHemiSphereLight) }; enum { SIGNATURE = NW_RES_SIGNATURE32('CHLT') }; NW_RES_CTOR_INHERIT( ResHemiSphereLight, ResLight ) //--------------------------------------------------------------------------- //! @fn void SetSkyColor(f32 r, f32 g, f32 b) //! @brief 空の色を設定します。 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //! @fn void SetLerpFactor(f32 value) //! @brief 線形補間係数を設定します。 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //! @fn void SetGroundColor(f32 r, f32 g, f32 b) //! @brief 地面の色を設定します。 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //! @fn void SetDirection(f32 x, f32 y, f32 z) //! @brief ライトの方向を設定します。 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //! @fn const nw::ut::FloatColor & GetSkyColor() const //! @brief 空の色を取得します。 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //! @fn f32 GetLerpFactor() const //! @brief 線形補間係数を取得します。 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //! @fn const nw::ut::FloatColor & GetGroundColor() const //! @brief 地面の色を取得します。 //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- //! @fn const nw::math::VEC3 & GetDirection() const //! @brief ライトの方向を取得します。 //--------------------------------------------------------------------------- NW_RES_FIELD_FLOAT_COLOR_DECL( nw::ut::FloatColor, GroundColor ) // FloatColor& GetGroundColor() NW_RES_FIELD_FLOAT_COLOR_DECL( nw::ut::FloatColor, SkyColor ) // FloatColor& GetSkyColor() NW_RES_FIELD_VECTOR3_DECL( nw::math::VEC3, Direction ) // VEC3& GetDirection() NW_RES_FIELD_PRIMITIVE_DECL( f32, LerpFactor ) // GetLerpFactor(), SetLerpFactor() //--------------------------------------------------------------------------- //! @brief Direction と Lerp を VEC4 として取得します。 //! //! @return w 値に Lerp が格納された 4 要素のベクトルです。 //--------------------------------------------------------------------------- nw::math::VEC4& GetDirectionAndLerp() { return reinterpret_cast( ref().m_Direction ); } //--------------------------------------------------------------------------- //! @brief Direction と Lerp を VEC4 として取得します。 //! //! @return w 値に Lerp が格納された 4 要素のベクトルです。 //--------------------------------------------------------------------------- const nw::math::VEC4& GetDirectionAndLerp() const { return reinterpret_cast( ref().m_Direction ); } }; } // namespace res } // namespace gfx } // namespace nw #endif // NW_GFX_RESLIGHT_H_