Guest User

Untitled

a guest
Dec 18th, 2010
373
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using Microsoft.Xna.Framework;
  5. using Microsoft.Xna.Framework.Audio;
  6. using Microsoft.Xna.Framework.Content;
  7. using Microsoft.Xna.Framework.GamerServices;
  8. using Microsoft.Xna.Framework.Graphics;
  9. using Microsoft.Xna.Framework.Input;
  10. using Microsoft.Xna.Framework.Media;
  11.  
  12.  
  13. namespace DeferredLighting
  14. {
  15.     /// <summary>
  16.     /// This is a game component that implements IUpdateable.
  17.     /// </summary>
  18.     public class DeferredRenderer : DrawableGameComponent
  19.     {
  20.         private Camera camera;
  21.         private QuadRenderComponent quadRenderer;
  22.         private Scene scene;
  23.  
  24.         private RenderTarget2D colorRT; //color and specular intensity
  25.         private RenderTarget2D normalRT; //normals + specular power
  26.         private RenderTarget2D depthRT; //depth
  27.         private RenderTarget2D lightRT; //lighting
  28.  
  29.         private Effect clearBufferEffect;
  30.         private Effect directionalLightEffect;
  31.  
  32.         private Effect pointLightEffect;
  33.         private Model sphereModel; //point light volume
  34.  
  35.         private Effect finalCombineEffect;
  36.  
  37.         private SpriteBatch spriteBatch;
  38.  
  39.         private Vector2 halfPixel;
  40.  
  41.         public DeferredRenderer(Game game)
  42.             : base(game)
  43.         {
  44.             scene = new Scene(Game);
  45.         }
  46.  
  47.         /// <summary>
  48.         /// Allows the game component to perform any initialization it needs to before starting
  49.         /// to run.  This is where it can query for any required services and load content.
  50.         /// </summary>
  51.         public override void Initialize()
  52.         {
  53.             // TODO: Add your initialization code here
  54.  
  55.             base.Initialize();
  56.             camera = new Camera(Game);
  57.             quadRenderer = new QuadRenderComponent(Game);
  58.             Game.Components.Add(camera);
  59.             Game.Components.Add(quadRenderer);
  60.         }
  61.  
  62.         protected override void LoadContent()
  63.         {
  64.             scene.InitializeScene();
  65.  
  66.             spriteBatch = new SpriteBatch(GraphicsDevice);
  67.  
  68.             int backbufferWidth = GraphicsDevice.PresentationParameters.BackBufferWidth;
  69.             int backbufferHeight = GraphicsDevice.PresentationParameters.BackBufferHeight;
  70.  
  71.             colorRT = new RenderTarget2D(GraphicsDevice, backbufferWidth, backbufferHeight, false, SurfaceFormat.Color, DepthFormat.Depth24);
  72.             normalRT = new RenderTarget2D(GraphicsDevice, backbufferWidth, backbufferHeight, false, SurfaceFormat.Color, DepthFormat.None); //Depth needed?
  73.             depthRT = new RenderTarget2D(GraphicsDevice, backbufferWidth, backbufferHeight, false, SurfaceFormat.Color, DepthFormat.None); //Depth needed?
  74.             lightRT = new RenderTarget2D(GraphicsDevice, backbufferWidth, backbufferHeight, false, SurfaceFormat.Color, DepthFormat.None); //Depth needed?
  75.             //TODO: veranderen naar Single als het niet meer nodig is dat deze appart gezien wordt
  76.  
  77.             clearBufferEffect = Game.Content.Load<Effect>("ClearGBuffer");
  78.             directionalLightEffect = Game.Content.Load<Effect>("DirectionalLight");
  79.             pointLightEffect = Game.Content.Load<Effect>("PointLight");
  80.             sphereModel = Game.Content.Load<Model>(@"Models\sphere");
  81.             finalCombineEffect = Game.Content.Load<Effect>("CombineFinal");
  82.            
  83.             halfPixel = new Vector2()
  84.             {
  85.                 X = 0.5f / (float)GraphicsDevice.PresentationParameters.BackBufferWidth,
  86.                 Y = 0.5f / (float)GraphicsDevice.PresentationParameters.BackBufferHeight
  87.             };
  88.            
  89.             base.LoadContent();
  90.         }
  91.  
  92.         private void SetGBuffer()
  93.         {
  94.             GraphicsDevice.SetRenderTargets(colorRT, normalRT, depthRT);
  95.         }
  96.  
  97.         private void ResolveGBuffer()
  98.         {
  99.             GraphicsDevice.SetRenderTargets(null);
  100.         }
  101.  
  102.         private void ClearGBuffer()
  103.         {            
  104.             clearBufferEffect.Techniques[0].Passes[0].Apply();
  105.             quadRenderer.Render(Vector2.One * -1, Vector2.One);            
  106.         }
  107.  
  108.         private void DrawDirectionalLight(Vector3 lightDirection, Color color)
  109.         {
  110.             directionalLightEffect.Parameters["colorMap"].SetValue(colorRT);
  111.             directionalLightEffect.Parameters["normalMap"].SetValue(normalRT);
  112.             directionalLightEffect.Parameters["depthMap"].SetValue(depthRT);
  113.  
  114.             directionalLightEffect.Parameters["lightDirection"].SetValue(lightDirection);
  115.             directionalLightEffect.Parameters["Color"].SetValue(color.ToVector3());
  116.  
  117.             directionalLightEffect.Parameters["cameraPosition"].SetValue(camera.Position);
  118.             directionalLightEffect.Parameters["InvertViewProjection"].SetValue(Matrix.Invert(camera.View * camera.Projection));
  119.  
  120.             directionalLightEffect.Parameters["halfPixel"].SetValue(halfPixel);
  121.  
  122.             directionalLightEffect.Techniques[0].Passes[0].Apply();
  123.             quadRenderer.Render(Vector2.One * -1, Vector2.One);            
  124.         }
  125.  
  126.         private void DrawPointLight(Vector3 lightPosition, Color color, float lightRadius, float lightIntensity)
  127.         {
  128.             //set the G-Buffer parameters
  129.             pointLightEffect.Parameters["colorMap"].SetValue(colorRT);
  130.             pointLightEffect.Parameters["normalMap"].SetValue(normalRT);
  131.             pointLightEffect.Parameters["depthMap"].SetValue(depthRT);
  132.  
  133.             //compute the light world matrix
  134.             //scale according to light radius, and translate it to light position
  135.             Matrix sphereWorldMatrix = Matrix.CreateScale(lightRadius) * Matrix.CreateTranslation(lightPosition);
  136.             pointLightEffect.Parameters["World"].SetValue(sphereWorldMatrix);
  137.             pointLightEffect.Parameters["View"].SetValue(camera.View);
  138.             pointLightEffect.Parameters["Projection"].SetValue(camera.Projection);
  139.             //light position
  140.             pointLightEffect.Parameters["lightPosition"].SetValue(lightPosition);
  141.  
  142.             //set the color, radius and Intensity
  143.             pointLightEffect.Parameters["Color"].SetValue(color.ToVector3());
  144.             pointLightEffect.Parameters["lightRadius"].SetValue(lightRadius);
  145.             pointLightEffect.Parameters["lightIntensity"].SetValue(lightIntensity);
  146.  
  147.             //parameters for specular computations
  148.             pointLightEffect.Parameters["cameraPosition"].SetValue(camera.Position);
  149.             pointLightEffect.Parameters["InvertViewProjection"].SetValue(Matrix.Invert(camera.View * camera.Projection));
  150.             //size of a halfpixel, for texture coordinates alignment
  151.             pointLightEffect.Parameters["halfPixel"].SetValue(halfPixel);
  152.             //calculate the distance between the camera and light center
  153.             float cameraToCenter = Vector3.Distance(camera.Position, lightPosition);
  154.             //if we are inside the light volume, draw the sphere's inside face
  155.             if (cameraToCenter < lightRadius)
  156.                 GraphicsDevice.RasterizerState = RasterizerState.CullClockwise;                
  157.             else
  158.                 GraphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise;            
  159.            
  160.             foreach (ModelMesh mesh in sphereModel.Meshes)
  161.             {
  162.                 foreach (ModelMeshPart meshPart in mesh.MeshParts)
  163.                 {
  164.                     GraphicsDevice.Indices = meshPart.IndexBuffer;
  165.                     GraphicsDevice.SetVertexBuffer(meshPart.VertexBuffer);
  166.  
  167.                     pointLightEffect.Techniques[0].Passes[0].Apply();
  168.                     GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, meshPart.NumVertices, meshPart.StartIndex, meshPart.PrimitiveCount);
  169.                 }
  170.             }                        
  171.             GraphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise;
  172.         }
  173.  
  174.         public override void Draw(GameTime gameTime)
  175.         {
  176.             SetGBuffer();            
  177.             ClearGBuffer();
  178.             scene.DrawScene(camera, gameTime);
  179.             ResolveGBuffer();
  180.             DrawLights(gameTime);
  181.  
  182.             //For debugging show all rt's
  183.            
  184.             //int w = GraphicsDevice.PresentationParameters.BackBufferWidth / 2;
  185.             //int h = GraphicsDevice.PresentationParameters.BackBufferHeight / 2;            
  186.             //spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.Opaque);
  187.             //spriteBatch.Draw(colorRT, new Rectangle(0,0, w, h), Color.White);          
  188.             //spriteBatch.Draw(normalRT, new Rectangle(0, h, w, h), Color.White);            
  189.             //spriteBatch.Draw(depthRT, new Rectangle(w, 0, w, h), Color.White);
  190.             //spriteBatch.End();
  191.            
  192.             base.Draw(gameTime);
  193.         }
  194.  
  195.         private void DrawLights(GameTime gameTime)
  196.         {
  197.             GraphicsDevice.SetRenderTarget(lightRT);
  198.             GraphicsDevice.Clear(Color.Transparent);
  199.             GraphicsDevice.BlendState = BlendState.AlphaBlend;
  200.             GraphicsDevice.DepthStencilState = DepthStencilState.None;
  201.            
  202.             DrawDirectionalLight(new Vector3(0, -1f, 1), Color.DimGray);
  203.             DrawPointLight(new Vector3(50 * (float)Math.Sin(gameTime.TotalGameTime.TotalSeconds), 10, 50 * (float)Math.Cos(gameTime.TotalGameTime.TotalSeconds)), Color.White, 300, 4);            
  204.             /*
  205.             DrawDirectionalLight(new Vector3(0, -1f, 1), Color.DimGray);
  206.             Color[] colors = new Color[10];
  207.             colors[0] = Color.ForestGreen;
  208.             colors[1] = Color.Blue;
  209.             colors[2] = Color.Pink;
  210.             colors[3] = Color.Yellow;
  211.             colors[4] = Color.Orange;
  212.             colors[5] = Color.Green;
  213.             colors[6] = Color.Crimson;
  214.             colors[7] = Color.CornflowerBlue;
  215.             colors[8] = Color.Gold;
  216.             colors[9] = Color.Honeydew;
  217.             float angle = (float)gameTime.TotalGameTime.TotalSeconds;
  218.             for (int i = 0; i < 10; i++)
  219.             {
  220.                 Vector3 pos = new Vector3((float)Math.Sin(i * MathHelper.TwoPi / 10 + gameTime.TotalGameTime.TotalSeconds), 0.3f,
  221.                                                                (float)Math.Cos(i * MathHelper.TwoPi / 10 + gameTime.TotalGameTime.TotalSeconds));
  222.                 DrawPointLight(pos * 20, colors[i], 12, 2);
  223.                 pos = new Vector3((float)Math.Cos(i * MathHelper.TwoPi / 10 + gameTime.TotalGameTime.TotalSeconds), -0.6f,
  224.                                                   (float)Math.Sin(i * MathHelper.TwoPi / 10 + gameTime.TotalGameTime.TotalSeconds));
  225.                 DrawPointLight(pos * 20, colors[i], 20, 1);
  226.             }
  227.             DrawPointLight(new Vector3(0, (float)Math.Sin(gameTime.TotalGameTime.TotalSeconds * 0.8) * 40, 0), Color.Red, 30, 5);
  228.             DrawPointLight(new Vector3(0, 0, 70), Color.Wheat, 55 + 10 * (float)Math.Sin(5 * gameTime.TotalGameTime.TotalSeconds), 3);            
  229.             */
  230.             //Totally reset blend states
  231.             GraphicsDevice.BlendState = BlendState.Opaque;
  232.             GraphicsDevice.DepthStencilState = DepthStencilState.None;            
  233.             GraphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise;
  234.  
  235.             GraphicsDevice.SetRenderTarget(null);
  236.  
  237.  
  238.             //Combine everything
  239.             finalCombineEffect.Parameters["colorMap"].SetValue(colorRT);
  240.             finalCombineEffect.Parameters["lightMap"].SetValue(lightRT);
  241.             finalCombineEffect.Parameters["halfPixel"].SetValue(halfPixel);
  242.  
  243.             finalCombineEffect.Techniques[0].Passes[0].Apply();
  244.             quadRenderer.Render(Vector2.One * -1, Vector2.One);
  245.         }
  246.  
  247.         /// <summary>
  248.         /// Allows the game component to update itself.
  249.         /// </summary>
  250.         /// <param name="gameTime">Provides a snapshot of timing values.</param>
  251.         public override void Update(GameTime gameTime)
  252.         {
  253.            
  254.             base.Update(gameTime);
  255.         }
  256.     }
  257. }
RAW Paste Data