158 lines
4.0 KiB
C#
158 lines
4.0 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Data.Common;
|
|
using System.Linq;
|
|
using System.Runtime.CompilerServices;
|
|
using System.Runtime.InteropServices;
|
|
using System.Runtime.Versioning;
|
|
using System.Security.AccessControl;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
|
|
namespace System
|
|
{
|
|
/// <summary>
|
|
/// A handle to an OpenGL object,
|
|
/// must be indexed from a <see cref="glHandleSet"/>.
|
|
/// Direct call will cause <see langword="InvalidOperationException"/>
|
|
/// </summary>
|
|
public unsafe struct glHandle
|
|
{
|
|
internal uint* valuePtr;
|
|
internal glHandleSet source;
|
|
|
|
public glHandle()
|
|
{
|
|
throw new InvalidOperationException();
|
|
}
|
|
|
|
public static glHandle Alloc(uint value)
|
|
{
|
|
glHandle ret = default;
|
|
ret.source = new glHandleSet(1);
|
|
*ret.valuePtr = value;
|
|
return ret;
|
|
}
|
|
|
|
internal glHandle(uint* val, glHandleSet set)
|
|
{
|
|
source = set;
|
|
valuePtr = val;
|
|
}
|
|
|
|
public IntPtr Handle
|
|
{
|
|
get
|
|
{
|
|
if (source.handle == (uint*)0)
|
|
{
|
|
throw new InvalidOperationException($"Handle set {nameof(source)} is not pinned.");
|
|
}
|
|
return (IntPtr)valuePtr;
|
|
}
|
|
}
|
|
|
|
public uint Value
|
|
{
|
|
get
|
|
{
|
|
if (source.handle == (uint*)0)
|
|
{
|
|
throw new InvalidOperationException($"Handle set {nameof(source)} is not pinned.");
|
|
}
|
|
return *valuePtr;
|
|
}
|
|
set
|
|
{
|
|
if (source.handle == (uint*)0)
|
|
{
|
|
throw new InvalidOperationException($"Handle set {nameof(source)} is not pinned.");
|
|
}
|
|
*valuePtr = value;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// A handle to an OpenGL object.
|
|
/// </summary>
|
|
public unsafe class glHandleSet
|
|
{
|
|
private readonly uint[] _value;
|
|
internal int length;
|
|
internal uint* handle;
|
|
|
|
public glHandle this[int index]
|
|
{
|
|
get
|
|
{
|
|
if (index > length)
|
|
{
|
|
throw new IndexOutOfRangeException();
|
|
}
|
|
return new glHandle(handle + index, this);
|
|
}
|
|
}
|
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
public void SetValue(int index, uint value)
|
|
{
|
|
_value[index] = value;
|
|
}
|
|
|
|
public glHandleSet(int count)
|
|
{
|
|
_value = new uint[count];
|
|
length = count;
|
|
handle = (uint*)GCHandle.Alloc(_value, GCHandleType.Pinned).AddrOfPinnedObject();
|
|
}
|
|
|
|
/// <summary>
|
|
/// temporarily release the handle of GLhandle sets.
|
|
/// Please call <see cref="Pin"/> method before indexing.
|
|
/// </summary>
|
|
public void Free()
|
|
{
|
|
if (_value == null)
|
|
{
|
|
return;
|
|
}
|
|
GCHandle h = GCHandle.FromIntPtr((IntPtr)handle);
|
|
h.Free();
|
|
handle = (uint*)0;
|
|
}
|
|
|
|
public void Pin()
|
|
{
|
|
if (_value == null)
|
|
{
|
|
return;
|
|
}
|
|
handle = (uint*)GCHandle.Alloc(_value, GCHandleType.Pinned).AddrOfPinnedObject();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Realse all resource in this handle.
|
|
/// This will release all resource in this <see cref="glHandle"/>.
|
|
/// This <see langword="glHandle"/> will be not usable.
|
|
/// </summary>
|
|
public void Release()
|
|
{
|
|
if (_value == null)
|
|
{
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
GCHandle.FromIntPtr((IntPtr)handle).Free();
|
|
handle = (uint*)IntPtr.Zero;
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|