示例#1
0
        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
        }
示例#2
0
        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)));
            }
        }
示例#3
0
 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)));
     }
 }
示例#4
0
        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));
            }
        }
示例#5
0
 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));
     }
 }
示例#6
0
 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));
     }
 }
示例#7
0
 public void UnbindVertexArray()
 {
     if (!Threading.IsOnUIThread())
     {
         Threading.BlockOnUIThread(() => { UnbindVertexArray(); });
     }
     else
     {
         GL.BindVertexArray(0);
         REngine.CheckGLError();
     }
 }
示例#8
0
 public void Unbind()
 {
     if (Threading.IsOnUIThread())
     {
         GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
         REngine.CheckGLError();
     }
     else
     {
         Threading.BlockOnUIThread(() => { Unbind(); });
     }
 }
示例#9
0
        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());
            }
        }
示例#10
0
 public void BindVertexArray()
 {
     if (!Threading.IsOnUIThread())
     {
         Threading.BlockOnUIThread(() => { BindVertexArray(); });
     }
     else
     {
         GenerateIfRequired();
         REngine.CheckGLError();
         GL.BindVertexArray(vao);
         REngine.CheckGLError();
     }
 }
示例#11
0
 internal void AddDisposeAction(Action disposeAction)
 {
     if (disposeAction == null)
     {
         throw new ArgumentNullException("disposeAction");
     }
     if (Threading.IsOnUIThread())
     {
         disposeAction();
     }
     else
     {
         lock (this.disposeActionsLock)
             this.disposeActions.Add(disposeAction);
     }
 }
示例#12
0
 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);
     }
 }
示例#13
0
        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
        }
示例#14
0
 /// <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);
         }
     }
 }
示例#15
0
 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)));
     }
 }
示例#16
0
        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
        }
示例#17
0
        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
        }
示例#18
0
        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
        }