public void SetData(DataType[] source, int sourceIndex = 0, int destIndex = 0, int count = -1)
{
#if !RUNS_WITH_SCISSORS
if (source == null)
throw new ArgumentNullException("source");
if (sourceIndex < 0 || sourceIndex >= source.Length)
throw new ArgumentOutOfRangeException("sourceIndex",
"The source index must be greater-than or equal to 0 and less-than the source length.");
if (destIndex < 0 || destIndex >= m_count)
throw new ArgumentOutOfRangeException("destIndex",
"The dest index must be greater-than or equal to 0 and less-than the buffer's count.");
#endif
if (count == -1)
count = Math.Min(source.Length - sourceIndex, m_count - destIndex);
#if !RUNS_WITH_SCISSORS
else if (source.Length - sourceIndex < count)
throw new ArgumentOutOfRangeException("count",
"The count specified is larger than the source array.");
else if (m_count - destIndex < count)
throw new ArgumentOutOfRangeException("count",
"The count specified is larger than the buffer's count.");
#endif
IntPtr offset = new IntPtr(m_stride * destIndex);
IntPtr size = new IntPtr(m_stride * count);
int sourceOffset = sourceIndex * m_stride;
int destOffset = destIndex * m_stride;
GL.BindBuffer(m_target, m_ID);
#if ES20
GL.BufferSubData(m_target, offset, size, source);
#else
IntPtr videoMemory = GL.MapBufferRange(m_target, offset, size, BufferAccessMask.MapWriteBit);
if (videoMemory == IntPtr.Zero)
{
videoMemory = GL.MapBuffer(m_target, BufferAccess.WriteOnly);
if (videoMemory == IntPtr.Zero)
{
throw new InvalidOperationException(
"Unable to map video memory.", new Exception(GL.GetError().ToString()));
}
}
else
destOffset = 0; // mapped the range, no need for an offset
GCHandle dataHandle = GCHandle.Alloc(source, GCHandleType.Pinned);
IntPtr systemMemory = dataHandle.AddrOfPinnedObject();
unsafe
{
byte* sourcePtr = ((byte*)systemMemory) + sourceOffset;
byte* destPtr = ((byte*)videoMemory) + destOffset;
for (int i = 0; i < count * m_stride; i++) destPtr[i] = sourcePtr[i];
}
dataHandle.Free();
GL.UnmapBuffer(m_target);
#endif
GL.BindBuffer(m_target, 0);
if (m_shadowCopy)
Array.Copy(source, sourceIndex, m_data, destIndex, count);
}