Пример #1
0
        /// <summary>
        /// Updates a subset of the buffer object's data store.
        /// </summary>
        /// <typeparam name="T">The type of data in the data array.</typeparam>
        /// <param name="vboID">The VBO whose buffer will be updated.</param>
        /// <param name="target">Specifies the target buffer object.  Must be ArrayBuffer, ElementArrayBuffer, PixelPackBuffer or PixelUnpackBuffer.</param>
        /// <param name="data">The new data that will be copied to the data store.</param>
        /// <param name="length">The size in bytes of the data store region being replaced.</param>
        public static void BufferSubData <T>(uint vboID, BufferTarget target, T[] data, int length)
            where T : struct
        {
            GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned);

            try
            {
                Gl.BindBuffer(target, vboID);
                Gl.BufferSubData(target, IntPtr.Zero, (IntPtr)(Marshal.SizeOf(data[0]) * length), handle.AddrOfPinnedObject());
            }
            finally
            {
                handle.Free();
            }
        }
Пример #2
0
        /// <summary>
        /// Updates a subset of the buffer object's data store.
        /// </summary>
        /// <param name="data">The new data that will be copied to the data store.</param>
        /// <param name="size">The size in bytes of the data store region being replaced.</param>
        /// <param name="offset">The offset in bytes into the buffer object's data store where data replacement will begin.</param>
        public void BufferSubData(T[] data, int size, int offset)
        {
            if (BufferTarget != OpenGL.BufferTarget.ArrayBuffer && BufferTarget != OpenGL.BufferTarget.ElementArrayBuffer &&
                BufferTarget != OpenGL.BufferTarget.PixelPackBuffer && BufferTarget != OpenGL.BufferTarget.PixelUnpackBuffer)
            {
                throw new InvalidOperationException(string.Format("BufferSubData cannot be called with a BufferTarget of type {0}", BufferTarget.ToString()));
            }

            GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned);

            try
            {
                Gl.BindBuffer(this);
                Gl.BufferSubData(BufferTarget, (IntPtr)offset, (IntPtr)size, handle.AddrOfPinnedObject());
            }
            finally
            {
                handle.Free();
            }
        }
Пример #3
0
        /// <summary>
        /// Actually create this BufferObject resources.
        /// </summary>
        /// <param name="ctx">
        /// A <see cref="GraphicsContext"/> used for allocating resources.
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// Exception thrown if <paramref name="ctx"/> is null.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// Exception thrown if <paramref name="ctx"/> is not current on the calling thread.
        /// </exception>
        /// <exception cref="InvalidOperationException">
        /// Exception thrown if this BufferObject has not client memory allocated and the hint is different from
        /// <see cref="BufferObjectHint.StaticCpuDraw"/> or <see cref="BufferObjectHint.DynamicCpuDraw"/>.
        /// </exception>
        /// <exception cref="InvalidOperationException">
        /// Exception thrown if this BufferObject is currently mapped.
        /// </exception>
        protected override void CreateObject(GraphicsContext ctx)
        {
            CheckCurrentContext(ctx);

            if ((ClientBufferAddress == IntPtr.Zero) && ((Hint != BufferObjectHint.StaticCpuDraw) && (Hint != BufferObjectHint.DynamicCpuDraw)))
            {
                throw new InvalidOperationException("no client buffer");
            }

            // Determine the client buffer size
            uint clientBufferSize = _ClientBufferSize;

            if (ClientBufferAddress != IntPtr.Zero)
            {
                clientBufferSize = ClientBufferSize;
            }

            Debug.Assert(clientBufferSize > 0);

            // Buffer must be bound
            Bind(ctx);

            if (ctx.Caps.GlExtensions.VertexBufferObject_ARB)
            {
                if (IsMapped)
                {
                    throw new InvalidOperationException("mapped");
                }

                // Define buffer object (type, size and hints)
                Gl.BufferData((int)BufferType, clientBufferSize, null, (int)Hint);
                // Store GPU buffer size
                _GpuBufferSize = clientBufferSize;

                // Define buffer object contents
                if (ClientBufferAddress != IntPtr.Zero)
                {
                    // Provide buffer contents
                    Gl.BufferSubData(BufferType, IntPtr.Zero, _GpuBufferSize, ClientBufferAddress);
                    // Release memory, if it is not required anymore
                    if (_MemoryBufferAutoDispose)
                    {
                        ReleaseClientBuffer();
                    }
                }
            }
            else
            {
                // Discard previous GPU buffer, if any
                if (_GpuBuffer != null)
                {
                    _GpuBuffer.Dispose();
                }

                if (ClientBufferAddress == IntPtr.Zero)
                {
                    // Note: GPU buffer size specified by _ClientBufferSize
                    Debug.Assert(_ClientBufferSize > 0);
                    // Allocate simulated GPU buffer
                    _GpuBuffer = new AlignedMemoryBuffer(_ClientBufferSize, MinimumBufferAlignment);
                }
                else
                {
                    // Let a virtual implementation decide how pass information from the client buffer and the "GPU" buffer
                    UploadClientBuffer();
                }

                // Store GPU buffer size
                _GpuBufferSize = _GpuBuffer.Size;
            }

            // Reset requested client buffer size
            _ClientBufferSize = 0;
        }