public void GetData <T>(int offsetInBytes, T[] data, int startIndex, int elementCount) where T : struct { if (data == null) { throw new ArgumentNullException("data is null"); } if (data.Length < (startIndex + elementCount)) { throw new InvalidOperationException("The array specified in the data parameter is not the correct size for the amount of data requested."); } if (BufferUsage == RBufferUsage.WriteOnly) { throw new NotSupportedException("This IndexBuffer was created with a usage type of BufferUsage.WriteOnly. Calling GetData on a resource that was created with BufferUsage.WriteOnly is not supported."); } #if GLES // Buffers are write-only on OpenGL ES 1.1 and 2.0. See the GL_OES_mapbuffer extension for more information. // http://www.khronos.org/registry/gles/extensions/OES/OES_mapbuffer.txt throw new NotSupportedException("Index buffers are write-only on OpenGL ES platforms"); #endif #if !GLES if (Threading.IsOnUIThread()) { GetBufferData(offsetInBytes, data, startIndex, elementCount); } else { Threading.BlockOnUIThread(() => GetBufferData(offsetInBytes, data, startIndex, elementCount)); } #endif }
protected void SetDataInternal <T>(int offsetInBytes, T[] data, int startIndex, int elementCount, int vertexStride, SetDataOptions options) where T : struct { if (data == null) { throw new ArgumentNullException("data is null"); } if (data.Length < startIndex + elementCount) { throw new InvalidOperationException("The array specified in the data parameter is not the correct size for the amount of data requested."); } int bufferSize = this.VertexCount * this.VertexDeclaration.VertexStride; if (vertexStride > bufferSize || vertexStride < this.VertexDeclaration.VertexStride) { throw new ArgumentOutOfRangeException("One of the following conditions is true:\nThe vertex stride is larger than the vertex buffer.\nThe vertex stride is too small for the type of data requested."); } int elementSizeInBytes = Marshal.SizeOf(typeof(T)); if (Threading.IsOnUIThread()) { this.SetBufferData <T>(bufferSize, elementSizeInBytes, offsetInBytes, data, startIndex, elementCount, vertexStride, options); } else { Threading.BlockOnUIThread((Action)(() => this.SetBufferData <T>(bufferSize, elementSizeInBytes, offsetInBytes, data, startIndex, elementCount, vertexStride, options))); } }
public void GetData <T>(int offsetInBytes, T[] data, int startIndex, int elementCount, int vertexStride) where T : struct { if (data == null) { throw new ArgumentNullException("data is null"); } if (data.Length < startIndex + elementCount) { throw new InvalidOperationException("The array specified in the data parameter is not the correct size for the amount of data requested."); } if (this.BufferUsage == BufferUsage.WriteOnly) { throw new NotSupportedException("This VertexBuffer was created with a usage type of BufferUsage.WriteOnly. Calling GetData on a resource that was created with BufferUsage.WriteOnly is not supported."); } if (elementCount * vertexStride > this.VertexCount * this.VertexDeclaration.VertexStride) { throw new ArgumentOutOfRangeException("The vertex stride is larger than the vertex buffer."); } if (Threading.IsOnUIThread()) { this.GetBufferData <T>(offsetInBytes, data, startIndex, elementCount, vertexStride); } else { Threading.BlockOnUIThread((Action)(() => this.GetBufferData <T>(offsetInBytes, data, startIndex, elementCount, vertexStride))); } }
public void GetData <T> (int offsetInBytes, T[] data, int startIndex, int elementCount, int vertexStride) where T : struct { if (data == null) { throw new ArgumentNullException("data", "This method does not accept null for this parameter."); } if (data.Length < (startIndex + elementCount)) { throw new ArgumentOutOfRangeException("elementCount", "This parameter must be a valid index within the array."); } if (BufferUsage == RBufferUsage.WriteOnly) { throw new NotSupportedException("Calling GetData on a resource that was created with BufferUsage.WriteOnly is not supported."); } if ((elementCount * vertexStride) > (VertexCount * VertexDeclaration.VertexStride)) { throw new InvalidOperationException("The array is not the correct size for the amount of data requested."); } if (Threading.IsOnUIThread()) { GetBufferData(offsetInBytes, data, startIndex, elementCount, vertexStride); } else { Threading.BlockOnUIThread(() => GetBufferData(offsetInBytes, data, startIndex, elementCount, vertexStride)); } }
private void PlatformSetDataInternal <T>(int offsetInBytes, T[] data, int startIndex, int elementCount, SetDataOptions options) where T : struct { if (Threading.IsOnUIThread()) { BufferData(offsetInBytes, data, startIndex, elementCount, options); } else { Threading.BlockOnUIThread(() => BufferData(offsetInBytes, data, startIndex, elementCount, options)); } }
private void PlatformSetDataInternal <T>(int offsetInBytes, T[] data, int startIndex, int elementCount, int vertexStride, SetDataOptions options, int bufferSize, int elementSizeInBytes) where T : struct { if (Threading.IsOnUIThread()) { SetBufferData(bufferSize, elementSizeInBytes, offsetInBytes, data, startIndex, elementCount, vertexStride, options); } else { Threading.BlockOnUIThread(() => SetBufferData(bufferSize, elementSizeInBytes, offsetInBytes, data, startIndex, elementCount, vertexStride, options)); } }
public void UnbindVertexArray() { if (!Threading.IsOnUIThread()) { Threading.BlockOnUIThread(() => { UnbindVertexArray(); }); } else { GL.BindVertexArray(0); REngine.CheckGLError(); } }
public void Unbind() { if (Threading.IsOnUIThread()) { GL.BindBuffer(BufferTarget.ArrayBuffer, 0); REngine.CheckGLError(); } else { Threading.BlockOnUIThread(() => { Unbind(); }); } }
public static void CheckGLError() { if (!Threading.IsOnUIThread()) { return; } ErrorCode error = GL.GetError(); if (error != ErrorCode.NoError) { throw new MonoGameGLException("GL.GetError() returned " + ((object)error).ToString()); } }
public void BindVertexArray() { if (!Threading.IsOnUIThread()) { Threading.BlockOnUIThread(() => { BindVertexArray(); }); } else { GenerateIfRequired(); REngine.CheckGLError(); GL.BindVertexArray(vao); REngine.CheckGLError(); } }
internal void AddDisposeAction(Action disposeAction) { if (disposeAction == null) { throw new ArgumentNullException("disposeAction"); } if (Threading.IsOnUIThread()) { disposeAction(); } else { lock (this.disposeActionsLock) this.disposeActions.Add(disposeAction); } }
internal static void AddDisposeAction(Action disposeAction) { if (disposeAction == null) { throw new ArgumentNullException("disposeAction"); } if (Threading.IsOnUIThread()) { disposeAction(); } else { lock (GraphicsDevice.disposeActionsLock) GraphicsDevice.disposeActions.Add(disposeAction); } }
private void PlatformGetData <T>(int offsetInBytes, T[] data, int startIndex, int elementCount, int vertexStride) where T : struct { #if GLES // Buffers are write-only on OpenGL ES 1.1 and 2.0. See the GL_OES_mapbuffer extension for more information. // http://www.khronos.org/registry/gles/extensions/OES/OES_mapbuffer.txt throw new NotSupportedException("Vertex buffers are write-only on OpenGL ES platforms"); #endif #if !GLES if (Threading.IsOnUIThread()) { GetBufferData(offsetInBytes, data, startIndex, elementCount, vertexStride); } else { Threading.BlockOnUIThread(() => GetBufferData(offsetInBytes, data, startIndex, elementCount, vertexStride)); } #endif }
/// <summary> /// Adds a dispose action to the list of pending dispose actions. These are executed at the end of each call to Present(). /// This allows GL resources to be disposed from other threads, such as the finalizer. /// </summary> /// <param name="disposeAction">The action to execute for the dispose.</param> static private void AddDisposeAction(Action disposeAction) { if (disposeAction == null) { throw new ArgumentNullException("disposeAction"); } if (Threading.IsOnUIThread()) { disposeAction(); } else { lock (disposeActionsLock) { disposeActions.Add(disposeAction); } } }
protected void SetDataInternal <T>(int offsetInBytes, T[] data, int startIndex, int elementCount, SetDataOptions options) where T : struct { if (data == null) { throw new ArgumentNullException("data is null"); } if (data.Length < startIndex + elementCount) { throw new InvalidOperationException("The array specified in the data parameter is not the correct size for the amount of data requested."); } if (Threading.IsOnUIThread()) { this.BufferData <T>(offsetInBytes, data, startIndex, elementCount, options); } else { Threading.BlockOnUIThread((Action)(() => this.BufferData <T>(offsetInBytes, data, startIndex, elementCount, options))); } }
protected void SetDataInternal <T>(int offsetInBytes, T[] data, int startIndex, int elementCount, SetDataOptions options) where T : struct { if (data == null) { throw new ArgumentNullException("data is null"); } if (data.Length < (startIndex + elementCount)) { throw new InvalidOperationException("The array specified in the data parameter is not the correct size for the amount of data requested."); } #if !PORTABLE #if DIRECTX GenerateIfRequired(); if (_isDynamic) { // We assume discard by default. var mode = SharpDX.Direct3D11.MapMode.WriteDiscard; if ((options & SetDataOptions.NoOverwrite) == SetDataOptions.NoOverwrite) { mode = SharpDX.Direct3D11.MapMode.WriteNoOverwrite; } var d3dContext = GraphicsDevice._d3dContext; lock (d3dContext) { var dataBox = d3dContext.MapSubresource(_buffer, 0, mode, SharpDX.Direct3D11.MapFlags.None); SharpDX.Utilities.Write(IntPtr.Add(dataBox.DataPointer, offsetInBytes), data, startIndex, elementCount); d3dContext.UnmapSubresource(_buffer, 0); } } else { var elementSizeInBytes = Marshal.SizeOf(typeof(T)); var dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned); var startBytes = startIndex * elementSizeInBytes; var dataPtr = (IntPtr)(dataHandle.AddrOfPinnedObject().ToInt64() + startBytes); var box = new SharpDX.DataBox(dataPtr, 1, 0); var region = new SharpDX.Direct3D11.ResourceRegion(); region.Top = 0; region.Front = 0; region.Back = 1; region.Bottom = 1; region.Left = offsetInBytes; region.Right = offsetInBytes + (elementCount * elementSizeInBytes); // TODO: We need to deal with threaded contexts here! var d3dContext = GraphicsDevice._d3dContext; lock (d3dContext) d3dContext.UpdateSubresource(box, _buffer, 0, region); dataHandle.Free(); } #elif PSM if (typeof(T) == typeof(ushort)) { Array.Copy(data, offsetInBytes / sizeof(ushort), _buffer, startIndex, elementCount); } else { throw new NotImplementedException("PSS Currently only supports ushort (SixteenBits) index elements"); //Something like as follows probably works if you really need this, but really just make a ushort array! /* * int indexOffset = offsetInBytes / sizeof(T); * for (int i = 0; i < elementCount; i++) * _buffer[i + startIndex] = (ushort)(object)data[i + indexOffset]; */ } #else if (Threading.IsOnUIThread()) { BufferData(offsetInBytes, data, startIndex, elementCount, options); } else { Threading.BlockOnUIThread(() => BufferData(offsetInBytes, data, startIndex, elementCount, options)); } #endif #endif }
protected void SetDataInternal <T>(int offsetInBytes, T[] data, int startIndex, int elementCount, int vertexStride, SetDataOptions options) where T : struct { if (data == null) { throw new ArgumentNullException("data is null"); } if (data.Length < (startIndex + elementCount)) { throw new InvalidOperationException("The array specified in the data parameter is not the correct size for the amount of data requested."); } var bufferSize = VertexCount * VertexDeclaration.VertexStride; if ((vertexStride > bufferSize) || (vertexStride < VertexDeclaration.VertexStride)) { throw new ArgumentOutOfRangeException("One of the following conditions is true:\nThe vertex stride is larger than the vertex buffer.\nThe vertex stride is too small for the type of data requested."); } #if !PSM var elementSizeInBytes = Marshal.SizeOf(typeof(T)); #endif #if DIRECTX GenerateIfRequired(); if (_isDynamic) { // We assume discard by default. var mode = SharpDX.Direct3D11.MapMode.WriteDiscard; if ((options & SetDataOptions.NoOverwrite) == SetDataOptions.NoOverwrite) { mode = SharpDX.Direct3D11.MapMode.WriteNoOverwrite; } var d3dContext = GraphicsDevice._d3dContext; lock (d3dContext) { var dataBox = d3dContext.MapSubresource(_buffer, 0, mode, SharpDX.Direct3D11.MapFlags.None); SharpDX.Utilities.Write(IntPtr.Add(dataBox.DataPointer, offsetInBytes), data, startIndex, elementCount); d3dContext.UnmapSubresource(_buffer, 0); } } else { var dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned); var startBytes = startIndex * elementSizeInBytes; var dataPtr = (IntPtr)(dataHandle.AddrOfPinnedObject().ToInt64() + startBytes); var box = new SharpDX.DataBox(dataPtr, 1, 0); var region = new SharpDX.Direct3D11.ResourceRegion(); region.Top = 0; region.Front = 0; region.Back = 1; region.Bottom = 1; region.Left = offsetInBytes; region.Right = offsetInBytes + (elementCount * elementSizeInBytes); lock (GraphicsDevice._d3dContext) GraphicsDevice._d3dContext.UpdateSubresource(box, _buffer, 0, region); dataHandle.Free(); } #elif PSM if (_vertexArray == null) { _vertexArray = new T[VertexCount]; } Array.Copy(data, offsetInBytes / vertexStride, _vertexArray, startIndex, elementCount); #else if (Threading.IsOnUIThread()) { SetBufferData(bufferSize, elementSizeInBytes, offsetInBytes, data, startIndex, elementCount, vertexStride, options); } else { Threading.BlockOnUIThread(() => SetBufferData(bufferSize, elementSizeInBytes, offsetInBytes, data, startIndex, elementCount, vertexStride, options)); } #endif }
public void GetData <T> (int offsetInBytes, T[] data, int startIndex, int elementCount, int vertexStride) where T : struct { #if GLES // Buffers are write-only on OpenGL ES 1.1 and 2.0. See the GL_OES_mapbuffer extension for more information. // http://www.khronos.org/registry/gles/extensions/OES/OES_mapbuffer.txt throw new NotSupportedException("Vertex buffers are write-only on OpenGL ES platforms"); #else if (data == null) { throw new ArgumentNullException("data", "This method does not accept null for this parameter."); } if (data.Length < (startIndex + elementCount)) { throw new ArgumentOutOfRangeException("elementCount", "This parameter must be a valid index within the array."); } if (BufferUsage == BufferUsage.WriteOnly) { throw new NotSupportedException("Calling GetData on a resource that was created with BufferUsage.WriteOnly is not supported."); } if ((elementCount * vertexStride) > (VertexCount * VertexDeclaration.VertexStride)) { throw new InvalidOperationException("The array is not the correct size for the amount of data requested."); } #if DIRECTX GenerateIfRequired(); if (_isDynamic) { throw new NotImplementedException(); } else { var deviceContext = GraphicsDevice._d3dContext; // Copy the buffer to a staging resource var stagingDesc = _buffer.Description; stagingDesc.BindFlags = SharpDX.Direct3D11.BindFlags.None; stagingDesc.CpuAccessFlags = SharpDX.Direct3D11.CpuAccessFlags.Read | SharpDX.Direct3D11.CpuAccessFlags.Write; stagingDesc.Usage = SharpDX.Direct3D11.ResourceUsage.Staging; stagingDesc.OptionFlags = SharpDX.Direct3D11.ResourceOptionFlags.None; var stagingBuffer = new SharpDX.Direct3D11.Buffer(GraphicsDevice._d3dDevice, stagingDesc); lock (GraphicsDevice._d3dContext) deviceContext.CopyResource(_buffer, stagingBuffer); int TsizeInBytes = SharpDX.Utilities.SizeOf <T>(); var dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned); var startBytes = startIndex * vertexStride; var dataPtr = (IntPtr)(dataHandle.AddrOfPinnedObject().ToInt64() + startBytes); SharpDX.DataPointer DataPointer = new SharpDX.DataPointer(dataPtr, data.Length * TsizeInBytes); lock (GraphicsDevice._d3dContext) { // Map the staging resource to a CPU accessible memory var box = deviceContext.MapSubresource(stagingBuffer, 0, SharpDX.Direct3D11.MapMode.Read, SharpDX.Direct3D11.MapFlags.None); if (vertexStride == TsizeInBytes) { SharpDX.Utilities.CopyMemory(dataPtr, box.DataPointer + offsetInBytes, vertexStride * elementCount); } else { for (int i = 0; i < data.Length; i++) { SharpDX.Utilities.CopyMemory(dataPtr + i * TsizeInBytes, box.DataPointer + i * vertexStride + offsetInBytes, TsizeInBytes); } } // Make sure that we unmap the resource in case of an exception deviceContext.UnmapSubresource(stagingBuffer, 0); } stagingBuffer.Dispose(); } #elif PSM throw new NotImplementedException(); #else if (Threading.IsOnUIThread()) { GetBufferData(offsetInBytes, data, startIndex, elementCount, vertexStride); } else { Threading.BlockOnUIThread(() => GetBufferData(offsetInBytes, data, startIndex, elementCount, vertexStride)); } #endif #endif }