/* * 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 } }