/* ----------------------------------------------------------------------------- GSFramework Copyright 2001-2013 Emmanuel Julien. All Rights Reserved. ----------------------------------------------------------------------------- */ #ifndef __NLIGHT__ #define __NLIGHT__ #include "core/item.h" #include "core/render_data.h" #include "color/color.h" #include "geometry/frustum.h" #include "reflection/nenum_string.h" #include "memory/nauto_ptr.h" namespace GS { namespace Core { /*! @short Light. @author Emmanuel Julien (ejulien@gsworks.fr) */ class Light : public Item { public: /// struct RenderData { Render::sTexture projection_texture; struct ShadowRenderData { virtual ~ShadowRenderData() {} }; /// Shadow data. struct ShadowData { AutoPtr render_data; float slice_distance; Vector4 crop_region; Matrix4 imatrix, pmatrix; }; Array shadow_data; }; static Reflection::Property serializable[]; /// Light model. enum Model { Model_None = 0, Model_Point, Model_Linear, Model_Spot, Model_Last }; static Reflection::Enum::Dict model_dict[]; /// Light falloff. enum Falloff { Falloff_Linear = 0, ///< Linear. Falloff_InvDist, ///< Inverse distance. Falloff_InvDist2 ///< Inverse squared distance. }; static Reflection::Enum::Dict falloff_dict[]; /// Light shadow method. enum Shadow { Shadow_None = 0, Shadow_ProjectionMap, Shadow_Map }; static Reflection::Enum::Dict shadow_dict[]; Model model; Frustum frustum; /*! @name Shadow section. @{ */ Shadow shadow; bool shadow_cast_all; float shadow_range, shadow_bias, shadow_distribution, z_near; /// @} /*! @name Volumetric section. @{ */ bool volumetric; float volumetric_sample_step, volumetric_range, volumetric_thickness; /// @} /*! @name Light section. @{ */ Falloff falloff; float range, volume_range, ///< Volume range (mainly used as an optimization hint). clip_distance; Color diffuse_color, specular_color, shadow_color; float diffuse_intensity, specular_intensity, cone_angle, edge_angle; String projection_texture; ///< Projection texture. /// @} /// Set the spot cone and edge angles. void SetSpotAngle(float cone = Units::Deg(40), float edge = Units::Deg(10)) { cone_angle = cone; edge_angle = edge; } /// Sample lighting contributed by this light to a location in space. bool SampleColor(const Vector4 &p, const Vector4 &n, Color &diff, Color &spec, Vector4 *view = 0, float gloss = 0.8); /*! @short Sample energy this light contribute to a location in space. This function can sample both the diffuse and specular lightning contribution from a given light to a given position in space. You can specify whether the specular should be computed using accurate Phong model or using the halfway vector (faster/less accurate). You can ask that specular reflection be evaluated using the Cook-Torrance model by calling the function with the parameter 'cooktorrance' set to true. The default specular reflection uses the Phong model. @note The default specular model used is the halfway vector one. @note Sampling the specular contribution requires a view vector and a glossiness value. @return True if the light contribute to the surface. */ bool SampleEnergy(const Vector4 &p,const Vector4 &n, float *diff = 0, float *spec = 0, Vector4 *view = 0, float gloss = 0.8, bool halfway = false, bool cooktorrance = false); virtual void ComputeMatrix(); void ComputeProjectionMatrix(Matrix4 &m_) const; void ComputeFrustrum(Frustum &f, float z_near = -1, float z_far = -1) const; float GetNearClippingPlane() const { return z_near; } float GetFarClippingPlane() const { return volume_range; } void SetNearClippingPlane(float z) { z_near = z; } void SetFarClippingPlane(float z) { volume_range = z; } void RenderSetup(ResourceFactories * = 0); AutoPtr render_data; void SetDefaults(); bool FromMetaTag(NML::Tag &); NML::Tag *AsMetaTag(); Light(); }; typedef Light * pLight; } // Core } // GS #endif // __NLIGHT__