/// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>

        protected override void Update(GameTime gameTime)
        {
            float timeDelta = (float)gameTime.ElapsedGameTime.TotalSeconds;

            mElapsedTime += timeDelta;

            #region Update Input
            KeyboardState keyState = Keyboard.GetState();

            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
            {
                this.Exit();
            }

            if (keyState.IsKeyDown(Keys.Escape))
            {
                this.Exit();
            }

            if (keyState.IsKeyDown(Keys.W))
            {
                camera.Walk(-mVelocity * timeDelta);
            }
            if (keyState.IsKeyDown(Keys.S))
            {
                camera.Walk(mVelocity * timeDelta);
            }
            if (keyState.IsKeyDown(Keys.A))
            {
                camera.Strafe(-mVelocity * timeDelta);
            }
            if (keyState.IsKeyDown(Keys.D))
            {
                camera.Strafe(mVelocity * timeDelta);
            }

            camera.UpdateMouse(Mouse.GetState(), timeDelta * mMouseScale);
            camera.BuildView();
            #endregion

            //update the models
            foreach (BaseMesh mesh in mModels)
            {
                mesh.Update(gameTime);
            }

            //update the frame rate
            if (mElapsedTime >= 0.5f)
            {
                mFrameRate   = mFrameCount * 2;
                mElapsedTime = 0.0f;
                mFrameCount  = 0;
            }

            base.Update(gameTime);
        }
        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>

        protected override void Initialize()
        {
            mModels = new List <BaseMesh>();

            // Create our camera

            camera = new Camera();
            camera.LookAt(new Vector3(0, 5, 20), new Vector3(0, 0, 0));
            float aspect = (float)graphics.PreferredBackBufferWidth / (float)graphics.PreferredBackBufferHeight;

            camera.SetLens(MathHelper.ToRadians(45.0f), aspect, .1f, 1000.0f);
            camera.BuildView();

            // Setup our dual-paraboloid camera

            dualParaCamera = new Camera();
            dualParaCamera.LookAt(new Vector3(0.0f, 0.0f, 0.0f), Vector3.UnitZ * 6);
            dualParaCamera.SetLens(MathHelper.ToRadians(90.0f), aspect, .1f, 1000.0f);

            // Make sure to set the projection matrix to the identity matrix sence we won't be using it

            dualParaCamera.Projection = Matrix.Identity;
            dualParaCamera.BuildView();

            List <Light> lights = createLights();

            // Initialize the reflective model

            mReflector             = new BaseMesh(this);
            mReflector.MeshAsset   = "Models/Dragon";
            mReflector.EffectAsset = "Shaders/DPMReflect";
            mReflector.Position    = dualParaCamera.View.Translation;
            mReflector.Scale       = Vector3.One * 3.0f;

            mModels.Add(mReflector);

            // Initialize the Environment box

            BaseMesh mesh = new Environment(this);

            mesh.MeshAsset               = "Models/SphereHighPoly";
            mesh.Scale                   = Vector3.One * 500.0f;
            mesh.EffectAsset             = "Shaders/EnvironmentMap";
            mesh.TextureAsset            = "Textures/whitetex";
            mesh.EnvironmentTextureAsset = "Textures/graceCUBE";

            mModels.Add(mesh);

            // Initialize the impostors

            BaseMesh quadMesh = new BaseMesh(this);

            quadMesh.Position       = new Vector3(0, -5f, 0);
            quadMesh.Rotation       = 0f;
            quadMesh.Scale          = new Vector3(1.5f);
            quadMesh.MeshAsset      = "Models/Ground";
            quadMesh.EffectAsset    = "Shaders/Texture";
            quadMesh.TextureAsset   = "Textures/wood";
            quadMesh.EnableLighting = false;

            mModels.Add(quadMesh);

            float p = 0.0f, y = 0.0f;

            for (int i = 0; i < 8; i++)
            {
                Vector3 pos = Vector3.Zero;
                pos.Y = y;

                p += 1.0f / 8.0f;
                Vector2 pos2 = Utils.GetVector2FromPolarCoord(p) * 8.0f;
                pos.X = pos2.X;
                pos.Z = pos2.Y;

                mesh              = new BaseMesh(this);
                mesh.Position     = pos;
                mesh.Scale        = Vector3.One * 1.0f;
                mesh.RotationAxis = Vector3.UnitY;
                mesh.Rotation     = 1.0f;
                mesh.EffectAsset  = "Shaders/Phong";
                mesh.MeshAsset    = "Models/SphereHighPoly";
                mesh.TextureAsset = "Textures/whitetex";
                mesh.Lights       = lights;

                mModels.Add(mesh);
            }

            // Initialize the render targets for the paraboloid maps

            int width  = graphics.PreferredBackBufferWidth;
            int height = graphics.PreferredBackBufferHeight;

            mDPMapFront = new RenderTarget2D(GraphicsDevice, width, height, true,
                                             SurfaceFormat.Color, DepthFormat.Depth24);
            mDPMapBack = new RenderTarget2D(GraphicsDevice, width, height, true,
                                            SurfaceFormat.Color, DepthFormat.Depth24);

            // Finally, initialize the models

            foreach (BaseMesh model in mModels)
            {
                model.Initialize();
            }

            base.Initialize();
        }
        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>

        protected override void Initialize()
        {
            mModels = new List<BaseMesh>();

            // Create our camera

            camera = new Camera();
            camera.LookAt(new Vector3(0, 5, 20), new Vector3(0, 0, 0));
			float aspect = (float)graphics.PreferredBackBufferWidth / (float)graphics.PreferredBackBufferHeight;
            camera.SetLens(MathHelper.ToRadians(45.0f), aspect, .1f, 1000.0f);
            camera.BuildView();

            // Setup our dual-paraboloid camera

            dualParaCamera = new Camera();
            dualParaCamera.LookAt(new Vector3(0.0f, 0.0f, 0.0f), Vector3.UnitZ * 6);
            dualParaCamera.SetLens(MathHelper.ToRadians(90.0f), aspect, .1f, 1000.0f);

            // Make sure to set the projection matrix to the identity matrix sence we won't be using it

            dualParaCamera.Projection = Matrix.Identity;
            dualParaCamera.BuildView(); 

            List<Light> lights = createLights();

			// Initialize the reflective model

            mReflector = new BaseMesh(this);
			mReflector.MeshAsset = "Models/Dragon";
            mReflector.EffectAsset = "Shaders/DPMReflect";
			mReflector.Position = dualParaCamera.View.Translation;
            mReflector.Scale = Vector3.One * 3.0f;

            mModels.Add(mReflector);
			
            // Initialize the Environment box

            BaseMesh mesh = new Environment(this);
			mesh.MeshAsset = "Models/SphereHighPoly";
            mesh.Scale = Vector3.One * 500.0f;
            mesh.EffectAsset = "Shaders/EnvironmentMap";
            mesh.TextureAsset = "Textures/whitetex";
            mesh.EnvironmentTextureAsset = "Textures/graceCUBE";

            mModels.Add(mesh);

            // Initialize the impostors

			BaseMesh quadMesh = new BaseMesh(this);
			quadMesh.Position = new Vector3(0, -5f, 0);
			quadMesh.Rotation = 0f;
			quadMesh.Scale = new Vector3(1.5f);
			quadMesh.MeshAsset = "Models/Ground";
			quadMesh.EffectAsset = "Shaders/Texture";
			quadMesh.TextureAsset = "Textures/wood";
			quadMesh.EnableLighting = false;

			mModels.Add(quadMesh);

            float p = 0.0f, y = 0.0f;

            for (int i = 0; i < 8; i++)
            {
                Vector3 pos = Vector3.Zero;
                pos.Y = y;

                p += 1.0f / 8.0f;
                Vector2 pos2 = Utils.GetVector2FromPolarCoord(p) * 8.0f;
                pos.X = pos2.X;
                pos.Z = pos2.Y;

                mesh = new BaseMesh(this);
                mesh.Position = pos;
                mesh.Scale = Vector3.One * 1.0f;
                mesh.RotationAxis = Vector3.UnitY;
                mesh.Rotation = 1.0f;
                mesh.EffectAsset = "Shaders/Phong";
				mesh.MeshAsset = "Models/SphereHighPoly";
                mesh.TextureAsset = "Textures/whitetex";
                mesh.Lights = lights;

                mModels.Add(mesh);
            }

			// Initialize the render targets for the paraboloid maps

			int width = graphics.PreferredBackBufferWidth;
			int height = graphics.PreferredBackBufferHeight;
            mDPMapFront = new RenderTarget2D(GraphicsDevice, width, height, true, 
				SurfaceFormat.Color, DepthFormat.Depth24);
            mDPMapBack = new RenderTarget2D(GraphicsDevice, width, height, true, 
				SurfaceFormat.Color, DepthFormat.Depth24);

            // Finally, initialize the models

            foreach (BaseMesh model in mModels)
			{
                model.Initialize();
			}

            base.Initialize();
        }