192 lines
4.2 KiB
C++
192 lines
4.2 KiB
C++
/* -----------------------------------------------------------------------------
|
|
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 <ShadowRenderData> render_data;
|
|
|
|
float slice_distance;
|
|
Vector4 crop_region;
|
|
|
|
Matrix4 imatrix, pmatrix;
|
|
};
|
|
|
|
Array <ShadowData> 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 <RenderData> render_data;
|
|
|
|
void SetDefaults();
|
|
|
|
bool FromMetaTag(NML::Tag &);
|
|
NML::Tag *AsMetaTag();
|
|
|
|
Light();
|
|
};
|
|
|
|
typedef Light * pLight;
|
|
|
|
} // Core
|
|
} // GS
|
|
|
|
|
|
#endif // __NLIGHT__
|