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;
}
}