Ejemplo n.º 1
0
 public static MapMode ConvertToMapMode(SetDataOptions options)
 {
     switch (options)
     {
         case SetDataOptions.None:
             return MapMode.Write;
         case SetDataOptions.Discard:
             return MapMode.WriteDiscard;
         case SetDataOptions.NoOverwrite:
             return MapMode.WriteNoOverwrite;
     }
     return MapMode.Write;
 }
Ejemplo n.º 2
0
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="offsetInBytes"></param>
        /// <param name="data"></param>
        /// <param name="startIndex"></param>
        /// <param name="elementCount"></param>
        /// <param name="options"></param>
        protected void SetDataInternal <T>(int offsetInBytes, T[] data, int startIndex, int elementCount, SetDataOptions options) where T : struct
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }
            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.");
            }

            PlatformSetDataInternal(offsetInBytes, data, startIndex, elementCount, options);
        }
Ejemplo n.º 3
0
        private unsafe void RenderBatch(Texture2D texture, SpriteData[] sprites, int offset, int count)
        {
            graphicsDevice.Textures[0] = texture;
            float num  = 1f / (float)texture.Width;
            float num2 = 1f / (float)texture.Height;

            while (count > 0)
            {
                SetDataOptions options = SetDataOptions.NoOverwrite;
                int            num3    = count;
                if (num3 > 2048 - vertexBufferPosition)
                {
                    num3 = 2048 - vertexBufferPosition;
                    if (num3 < 256)
                    {
                        vertexBufferPosition = 0;
                        options = SetDataOptions.Discard;
                        num3    = count;
                        if (num3 > 2048)
                        {
                            num3 = 2048;
                        }
                    }
                }

                fixed(SpriteData *ptr = &sprites[offset])
                {
                    fixed(VertexPositionColorTexture *ptr3 = &vertices[0])
                    {
                        SpriteData *ptr2 = ptr;
                        VertexPositionColorTexture *ptr4 = ptr3;

                        for (int i = 0; i < num3; i++)
                        {
                            float num4 = ptr2->Origin.X / ptr2->Source.Z;
                            float num5 = ptr2->Origin.Y / ptr2->Source.W;
                            ptr4->Color   = ptr2->Colors.TopLeftColor;
                            ptr4[1].Color = ptr2->Colors.TopRightColor;
                            ptr4[2].Color = ptr2->Colors.BottomRightColor;
                            ptr4[3].Color = ptr2->Colors.BottomLeftColor;
                            for (int j = 0; j < 4; j++)
                            {
                                float num6 = xCornerOffsets[j];
                                float num7 = yCornerOffsets[j];
                                float num8 = (num6 - num4) * ptr2->Destination.Z;
                                float num9 = (num7 - num5) * ptr2->Destination.W;
                                float x    = ptr2->Destination.X + num8;
                                float y    = ptr2->Destination.Y + num9;
                                if ((ptr2->Effects & SpriteEffects.FlipVertically) != 0)
                                {
                                    num6 = 1f - num6;
                                }
                                if ((ptr2->Effects & SpriteEffects.FlipHorizontally) != 0)
                                {
                                    num7 = 1f - num7;
                                }
                                ptr4->Position.X          = x;
                                ptr4->Position.Y          = y;
                                ptr4->Position.Z          = 0f;
                                ptr4->TextureCoordinate.X = (ptr2->Source.X + num6 * ptr2->Source.Z) * num;
                                ptr4->TextureCoordinate.Y = (ptr2->Source.Y + num7 * ptr2->Source.W) * num2;
                                ptr4++;
                            }
                            ptr2++;
                        }
                    }
                }

                int offsetInBytes = vertexBufferPosition * sizeof(VertexPositionColorTexture) * 4;
                vertexBuffer.SetData(offsetInBytes, vertices, 0, num3 * 4, sizeof(VertexPositionColorTexture), options);
                int minVertexIndex = vertexBufferPosition * 4;
                int numVertices    = num3 * 4;
                int startIndex     = vertexBufferPosition * 6;
                int primitiveCount = num3 * 2;
                graphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, minVertexIndex, numVertices, startIndex, primitiveCount);
                vertexBufferPosition += num3;
                offset += num3;
                count  -= num3;
            }
        }
Ejemplo n.º 4
0
        /// <inheritdoc/>
        public override void SetDataAligned <T>(T[] data, Int32 dataOffset, Int32 dataCount, Int32 bufferOffset, out Int32 bufferSize, SetDataOptions options)
        {
            Contract.Require(data, nameof(data));
            Contract.EnsureRange(dataCount > 0, nameof(dataCount));
            Contract.EnsureRange(dataOffset >= 0 && dataOffset + dataCount <= data.Length, nameof(dataOffset));
            Contract.EnsureRange(bufferOffset >= 0, nameof(bufferOffset));
            Contract.Ensure(dataCount <= IndexCount, OpenGLStrings.DataTooLargeForBuffer);

            var indexStride = GetElementSize();

            bufferSize = indexStride * dataCount;

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

            try
            {
                var caps = (OpenGLGraphicsCapabilities)Ultraviolet.GetGraphics().Capabilities;
                if (caps.MinMapBufferAlignment > 0)
                {
                    bufferSize = Math.Min(Math.Max(caps.MinMapBufferAlignment, MathUtil.FindNextPowerOfTwo(bufferSize)), SizeInBytes - bufferOffset);
                }

                using (OpenGLState.ScopedBindElementArrayBuffer(buffer))
                {
                    var isPartialUpdate = (bufferOffset > 0 || bufferSize < SizeInBytes);
                    var isDiscarding    = (options == SetDataOptions.Discard);
                    if (isDiscarding || !isPartialUpdate)
                    {
                        gl.NamedBufferData(buffer, gl.GL_ELEMENT_ARRAY_BUFFER, this.size, isPartialUpdate ? null : handle.AddrOfPinnedObject().ToPointer(), usage);
                        gl.ThrowIfError();
                    }

                    if (isPartialUpdate)
                    {
                        if (caps.MinMapBufferAlignment >= 0)
                        {
                            var bufferRangeAccess = gl.GL_MAP_WRITE_BIT | (options == SetDataOptions.NoOverwrite ? gl.GL_MAP_UNSYNCHRONIZED_BIT : 0);
                            var bufferRangePtr    = (Byte *)gl.MapNamedBufferRange(buffer, gl.GL_ELEMENT_ARRAY_BUFFER,
                                                                                   (IntPtr)bufferOffset, (IntPtr)bufferSize, bufferRangeAccess);
                            gl.ThrowIfError();

                            var sourceRangePtr    = (Byte *)handle.AddrOfPinnedObject() + (dataOffset * indexStride);
                            var sourceSizeInBytes = dataCount * indexStride;

                            for (int i = 0; i < sourceSizeInBytes; i++)
                            {
                                *bufferRangePtr++ = *sourceRangePtr++;
                            }

                            gl.UnmapNamedBuffer(buffer, gl.GL_ELEMENT_ARRAY_BUFFER);
                            gl.ThrowIfError();
                        }
                        else
                        {
                            gl.NamedBufferSubData(buffer, gl.GL_ELEMENT_ARRAY_BUFFER,
                                                  (IntPtr)bufferOffset, (IntPtr)bufferSize, (Byte *)handle.AddrOfPinnedObject().ToPointer() + (dataOffset * indexStride));
                            gl.ThrowIfError();
                        }
                    }
                }
            }
            finally
            {
                handle.Free();
            }
        }
Ejemplo n.º 5
0
        private void SetBufferData <T>(int bufferSize, int elementSizeInBytes, int offsetInBytes, T[] data, int startIndex, int elementCount, int vertexStride, SetDataOptions options) where T : struct
        {
            GenerateIfRequired();

            var sizeInBytes = elementSizeInBytes * elementCount;

            GL.BindBuffer(BufferTarget.ArrayBuffer, vbo);
            GraphicsExtensions.CheckGLError();

            if (options == SetDataOptions.Discard)
            {
                // By assigning NULL data to the buffer this gives a hint
                // to the device to discard the previous content.
                GL.BufferData(BufferTarget.ArrayBuffer,
                              (IntPtr)bufferSize,
                              IntPtr.Zero,
                              _isDynamic ? BufferUsageHint.StreamDraw : BufferUsageHint.StaticDraw);
                GraphicsExtensions.CheckGLError();
            }

            var dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned);
            var dataPtr    = (IntPtr)(dataHandle.AddrOfPinnedObject().ToInt64() + startIndex * elementSizeInBytes);

            GL.BufferSubData(BufferTarget.ArrayBuffer, (IntPtr)offsetInBytes, (IntPtr)sizeInBytes, dataPtr);
            GraphicsExtensions.CheckGLError();

            dataHandle.Free();
        }
Ejemplo n.º 6
0
 public void SetData <T>(T[] data, int startIndex, int elementCount, SetDataOptions options) where T : struct
 {
     base.SetDataInternal <T>(0, data, startIndex, elementCount, options);
 }
Ejemplo n.º 7
0
        /// <summary>
        /// Sets the data contained by the vertex buffer.
        /// </summary>
        private void SetDataInternal <T>(T[] data, Int32 offsetInBytes, Int32 countInBytes, SetDataOptions options)
        {
            var handle = GCHandle.Alloc(data, GCHandleType.Pinned);

            try
            {
                using (OpenGLState.ScopedBindArrayBuffer(buffer))
                {
                    var isPartialUpdate = (offsetInBytes > 0 || countInBytes < SizeInBytes);
                    var isDiscarding    = (options == SetDataOptions.Discard);
                    if (isDiscarding || !isPartialUpdate)
                    {
                        gl.NamedBufferData(buffer, gl.GL_ARRAY_BUFFER, this.size, isPartialUpdate ? null : handle.AddrOfPinnedObject().ToPointer(), usage);
                        gl.ThrowIfError();

                        /* FIX:
                         * I have no idea why the following code is necessary, but
                         * it seems to fix flickering sprites on Intel HD 4000 devices. */
                        if (gl.IsVertexArrayObjectAvailable)
                        {
                            var vao = (uint)OpenGLState.GL_VERTEX_ARRAY_BINDING;
                            gl.BindVertexArray(vao);
                            gl.ThrowIfError();
                        }
                    }

                    if (isPartialUpdate)
                    {
                        gl.NamedBufferSubData(buffer, gl.GL_ARRAY_BUFFER, (IntPtr)offsetInBytes, (IntPtr)countInBytes, handle.AddrOfPinnedObject().ToPointer());
                        gl.ThrowIfError();
                    }
                }
            }
            finally
            {
                handle.Free();
            }
        }
Ejemplo n.º 8
0
 public void SetData <T>(int offsetInBytes, T[] data, int startIndex, int elementCount, SetDataOptions options) where T : struct
 {
     throw new NotImplementedException();
 }
Ejemplo n.º 9
0
        /// <summary>
        /// Performs rendering of particles.
        /// </summary>
        /// <param name="iterator">The particle iterator object.</param>
        /// <param name="context">The render context containing rendering information.</param>
        protected override void Render(ref RenderContext context, ref ParticleIterator iterator)
        {
            Int32 vertexCount = 0;
            Vector3 cameraPos = context.CameraPosition;
            Vector3 rotationAxis = context.BillboardRotationalAxis;
            bool squareTexture = (context.Texture.Height == context.Texture.Width);
            float aspectRatio = context.Texture.Height / (float)context.Texture.Width ;

            SetDataOptions setDataOptions = SetDataOptions.NoOverwrite;

            //Use the SpriteBatch style of filling buffers
            //http://blogs.msdn.com/b/shawnhar/archive/2010/07/07/setdataoptions-nooverwrite-versus-discard.aspx
            if (_vertexBufferPosition + context.Count * VerticesPerParticle > NumVertices)
            {
                //Too much to fit in the remaining space - start at the beginning and discard
                _vertexBufferPosition = 0;
                setDataOptions = SetDataOptions.Discard;
            }

#if UNSAFE
            unsafe
            {
                fixed (ParticleVertex* vertexArray = Vertices)
                {
                    ParticleVertex* verts = vertexArray +_vertexBufferPosition;
#else
                    int vertexIndex = _vertexBufferPosition;
#endif
                    var particle = iterator.First;
                    do
                    {
#if UNSAFE
                        Single scale = particle->Scale;
                        Vector3 position = particle->Position;
                        Vector3 rotation = particle->Rotation;
                        Vector4 colour = particle->Colour;
                        //Work out our world transform - and set a flag to avoid some multiplies if world ends up as zero
                        bool worldIsNotIdentity = true;
                        Matrix effectWorld;
                        if (context.WorldIsIdentity)
                        {
                            if (particle->EffectProxyIndex > 0)
                            {
                                effectWorld = ParticleEffectProxy.Proxies[particle->EffectProxyIndex].World;
                            }
                            else
                            {
                                worldIsNotIdentity = false;
                                effectWorld = Matrix.Identity; //Makes the compiler happy though we will never actually use it.
                            }
                        }
                        else
                        {
                            effectWorld = particle->EffectProxyIndex > 0 ? ParticleEffectProxy.Proxies[particle->EffectProxyIndex].FinalWorld : context.World;
                        }

#else
                        Single scale = particle.Scale;
                        Vector3 position = particle.Position;
                        Vector3 rotation = particle.Rotation;
                        Vector4 colour = particle.Colour;
                        //If we have a proxy then multiply in the proxy world matrix
                        bool worldIsNotIdentity = true;
                        Matrix effectWorld;
                        if (context.WorldIsIdentity)
                        {
                            if (particle.EffectProxyIndex > 0)
                            {
                                effectWorld = ParticleEffectProxy.Proxies[particle.EffectProxyIndex].World;
                            }
                            else
                            {
                                worldIsNotIdentity = false;
                                effectWorld = Matrix.Identity;
                                    //Makes the compiler happy though we will never actually use it.
                            }
                        }
                        else
                        {
                            effectWorld = particle.EffectProxyIndex > 0
                                              ? ParticleEffectProxy.Proxies[particle.EffectProxyIndex].FinalWorld
                                              : context.World;
                        }
#endif

                        //Individual particle transformations - scale and rotation
                        //The Rotation setup will fill in the top 3x3 so we just need to initialise 44
                        var transform = new Matrix {M44 = 1};

                        float scaleX = scale;
                        float scaleY = squareTexture ? scale : scale * aspectRatio;
                        //ScaleZ is always 1 so no need multiple into M_3

                        //Inline the rotation and scale calculations and do each element in one go
                        //Fast rotation matrix - see http://en.wikipedia.org/wiki/Rotation_matrix#General_rotations
                        //This set matches
                        //Matrix temp2 = Matrix.CreateRotationX(rotation.X) * Matrix.CreateRotationY(rotation.Y) * Matrix.CreateRotationZ(rotation.Z); //Matches math od Rotx*RotY*RotZ
                        //var cosX = (float) Math.Cos(rotation.X);
                        //var cosY = (float) Math.Cos(rotation.Y);
                        //var cosZ = (float) Math.Cos(rotation.Z);
                        //var sinX = (float) Math.Sin(rotation.X);
                        //var sinY = (float) Math.Sin(rotation.Y);
                        //var sinZ = (float) Math.Sin(rotation.Z);
                        //transform.M11 = cosY*cosZ;
                        //transform.M12 = cosY * sinZ;
                        //transform.M13 = -sinY;
                        //transform.M21 = sinX*sinY*cosZ - cosX * sinZ;
                        //transform.M22 = sinX*sinY*sinZ + cosX*cosZ;
                        //transform.M23 = sinX*cosY;
                        //transform.M31 = cosX*sinY*cosZ + sinX * sinZ;
                        //transform.M32 = cosX*sinY*sinZ - sinX * cosZ;
                        //transform.M33 = cosX * cosY;

                        //This set matches
                        //Matrix temp2 = Matrix.CreateScale(new VEctor3(scaleX, scaleY,1) * Matrix.CreateRotationZ(rotation.Z) * Matrix.CreateRotationX(rotation.Y) * Matrix.CreateRotationY(rotation.X) ; //Matches YawPitchRoll order
                        //Matrix temp = Matrix.CreateScale(new VEctor3(scaleX, scaleY,1) * Matrix.CreateFromYawPitchRoll(rotation.X, rotation.Y, rotation.Z);
                        //TODO - can we optimise out a rotation e.g.fast path if rotation.Y=0 etc
                        //TODO - can we optimise out rotation(s) if we know its a billboard? That overwrites much of the transform
                        var cosX = (float)Math.Cos(rotation.Y);
                        var cosY = (float)Math.Cos(rotation.X);
                        var cosZ = (float)Math.Cos(rotation.Z);
                        var sinX = (float)Math.Sin(rotation.Y);
                        var sinY = (float)Math.Sin(rotation.X);
                        var sinZ = (float)Math.Sin(rotation.Z);
                        var cosYcosZ = cosY*cosZ;
                        var cosYsinZ = cosY*sinZ;
                        var sinXsinY = sinX*sinY;
                        transform.M11 = (cosYcosZ + sinXsinY * sinZ) * scaleX;
                        transform.M12 = (cosX * sinZ) * scaleX;
                        transform.M13 = (sinX * cosYsinZ - sinY * cosZ) * scaleX;
                        transform.M21 = (sinXsinY * cosZ - cosYsinZ) * scaleY;
                        transform.M22 = (cosX * cosZ) *scaleY;
                        transform.M23 = (sinY * sinZ + sinX * cosYcosZ) * scaleY;
                        transform.M31 = cosX * sinY;
                        transform.M32 = -sinX;
                        transform.M33 = cosX * cosY;

                        switch (context.BillboardStyle)
                        {
                            case BillboardStyle.None:
                                //Position the particle without a multiplication!
                                transform.M41 = position.X;
                                transform.M42 = position.Y;
                                transform.M43 = position.Z;
                                //Just apply the world
                                //TODO - we can just do this in Basic effect instead of per vertex - only if there is no proxy, sort of a fast path!
                                if (worldIsNotIdentity)
                                {
                                    Matrix.Multiply(ref transform, ref effectWorld, out transform);
                                }
                                break;

                            default: //Its billboarded

                                Vector3 worldPos;
                                if (worldIsNotIdentity)
                                {
                                    Vector3.Transform(ref position, ref effectWorld, out worldPos);
                                }
                                else
                                {
                                    worldPos = position;
                                }


                                //Apply the billboard (which includes the world translation)
                                Matrix billboardMatrix;
                                if (context.BillboardStyle == BillboardStyle.Spherical)
                                {
                                    //Spherical billboards (always face the camera)
                                    Matrix.CreateBillboard(ref worldPos, ref cameraPos, ref Up, Forward,
                                                           out billboardMatrix);
                                }
                                else
                                {
                                    //HACK: For progenitor DBP use the velocity as the axis for a per particle axis
                                    if (context.UseVelocityAsBillboardAxis)
                                    {
#if UNSAFE
                                        Matrix.CreateConstrainedBillboard(ref worldPos, ref cameraPos, ref particle->Velocity,
                                                                          Forward, null, out billboardMatrix);
#else
                                        Matrix.CreateConstrainedBillboard(ref worldPos, ref cameraPos, ref particle.Velocity,
                                                                          Forward, null, out billboardMatrix);

#endif
                                    }
                                    else
                                    {
                                        //Cylindrical billboards have a vector they are allowed to rotate around
                                        Matrix.CreateConstrainedBillboard(ref worldPos, ref cameraPos, ref rotationAxis,
                                                                          Forward, null, out billboardMatrix);
                                    }


                                }

                                Matrix.Multiply(ref transform, ref billboardMatrix, out transform);
                                break;
                        }

                        Vector3 v1;
                        Vector3 v2;
                        Vector3 v3;
                        Vector3 v4;

                        Vector3.Transform(ref inv1, ref transform, out v1);
                        Vector3.Transform(ref inv2, ref transform, out v2);
                        Vector3.Transform(ref inv3, ref transform, out v3);
                        Vector3.Transform(ref inv4, ref transform, out v4);
#if UNSAFE

                        //inline particle value assignments - removes 4 calls with their parameters and its a struct anyway
                        verts->Position.X = v1.X;
                        verts->Position.Y = v1.Y;
                        verts->Position.Z = v1.Z;
                        verts->Colour.X = colour.X;
                        verts->Colour.Y = colour.Y;
                        verts->Colour.Z = colour.Z;
                        verts->Colour.W = colour.W;
                        verts++;

                        verts->Position.X = v2.X;
                        verts->Position.Y = v2.Y;
                        verts->Position.Z = v2.Z;
                        verts->Colour.X = colour.X;
                        verts->Colour.Y = colour.Y;
                        verts->Colour.Z = colour.Z;
                        verts->Colour.W = colour.W;
                        verts++;

                        verts->Position.X = v3.X;
                        verts->Position.Y = v3.Y;
                        verts->Position.Z = v3.Z;
                        verts->Colour.X = colour.X;
                        verts->Colour.Y = colour.Y;
                        verts->Colour.Z = colour.Z;
                        verts->Colour.W = colour.W;
                        verts++;

                        verts->Position.X = v4.X;
                        verts->Position.Y = v4.Y;
                        verts->Position.Z = v4.Z;
                        verts->Colour.X = colour.X;
                        verts->Colour.Y = colour.Y;
                        verts->Colour.Z = colour.Z;
                        verts->Colour.W = colour.W;
                        verts++;
#else
                        //inline particle value assignments - removes 4 calls with their parameters and its a struct anyway

                        this.Vertices[vertexIndex].Position = v1;
                        this.Vertices[vertexIndex].Colour = colour;
                        this.Vertices[vertexIndex++].TextureCoordinate = uv1;
                        this.Vertices[vertexIndex].Position = v2;
                        this.Vertices[vertexIndex].Colour = colour;
                        this.Vertices[vertexIndex++].TextureCoordinate = uv2;
                        this.Vertices[vertexIndex].Position = v3;
                        this.Vertices[vertexIndex].Colour = colour;
                        this.Vertices[vertexIndex++].TextureCoordinate = uv3;
                        this.Vertices[vertexIndex].Position = v4;
                        this.Vertices[vertexIndex].Colour = colour;
                        this.Vertices[vertexIndex++].TextureCoordinate = uv4;
#endif
                        vertexCount += 4;
                    }
#if UNSAFE
                    while (iterator.MoveNext(&particle));
#else
                    while (iterator.MoveNext(ref particle));
#endif

                    base.GraphicsDeviceService.GraphicsDevice.BlendState = context.BlendState;
                    this.BasicEffect.Texture = context.Texture;

                    //Xbox need the vertex buffer to be set to null before SetData is called
                    //Windows does not
                    //TODO: Is this a bug? see http://forums.create.msdn.com/forums/p/61885/399495.aspx#399495
#if XBOX
                    if (setDataOptions == SetDataOptions.Discard)
                    {
                        base.GraphicsDeviceService.GraphicsDevice.SetVertexBuffer(null);
                    }
#endif
                    _vertexBuffer.SetData(_vertexBufferPosition * ParticleVertex.Size, Vertices, _vertexBufferPosition, vertexCount, ParticleVertex.Size, setDataOptions);
                    Debug.WriteLine(String.Format("position: {0} Count: {1} Hint: {2}", _vertexBufferPosition, vertexCount, setDataOptions));
                    base.GraphicsDeviceService.GraphicsDevice.SetVertexBuffer(_vertexBuffer);

                    foreach (EffectPass pass in this.BasicEffect.CurrentTechnique.Passes)
                    {
                        pass.Apply();

                        base.GraphicsDeviceService.GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, _vertexBufferPosition, vertexCount,
                                                                                        _vertexBufferPosition/4*6, vertexCount/2);
                    }

                    //Move to the next free part of the array
                    _vertexBufferPosition += vertexCount;
#if UNSAFE
                }
            }
#endif
        }
Ejemplo n.º 10
0
        public void SetData <T>(T[] data, int startIndex, int elementCount, SetDataOptions options) where T : struct
        {
            var elementSizeInBytes = Utilities.ReflectionHelpers.SizeOf <T> .Get();

            base.SetDataInternal <T>(0, data, startIndex, elementCount, elementSizeInBytes, options);
        }
Ejemplo n.º 11
0
 public void SetData <T>(int offsetInBytes, T[] data, int startIndex, int elementCount, int vertexStride, SetDataOptions options) where T : struct
 {
     base.SetDataInternal <T>(offsetInBytes, data, startIndex, elementCount, vertexStride, options);
 }
Ejemplo n.º 12
0
        private void PlatformSetDataInternal <T>(int offsetInBytes, T[] data, int startIndex, int elementCount, int vertexStride, SetDataOptions options, int bufferSize, int elementSizeInBytes) where T : struct
        {
            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);
                    if (vertexStride == elementSizeInBytes)
                    {
                        SharpDX.Utilities.Write(dataBox.DataPointer + offsetInBytes, data, startIndex, elementCount);
                    }
                    else
                    {
                        for (int i = 0; i < elementCount; i++)
                        {
                            SharpDX.Utilities.Write(dataBox.DataPointer + offsetInBytes + i * vertexStride, data, startIndex + i, 1);
                        }
                    }

                    d3dContext.UnmapSubresource(_buffer, 0);
                }
            }
            else
            {
                var dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned);
                try
                {
                    var startBytes = startIndex * elementSizeInBytes;
                    var dataPtr    = (IntPtr)(dataHandle.AddrOfPinnedObject().ToInt64() + startBytes);

                    var d3dContext = GraphicsDevice._d3dContext;

                    if (vertexStride == elementSizeInBytes)
                    {
                        var box = new SharpDX.DataBox(dataPtr, elementCount * elementSizeInBytes, 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 (d3dContext)
                            d3dContext.UpdateSubresource(box, _buffer, 0, region);
                    }
                    else
                    {
                        // Copy the buffer to a staging resource, so that any elements we don't write to will still be correct.
                        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;
                        using (var stagingBuffer = new SharpDX.Direct3D11.Buffer(GraphicsDevice._d3dDevice, stagingDesc))
                        {
                            lock (d3dContext)
                            {
                                d3dContext.CopyResource(_buffer, stagingBuffer);

                                // Map the staging resource to a CPU accessible memory
                                var box = d3dContext.MapSubresource(stagingBuffer, 0, SharpDX.Direct3D11.MapMode.Read,
                                                                    SharpDX.Direct3D11.MapFlags.None);

                                for (int i = 0; i < elementCount; i++)
                                {
                                    SharpDX.Utilities.CopyMemory(
                                        box.DataPointer + i * vertexStride + offsetInBytes,
                                        dataPtr + i * elementSizeInBytes, elementSizeInBytes);
                                }

                                // Make sure that we unmap the resource in case of an exception
                                d3dContext.UnmapSubresource(stagingBuffer, 0);

                                // Copy back from staging resource to real buffer.
                                d3dContext.CopyResource(stagingBuffer, _buffer);
                            }
                        }
                    }
                }
                finally
                {
                    dataHandle.Free();
                }
            }
        }
Ejemplo n.º 13
0
 /// <summary>
 /// As long as we did not put anything new into the buffer we can discard the old content.
 /// However once AddDataNative was called we need to use NoOverwrite until drawing happens.
 /// </summary>
 protected override void BufferIsFullResetToBeginning()
 {
     base.BufferIsFullResetToBeginning();
     currentDataHint = SetDataOptions.Discard;
 }
Ejemplo n.º 14
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
        }
Ejemplo n.º 15
0
        public void SetData <T>(int offsetInBytes, T[] data, int startIndex, int elementCount, SetDataOptions options)
        {
            int indexSize = indexElementSize == IndexElementSize.SixteenBits ? 2 : 4;

            data = getSubData <T>(data, startIndex, elementCount);
            Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, bufferIdentifier);
            Gl.glBufferSubData(Gl.GL_ARRAY_BUFFER, new IntPtr(offsetInBytes), new IntPtr(indexSize * elementCount), data);
        }
Ejemplo n.º 16
0
 /// <summary>
 /// Sets the data contained by the index buffer.
 /// </summary>
 /// <typeparam name="T">The type of the elements of the array to set as the buffer's data.</typeparam>
 /// <param name="data">An array containing the data to set in the index buffer.</param>
 /// <param name="offset">The offset into <paramref name="data"/> at which to begin setting elements into the buffer.</param>
 /// <param name="count">The number of elements from <paramref name="data"/> to set into the buffer.</param>
 /// <param name="options">A hint to the underlying driver indicating whether data will be overwritten by this operation.</param>
 public abstract void SetData <T>(T[] data, Int32 offset, Int32 count, SetDataOptions options);
Ejemplo n.º 17
0
 /// <summary>
 /// Sets the index buffer's data from the data at the specified pointer.
 /// </summary>
 /// <param name="data">A pointer to the data to set.</param>
 /// <param name="srcOffsetInBytes">The offset from the beginning of the source data, in bytes, at which to begin copying.</param>
 /// <param name="dstOffsetInBytes">The offset from the beginning of the index buffer, in bytes, at which to begin copying.</param>
 /// <param name="sizeInBytes">The number of bytes to copy.</param>
 /// <param name="options">A hint to the underlying driver indicating whether data will be overwritten by this operation.</param>
 public abstract void SetRawData(IntPtr data, Int32 srcOffsetInBytes, Int32 dstOffsetInBytes, Int32 sizeInBytes, SetDataOptions options);
Ejemplo n.º 18
0
        /// <summary>
        /// Forces drawing of the current batch.
        /// </summary>
        public void Flush()
        {
            var graphicsDevice = _instanceVertexBuffer.GraphicsDevice;

            int numberOfInstances = _nextInstance - _startInstance;

            if (numberOfInstances > 0)
            {
#if XBOX
                // Required by Xbox 360:
                if (_setDataOptions == SetDataOptions.Discard)
                {
                    graphicsDevice.SetVertexBuffer(null);
                    graphicsDevice.Indices = null;
                }
#endif

                var vertexBuffer = _submesh.VertexBuffer;
                var indexBuffer  = _submesh.IndexBuffer;
                Debug.Assert(indexBuffer != null, "Hardware instancing failed: The submesh has no index buffer.");

                // Copy instance data to instance vertex buffer.
                int vertexSize = _vertexDeclaration.VertexStride;
                _instanceVertexBuffer.SetData(_startInstance * vertexSize, Instances, _startInstance, numberOfInstances,
                                              vertexSize, _setDataOptions);

                // Set vertex buffers and index buffer.
                _vertexBuffers[0] = new VertexBufferBinding(vertexBuffer, _submesh.StartVertex, 0);
                _vertexBuffers[1] = new VertexBufferBinding(_instanceVertexBuffer, _startInstance, 1);
                graphicsDevice.SetVertexBuffers(_vertexBuffers);
                graphicsDevice.Indices = indexBuffer;

                foreach (var pass in _effectPassBinding)
                {
                    // Update and apply local, per-instance and per-pass bindings.
                    foreach (var binding in _effectPassParameterBindings)
                    {
                        if (binding.Description.Hint == EffectParameterHint.PerPass)
                        {
                            binding.Update(_renderContext);
                        }

                        binding.Apply(_renderContext);
                    }

                    pass.Apply();
                    graphicsDevice.DrawInstancedPrimitives(
                        _submesh.PrimitiveType,
                        0,
                        0,
                        _submesh.VertexCount,
                        _submesh.StartIndex,
                        _submesh.PrimitiveCount,
                        numberOfInstances);
                }

                _startInstance  = _nextInstance;
                _setDataOptions = SetDataOptions.NoOverwrite;
            }

            //// Restart from beginning if remaining capacity is low.
            //var vertexBufferBatchCapacity = Vertices.Length - _startVertex;
            //var indexBufferBatchCapacity = Indices.Length - _startIndex;
            //if (vertexBufferBatchCapacity < 128 || indexBufferBatchCapacity < 128 * 3)
            //  Reset();

            // Remove strong references.
            _vertexBuffers[0] = new VertexBufferBinding();

            // Reset vertex buffer to remove second vertex stream.
            graphicsDevice.SetVertexBuffer(null);
        }
Ejemplo n.º 19
0
 /// <summary>
 /// Sets the data contained by the index buffer, allowing the driver to align the data in such a way as to
 /// optimize the speed of the operation, perhaps at the cost of video memory.
 /// </summary>
 /// <typeparam name="T">The type of the elements of the array to set as the buffer's data.</typeparam>
 /// <param name="data">An array containing the data to set in the index buffer.</param>
 /// <param name="dataOffset">The offset into <paramref name="data"/> at which to begin setting elements into the buffer.</param>
 /// <param name="dataCount">The number of elements from <paramref name="data"/> to set into the buffer.</param>
 /// <param name="bufferOffset">The offset into the index buffer at which to begin uploading index data.</param>
 /// <param name="bufferSize">The size, in bytes, of the buffer region to which the data was uploaded. This may be larger than
 /// is strictly required by the uploaded data due to driver-specific alignment concerns.</param>
 /// <param name="options">A hint to the underlying driver indicating whether data will be overwritten by this operation.</param>
 public abstract void SetDataAligned <T>(T[] data, Int32 dataOffset, Int32 dataCount, Int32 bufferOffset, out Int32 bufferSize, SetDataOptions options) where T : struct;
Ejemplo n.º 20
0
        /// <inheritdoc/>
        public override void SetDataAligned <T>(T[] data, Int32 dataOffset, Int32 dataCount, Int32 bufferOffset, out Int32 bufferSize, SetDataOptions options)
        {
            Contract.Require(data, nameof(data));
            Contract.EnsureRange(dataCount > 0, nameof(dataCount));
            Contract.EnsureRange(dataOffset >= 0 && dataOffset + dataCount <= data.Length, nameof(dataOffset));
            Contract.EnsureRange(bufferOffset >= 0, nameof(bufferOffset));
            Contract.Ensure(dataCount <= VertexCount, OpenGLStrings.DataTooLargeForBuffer);

            bufferSize = vdecl.VertexStride * dataCount;

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

            try
            {
                var caps = (OpenGLGraphicsCapabilities)Ultraviolet.GetGraphics().Capabilities;
                if (caps.MinMapBufferAlignment > 0)
                {
                    bufferSize = Math.Min(Math.Max(caps.MinMapBufferAlignment, MathUtil.FindNextPowerOfTwo(bufferSize)), SizeInBytes - bufferOffset);
                }

                using (OpenGLState.ScopedBindArrayBuffer(buffer))
                {
                    var isPartialUpdate = (bufferOffset > 0 || bufferSize < SizeInBytes);
                    var isDiscarding    = (options == SetDataOptions.Discard);
                    if (isDiscarding || !isPartialUpdate)
                    {
                        gl.NamedBufferData(buffer, gl.GL_ARRAY_BUFFER, this.size, isPartialUpdate ? null : handle.AddrOfPinnedObject().ToPointer(), usage);
                        gl.ThrowIfError();

                        /* FIX:
                         * I have no idea why the following code is necessary, but
                         * it seems to fix flickering sprites on Intel HD 4000 devices. */
                        if (gl.IsVertexArrayObjectAvailable)
                        {
                            var vao = (uint)OpenGLState.GL_VERTEX_ARRAY_BINDING;
                            gl.BindVertexArray(vao);
                            gl.ThrowIfError();
                        }
                    }

                    if (isPartialUpdate)
                    {
                        if (caps.MinMapBufferAlignment >= 0)
                        {
                            var bufferRangeAccess = gl.GL_MAP_WRITE_BIT | (options == SetDataOptions.NoOverwrite ? gl.GL_MAP_UNSYNCHRONIZED_BIT : 0);
                            var bufferRangePtr    = (Byte *)gl.MapNamedBufferRange(buffer, gl.GL_ARRAY_BUFFER,
                                                                                   (IntPtr)bufferOffset, (IntPtr)bufferSize, bufferRangeAccess);
                            gl.ThrowIfError();

                            var sourceRangePtr    = (Byte *)handle.AddrOfPinnedObject() + (dataOffset * vdecl.VertexStride);
                            var sourceSizeInBytes = dataCount * vdecl.VertexStride;

                            for (int i = 0; i < sourceSizeInBytes; i++)
                            {
                                *bufferRangePtr++ = *sourceRangePtr++;
                            }

                            gl.UnmapNamedBuffer(buffer, gl.GL_ARRAY_BUFFER);
                            gl.ThrowIfError();
                        }
                        else
                        {
                            gl.NamedBufferSubData(buffer, gl.GL_ARRAY_BUFFER,
                                                  (IntPtr)bufferOffset, (IntPtr)bufferSize, (Byte *)handle.AddrOfPinnedObject().ToPointer() + (dataOffset * vdecl.VertexStride));
                            gl.ThrowIfError();
                        }
                    }
                }
            }
            finally
            {
                handle.Free();
            }
        }
        private void PlatformSetDataInternal <T>(int offsetInBytes, T[] data, int startIndex, int elementCount, SetDataOptions options) where T : struct
        {
            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);
                try
                {
                    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);
                }
                finally
                {
                    dataHandle.Free();
                }
            }
        }
Ejemplo n.º 22
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));
     }
 }
Ejemplo n.º 23
0
		public void SetIndexBufferData(
			IGLBuffer buffer,
			int offsetInBytes,
			IntPtr data,
			int startIndex,
			int elementCount,
			int elementSizeInBytes,
			SetDataOptions options
		) {
#if !DISABLE_THREADING
			ForceToMainThread(() => {
#endif

			BindIndexBuffer(buffer);

			if (options == SetDataOptions.Discard)
			{
				glBufferData(
					GLenum.GL_ELEMENT_ARRAY_BUFFER,
					buffer.BufferSize,
					IntPtr.Zero,
					(buffer as OpenGLBuffer).Dynamic
				);
			}

			glBufferSubData(
				GLenum.GL_ELEMENT_ARRAY_BUFFER,
				(IntPtr) offsetInBytes,
				(IntPtr) (elementSizeInBytes * elementCount),
				data + (startIndex * elementSizeInBytes)
			);

#if !DISABLE_THREADING
			});
#endif
		}
Ejemplo n.º 24
0
        /// <summary>
        /// Sets the data contained by the vertex buffer.
        /// </summary>
        private void SetDataInternal <T>(T[] data, Int32 offsetInBytes, Int32 countInBytes, SetDataOptions options)
        {
            var handle = GCHandle.Alloc(data, GCHandleType.Pinned);

            try
            {
                using (OpenGLState.ScopedBindElementArrayBuffer(buffer))
                {
                    var isPartialUpdate = (offsetInBytes > 0 || countInBytes < SizeInBytes);
                    var isDiscarding    = (options == SetDataOptions.Discard);
                    if (isDiscarding || !isPartialUpdate)
                    {
                        gl.NamedBufferData(buffer, gl.GL_ELEMENT_ARRAY_BUFFER, this.size, isPartialUpdate ? null : handle.AddrOfPinnedObject().ToPointer(), usage);
                        gl.ThrowIfError();
                    }

                    if (isPartialUpdate)
                    {
                        gl.NamedBufferSubData(buffer, gl.GL_ELEMENT_ARRAY_BUFFER, (IntPtr)offsetInBytes, (IntPtr)countInBytes, handle.AddrOfPinnedObject().ToPointer());
                        gl.ThrowIfError();
                    }
                }
            }
            finally
            {
                handle.Free();
            }
        }
Ejemplo n.º 25
0
 public void SetData <T>(int offsetInBytes, T[] data, int startIndex, int elementCount, SetDataOptions options) where T : struct
 {
     this.SetDataInternal <T>(offsetInBytes, data, startIndex, elementCount, options);
 }
Ejemplo n.º 26
0
        public void SetData <T> (int level, Rectangle?rect, T[] data, int startIndex, int elementCount, SetDataOptions options)
        {
            if (data == null)
            {
                throw new ArgumentException("data cannot be null");
            }

            if (data.Length < startIndex + elementCount)
            {
                throw new ArgumentException("The data passed has a length of " + data.Length + " but " + elementCount + " pixels have been requested.");
            }

            Rectangle r;

            if (rect != null)
            {
                r = rect.Value;
            }
            else
            {
                r = new Rectangle(0, 0, Width, Height);
            }
        }
Ejemplo n.º 27
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));
     }
 }
Ejemplo n.º 28
0
        protected void SetData <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));

            Threading.BlockOnUIThread((Action)(() =>
            {
                int local_0 = elementSizeInBytes * elementCount;
                GL.BindBuffer(BufferTarget.ArrayBuffer, this.vbo);
                if (options == SetDataOptions.Discard)
                {
                    GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)bufferSize, IntPtr.Zero, this._isDynamic ? BufferUsageHint.StreamDraw : BufferUsageHint.StaticDraw);
                }
                GL.BufferSubData <T>(BufferTarget.ArrayBuffer, (IntPtr)offsetInBytes, (IntPtr)local_0, data);
            }));
        }
Ejemplo n.º 29
0
 public void SetData <T>(T[] data, int startIndex, int elementCount, SetDataOptions options)
 {
     throw new NotImplementedException();
 }
Ejemplo n.º 30
0
 public void SetData <T>(T[] data, int startIndex, int elementCount, SetDataOptions options)
 {
     SetData <T>(0, data, startIndex, elementCount, options);
 }
Ejemplo n.º 31
0
 public void SetData <T>(int level, Rectangle?rect, T[] data, int startIndex, int elementCount, SetDataOptions options)
 {
     throw new NotImplementedException();
 }
Ejemplo n.º 32
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");
            }

            var elementSizeInBytes = Marshal.SizeOf(typeof(T));
            var bufferSize         = VertexCount * VertexDeclaration.VertexStride;

            if (vertexStride == 0)
            {
                vertexStride = elementSizeInBytes;
            }

            if (startIndex + elementCount > data.Length || elementCount <= 0)
            {
                throw new ArgumentOutOfRangeException("data", "The array specified in the data parameter is not the correct size for the amount of data requested.");
            }
            if (elementCount > 1 && (elementCount * vertexStride > bufferSize))
            {
                throw new InvalidOperationException("The vertex stride is larger than the vertex buffer.");
            }
            if (vertexStride < elementSizeInBytes)
            {
                throw new ArgumentOutOfRangeException("The vertex stride must be greater than or equal to the size of the specified data (" + elementSizeInBytes + ").");
            }

            PlatformSetDataInternal <T> (offsetInBytes, data, startIndex, elementCount, vertexStride, options, bufferSize, elementSizeInBytes);
        }
Ejemplo n.º 33
0
        public void SetVertexBufferData(
			IGLBuffer buffer,
			int offsetInBytes,
			IntPtr data,
			int startIndex,
			int elementCount,
			int elementSizeInBytes,
			SetDataOptions options
		)
        {
            #if !DISABLE_THREADING
            ForceToMainThread(() => {
            #endif
            uint handle = (buffer as OpenGLBuffer).Handle;

            if (options == SetDataOptions.Discard)
            {
                glNamedBufferData(
                    handle,
                    buffer.BufferSize,
                    IntPtr.Zero,
                    (buffer as OpenGLBuffer).Dynamic
                );
            }

            glNamedBufferSubData(
                handle,
                (IntPtr) offsetInBytes,
                (IntPtr) (elementSizeInBytes * elementCount),
                data + (startIndex * elementSizeInBytes)
            );

            #if !DISABLE_THREADING
            });
            #endif
        }