using System; using Chernobyl.Collections.Generic.Event; using Chernobyl.Dependency; using Chernobyl.Graphics.Material.Shader.Parameters; using Chernobyl.Mathematics; using Chernobyl.Mathematics.Geometry; using Chernobyl.Plugin; using Chernobyl.Utility; using Microsoft.Xna.Framework.Graphics; namespace Chernobyl.Graphics.Xna { /// /// The viewport of the back buffer. /// public class XnaBackBufferViewport : IBackBufferViewport { /// /// Initializes a new instance of the /// class. /// /// The instance whose /// is used to build this instance. /// The instance that is modified with /// changes to the projection. public XnaBackBufferViewport(GraphicsDevice graphicsDevice, IShaderParameter projectionMatrix) { graphicsDevice.ThrowIfNull("graphicsDevice"); projectionMatrix.ThrowIfNull("projectionMatrix"); ViewArea = new Rectangle(graphicsDevice.Viewport.X, graphicsDevice.Viewport.Y, graphicsDevice.Viewport.Width, graphicsDevice.Viewport.Height); // TODO: this shouldn't be placed here. We need to create a view frustum type class that includes // information about the near and far plane. This view frustum should probably be collidable so // we can do frustum culling. It should probably also be an IDrawable so that we can change the // view frustum per draw graph and while drawing. projectionMatrix.Value = Matrix4.Perspective((float)(Math.PI / 4.0), Width / Height, 0.1f, 100.0f); } /// /// The width of the viewport, in pixels. /// public float Width { get { return ViewArea.Width; } } /// /// The height of the viewport, in pixels. /// public float Height { get { return ViewArea.Height; } } /// /// The X pixel coordinate of the bottom left point on the viewport. /// public float X { get { return ViewArea.LeftSide; } } /// /// The Y pixel coordinate of the bottom left point on the viewport. /// public float Y { get { return ViewArea.Bottom; } } /// /// The viewable area of the render target. Note that all coordinates /// specified by the rectangle are in pixels. /// public Rectangle ViewArea { get; private set; } /// /// An Chernobyl plug-in that adds an /// instance ( implementation) to the /// services passed to the constructor /// of this instance. This type is auto-loaded by Chernobyl. /// public class Plugin : IPlugin { /// /// Initializes a new instance of the class. /// /// The /// instance that gives and takes services. public Plugin(IEventCollection services) { _services = services; services.Inject(this); } /// /// The instance that is modified with changes to the projection. /// [Inject] public IProjectionMatrixParameter ProjectionMatrix { set { _projectionMatrix = value; Configure(); } } /// /// The instance whose /// /// is used to build this instance. /// [Inject] public GraphicsDevice GraphicsDevice { set { _graphicsDevice = value; Configure(); } } /// /// Resets the projection matrix to a default value. /// void Configure() { if (_graphicsDevice != null && _projectionMatrix != null) _services.Add(new XnaBackBufferViewport(_graphicsDevice, _projectionMatrix)); } /// /// The instance that gives and /// takes services. /// readonly IEventCollection _services; /// /// The backing field to . /// GraphicsDevice _graphicsDevice; /// /// The backing field to . /// IProjectionMatrixParameter _projectionMatrix; } } }