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 { /// /// A handle to an OpenGL object, /// must be indexed from a . /// Direct call will cause /// public unsafe struct glHandle { internal uint* valuePtr; public glHandle() { throw new InvalidOperationException(); } internal glHandle(uint* val) { valuePtr = val; } public uint Value { get { return *valuePtr; } } } /// /// A handle to an OpenGL object. /// 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); } } [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(); } /// /// temporarily release the handle of GLhandle sets. /// Please call method before indexing. /// public void Free() { if (_value == null) { return; } GCHandle h = GCHandle.FromIntPtr((IntPtr)handle); h.Free(); } public void Pin() { if (_value == null) { return; } handle = (uint*)GCHandle.Alloc(_value, GCHandleType.Pinned).AddrOfPinnedObject(); } /// /// Realse all resource in this handle. /// This will release all resource in this . /// This will be not usable. /// public void Release() { if (_value == null) { return; } else { GCHandle.FromIntPtr((IntPtr)handle).Free(); handle = (uint*)IntPtr.Zero; } } } }