/*
* LightingManager.cs
* Authors: Mike Dapiran
* Copyright (c) 2007-2008 Cornell University
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Util;
namespace tAC_Engine.Graphics
{
///
/// Manages how lighting is processed
///
public static class LightingManager
{
#region Fields
// Reference to the current content manager
private static ContentManager Content;
// Struct that will hold the light or lightArray, depending on max shader value
private static EffectParameter m_Lights;
// A reference to the effect that will be used
private static Effect m_Effect;
// The color of ambient light that the shader will use
private static Vector4 m_AmbientColor = Vector4.Zero;
// The max shader profile that the graphics card can handle
private static ShaderProfile maxPixelShaderProfile;
#endregion
#region Properties
///
/// Gets/Sets the reference to the effect that will be used
///
public static Effect CurrentEffect
{
get { return m_Effect; }
set { m_Effect = value; }
}
///
///Gets/Sets the color of ambient light that the shader will use
///
public static Vector4 AmbientColor
{
get { return m_AmbientColor; }
set
{
m_AmbientColor = value;
m_Effect.Parameters["ambientColor"].SetValue(m_AmbientColor);
}
}
///
/// Gets/Sets the max shader profile that the graphics card can handle
///
public static ShaderProfile MaxShaderVersion
{
get { return maxPixelShaderProfile; }
set
{
maxPixelShaderProfile = value;
if (maxPixelShaderProfile >= ShaderProfile.PS_2_0)
{
m_Effect = Content.Load(AssemblyLocator.GetLocation(typeof(LightingManager).Assembly.FullName) + @"\Content\BasicShader20");
m_Lights = m_Effect.Parameters["light"];
}
else if (maxPixelShaderProfile >= ShaderProfile.PS_1_1)
{
m_Effect = Content.Load(AssemblyLocator.GetLocation(typeof(LightingManager).Assembly.FullName) + @"\Content\BasicShader10");
m_Lights = m_Effect.Parameters["light"];
}
}
}
///
/// Gets/Sets the position of the camera
///
public static Vector3 CameraPosition
{
get
{
if(MaxShaderVersion >= ShaderProfile.PS_2_0)
return m_Effect.Parameters["cameraPostion"].GetValueVector3();
else
return Vector3.Zero;
}
set
{
if(MaxShaderVersion >= ShaderProfile.PS_2_0)
m_Effect.Parameters["cameraPosition"].SetValue(value);
}
}
#endregion
#region Modifiers
///
/// Used to change the color of a particular light
///
/// The light to change
/// The color of the light
public static void SetLightColor(int p_LightNumber, Vector4 p_LightColor)
{
if (maxPixelShaderProfile >= ShaderProfile.PS_2_0)
{
m_Lights.StructureMembers["color"].SetValue(p_LightColor);
}
else
{
if (p_LightNumber > 0)
throw new IndexOutOfRangeException("Shader 1.1 supports a max of 1 one light");
m_Lights.StructureMembers["color"].SetValue(p_LightColor);
}
}
///
/// Used to set the position of a light
///
/// The number of the light to change
/// The direciton of the light to change
public static void SetLightDirection(int p_LightNumber, Vector3 p_LightDirection)
{
if (maxPixelShaderProfile >= ShaderProfile.PS_2_0)
{
m_Lights.StructureMembers["direction"].SetValue(p_LightDirection);
}
else
{
if (p_LightNumber > 0)
throw new InvalidOperationException("Shader 1.1 supports a max of 1 one light");
m_Lights.StructureMembers["direction"].SetValue(p_LightDirection);
}
}
///
/// Used to enable and disable lights
///
/// The number of the light
/// The new state of the light
public static void SetLightEnabled(int p_LightNumber, bool p_Enabled)
{
if (maxPixelShaderProfile >= ShaderProfile.PS_2_0)
{
m_Lights.StructureMembers["enable"].SetValue(p_Enabled);
}
else
{
if (p_LightNumber > 0)
throw new InvalidOperationException("Shader 1.1 supports a max of 1 one light");
m_Lights.StructureMembers["enable"].SetValue(p_Enabled);
}
}
///
/// Sends the shader changes to the graphics card
///
public static void ApplyLightChanges()
{
m_Effect.CommitChanges();
}
#endregion
#region Initialization
///
/// Needs to be called to set the game object and determine the max shader profile for the current graphics card
///
/// Reference to the current content manager
/// Reference to the current graphics device
public static void Initialize(ContentManager content, GraphicsDevice graphicsDevice)
{
Content = content;
MaxShaderVersion = graphicsDevice.GraphicsDeviceCapabilities.MaxPixelShaderProfile;
}
#endregion
#region Value Returns
///
/// Returns the struct that the shader uses to store the lights
///
/// The number of the light to get
///
private static EffectParameter GetLight(int p_LightNumber)
{
if (maxPixelShaderProfile >= ShaderProfile.PS_2_0)
{
try
{
return m_Lights.Elements[p_LightNumber];
}
catch (IndexOutOfRangeException)
{
throw new IndexOutOfRangeException("Out of range of lights");
}
}
else
{
if (p_LightNumber > 0)
{
throw new InvalidOperationException("Shader 1.1 only supports a max of 1 light");
}
else
{
return m_Lights;
}
}
}
#endregion
}
}