#ifndef _ShadowMap_H__ #define _ShadowMap_H__ #include "common.h" #include "AxisAlignedBox3.h" #include "Matrix4x4.h" namespace CHCDemoEngine { class FrameBufferObject; class RenderTraverser; class Vector3; class PerspectiveCamera; class DirectionalLight; /** This class implements a the computation of single shadow map using LispSM (light space perspective shadow mapping) */ class ShadowMap { public: /** Constructor taking the scene boundig box and the current camera. The shadow map has resolution size squared. */ ShadowMap(DirectionalLight *light, int size, const AxisAlignedBox3 &sceneBox, PerspectiveCamera *cam); ~ShadowMap(); /** Computes the shadow map */ void ComputeShadowMap(RenderTraverser *traverser, const Matrix4x4 &projView); /** Returns computed shadow color texture. */ unsigned int GetShadowColorTexture() const; /** Returns the depth texture used for shadow comparison. */ unsigned int GetDepthTexture() const; /** Returns computed texture matrix. It must be applied on the the world space positions. The texture matrix can be directly applied if the world space position is available (deferred shading), otherwise it must be multiplied with the inverse model matrix. */ void GetTextureMatrix(Matrix4x4 &m) const; /** Return shadow size. */ int GetSize() const { return mSize; } /** Returns the camera used for light view rendering. */ PerspectiveCamera *GetShadowCamera() const { return mShadowCam; } /** Renders the scene from shadow view using conventional shading. */ void RenderShadowView(RenderTraverser *renderer, const Matrix4x4 &projView); /** Draws LispSM intersection body B and the used light frustrum */ static void VisualizeFrustra(); protected: /** Calculates the intersection of the frustum with the box, returns resultin polyhedron as array of polygons. */ Polyhedron *CalcClippedFrustum(const AxisAlignedBox3 &box) const; bool CalcLightProjection(Matrix4x4 &lightProj); Matrix4x4 CalcLispSMTransform(const Matrix4x4 &lightProjView, const AxisAlignedBox3 &bounds, const VertexArray &pts); void IncludeLightVolume(const Polyhedron &polyhedron, VertexArray &frustumPoints, const Vector3 lightDir, const AxisAlignedBox3 &sceneBox); float ComputeN(const AxisAlignedBox3 &extremalPoints) const; float ComputeNOpt(const Matrix4x4 &lightSpace, const AxisAlignedBox3 &extremalPoints, const VertexArray &body) const; Vector3 GetNearCameraPointE(const VertexArray &pts) const; Vector3 GetProjViewDir(const Matrix4x4 &lightSpace, const VertexArray &pts) const; /** Internal shador render method. */ void _Render(RenderTraverser *renderer); Vector3 GetLightSpaceZ0(const Matrix4x4 &lightSpace, const Vector3 &e, const float maxZ, const Vector3 &eyeDir) const; ////////////// /// the scene bounding box AxisAlignedBox3 mSceneBox; /// fbo storing the shadow texture FrameBufferObject *mFbo; /// size of the shadow map int mSize; /// the shadow view PerspectiveCamera *mShadowCam; /// the texture matrix Matrix4x4 mTextureMatrix; /// the used light DirectionalLight *mLight; /// the scene camera PerspectiveCamera *mCamera; Matrix4x4 mLightProjView; }; } // namespace #endif // _ShadowMapping_H__