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); }