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