using System; using System.Collections.Generic; using System.Text; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; namespace WindowsGame1 { public static class LightingManager { //A reference to game, needed to use the content manager private static Game m_Game; //A reference to the effect that will be used private static Effect m_Effect; public static Effect CurrentEffect { get { return m_Effect; } set { m_Effect = value; } } //the max shader profile that the graphics card can handle private static ShaderProfile maxPixelShaderProfile; //the color of ambient light that the shader will use private static Vector4 m_AmbientColor = Vector4.Zero; public static Vector4 AmbientColor { get { return m_AmbientColor; } set { m_AmbientColor = value; m_Effect.Parameters["ambientColor"].SetValue(m_AmbientColor); } } //struct that will hold the light or lightArray, depending on max shader value private static EffectParameter m_Lights; public static ShaderProfile MaxShaderVersion { get { return maxPixelShaderProfile; } set { maxPixelShaderProfile = value; if (maxPixelShaderProfile >= ShaderProfile.PS_2_0) { m_Effect = m_Game.Content.Load("BasicShader20"); m_Lights = m_Effect.Parameters["lights"]; } else if (maxPixelShaderProfile >= ShaderProfile.PS_1_1) { m_Effect = m_Game.Content.Load("BasicShader10"); m_Lights = m_Effect.Parameters["light"]; } } } /// /// 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.Elements[p_LightNumber].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 position of the light to change public static void SetLightPosition(int p_LightNumber, Vector3 p_LightPosition) { if(maxPixelShaderProfile >= ShaderProfile.PS_2_0) { m_Lights.Elements[p_LightNumber].StructureMembers["position"].SetValue(p_LightPosition); } else { if(p_LightNumber > 0) throw new IndexOutOfRangeException("Shader 1.1 supports a max of 1 one light"); m_Lights.StructureMembers["position"].SetValue(p_LightPosition); } } /// /// Used the set the range of a light /// /// The number of the light to change /// The new range of the light public static void SetLightRange(int p_LightNumber, float p_LightRange) { if (maxPixelShaderProfile >= ShaderProfile.PS_2_0) { m_Lights.Elements[p_LightNumber].StructureMembers["range"].SetValue(p_LightRange); } else { throw new NullReferenceException("Shader 1.0 does not support light range"); } } /// /// Used to set the falloff of a light /// /// The number of the light /// The new falloff of the light public static void SetLightFalloff(int p_LightNumber, float p_LightFalloff) { if (maxPixelShaderProfile >= ShaderProfile.PS_2_0) { m_Lights.Elements[p_LightNumber].StructureMembers["falloff"].SetValue(p_LightFalloff); } else { throw new NullReferenceException("Shader 1.0 does not support light falloff"); } } /// /// 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.Elements[p_LightNumber].StructureMembers["enabled"].SetValue(p_Enabled); } else { if (p_LightNumber > 0) throw new IndexOutOfRangeException("Shader 1.1 supports a max of 1 one light"); m_Lights.StructureMembers["enabled"].SetValue(p_Enabled); } } /// /// Needs to be called to set the game object and determine the max shader profile for the current graphics card /// /// The current game object public static void Initialize(Game p_Game) { m_Game = p_Game; maxPixelShaderProfile = m_Game.GraphicsDevice.GraphicsDeviceCapabilities.MaxPixelShaderProfile; if (maxPixelShaderProfile >= ShaderProfile.PS_2_0) { m_Effect = m_Game.Content.Load("BasicShader20"); m_Lights = m_Effect.Parameters["lights"]; } else if (maxPixelShaderProfile >= ShaderProfile.PS_1_1) { m_Effect = m_Game.Content.Load("BasicShader10"); m_Lights = m_Effect.Parameters["light"]; } } /// /// 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 IndexOutOfRangeException("Shader 1.0 only supports a max of 1 light"); } else { return m_Lights; } } } /// /// Sends the shader changes to the graphics card /// public static void ApplyLightChanges() { m_Effect.CommitChanges(); } } }