Also did some Refactoring for Classes that implement and use INativeBuffer. The memory usage reduction for rendertargets resulted in some refactoring of the directx texture classes. Also added DebugNames for some DirectX resources in case of a debug build.
259 lines
6.2 KiB
C#
259 lines
6.2 KiB
C#
using System;
|
|
using ANX.Framework.Graphics;
|
|
using ANX.Framework.NonXNA.RenderSystem;
|
|
using OpenTK.Graphics.OpenGL;
|
|
using ANX.RenderSystem.GL3.Helpers;
|
|
|
|
// 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.GL3
|
|
{
|
|
/// <summary>
|
|
/// Native OpenGL implementation of a Index Buffer.
|
|
/// </summary>
|
|
public class IndexBufferGL3 : INativeIndexBuffer
|
|
{
|
|
#region Private
|
|
private IndexBuffer managedBuffer;
|
|
|
|
private int bufferHandle;
|
|
/// <summary>
|
|
/// Native index buffer handle.
|
|
/// </summary>
|
|
internal int BufferHandle
|
|
{
|
|
get
|
|
{
|
|
return bufferHandle;
|
|
}
|
|
}
|
|
|
|
private int indexCount;
|
|
|
|
internal IndexElementSize elementSize;
|
|
|
|
private BufferUsage usage;
|
|
|
|
private BufferUsageHint usageHint;
|
|
|
|
internal bool IsDisposed;
|
|
#endregion
|
|
|
|
#region Constructor
|
|
/// <summary>
|
|
/// Create a new Index Buffer object.
|
|
/// </summary>
|
|
internal IndexBufferGL3(IndexBuffer setManagedBuffer,
|
|
IndexElementSize setElementSize, int setIndexCount, BufferUsage setUsage)
|
|
{
|
|
GraphicsResourceManager.UpdateResource(this, true);
|
|
|
|
managedBuffer = setManagedBuffer;
|
|
indexCount = setIndexCount;
|
|
elementSize = setElementSize;
|
|
usage = setUsage;
|
|
|
|
bool isDynamicBuffer = managedBuffer is DynamicIndexBuffer;
|
|
|
|
usageHint = isDynamicBuffer ?
|
|
BufferUsageHint.DynamicDraw :
|
|
BufferUsageHint.StaticDraw;
|
|
|
|
CreateBuffer();
|
|
}
|
|
|
|
~IndexBufferGL3()
|
|
{
|
|
GraphicsResourceManager.UpdateResource(this, false);
|
|
}
|
|
#endregion
|
|
|
|
#region CreateBuffer
|
|
private void CreateBuffer()
|
|
{
|
|
GL.GenBuffers(1, out bufferHandle);
|
|
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
|
|
|
|
#region SetData
|
|
public void SetData<T>(T[] data)
|
|
where T : struct
|
|
{
|
|
BufferData(data, 0);
|
|
}
|
|
|
|
public void SetData<T>(T[] data, int startIndex, int elementCount) where T : struct
|
|
{
|
|
if (startIndex != 0 ||
|
|
elementCount != data.Length)
|
|
{
|
|
T[] subArray = new T[elementCount];
|
|
Array.Copy(data, startIndex, subArray, 0, elementCount);
|
|
BufferData(subArray, 0);
|
|
}
|
|
else
|
|
{
|
|
BufferData(data, 0);
|
|
}
|
|
}
|
|
|
|
public void SetData<T>(int offsetInBytes, T[] data, int startIndex, int elementCount) where T : struct
|
|
{
|
|
if (startIndex != 0 ||
|
|
elementCount != data.Length)
|
|
{
|
|
T[] subArray = new T[elementCount];
|
|
Array.Copy(data, startIndex, subArray, 0, elementCount);
|
|
BufferData(subArray, offsetInBytes);
|
|
}
|
|
else
|
|
{
|
|
BufferData(data, offsetInBytes);
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region BufferData (private helper)
|
|
private void BufferData<T>(T[] data, int offset) where T : struct
|
|
{
|
|
int size = (elementSize == IndexElementSize.SixteenBits ?
|
|
2 : 4) * data.Length;
|
|
|
|
GL.BindBuffer(BufferTarget.ElementArrayBuffer, bufferHandle);
|
|
ErrorHelper.Check("BindBuffer");
|
|
|
|
if (offset == 0)
|
|
{
|
|
GL.BufferData(BufferTarget.ElementArrayBuffer, (IntPtr)size, data,
|
|
usageHint);
|
|
ErrorHelper.Check("BufferData size=" + size);
|
|
}
|
|
else
|
|
{
|
|
GL.BufferSubData(BufferTarget.ElementArrayBuffer, (IntPtr)offset,
|
|
(IntPtr)size, data);
|
|
ErrorHelper.Check("BufferSubData offset=" + offset + " size=" + size);
|
|
}
|
|
|
|
int setSize;
|
|
GL.GetBufferParameter(BufferTarget.ElementArrayBuffer,
|
|
BufferParameterName.BufferSize, out setSize);
|
|
if (setSize != size)
|
|
{
|
|
throw new Exception("Failed to set the indexBuffer data. DataSize=" +
|
|
size + " SetSize=" + setSize);
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region GetData
|
|
public void GetData<T>(T[] data) where T : struct
|
|
{
|
|
BufferData(data, 0);
|
|
}
|
|
#endregion
|
|
|
|
#region GetData
|
|
public void GetData<T>(T[] data, int startIndex, int elementCount)
|
|
where T : struct
|
|
{
|
|
if (startIndex != 0 ||
|
|
elementCount != data.Length)
|
|
{
|
|
T[] subArray = new T[elementCount];
|
|
Array.Copy(data, startIndex, subArray, 0, elementCount);
|
|
BufferData(subArray, 0);
|
|
}
|
|
else
|
|
{
|
|
BufferData(data, 0);
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region GetData
|
|
public void GetData<T>(int offsetInBytes, T[] data, int startIndex,
|
|
int elementCount) where T : struct
|
|
{
|
|
if (startIndex != 0 ||
|
|
elementCount != data.Length)
|
|
{
|
|
T[] subArray = new T[elementCount];
|
|
Array.Copy(data, startIndex, subArray, 0, elementCount);
|
|
BufferData(subArray, offsetInBytes);
|
|
}
|
|
else
|
|
{
|
|
BufferData(data, offsetInBytes);
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region GetBufferData (private helper)
|
|
private void GetBufferData<T>(T[] data, int offset) where T : struct
|
|
{
|
|
int size = (elementSize == IndexElementSize.SixteenBits ?
|
|
2 : 4) * data.Length;
|
|
|
|
GL.BindBuffer(BufferTarget.ElementArrayBuffer, bufferHandle);
|
|
ErrorHelper.Check("BindBuffer");
|
|
|
|
GL.GetBufferSubData(BufferTarget.ElementArrayBuffer, (IntPtr)offset,
|
|
(IntPtr)size, data);
|
|
ErrorHelper.Check("GetBufferSubData");
|
|
}
|
|
#endregion
|
|
|
|
#region Dispose
|
|
/// <summary>
|
|
/// Dispose the native index buffer data.
|
|
/// </summary>
|
|
public void Dispose()
|
|
{
|
|
if (IsDisposed == false)
|
|
{
|
|
IsDisposed = true;
|
|
DisposeResource();
|
|
}
|
|
}
|
|
|
|
internal void DisposeResource()
|
|
{
|
|
if (bufferHandle != -1 &&
|
|
GraphicsDeviceWindowsGL3.IsContextCurrent)
|
|
{
|
|
GL.DeleteBuffers(1, ref bufferHandle);
|
|
ErrorHelper.Check("DeleteBuffers");
|
|
bufferHandle = -1;
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
}
|