using ANX.Framework.Graphics; using ANX.Framework.NonXNA; using ANX.Framework.NonXNA.Development; using OpenTK.Graphics.OpenGL; // This file is part of the ANX.Framework created by the // "ANX.Framework developer group" and released under the Ms-PL license. // For details see: http://anxframework.codeplex.com/license namespace ANX.RenderSystem.Windows.GL3 { /// /// Native Rasterizer State object for OpenGL. /// /// Basically this is a wrapper class for setting the different values all /// at once, because OpenGL has no State objects like DirectX. /// [PercentageComplete(100)] [TestStateAttribute(TestStateAttribute.TestState.Untested)] public class RasterizerStateGL3 : INativeRasterizerState { #region Private internal static RasterizerStateGL3 Current { get; private set; } #endregion #region Public #region IsBound /// /// Flag if the state object is bound to the device. /// public bool IsBound { get; private set; } #endregion #region CullMode /// /// The cull mode of the state object. /// public CullMode CullMode { set; private get; } #endregion #region ScissorTestEnable /// /// Flag if the state object has scissor test enabled. /// public bool ScissorTestEnable { set; private get; } #endregion #region FillMode /// /// The fill mode of the state object. /// public FillMode FillMode { set; private get; } #endregion #region SlopeScaleDepthBias /// /// The SlopeScaleDepthBias of the state object. /// public float SlopeScaleDepthBias { set; private get; } #endregion #region DepthBias /// /// The depth bias of the state object. /// public float DepthBias { set; private get; } #endregion #region MultiSampleAntiAlias /// /// Flag if the state object has MSAA enabled. /// public bool MultiSampleAntiAlias { set; private get; } #endregion #endregion #region Constructor /// /// Create a new rasterizer state object. /// internal RasterizerStateGL3() { IsBound = false; } #endregion #region Apply /// /// Apply the rasterizer state to the graphics device. /// /// The current graphics device. public void Apply(GraphicsDevice graphicsDevice) { IsBound = true; Current = this; #region Cull Mode GL.FrontFace(FrontFaceDirection.Cw); ErrorHelper.Check("FrontFace"); if (CullMode == CullMode.None) { GL.Disable(EnableCap.CullFace); GL.CullFace(CullFaceMode.FrontAndBack); } else { GL.Enable(EnableCap.CullFace); GL.CullFace(CullMode == CullMode.None ? CullFaceMode.FrontAndBack : CullMode == CullMode.CullClockwiseFace ? CullFaceMode.Front : CullFaceMode.Back); } ErrorHelper.Check("Set CullMode"); #endregion GL.PolygonMode(MaterialFace.FrontAndBack, FillMode == FillMode.WireFrame ? PolygonMode.Line : PolygonMode.Fill); ErrorHelper.Check("PolygonMode"); #region ScissorTestEnable if (ScissorTestEnable) { GL.Enable(EnableCap.ScissorTest); } else { GL.Disable(EnableCap.ScissorTest); } ErrorHelper.Check("Set ScissorTest"); #endregion #region DepthBias / SlopeScaleDepthBias (TODO: test!) // NOTE: http://www.opengl.org/sdk/docs/man/xhtml/glPolygonOffset.xml // Good article about difference between OpenGL and DirectX concerning // Depth Bias: http://aras-p.info/blog/2008/06/12/depth-bias-and-the-power-of-deceiving-yourself/ if (DepthBias != 0f && SlopeScaleDepthBias != 0f) { GL.Enable(EnableCap.PolygonOffsetFill); GL.PolygonOffset(SlopeScaleDepthBias, DepthBias); } else { GL.Disable(EnableCap.PolygonOffsetFill); } ErrorHelper.Check("Set DepthBias"); #endregion #region MultiSampleAntiAlias if (MultiSampleAntiAlias) { GL.Enable(EnableCap.Multisample); } else { GL.Disable(EnableCap.Multisample); } ErrorHelper.Check("Set Multisample"); #endregion } #endregion #region Release /// /// Release the rasterizer state. /// public void Release() { IsBound = false; Current = null; } #endregion #region Dispose /// /// Dispose the rasterizer state object. /// public void Dispose() { } #endregion } }