using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using Chernobyl.Collections.Generic.Event; using Chernobyl.Dependency; using Chernobyl.Graphics.Drawing; using Chernobyl.Graphics.Material; using Chernobyl.Graphics.Material.Shader.Parameters; using Chernobyl.Graphics.Polygon.Buffers; using Chernobyl.Graphics.Texture; using Chernobyl.Graphics.Writing; using Chernobyl.Graphics.Xna.Controllers; using Chernobyl.Graphics.Xna.Controllers.Shaders; using Chernobyl.Graphics.Xna.Resources; using Chernobyl.Graphics.Xna.Texture; using Chernobyl.Graphics.Xna.Writing; using Chernobyl.Plugin; using Chernobyl.Resources; using Microsoft.Xna.Framework.Graphics; namespace Chernobyl.Graphics.Xna { /// /// The XNA graphics plug-in for Chernobyl.Graphics. /// public class XnaPlugin : IPlugin { /// /// Constructor. /// /// The instance that /// gives and takes services. public XnaPlugin(IEventCollection services) { Trace = new TraceSource("Chernobyl.Graphics.Xna"); Services = services; services.Add((MeshFactoryServiceCreator)XnaMeshFactoryServiceCreator); services.Add((IndexBufferFactoryServiceCreator)XnaIndexBufferServiceCreator); RenderFactory = (serv, primType, drawable, transform, volume) => new XnaRender(serv, primType, drawable, transform, volume); Texture2DFactory = (serv, width, height, mipmapLevels, textureFormat) => new XnaTexture2D(serv, width, height, mipmapLevels, textureFormat); BackBuffer = new XnaBackBuffer(); TextureParameterFactory = (serv, val, paramName) => new XnaTextureParameter(serv, val, paramName); BasicEffectFactory = (serv) => new Effects.BasicEffect(serv); TextFactory = (serv, font) => new XnaText(serv, font); // Create the effect parameter converters { EffectParameterConverters = new SortedList>(1); // if you add more parameters, make sure to update the capacity set in the SortedList constructor above EffectParameterConverters.Add(EffectParameterType.Texture2D, param => new XnaTextureParameter(services, new XnaTexture2D(services, param.GetValueTexture2D()), param.Name)); } services.Inject(this); } /// /// The services provided by this plug-in or null if no services are /// provided. /// public IEventCollection Services { get; private set; } /// /// A used to output errors, warnings, information, /// etc., that are specific to Chernobyl.Graphics.Xna. This /// will have the name "Chernobyl.Graphics.Xna". /// public static TraceSource Trace { get; private set; } /// /// Holds vertex declarations that were previously created /// so that they can be re-used. /// [Provide] public IDictionary VertexDeclarationStore { get { return _vertexDeclarationStore ?? (_vertexDeclarationStore = new Dictionary()); } } /// /// Creates DrawBufferFactory controllers. /// [Provide] public IDrawBufferFactory DrawBufferFactory { get { return _drawBufferFactory ?? (_drawBufferFactory = new XnaDrawBuffer.Factory()); } } /// /// Creates IRender controllers. /// [Provide] public RenderFactory RenderFactory { get; set; } /// /// Creates Texture2D controllers /// [Provide] public Texture2DFactory Texture2DFactory { get; set; } /// /// The back buffer provided by XNA. /// [Provide] public IBackBuffer BackBuffer { get; private set; } /// /// The texture shader parameter factory. /// [Provide] public ShaderParameterFactory TextureParameterFactory { get; set; } /// /// The factory that creates basic effects. /// [Provide] public BasicEffectFactory BasicEffectFactory { get; set; } /// /// The factory that produces the IText instances. /// [Provide] public TextFactory TextFactory { get; set; } /// /// A that holds mappings of an /// to converter methods. These /// converter methods are responsible for converting the passed in XNA /// (which of type ) /// to a Chernobyl . /// [Provide] public SortedList> EffectParameterConverters { get; private set; } /// /// The root shader IResourceProcessor that was added by Chernobyl.Graphics. /// [Inject] public IResourceProcessor RootEffectProcessor { set { FileStreamProcessor effectFileStreamProcessor = value.OfType>().First(); // TODO: add in the XNA IEffect processor //effectFileStreamProcessor.FileStreamProcessors.Add("[a-zA-Z]*\\.fx", ); } } /// /// The root font resource processor. /// [Inject] public IResourceProcessor RootFontProcessor { set { // get the resource processor at the end of the resource processing chain IResourceProcessor lastFontProcessor = value.First(proc => proc.NextResourceProcessor == null); lastFontProcessor.NextResourceProcessor = new XnaResourceProcessor(Services, spriteFont => new XnaFont(Services, spriteFont)); } } /// /// The root texture resource processor. /// [Inject] public IResourceProcessor RootTextureProcessor { set { // get the resource processor at the end of the resource processing chain IResourceProcessor lastTextureProcessor = value.First(proc => proc.NextResourceProcessor == null); lastTextureProcessor.NextResourceProcessor = new XnaResourceProcessor(Services, texture => new XnaTexture2D(Services, texture)); } } /// /// Method that creates the . /// /// Type of the data that will be stored in the /// created by the . /// The in the form of an /// . public static object XnaMeshFactoryServiceCreator(Type dataType) { MethodInfo method = typeof(XnaPlugin).GetMethod("MeshFactory").MakeGenericMethod(dataType); Type methodType = typeof (MeshFactory<>).MakeGenericType(dataType); return Delegate.CreateDelegate(methodType, method); } /// /// Method that creates the . /// /// Type of the data. /// public static object XnaIndexBufferServiceCreator(Type dataType) { MethodInfo method = typeof(XnaPlugin).GetMethod("IndexBufferFactory").MakeGenericMethod(dataType); Type methodType = typeof(MeshFactory<>).MakeGenericType(dataType); return Delegate.CreateDelegate(methodType, method); } /// /// A method that creates meshes that interface with XNA vertex buffers. /// /// The type of data that is going to be stored in /// the buffer like ints, floats, shorts, a custom mesh element type, etc. /// The list of services to inject into this buffer. /// The mesh element data to place in the mesh. /// The that represents the mesh. public static IBuffer MeshFactory(IEventCollection services, TData[] meshElements) where TData : struct { return new XnaMesh(services, meshElements); } /// /// A method that creates index buffer that interface with XNA index buffers. /// /// The type of data that is going to be stored in /// the buffer like ints, floats, shorts, a custom mesh element type, etc. /// The list of services to inject into this buffer. /// The index data to place in this buffer. /// The that represents the mesh. public static IBuffer IndexBufferFactory(IEventCollection services, TData[] indices) where TData : struct { return new XnaIndexBuffer(services, indices); } /// /// The backing field to . /// IDictionary _vertexDeclarationStore; /// /// The backing field to . /// IDrawBufferFactory _drawBufferFactory; } }