- OpenGL render system now keeps track of all it's resources and Disposes and Recreates them if needed

- OpenGL Device is now Reset correctly when for example the window size changes (Recreating all resources)
- OpenGL render system doesn't crash anymore when closing the application
- Introduced TestStateAttribute for development to mark a file as tested/untested
This commit is contained in:
SND\AstrorEnales_cp 2012-02-18 22:43:08 +00:00
parent 9b31c1b45d
commit 772d4be8d3
18 changed files with 795 additions and 70 deletions

View File

@ -416,6 +416,7 @@
<Compile Include="NonXNA\AddInLoadingException.cs" /> <Compile Include="NonXNA\AddInLoadingException.cs" />
<Compile Include="NonXNA\AddInSystemInfo.cs" /> <Compile Include="NonXNA\AddInSystemInfo.cs" />
<Compile Include="NonXNA\AddInType.cs" /> <Compile Include="NonXNA\AddInType.cs" />
<Compile Include="NonXNA\Development\TestStateAttribute.cs" />
<Compile Include="NonXNA\Development\PercentageCompleteAttribute.cs" /> <Compile Include="NonXNA\Development\PercentageCompleteAttribute.cs" />
<Compile Include="NonXNA\InputDeviceFactory.cs" /> <Compile Include="NonXNA\InputDeviceFactory.cs" />
<Compile Include="NonXNA\InputSystem\IGamePadCreator.cs" /> <Compile Include="NonXNA\InputSystem\IGamePadCreator.cs" />

View File

@ -349,7 +349,7 @@ namespace ANX.Framework.Graphics
} }
// reset presentation parameters // reset presentation parameters
nativeDevice.ResizeBuffers(presentationParameters); //TODO: check if necessary nativeDevice.ResizeBuffers(presentationParameters);
raise_DeviceReset(this, EventArgs.Empty); raise_DeviceReset(this, EventArgs.Empty);
} }

View File

@ -0,0 +1,82 @@
using System;
#region License
//
// This file is part of the ANX.Framework created by the "ANX.Framework developer group".
//
// This file is released under the Ms-PL license.
//
//
//
// Microsoft Public License (Ms-PL)
//
// This license governs use of the accompanying software. If you use the software, you accept this license.
// If you do not accept the license, do not use the software.
//
// 1.Definitions
// The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning
// here as under U.S. copyright law.
// A "contribution" is the original software, or any additions or changes to the software.
// A "contributor" is any person that distributes its contribution under this license.
// "Licensed patents" are a contributor's patent claims that read directly on its contribution.
//
// 2.Grant of Rights
// (A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations
// in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to
// reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution
// or any derivative works that you create.
// (B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in
// section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed
// patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution
// in the software or derivative works of the contribution in the software.
//
// 3.Conditions and Limitations
// (A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
// (B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your
// patent license from such contributor to the software ends automatically.
// (C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution
// notices that are present in the software.
// (D) If you distribute any portion of the software in source code form, you may do so only under this license by including
// a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or
// object code form, you may only do so under a license that complies with this license.
// (E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees,
// or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the
// extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a
// particular purpose and non-infringement.
#endregion // License
namespace ANX.Framework.NonXNA.Development
{
public class TestStateAttribute : Attribute
{
#region TestState (enum)
public enum TestState
{
Untested,
InProgress,
Tested,
}
#endregion
#region Public
public TestState State
{
get;
private set;
}
#endregion
#region Constructor
/// <summary>
/// Create a new test state attribute.
/// </summary>
/// <param name="setState">The state of testing.</param>
public TestStateAttribute(TestState setState)
{
State = setState;
}
#endregion
}
}

View File

@ -50,7 +50,7 @@
<ItemGroup> <ItemGroup>
<Compile Include="BlendStateGL3.cs" /> <Compile Include="BlendStateGL3.cs" />
<Compile Include="Creator.cs" /> <Compile Include="Creator.cs" />
<Compile Include="DatatypesMapping.cs" /> <Compile Include="Helpers\DatatypesMapping.cs" />
<Compile Include="DepthStencilStateGL3.cs" /> <Compile Include="DepthStencilStateGL3.cs" />
<Compile Include="EffectGL3.cs" /> <Compile Include="EffectGL3.cs" />
<Compile Include="EffectParameterGL3.cs" /> <Compile Include="EffectParameterGL3.cs" />
@ -58,6 +58,7 @@
<Compile Include="EffectTechniqueGL3.cs" /> <Compile Include="EffectTechniqueGL3.cs" />
<Compile Include="ErrorHelper.cs" /> <Compile Include="ErrorHelper.cs" />
<Compile Include="GraphicsDeviceWindowsGL3.cs" /> <Compile Include="GraphicsDeviceWindowsGL3.cs" />
<Compile Include="Helpers\GraphicsResourceManager.cs" />
<Compile Include="Helpers\LinuxInterop.cs" /> <Compile Include="Helpers\LinuxInterop.cs" />
<Compile Include="Helpers\WindowsInterop.cs" /> <Compile Include="Helpers\WindowsInterop.cs" />
<Compile Include="IndexBufferGL3.cs" /> <Compile Include="IndexBufferGL3.cs" />

View File

@ -1,6 +1,8 @@
using System; using System;
using ANX.Framework.Graphics; using ANX.Framework.Graphics;
using ANX.Framework.NonXNA; using ANX.Framework.NonXNA;
using ANX.Framework.NonXNA.Development;
using ANX.Framework.Windows.GL3.Helpers;
using OpenTK.Graphics.OpenGL; using OpenTK.Graphics.OpenGL;
#region License #region License
@ -60,8 +62,18 @@ namespace ANX.Framework.Windows.GL3
/// <para /> /// <para />
/// For Information on OpenGL blending: http://www.opengl.org/wiki/Blending /// For Information on OpenGL blending: http://www.opengl.org/wiki/Blending
/// </summary> /// </summary>
[PercentageComplete(90)]
[TestStateAttribute(TestStateAttribute.TestState.Untested)]
public class BlendStateGL3 : INativeBlendState public class BlendStateGL3 : INativeBlendState
{ {
#region Private
internal static BlendStateGL3 Current
{
get;
private set;
}
#endregion
#region Public #region Public
#region IsBound #region IsBound
/// <summary> /// <summary>
@ -181,7 +193,7 @@ namespace ANX.Framework.Windows.GL3
} }
#endregion #endregion
#region Apply #region Apply (TODO)
/// <summary> /// <summary>
/// Apply the blend state on the graphics device. /// Apply the blend state on the graphics device.
/// </summary> /// </summary>
@ -189,6 +201,7 @@ namespace ANX.Framework.Windows.GL3
public void Apply(GraphicsDevice graphicsDevice) public void Apply(GraphicsDevice graphicsDevice)
{ {
IsBound = true; IsBound = true;
Current = this;
GL.Enable(EnableCap.Blend); GL.Enable(EnableCap.Blend);
@ -226,6 +239,7 @@ namespace ANX.Framework.Windows.GL3
public void Release() public void Release()
{ {
IsBound = false; IsBound = false;
Current = null;
} }
#endregion #endregion
@ -236,7 +250,6 @@ namespace ANX.Framework.Windows.GL3
public void Dispose() public void Dispose()
{ {
} }
#endregion #endregion
#region SetColorWriteChannel #region SetColorWriteChannel
@ -247,10 +260,10 @@ namespace ANX.Framework.Windows.GL3
/// <param name="channels">Mask channels to enable.</param> /// <param name="channels">Mask channels to enable.</param>
private void SetColorWriteChannel(int index, ColorWriteChannels channels) private void SetColorWriteChannel(int index, ColorWriteChannels channels)
{ {
bool r = (channels & Graphics.ColorWriteChannels.Red) == Graphics.ColorWriteChannels.Red; bool r = (channels | Graphics.ColorWriteChannels.Red) == channels;
bool g = (channels & Graphics.ColorWriteChannels.Green) == Graphics.ColorWriteChannels.Green; bool g = (channels | Graphics.ColorWriteChannels.Green) == channels;
bool b = (channels & Graphics.ColorWriteChannels.Blue) == Graphics.ColorWriteChannels.Blue; bool b = (channels | Graphics.ColorWriteChannels.Blue) == channels;
bool a = (channels & Graphics.ColorWriteChannels.Alpha) == Graphics.ColorWriteChannels.Alpha; bool a = (channels | Graphics.ColorWriteChannels.Alpha) == channels;
GL.ColorMask(index, r, g, b, a); GL.ColorMask(index, r, g, b, a);
ErrorHelper.Check("ColorMask"); ErrorHelper.Check("ColorMask");
@ -267,10 +280,6 @@ namespace ANX.Framework.Windows.GL3
{ {
switch (blending) switch (blending)
{ {
default:
throw new NotSupportedException("The blend mode '" + blending +
"' is not supported for OpenGL BlendingFactorSrc!");
case Blend.SourceAlpha: case Blend.SourceAlpha:
return BlendingFactorSrc.SrcAlpha; return BlendingFactorSrc.SrcAlpha;
@ -297,6 +306,10 @@ namespace ANX.Framework.Windows.GL3
case Blend.Zero: case Blend.Zero:
return BlendingFactorSrc.Zero; return BlendingFactorSrc.Zero;
default:
throw new ArgumentException("Unable to translate SourceBlend '" +
blending + "' to OpenGL BlendingFactorSrc.");
} }
} }
#endregion #endregion
@ -314,10 +327,6 @@ namespace ANX.Framework.Windows.GL3
case Blend.SourceAlpha: case Blend.SourceAlpha:
return BlendingFactorDest.SrcAlpha; return BlendingFactorDest.SrcAlpha;
default:
throw new NotSupportedException("The blend mode '" + blending +
"' is not supported for OpenGL BlendingFactorDest!");
case Blend.DestinationAlpha: case Blend.DestinationAlpha:
return BlendingFactorDest.DstAlpha; return BlendingFactorDest.DstAlpha;
@ -344,6 +353,10 @@ namespace ANX.Framework.Windows.GL3
case Blend.Zero: case Blend.Zero:
return BlendingFactorDest.Zero; return BlendingFactorDest.Zero;
default:
throw new ArgumentException("Unable to translate DestinationBlend '" +
blending + "' to OpenGL BlendingFactorDest.");
} }
} }
#endregion #endregion
@ -374,7 +387,8 @@ namespace ANX.Framework.Windows.GL3
return BlendEquationMode.Max; return BlendEquationMode.Max;
} }
throw new ArgumentException("don't know how to translate BlendFunction '" + func.ToString() + "' to BlendEquationMode"); throw new ArgumentException("Unable to translate BlendFunction '" +
func + "' to OpenGL BlendEquationMode.");
} }
#endregion #endregion
} }

View File

@ -4,6 +4,7 @@ using System.Collections.ObjectModel;
using System.IO; using System.IO;
using ANX.Framework.Graphics; using ANX.Framework.Graphics;
using ANX.Framework.NonXNA; using ANX.Framework.NonXNA;
using ANX.Framework.NonXNA.Development;
using ANX.Framework.NonXNA.RenderSystem; using ANX.Framework.NonXNA.RenderSystem;
using NLog; using NLog;
using OpenTK; using OpenTK;
@ -60,6 +61,8 @@ namespace ANX.Framework.Windows.GL3
/// <summary> /// <summary>
/// OpenGL graphics creator. /// OpenGL graphics creator.
/// </summary> /// </summary>
[PercentageComplete(90)]
[TestState(TestStateAttribute.TestState.Untested)]
public class Creator : IRenderSystemCreator public class Creator : IRenderSystemCreator
{ {
private static Logger logger = LogManager.GetCurrentClassLogger(); private static Logger logger = LogManager.GetCurrentClassLogger();
@ -283,7 +286,7 @@ namespace ANX.Framework.Windows.GL3
} }
#endregion #endregion
#region GetAdapterList #region GetAdapterList (TODO)
/// <summary> /// <summary>
/// Get a list of available graphics adapter information. /// Get a list of available graphics adapter information.
/// </summary> /// </summary>

View File

@ -1,6 +1,6 @@
using System; using ANX.Framework.Graphics;
using ANX.Framework.NonXNA; using ANX.Framework.NonXNA;
using ANX.Framework.Graphics; using ANX.Framework.NonXNA.Development;
using OpenTK.Graphics.OpenGL; using OpenTK.Graphics.OpenGL;
#region License #region License
@ -58,8 +58,18 @@ namespace ANX.Framework.Windows.GL3
/// Basically this is a wrapper class for setting the different values all /// Basically this is a wrapper class for setting the different values all
/// at once, because OpenGL has no State objects like DirectX. /// at once, because OpenGL has no State objects like DirectX.
/// </summary> /// </summary>
[PercentageComplete(100)]
[TestStateAttribute(TestStateAttribute.TestState.Untested)]
public class DepthStencilStateGL3 : INativeDepthStencilState public class DepthStencilStateGL3 : INativeDepthStencilState
{ {
#region Private
internal static DepthStencilStateGL3 Current
{
get;
private set;
}
#endregion
#region Public #region Public
#region IsBound #region IsBound
/// <summary> /// <summary>
@ -219,6 +229,7 @@ namespace ANX.Framework.Windows.GL3
public void Apply(GraphicsDevice graphicsDevice) public void Apply(GraphicsDevice graphicsDevice)
{ {
IsBound = true; IsBound = true;
Current = this;
#region Depth #region Depth
if (DepthBufferEnable) if (DepthBufferEnable)
@ -416,6 +427,7 @@ namespace ANX.Framework.Windows.GL3
public void Release() public void Release()
{ {
IsBound = false; IsBound = false;
Current = null;
} }
#endregion #endregion

View File

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.IO; using System.IO;
using ANX.Framework.Graphics; using ANX.Framework.Graphics;
using ANX.Framework.NonXNA; using ANX.Framework.NonXNA;
using ANX.Framework.Windows.GL3.Helpers;
using OpenTK.Graphics.OpenGL; using OpenTK.Graphics.OpenGL;
#region License #region License
@ -84,6 +85,11 @@ namespace ANX.Framework.Windows.GL3
{ {
get get
{ {
if (managedEffect.CurrentTechnique == null)
{
return null;
}
return managedEffect.CurrentTechnique.NativeTechnique as EffectTechniqueGL3; return managedEffect.CurrentTechnique.NativeTechnique as EffectTechniqueGL3;
} }
} }
@ -92,6 +98,8 @@ namespace ANX.Framework.Windows.GL3
/// The active uniforms of this technique. /// The active uniforms of this technique.
/// </summary> /// </summary>
internal List<EffectParameter> parameters; internal List<EffectParameter> parameters;
internal bool IsDisposed;
#endregion #endregion
#region Public #region Public
@ -102,7 +110,7 @@ namespace ANX.Framework.Windows.GL3
{ {
if (techniques.Count == 0) if (techniques.Count == 0)
{ {
CompileTechniques(); Compile();
} }
return techniques; return techniques;
@ -115,6 +123,11 @@ namespace ANX.Framework.Windows.GL3
{ {
get get
{ {
if (techniques.Count == 0)
{
Compile();
}
return parameters; return parameters;
} }
} }
@ -128,11 +141,18 @@ namespace ANX.Framework.Windows.GL3
/// <param name="setManagedEffect"></param> /// <param name="setManagedEffect"></param>
private EffectGL3(Effect setManagedEffect) private EffectGL3(Effect setManagedEffect)
{ {
GraphicsResourceManager.UpdateResource(this, true);
parameters = new List<EffectParameter>(); parameters = new List<EffectParameter>();
techniques = new List<EffectTechnique>(); techniques = new List<EffectTechnique>();
managedEffect = setManagedEffect; managedEffect = setManagedEffect;
} }
~EffectGL3()
{
GraphicsResourceManager.UpdateResource(this, false);
}
/// <summary> /// <summary>
/// Create a new effect instance of separate streams. /// Create a new effect instance of separate streams.
/// </summary> /// </summary>
@ -160,8 +180,15 @@ namespace ANX.Framework.Windows.GL3
} }
#endregion #endregion
#region CompileTechniques #region RecreateData
private void CompileTechniques() internal void RecreateData()
{
Compile();
}
#endregion
#region Compile
private void Compile()
{ {
parameters.Clear(); parameters.Clear();
techniques.Clear(); techniques.Clear();
@ -302,9 +329,24 @@ namespace ANX.Framework.Windows.GL3
/// </summary> /// </summary>
public void Dispose() public void Dispose()
{ {
if (IsDisposed == false)
{
IsDisposed = true;
DisposeResource();
}
}
internal void DisposeResource()
{
if (GraphicsDeviceWindowsGL3.IsContextCurrent == false)
{
return;
}
foreach (EffectTechnique technique in techniques) foreach (EffectTechnique technique in techniques)
{ {
int programHandle = (technique.NativeTechnique as EffectTechniqueGL3).programHandle; int programHandle =
(technique.NativeTechnique as EffectTechniqueGL3).programHandle;
GL.DeleteProgram(programHandle); GL.DeleteProgram(programHandle);
ErrorHelper.Check("DeleteProgram"); ErrorHelper.Check("DeleteProgram");
@ -315,12 +357,12 @@ namespace ANX.Framework.Windows.GL3
{ {
string deleteError; string deleteError;
GL.GetProgramInfoLog(programHandle, out deleteError); GL.GetProgramInfoLog(programHandle, out deleteError);
throw new Exception("Failed to delete the shader program '" + technique.Name + throw new Exception("Failed to delete the shader program '" +
"' because of: " + deleteError); technique.Name + "' because of: " + deleteError);
} }
} }
techniques.Clear(); techniques.Clear();
parameters.Clear();
} }
#endregion #endregion
} }

View File

@ -1,6 +1,6 @@
using System; using System;
using ANX.Framework.NonXNA;
using ANX.Framework.Graphics; using ANX.Framework.Graphics;
using ANX.Framework.NonXNA;
using OpenTK.Graphics.OpenGL; using OpenTK.Graphics.OpenGL;
#region License #region License
@ -161,8 +161,9 @@ namespace ANX.Framework.Windows.GL3
GL.UseProgram(parentTechnique.programHandle); GL.UseProgram(parentTechnique.programHandle);
ErrorHelper.Check("UseProgram"); ErrorHelper.Check("UseProgram");
if (textureCache == null || if (textureCache == null ||
textureCache != value) textureCache != value)
{ {
textureCache = value;
// TODO: multiple texture units // TODO: multiple texture units
TextureUnit textureUnit = TextureUnit.Texture0; TextureUnit textureUnit = TextureUnit.Texture0;
GL.ActiveTexture(textureUnit); GL.ActiveTexture(textureUnit);

View File

@ -76,12 +76,24 @@ namespace ANX.Framework.Windows.GL3
/// </summary> /// </summary>
private IWindowInfo nativeWindowInfo; private IWindowInfo nativeWindowInfo;
internal static VertexBufferGL3[] boundVertexBuffers = internal static VertexBufferGL3[] boundVertexBuffers;
new VertexBufferGL3[0]; private static RenderTarget2DGL3[] boundRenderTargets;
private static RenderTarget2DGL3[] boundRenderTargets =
new RenderTarget2DGL3[0];
internal static IndexBufferGL3 boundIndexBuffer; internal static IndexBufferGL3 boundIndexBuffer;
internal static EffectGL3 activeEffect; internal static EffectGL3 activeEffect;
internal static GraphicsDeviceWindowsGL3 Current
{
get;
private set;
}
internal static bool IsContextCurrent
{
get
{
return Current.nativeContext.IsCurrent;
}
}
#endregion #endregion
#region Public #region Public
@ -109,6 +121,7 @@ namespace ANX.Framework.Windows.GL3
internal GraphicsDeviceWindowsGL3( internal GraphicsDeviceWindowsGL3(
PresentationParameters presentationParameters) PresentationParameters presentationParameters)
{ {
Current = this;
ResetDevice(presentationParameters); ResetDevice(presentationParameters);
} }
#endregion #endregion
@ -125,17 +138,16 @@ namespace ANX.Framework.Windows.GL3
#region Validation #region Validation
if (nativeContext != null) if (nativeContext != null)
{ {
nativeContext.Dispose(); Dispose();
nativeContext = null;
}
if (nativeWindowInfo != null)
{
nativeWindowInfo.Dispose();
nativeWindowInfo = null;
} }
#endregion #endregion
// Reset the previous set buffers, effects and targets.
boundVertexBuffers = new VertexBufferGL3[0];
boundRenderTargets = new RenderTarget2DGL3[0];
boundIndexBuffer = null;
activeEffect = null;
// OpenGL Depth Buffer Size: 0/16/24/32 // OpenGL Depth Buffer Size: 0/16/24/32
int depth = 0; int depth = 0;
int stencil = 0; int stencil = 0;
@ -183,6 +195,8 @@ namespace ANX.Framework.Windows.GL3
// int.Parse(parts[0]), int.Parse(parts[1]), GraphicsContextFlags.Default); // int.Parse(parts[0]), int.Parse(parts[1]), GraphicsContextFlags.Default);
//nativeContext.MakeCurrent(nativeWindowInfo); //nativeContext.MakeCurrent(nativeWindowInfo);
//nativeContext.LoadAll(); //nativeContext.LoadAll();
GraphicsResourceManager.RecreateAllResources();
} }
#endregion #endregion
@ -223,7 +237,7 @@ namespace ANX.Framework.Windows.GL3
#endregion #endregion
#region Clear #region Clear
private uint lastClearColor; private uint? lastClearColor;
/// <summary> /// <summary>
/// Clear the current screen by the specified clear color. /// Clear the current screen by the specified clear color.
/// </summary> /// </summary>
@ -231,7 +245,8 @@ namespace ANX.Framework.Windows.GL3
public void Clear(ref Color color) public void Clear(ref Color color)
{ {
uint newClearColor = color.PackedValue; uint newClearColor = color.PackedValue;
if (lastClearColor != newClearColor) if (lastClearColor.HasValue == false ||
lastClearColor != newClearColor)
{ {
lastClearColor = newClearColor; lastClearColor = newClearColor;
GL.ClearColor(color.R * ColorMultiplier, color.G * ColorMultiplier, GL.ClearColor(color.R * ColorMultiplier, color.G * ColorMultiplier,
@ -422,7 +437,9 @@ namespace ANX.Framework.Windows.GL3
} }
else else
{ {
throw new NotImplementedException(); LinuxInterop.ResizeWindow(presentationParameters.DeviceWindowHandle,
presentationParameters.BackBufferWidth,
presentationParameters.BackBufferHeight);
} }
} }
#endregion #endregion
@ -467,6 +484,7 @@ namespace ANX.Framework.Windows.GL3
public void GetBackBufferData<T>(T[] data) where T : struct public void GetBackBufferData<T>(T[] data) where T : struct
{ {
//glReadPixels(0, 0, nWidth, nHeight, GL_RGB, GL_UNSIGNED_BYTE, m_pPixelData)
throw new NotImplementedException(); throw new NotImplementedException();
} }
@ -477,18 +495,24 @@ namespace ANX.Framework.Windows.GL3
} }
#endregion #endregion
#region ResizeBuffers (TODO) #region ResizeBuffers
public void ResizeBuffers(PresentationParameters presentationParameters) public void ResizeBuffers(PresentationParameters presentationParameters)
{ {
ResizeRenderWindow(presentationParameters); ResizeRenderWindow(presentationParameters);
throw new NotImplementedException(); GL.Viewport(0, 0, presentationParameters.BackBufferWidth,
presentationParameters.BackBufferHeight);
ResetDevice(presentationParameters);
} }
#endregion #endregion
#region Dispose #region Dispose
public void Dispose() public void Dispose()
{ {
GraphicsResourceManager.DisposeAllResources();
lastClearColor = new uint?();
boundVertexBuffers = null; boundVertexBuffers = null;
boundIndexBuffer = null; boundIndexBuffer = null;
activeEffect = null; activeEffect = null;

View File

@ -50,7 +50,7 @@ using OpenTK.Graphics.OpenGL;
#endregion // License #endregion // License
namespace ANX.Framework.Windows.GL3 namespace ANX.Framework.Windows.GL3.Helpers
{ {
internal static class DatatypesMapping internal static class DatatypesMapping
{ {
@ -198,6 +198,7 @@ namespace ANX.Framework.Windows.GL3
case SurfaceFormat.HalfVector2: case SurfaceFormat.HalfVector2:
return PixelInternalFormat.Rg16; return PixelInternalFormat.Rg16;
case SurfaceFormat.Rgba64:
case SurfaceFormat.HalfVector4: case SurfaceFormat.HalfVector4:
return PixelInternalFormat.Rgba16f; return PixelInternalFormat.Rgba16f;
@ -210,24 +211,19 @@ namespace ANX.Framework.Windows.GL3
case SurfaceFormat.Alpha8: case SurfaceFormat.Alpha8:
return PixelInternalFormat.Alpha8; return PixelInternalFormat.Alpha8;
case SurfaceFormat.Vector2:
case SurfaceFormat.Rg32: case SurfaceFormat.Rg32:
return PixelInternalFormat.Rg32f; return PixelInternalFormat.Rg32f;
case SurfaceFormat.Rgba1010102: case SurfaceFormat.Rgba1010102:
return PixelInternalFormat.Rgb10A2; return PixelInternalFormat.Rgb10A2;
case SurfaceFormat.Rgba64:
return PixelInternalFormat.Rgba16f;
case SurfaceFormat.HalfSingle: case SurfaceFormat.HalfSingle:
return PixelInternalFormat.R16f; return PixelInternalFormat.R16f;
case SurfaceFormat.Single: case SurfaceFormat.Single:
return PixelInternalFormat.R32f; return PixelInternalFormat.R32f;
case SurfaceFormat.Vector2:
return PixelInternalFormat.Rg32f;
case SurfaceFormat.Vector4: case SurfaceFormat.Vector4:
return PixelInternalFormat.Rgba32f; return PixelInternalFormat.Rgba32f;
} }
@ -268,6 +264,26 @@ namespace ANX.Framework.Windows.GL3
#region Tests #region Tests
private class Tests private class Tests
{ {
#region TestConvertColorToOtkColor
public static void TestConvertColorToOtkColor()
{
Color anxColor = new Color(1f, 0.5f, 0.75f, 0f);
Color4 color;
DatatypesMapping.Convert(ref anxColor, out color);
Console.WriteLine(color.ToString());
}
#endregion
#region TestConvertOtkColorToColor
public static void TestConvertOtkColorToColor()
{
Color4 color = new Color4(1f, 0.5f, 0.75f, 0f);
Color anxColor;
DatatypesMapping.Convert(ref color, out anxColor);
Console.WriteLine(anxColor.ToString());
}
#endregion
#region TestConvertVector4ToColor #region TestConvertVector4ToColor
public static void TestConvertVector4ToColor() public static void TestConvertVector4ToColor()
{ {
@ -277,6 +293,49 @@ namespace ANX.Framework.Windows.GL3
Console.WriteLine(color.ToString()); Console.WriteLine(color.ToString());
} }
#endregion #endregion
#region TestPrimitiveTypeToBeginMode
public static void TestPrimitiveTypeToBeginMode()
{
PrimitiveType type = PrimitiveType.LineList;
int primitiveCount = 10;
int count = 0;
BeginMode result = DatatypesMapping.PrimitiveTypeToBeginMode(type,
primitiveCount, out count);
AssetValues(result, BeginMode.Lines);
AssetValues(count, primitiveCount * 2);
type = PrimitiveType.LineStrip;
result = DatatypesMapping.PrimitiveTypeToBeginMode(type, primitiveCount,
out count);
AssetValues(result, BeginMode.LineStrip);
AssetValues(count, primitiveCount + 1);
type = PrimitiveType.TriangleList;
result = DatatypesMapping.PrimitiveTypeToBeginMode(type, primitiveCount,
out count);
AssetValues(result, BeginMode.Triangles);
AssetValues(count, primitiveCount * 3);
type = PrimitiveType.TriangleStrip;
result = DatatypesMapping.PrimitiveTypeToBeginMode(type, primitiveCount,
out count);
AssetValues(result, BeginMode.TriangleStrip);
AssetValues(count, primitiveCount + 2);
}
#endregion
#region AssetValues
private static void AssetValues<T>(T first, T second)
{
if (first.Equals(second) == false)
{
throw new Exception("The two values are not equal:\n\t1: " + first +
"\n\t2: " + second);
}
}
#endregion
} }
#endregion #endregion
} }

View File

@ -0,0 +1,238 @@
using System;
using System.Collections.Generic;
#region License
//
// This file is part of the ANX.Framework created by the "ANX.Framework developer group".
//
// This file is released under the Ms-PL license.
//
//
//
// Microsoft Public License (Ms-PL)
//
// This license governs use of the accompanying software. If you use the software, you accept this license.
// If you do not accept the license, do not use the software.
//
// 1.Definitions
// The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning
// here as under U.S. copyright law.
// A "contribution" is the original software, or any additions or changes to the software.
// A "contributor" is any person that distributes its contribution under this license.
// "Licensed patents" are a contributor's patent claims that read directly on its contribution.
//
// 2.Grant of Rights
// (A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations
// in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to
// reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution
// or any derivative works that you create.
// (B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in
// section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed
// patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution
// in the software or derivative works of the contribution in the software.
//
// 3.Conditions and Limitations
// (A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
// (B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your
// patent license from such contributor to the software ends automatically.
// (C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution
// notices that are present in the software.
// (D) If you distribute any portion of the software in source code form, you may do so only under this license by including
// a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or
// object code form, you may only do so under a license that complies with this license.
// (E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees,
// or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the
// extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a
// particular purpose and non-infringement.
#endregion // License
namespace ANX.Framework.Windows.GL3.Helpers
{
internal static class GraphicsResourceManager
{
#region Private
private static List<Texture2DGL3> allTextures;
private static List<EffectGL3> allEffects;
private static List<VertexBufferGL3> allVertexBuffers;
private static List<IndexBufferGL3> allIndexBuffers;
#endregion
#region Constructor
static GraphicsResourceManager()
{
allTextures = new List<Texture2DGL3>();
allEffects = new List<EffectGL3>();
allVertexBuffers = new List<VertexBufferGL3>();
allIndexBuffers = new List<IndexBufferGL3>();
}
#endregion
#region UpdateResource
public static void UpdateResource<T>(T resource, bool register)
{
IList<T> list = null;
if (typeof(T) == typeof(Texture2DGL3))
{
list = (IList<T>)allTextures;
}
else if (typeof(T) == typeof(EffectGL3))
{
list = (IList<T>)allEffects;
}
else if (typeof(T) == typeof(VertexBufferGL3))
{
list = (IList<T>)allVertexBuffers;
}
else if (typeof(T) == typeof(IndexBufferGL3))
{
list = (IList<T>)allIndexBuffers;
}
lock (list)
{
if (register)
{
list.Add(resource);
}
else
{
list.Remove(resource);
}
}
}
#endregion
#region DisposeAllResources
public static void DisposeAllResources()
{
#region Textures
lock (allTextures)
{
foreach (Texture2DGL3 texture in allTextures)
{
if (texture.IsDisposed == false)
{
texture.DisposeResource();
}
}
}
#endregion
#region Effects
lock (allEffects)
{
foreach (EffectGL3 effect in allEffects)
{
if (effect.IsDisposed == false)
{
effect.DisposeResource();
}
}
}
#endregion
#region VertexBuffers
lock (allVertexBuffers)
{
foreach (VertexBufferGL3 buffer in allVertexBuffers)
{
if (buffer.IsDisposed == false)
{
buffer.DisposeResource();
}
}
}
#endregion
#region IndexBuffers
lock (allIndexBuffers)
{
foreach (IndexBufferGL3 buffer in allIndexBuffers)
{
if (buffer.IsDisposed == false)
{
buffer.DisposeResource();
}
}
}
#endregion
}
#endregion
#region RecreateAllResources
public static void RecreateAllResources()
{
#region Textures
lock (allTextures)
{
foreach (Texture2DGL3 texture in allTextures)
{
if (texture.IsDisposed == false)
{
texture.RecreateData();
}
}
}
#endregion
#region Effects
lock (allEffects)
{
foreach (EffectGL3 effect in allEffects)
{
if (effect.IsDisposed == false)
{
effect.RecreateData();
}
}
}
#endregion
#region VertexBuffers
lock (allVertexBuffers)
{
foreach (VertexBufferGL3 buffer in allVertexBuffers)
{
if (buffer.IsDisposed == false)
{
buffer.RecreateData();
}
}
}
#endregion
#region IndexBuffers
lock (allIndexBuffers)
{
foreach (IndexBufferGL3 buffer in allIndexBuffers)
{
if (buffer.IsDisposed == false)
{
buffer.RecreateData();
}
}
}
#endregion
if (BlendStateGL3.Current != null)
{
BlendStateGL3.Current.Apply(null);
}
if (RasterizerStateGL3.Current != null)
{
RasterizerStateGL3.Current.Apply(null);
}
if (DepthStencilStateGL3.Current != null)
{
DepthStencilStateGL3.Current.Apply(null);
}
}
#endregion
}
}

View File

@ -88,6 +88,10 @@ namespace ANX.Framework.Windows.GL3.Helpers
[DllImport("libX11")] [DllImport("libX11")]
private static extern int XPending(IntPtr diplay); private static extern int XPending(IntPtr diplay);
[DllImport("libX11")]
private static extern void XResizeWindow(IntPtr display, IntPtr window,
int width, int height);
#endregion #endregion
#region GetStaticFieldValue #region GetStaticFieldValue
@ -145,5 +149,13 @@ namespace ANX.Framework.Windows.GL3.Helpers
rootWindow, infoPtr); rootWindow, infoPtr);
} }
#endregion #endregion
#region ResizeWindow
public static void ResizeWindow(IntPtr windowHandle, int backBufferWidth,
int backBufferHeight)
{
XResizeWindow(IntPtr.Zero, windowHandle, backBufferWidth, backBufferHeight);
}
#endregion
} }
} }

View File

@ -1,6 +1,7 @@
using System; using System;
using ANX.Framework.NonXNA;
using ANX.Framework.Graphics; using ANX.Framework.Graphics;
using ANX.Framework.NonXNA;
using ANX.Framework.Windows.GL3.Helpers;
using OpenTK.Graphics.OpenGL; using OpenTK.Graphics.OpenGL;
#region License #region License
@ -77,6 +78,8 @@ namespace ANX.Framework.Windows.GL3
private BufferUsage usage; private BufferUsage usage;
private BufferUsageHint usageHint; private BufferUsageHint usageHint;
internal bool IsDisposed;
#endregion #endregion
#region Constructor #region Constructor
@ -86,6 +89,8 @@ namespace ANX.Framework.Windows.GL3
internal IndexBufferGL3(IndexElementSize setElementSize, internal IndexBufferGL3(IndexElementSize setElementSize,
int setIndexCount, BufferUsage setUsage) int setIndexCount, BufferUsage setUsage)
{ {
GraphicsResourceManager.UpdateResource(this, true);
indexCount = setIndexCount; indexCount = setIndexCount;
elementSize = setElementSize; elementSize = setElementSize;
usage = setUsage; usage = setUsage;
@ -97,8 +102,43 @@ namespace ANX.Framework.Windows.GL3
BufferUsageHint.DynamicDraw : BufferUsageHint.DynamicDraw :
BufferUsageHint.StaticDraw; BufferUsageHint.StaticDraw;
CreateBuffer();
}
~IndexBufferGL3()
{
GraphicsResourceManager.UpdateResource(this, false);
}
#endregion
#region CreateBuffer
private void CreateBuffer()
{
GL.GenBuffers(1, out bufferHandle); GL.GenBuffers(1, out bufferHandle);
ErrorHelper.Check("GenBuffers"); ErrorHelper.Check("GenBuffers");
GL.BindBuffer(BufferTarget.ElementArrayBuffer, bufferHandle);
ErrorHelper.Check("BindBuffer");
int size = indexCount *
(elementSize == IndexElementSize.SixteenBits ? 16 : 32);
GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)size, IntPtr.Zero,
usageHint);
ErrorHelper.Check("BufferData");
int setSize;
GL.GetBufferParameter(BufferTarget.ElementArrayBuffer,
BufferParameterName.BufferSize, out setSize);
if (setSize != size)
{
throw new Exception("Failed to set the vertexBuffer data. DataSize=" +
size + " SetSize=" + setSize);
}
}
#endregion
#region RecreateData
internal void RecreateData()
{
CreateBuffer();
} }
#endregion #endregion
@ -185,8 +225,22 @@ namespace ANX.Framework.Windows.GL3
/// </summary> /// </summary>
public void Dispose() public void Dispose()
{ {
GL.DeleteBuffers(1, ref bufferHandle); if (IsDisposed == false)
ErrorHelper.Check("DeleteBuffers"); {
IsDisposed = true;
DisposeResource();
}
}
internal void DisposeResource()
{
if (bufferHandle != -1 &&
GraphicsDeviceWindowsGL3.IsContextCurrent)
{
GL.DeleteBuffers(1, ref bufferHandle);
ErrorHelper.Check("DeleteBuffers");
bufferHandle = -1;
}
} }
#endregion #endregion
} }

View File

@ -1,6 +1,6 @@
using System; using ANX.Framework.Graphics;
using ANX.Framework.NonXNA; using ANX.Framework.NonXNA;
using ANX.Framework.Graphics; using ANX.Framework.NonXNA.Development;
using OpenTK.Graphics.OpenGL; using OpenTK.Graphics.OpenGL;
#region License #region License
@ -58,8 +58,18 @@ namespace ANX.Framework.Windows.GL3
/// Basically this is a wrapper class for setting the different values all /// Basically this is a wrapper class for setting the different values all
/// at once, because OpenGL has no State objects like DirectX. /// at once, because OpenGL has no State objects like DirectX.
/// </summary> /// </summary>
[PercentageComplete(100)]
[TestStateAttribute(TestStateAttribute.TestState.Untested)]
public class RasterizerStateGL3 : INativeRasterizerState public class RasterizerStateGL3 : INativeRasterizerState
{ {
#region Private
internal static RasterizerStateGL3 Current
{
get;
private set;
}
#endregion
#region Public #region Public
#region IsBound #region IsBound
/// <summary> /// <summary>
@ -157,6 +167,7 @@ namespace ANX.Framework.Windows.GL3
public void Apply(GraphicsDevice graphicsDevice) public void Apply(GraphicsDevice graphicsDevice)
{ {
IsBound = true; IsBound = true;
Current = this;
#region Cull Mode #region Cull Mode
GL.FrontFace(FrontFaceDirection.Cw); GL.FrontFace(FrontFaceDirection.Cw);
@ -234,6 +245,7 @@ namespace ANX.Framework.Windows.GL3
public void Release() public void Release()
{ {
IsBound = false; IsBound = false;
Current = null;
} }
#endregion #endregion

View File

@ -1,6 +1,7 @@
using System; using System;
using ANX.Framework.Graphics; using ANX.Framework.Graphics;
using ANX.Framework.NonXNA.RenderSystem; using ANX.Framework.NonXNA.RenderSystem;
using ANX.Framework.Windows.GL3.Helpers;
using OpenTK.Graphics.OpenGL; using OpenTK.Graphics.OpenGL;
namespace ANX.Framework.Windows.GL3 namespace ANX.Framework.Windows.GL3
@ -19,6 +20,7 @@ namespace ANX.Framework.Windows.GL3
public RenderTarget2DGL3(int width, int height, bool mipMap, public RenderTarget2DGL3(int width, int height, bool mipMap,
SurfaceFormat preferredFormat, DepthFormat preferredDepthFormat, SurfaceFormat preferredFormat, DepthFormat preferredDepthFormat,
int preferredMultiSampleCount, RenderTargetUsage usage) int preferredMultiSampleCount, RenderTargetUsage usage)
: base()
{ {
generateMipmaps = mipMap; generateMipmaps = mipMap;
PixelInternalFormat nativeFormat = PixelInternalFormat nativeFormat =

View File

@ -2,6 +2,7 @@
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using ANX.Framework.Graphics; using ANX.Framework.Graphics;
using ANX.Framework.NonXNA.RenderSystem; using ANX.Framework.NonXNA.RenderSystem;
using ANX.Framework.Windows.GL3.Helpers;
using OpenTK.Graphics.OpenGL; using OpenTK.Graphics.OpenGL;
#region License #region License
@ -83,6 +84,17 @@ namespace ANX.Framework.Windows.GL3
/// Flag if the texture is a compressed format or not. /// Flag if the texture is a compressed format or not.
/// </summary> /// </summary>
private bool isCompressed; private bool isCompressed;
internal bool IsDisposed;
private int uncompressedDataSize;
private byte[] texData;
/// <summary>
/// TODO: find better solution
/// </summary>
private int maxSetDataSize;
#endregion #endregion
#region Public #region Public
@ -99,6 +111,7 @@ namespace ANX.Framework.Windows.GL3
#region Constructor #region Constructor
internal Texture2DGL3() internal Texture2DGL3()
{ {
GraphicsResourceManager.UpdateResource(this, true);
} }
/// <summary> /// <summary>
@ -111,13 +124,28 @@ namespace ANX.Framework.Windows.GL3
internal Texture2DGL3(SurfaceFormat surfaceFormat, int setWidth, internal Texture2DGL3(SurfaceFormat surfaceFormat, int setWidth,
int setHeight, int mipCount) int setHeight, int mipCount)
{ {
GraphicsResourceManager.UpdateResource(this, true);
width = setWidth; width = setWidth;
height = setHeight; height = setHeight;
numberOfMipMaps = mipCount; numberOfMipMaps = mipCount;
nativeFormat = nativeFormat = DatatypesMapping.SurfaceToPixelInternalFormat(surfaceFormat);
DatatypesMapping.SurfaceToPixelInternalFormat(surfaceFormat);
isCompressed = nativeFormat.ToString().StartsWith("Compressed"); isCompressed = nativeFormat.ToString().StartsWith("Compressed");
uncompressedDataSize = GetUncompressedDataSize();
CreateTexture();
}
~Texture2DGL3()
{
GraphicsResourceManager.UpdateResource(this, false);
}
#endregion
#region CreateTexture
private void CreateTexture()
{
NativeHandle = GL.GenTexture(); NativeHandle = GL.GenTexture();
#if DEBUG #if DEBUG
ErrorHelper.Check("GenTexture"); ErrorHelper.Check("GenTexture");
@ -128,7 +156,9 @@ namespace ANX.Framework.Windows.GL3
#endif #endif
int wrapMode = (int)All.ClampToEdge; int wrapMode = (int)All.ClampToEdge;
int filter = (int)(mipCount > 1 ? All.LinearMipmapLinear : All.Linear); int filter = (int)(numberOfMipMaps > 1 ?
All.LinearMipmapLinear :
All.Linear);
GL.TexParameter(TextureTarget.Texture2D, GL.TexParameter(TextureTarget.Texture2D,
TextureParameterName.TextureWrapS, wrapMode); TextureParameterName.TextureWrapS, wrapMode);
@ -174,6 +204,11 @@ namespace ANX.Framework.Windows.GL3
ErrorHelper.Check("BindTexture"); ErrorHelper.Check("BindTexture");
#endif #endif
if (data.Length > maxSetDataSize)
{
maxSetDataSize = data.Length;
}
GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned); GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned);
// TODO: get size of first mipmap! // TODO: get size of first mipmap!
@ -195,9 +230,9 @@ namespace ANX.Framework.Windows.GL3
} }
else else
{ {
GL.TexImage2D(TextureTarget.Texture2D, 0, nativeFormat, GL.TexImage2D(TextureTarget.Texture2D, 0, nativeFormat,
width, height, 0, (PixelFormat)nativeFormat, width, height, 0, (PixelFormat)nativeFormat,
PixelType.UnsignedByte, dataPointer); PixelType.UnsignedByte, dataPointer);
#if DEBUG #if DEBUG
ErrorHelper.Check("TexImage2D Format=" + nativeFormat); ErrorHelper.Check("TexImage2D Format=" + nativeFormat);
#endif #endif
@ -240,16 +275,111 @@ namespace ANX.Framework.Windows.GL3
} }
#endregion #endregion
#region GetTextureData
private void GetTextureData()
{
GL.BindTexture(TextureTarget.Texture2D, NativeHandle);
if (isCompressed)
{
texData = new byte[maxSetDataSize];
GCHandle handle = GCHandle.Alloc(texData, GCHandleType.Pinned);
GL.GetCompressedTexImage(TextureTarget.Texture2D, 0,
handle.AddrOfPinnedObject());
handle.Free();
}
else
{
texData = new byte[uncompressedDataSize];
GCHandle handle = GCHandle.Alloc(texData, GCHandleType.Pinned);
GL.GetTexImage(TextureTarget.Texture2D, 0, (PixelFormat)nativeFormat,
PixelType.UnsignedByte, handle.AddrOfPinnedObject());
handle.Free();
}
}
#endregion
#region RecreateData
internal void RecreateData()
{
CreateTexture();
SetData(null, texData);
texData = null;
}
#endregion
#region GetUncompressedDataSize
private int GetUncompressedDataSize()
{
int size = width * height;
switch (nativeFormat)
{
default:
case PixelInternalFormat.R32f:
case PixelInternalFormat.Rgb10A2:
case PixelInternalFormat.Rg16:
case PixelInternalFormat.Rgba:
size *= 4;
break;
case PixelInternalFormat.Rg32f:
case PixelInternalFormat.Rgba16f:
size *= 8;
break;
case PixelInternalFormat.R16f:
case PixelInternalFormat.Rgb5A1:
case PixelInternalFormat.Rgba4:
size *= 2;
break;
case PixelInternalFormat.Alpha8:
//size *= 1;
break;
case PixelInternalFormat.Rgba32f:
size *= 16;
break;
}
return size;
}
#endregion
#region Dispose #region Dispose
/// <summary> /// <summary>
/// Dispose the native OpenGL texture handle. /// Dispose the native OpenGL texture handle.
/// </summary> /// </summary>
public virtual void Dispose() public virtual void Dispose()
{ {
GL.DeleteTexture(NativeHandle); if (IsDisposed == false)
{
IsDisposed = true;
DisposeResource();
}
}
internal void DisposeResource()
{
if (IsDisposed == false)
{
GetTextureData();
}
if (NativeHandle != -1 &&
GraphicsDeviceWindowsGL3.IsContextCurrent)
{
GL.DeleteTexture(NativeHandle);
NativeHandle = -1;
#if DEBUG #if DEBUG
ErrorHelper.Check("DeleteTexture"); ErrorHelper.Check("DeleteTexture");
#endif #endif
}
} }
#endregion #endregion
} }

View File

@ -1,6 +1,7 @@
using System; using System;
using ANX.Framework.NonXNA;
using ANX.Framework.Graphics; using ANX.Framework.Graphics;
using ANX.Framework.NonXNA;
using ANX.Framework.Windows.GL3.Helpers;
using OpenTK.Graphics.OpenGL; using OpenTK.Graphics.OpenGL;
#region License #region License
@ -80,6 +81,8 @@ namespace ANX.Framework.Windows.GL3
private int vertexCount; private int vertexCount;
private BufferUsageHint usageHint; private BufferUsageHint usageHint;
internal bool IsDisposed;
#endregion #endregion
#region Constructor #region Constructor
@ -89,6 +92,8 @@ namespace ANX.Framework.Windows.GL3
internal VertexBufferGL3(VertexDeclaration setVertexDeclaration, internal VertexBufferGL3(VertexDeclaration setVertexDeclaration,
int setVertexCount, BufferUsage setUsage) int setVertexCount, BufferUsage setUsage)
{ {
GraphicsResourceManager.UpdateResource(this, true);
vertexDeclaration = setVertexDeclaration; vertexDeclaration = setVertexDeclaration;
usage = setUsage; usage = setUsage;
vertexCount = setVertexCount; vertexCount = setVertexCount;
@ -100,11 +105,23 @@ namespace ANX.Framework.Windows.GL3
BufferUsageHint.DynamicDraw : BufferUsageHint.DynamicDraw :
BufferUsageHint.StaticDraw; BufferUsageHint.StaticDraw;
CreateBuffer();
}
~VertexBufferGL3()
{
GraphicsResourceManager.UpdateResource(this, false);
}
#endregion
#region CreateBuffer
private void CreateBuffer()
{
GL.GenBuffers(1, out bufferHandle); GL.GenBuffers(1, out bufferHandle);
ErrorHelper.Check("GenBuffers"); ErrorHelper.Check("GenBuffers");
GL.BindBuffer(BufferTarget.ArrayBuffer, bufferHandle); GL.BindBuffer(BufferTarget.ArrayBuffer, bufferHandle);
ErrorHelper.Check("BindBuffer"); ErrorHelper.Check("BindBuffer");
int size = vertexDeclaration.VertexStride * setVertexCount; int size = vertexDeclaration.VertexStride * vertexCount;
GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)size, IntPtr.Zero, GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)size, IntPtr.Zero,
usageHint); usageHint);
ErrorHelper.Check("BufferData"); ErrorHelper.Check("BufferData");
@ -120,6 +137,13 @@ namespace ANX.Framework.Windows.GL3
} }
#endregion #endregion
#region RecreateData
internal void RecreateData()
{
CreateBuffer();
}
#endregion
#region SetData #region SetData
public void SetData<T>(GraphicsDevice graphicsDevice, T[] data) public void SetData<T>(GraphicsDevice graphicsDevice, T[] data)
where T : struct where T : struct
@ -243,8 +267,22 @@ namespace ANX.Framework.Windows.GL3
/// </summary> /// </summary>
public void Dispose() public void Dispose()
{ {
GL.DeleteBuffers(1, ref bufferHandle); if (IsDisposed == false)
ErrorHelper.Check("DeleteBuffers"); {
IsDisposed = true;
DisposeResource();
}
}
internal void DisposeResource()
{
if (bufferHandle != -1 &&
GraphicsDeviceWindowsGL3.IsContextCurrent)
{
GL.DeleteBuffers(1, ref bufferHandle);
ErrorHelper.Check("DeleteBuffers");
bufferHandle = -1;
}
} }
#endregion #endregion
} }