/ShevaEngine2/Modules/Graphics/ShadowMaps/DualParaboloidShadowMaps.cs
http://shevaengine.codeplex.com · C# · 157 lines · 95 code · 33 blank · 29 comment · 4 complexity · 074dbec9e506c8b47d54c5458dc542b1 MD5 · raw file
- using System;
- using System.Collections.Generic;
- using Microsoft.Xna.Framework;
- using Microsoft.Xna.Framework.Graphics;
- using ShevaEngine.Core.Modules.Graphics.Lights;
- using ShevaEngine.Core.Modules.Materials;
- using ShevaEngine.Core.Modules.Scenes;
-
- namespace ShevaEngine.Core.Modules.Graphics.ShadowMaps
- {
- /// <summary>
- /// Dual paraboloid shadow maps.
- /// </summary>
- public class DualParaboloidShadowMaps : ShadowMap
- {
- /// <summary>Shadow map.</summary>
- public RenderTarget2D ShadowMapTop;
- /// <summary>Shadow map.</summary>
- public RenderTarget2D ShadowMapBottom;
- /// <summary>Shadow map size.</summary>
- public Int32 ShadowMapSize;
- /// <summary>Light.</summary>
- public Light Light;
- /// <summary>Scene.</summary>
- public Scene Scene;
- /// <summary>Light camera.</summary>
- private Matrix LightViewCamera;
- /// <summary>Shadow map effect.</summary>
- private Effect ShadowMapEffect;
- /// <summary>Last draw call.</summary>
- private DrawCallKey LastDrawCallKey;
- /// <summary>Initial draw call.</summary>
- private DrawCallKey InitialDrawCallKey;
-
- /// <summary>
- /// Constructor.
- /// </summary>
- public DualParaboloidShadowMaps(Light light, Scene scene)
- {
- this.ShadowMapSize = 512;
-
- this.ShadowMapTop = new RenderTarget2D(ShevaEngine.Instance.GraphicsDevice,
- ShadowMapSize, ShadowMapSize, false, SurfaceFormat.Single, DepthFormat.Depth24Stencil8);
- this.ShadowMapBottom = new RenderTarget2D(ShevaEngine.Instance.GraphicsDevice,
- ShadowMapSize, ShadowMapSize, false, SurfaceFormat.Single, DepthFormat.Depth24Stencil8);
-
- this.Light = light;
- this.Scene = scene;
-
- this.ShadowMapEffect = MaterialManager.Instance.GetEffect("DualParaboloidSM");
-
- this.InitialDrawCallKey = new DrawCallKey(
- UInt16.MaxValue, UInt16.MaxValue, UInt16.MaxValue, UInt16.MaxValue);
- }
-
-
- /// <summary>
- /// Method creates shadow map.
- /// </summary>
- public override void CreateShadowMap()
- {
- ShevaEngine.Instance.GraphicsDevice.SetRenderTarget(this.ShadowMapTop);
-
- ShevaEngine.Instance.GraphicsDevice.Clear(ClearOptions.DepthBuffer | ClearOptions.Target, Color.White, 1.0f, 1);
-
- ShevaEngine.Instance.GraphicsDevice.BlendState = BlendState.Opaque;
- //GraphicsEngine.Instance.GraphicsDevice.RenderState.AlphaBlendEnable = false;
-
- DepthStencilState depthStencilState = new DepthStencilState();
- depthStencilState.DepthBufferEnable = true;
- depthStencilState.DepthBufferWriteEnable = true;
- depthStencilState.DepthBufferFunction = CompareFunction.Less;
- ShevaEngine.Instance.GraphicsDevice.DepthStencilState = depthStencilState;
-
- {
- RasterizerState rasterizerState = new RasterizerState();
- rasterizerState.CullMode = CullMode.CullCounterClockwiseFace;
- ShevaEngine.Instance.GraphicsDevice.RasterizerState = rasterizerState;
- }
-
- RenderingPipeline pipeline = this.Scene.GetRenderingPipeline(this.LightViewCamera);
-
- this.LightViewCamera = Matrix.CreateLookAt(
- this.Light.World.Translation, this.Light.World.Translation - new Vector3(0, 1, 0), Vector3.UnitZ);
-
- this.ShadowMapEffect.Parameters["ShadowMapFarPlane"].SetValue(this.Light.Radius);
- this.ShadowMapEffect.Parameters["View"].SetValue(this.LightViewCamera);
-
- this.ShadowMapEffect.Parameters["ShadowMapDirection"].SetValue(1.0f);
-
- this.ShadowMapEffect.CurrentTechnique.Passes[0].Apply();
-
- this.RenderPipeline(pipeline);
-
- ShevaEngine.Instance.GraphicsDevice.SetRenderTarget(this.ShadowMapBottom);
-
- ShevaEngine.Instance.GraphicsDevice.Clear(ClearOptions.DepthBuffer | ClearOptions.Target, Color.White, 1.0f, 1);
-
- {
- RasterizerState rasterizerState = new RasterizerState();
- rasterizerState.CullMode = CullMode.CullClockwiseFace;
- ShevaEngine.Instance.GraphicsDevice.RasterizerState = rasterizerState;
- }
-
- this.ShadowMapEffect.Parameters["ShadowMapDirection"].SetValue(-1.0f);
-
- this.RenderPipeline(pipeline);
-
- ShevaEngine.Instance.GraphicsDevice.SetRenderTarget(null);
- }
-
- /// <summary>
- /// Render pipeline method.
- /// </summary>
- private void RenderPipeline(RenderingPipeline pipeline)
- {
- this.LastDrawCallKey = this.InitialDrawCallKey;
-
- foreach (KeyValuePair<DrawCallKey, List<DrawCallPipeline>> item in pipeline.OpaqueObjects)
- {
- if (item.Key.TextureState != this.LastDrawCallKey.TextureState)
- {
- TextureState textureState = TextureManager.Instance[item.Key.TextureState];
-
- //if (textureState.ContainsKey("Diffuse"))
- // this.ShadowMapEffect.Parameters["Diffuse"].SetValue(textureState["Diffuse"]);
- }
-
- this.Scene.GraphicsBuffersManager.SetBuffers(item.Key.BuffersID);
-
- this.RenderDrawCalls(item.Value);
- }
- }
-
- /// <summary>
- /// Method renders draw call.
- /// </summary>
- /// <param name="drawCall"></param>
- /// <param name="worldMatrices"></param>
- private void RenderDrawCalls(List<DrawCallPipeline> pipeline)
- {
- for (int drawCallIndex = 0; drawCallIndex < pipeline.Count; drawCallIndex++)
- {
- int matricesCount = pipeline[drawCallIndex].WorldMatrices.Count;
-
- for (int i = 0; i < matricesCount; i++)
- {
- this.ShadowMapEffect.Parameters["World"].SetValue(pipeline[drawCallIndex].WorldMatrices[i]);
-
- this.ShadowMapEffect.CurrentTechnique.Passes[0].Apply();
-
- pipeline[drawCallIndex].DrawCall.Render();
- }
- }
- }
- }
- }