public override void Draw(Camera camera)
        {
			mGraphicsDevice.SamplerStates[0] = SamplerState.PointWrap;
			mGraphicsDevice.RasterizerState = RasterizerState.CullClockwise;

            Matrix world = mWorld * Matrix.CreateTranslation(camera.Position);
            mEffect.Parameters["WorldViewProj"].SetValue(world * camera.ViewProj);

			foreach (ModelMesh mesh in mMesh.Meshes)
			{
				foreach (ModelMeshPart meshPart in mesh.MeshParts)
				{
					//set the index buffer 
					mGraphicsDevice.Indices = meshPart.IndexBuffer;
					mGraphicsDevice.SetVertexBuffer(
						meshPart.VertexBuffer, meshPart.VertexOffset);

					foreach (EffectPass pass in mEffect.CurrentTechnique.Passes)
					{
						pass.Apply();
						mGraphicsDevice.DrawIndexedPrimitives(
							PrimitiveType.TriangleList, 0, 0,
							meshPart.NumVertices, meshPart.StartIndex, meshPart.PrimitiveCount);
					}
                }
            }

            mGraphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise;
        }
		public override void Draw(Camera camera)
		{
			Vector2 v1 = new Vector2(Scale.X, Scale.Y);
			Vector2 v2 = new Vector2(Scale.X, Scale.Y);
			v2 = -v2;

			verts[0].Position.X = v2.X;
			verts[0].Position.Y = v1.Y;

			verts[1].Position.X = v1.X;
			verts[1].Position.Y = v1.Y;

			verts[2].Position.X = v1.X;
			verts[2].Position.Y = v2.Y;

			verts[3].Position.X = v2.X;
			verts[3].Position.Y = v2.Y;
			/*
            foreach (ModelMesh mesh in mMesh.Meshes)
            {
                foreach (BasicEffect effect in mesh.Effects)
                {
                    effect.World = mWorld;//boneTransforms[mesh.ParentBone.Index] * mWorld;
                    effect.View = camera.View;
                    effect.Projection = camera.Projection;

                    if (mTexture != null)
                    {
                        effect.Texture = mTexture;
                        effect.TextureEnabled = true;
                    }

                    if (mLightingEnabled)
                    {
                        effect.EnableDefaultLighting();
                        effect.PreferPerPixelLighting = true;
                    }
                    else
                    {
                        effect.LightingEnabled = false;
                    }
                }
			}
			*/

			Matrix world = mWorld * Matrix.CreateTranslation(camera.Position);

			mEffect.CurrentTechnique = mEffect.Techniques["Texture"];
			mEffect.Parameters["WorldViewProj"].SetValue(world * camera.ViewProj);

			foreach (EffectPass pass in mEffect.CurrentTechnique.Passes)
			{
				pass.Apply();
				device.DrawUserIndexedPrimitives<VertexPositionTexture>
					(PrimitiveType.TriangleList, verts, 0, 4, ib, 0, 2);
			}

			mEffect.CurrentTechnique = mEffect.Techniques["BuildDP"];
		}
        protected virtual void DrawCustomEffect(Camera camera)
        {
            Matrix[] boneTransforms = new Matrix[mMesh.Bones.Count];
            mMesh.CopyAbsoluteBoneTransformsTo(boneTransforms);

            foreach (ModelMesh mesh in mMesh.Meshes)
            {
                Matrix world = boneTransforms[mesh.ParentBone.Index] * mWorld;

                Matrix worldInvTrans = Matrix.Invert(world);
                worldInvTrans = Matrix.Transpose(worldInvTrans);

                mEffect.Parameters["World"].SetValue(world);
                mEffect.Parameters["WorldInvTrans"].SetValue(worldInvTrans);
                mEffect.Parameters["WorldViewProj"].SetValue(world * camera.ViewProj);
                
                if (mTexture != null)
                    mEffect.Parameters["DiffuseTex"].SetValue(mTexture);

                mEffect.Parameters["TexScale"].SetValue(mTexScale);

                foreach (ModelMeshPart meshPart in mesh.MeshParts)
                {
					//set the vertex and index buffers
					mGraphicsDevice.Indices = meshPart.IndexBuffer;
					mGraphicsDevice.SetVertexBuffer(meshPart.VertexBuffer, meshPart.VertexOffset);

					foreach (EffectPass pass in mEffect.CurrentTechnique.Passes)
					{
						pass.Apply();
						mGraphicsDevice.DrawIndexedPrimitives(
							PrimitiveType.TriangleList, 0, 0,
							meshPart.NumVertices, meshPart.StartIndex, meshPart.PrimitiveCount);
					}
                    // End pass
                }
            }
			// End mesh render
        }               
        protected virtual void DrawBasicEffect(Camera camera)
        {
            Matrix[] boneTransforms = new Matrix[mMesh.Bones.Count];
            mMesh.CopyAbsoluteBoneTransformsTo(boneTransforms);
            
            foreach (ModelMesh mesh in mMesh.Meshes)
            {
                foreach (BasicEffect effect in mesh.Effects)
                {
                    effect.World = boneTransforms[mesh.ParentBone.Index] * mWorld;
                    effect.View = camera.View;
                    effect.Projection = camera.Projection;

                    if (mTexture != null)
                    {
                        effect.Texture = mTexture;
                        effect.TextureEnabled = true;
                    }

                    if (mLightingEnabled)
                    {
                        effect.EnableDefaultLighting();
                        effect.PreferPerPixelLighting = true;
                    }
                    else
                    {
                        effect.LightingEnabled = false;
                    }
                }
                
                mesh.Draw();
            }
        }
        public virtual void Draw(Camera camera)
        {
			mGraphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise;

            //draw with the basic effect
            if (mEffect == null)
            {
                DrawBasicEffect(camera);
            }
            else
            {
                DrawCustomEffect(camera);
            }
        }
        /// <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();
        }
        //copy constructor
        public Camera(Camera camera)
        {
            mView = camera.View;
            mProj = camera.Projection;
            mViewProj = camera.ViewProj;

            mFieldOfView = camera.FOV;
            mAspect = camera.Aspect;
            mNearZ = camera.NearZ;
            mFarZ = camera.FarZ;

            mPosition = camera.Position;
            mRight = camera.Right;
            mUp = camera.Up;
            mLook = camera.Look;
        }