Example #1
0
 /// <summary>
 /// Determines if two batches can be merged into a single batch.
 /// </summary>
 private static bool CanMerge(ref PrimitiveGroupEntry oldBatch, ref PrimitiveGroupEntry newBatch)
 {
     if (oldBatch.PrimitiveType != newBatch.PrimitiveType)
     {
         return(false);
     }
     if (oldBatch.LineWidth != newBatch.LineWidth)
     {
         return(false);
     }
     if (oldBatch.PrimitiveType != PrimitiveType.LineList && oldBatch.PrimitiveType != PrimitiveType.TriangleList)
     {
         return(false);
     }
     if (oldBatch.Texture != newBatch.Texture)
     {
         return(false);
     }
     if (oldBatch.World.HasValue || newBatch.World.HasValue)
     {
         return(false);
     }
     if ((oldBatch.IndexCount > 0 && newBatch.IndexCount == 0) || (oldBatch.IndexCount == 0 && newBatch.IndexCount > 0))
     {
         return(false);
     }
     return(true);
 }
Example #2
0
        /// <summary>
        /// Begins a new primitive.
        /// </summary>
#if WINDOWS_PHONE
        /// <param name="lineWidth">This value will always be 1 on Windows Phone.</param>
#endif
        public void BeginPrimitive(PrimitiveType primitiveType, Texture2D texture, Matrix?world, float lineWidth)
        {
            if (hasPrimitiveBegin)
            {
                throw new InvalidOperationException("Begin cannot be called until End has been successfully called.");
            }

            hasPrimitiveBegin = true;

            currentPrimitive               = new PrimitiveGroupEntry();
            currentPrimitive.LineWidth     = lineWidth;
            currentPrimitive.World         = world;
            currentPrimitive.PrimitiveType = primitiveType;
            currentPrimitive.Texture       = texture;
            currentPrimitive.StartVertex   = currentVertex;
            currentPrimitive.StartIndex    = currentIndex;

            currentBaseVertex = currentVertex;
            currentBaseIndex  = currentIndex;

            beginSegment = currentSegment;

#if !WINDOWS_PHONE
            lineIndices.Clear();
            currentLineVertex = 0;
            lastLineVertex    = -1;
#endif
        }
Example #3
0
        private void DrawBatch(DrawingContext context, ref PrimitiveGroupEntry entry, Material material)
        {
            if (entry.VertexCount <= 0 && entry.IndexCount <= 0)
            {
                return;
            }

            material.texture = entry.Texture;
            material.world   = entry.World.HasValue ? entry.World.Value * AbsoluteTransform : AbsoluteTransform;
            material.BeginApply(context);

#if !WINDOWS_PHONE
            if (entry.LineWidth > 0)
            {
                if (thickLineMaterial == null)
                {
                    thickLineMaterial = new ThickLineMaterial(graphics);
                }
                thickLineMaterial.Thickness = entry.LineWidth;
                thickLineMaterial.world     = material.world;
                thickLineMaterial.BeginApply(context);
            }
#endif

            var vertexBufferSize = vertexSegments[entry.Segment + 1] - vertexSegments[entry.Segment];
#if SILVERLIGHT
            if (vertexBuffer == null || vertexBuffer.VertexCount < vertexBufferSize)
#else
            if (vertexBuffer == null || vertexBuffer.VertexCount < vertexBufferSize || vertexBuffer.IsContentLost)
#endif
            {
                if (vertexBuffer != null)
                {
                    vertexBuffer.Dispose();
                }
                vertexBuffer = new DynamicVertexBuffer(graphics, typeof(VertexPositionColorNormalTexture), Math.Max(initialBufferCapacity, vertexBufferSize), BufferUsage.WriteOnly);
            }

            context.SetVertexBuffer(null, 0);
            vertexBuffer.SetData(vertexData, vertexSegments[entry.Segment], vertexBufferSize, SetDataOptions.Discard);

            // Previous segments are not used, so use SetDataOption.Discard to boost performance.
            context.SetVertexBuffer(vertexBuffer, 0);

            if (entry.IndexCount > 0)
            {
                var indexBufferSize = indexSegments[entry.Segment + 1] - indexSegments[entry.Segment];
#if SILVERLIGHT
                if (indexBuffer == null || indexBuffer.IndexCount < indexBufferSize)
#else
                if (indexBuffer == null || indexBuffer.IndexCount < indexBufferSize || indexBuffer.IsContentLost)
#endif
                {
                    if (indexBuffer != null)
                    {
                        indexBuffer.Dispose();
                    }
                    indexBuffer = new DynamicIndexBuffer(graphics, IndexElementSize.SixteenBits, Math.Max(initialBufferCapacity, indexBufferSize), BufferUsage.WriteOnly);
                }

                graphics.Indices = null;
                indexBuffer.SetData(indexData, indexSegments[entry.Segment], indexBufferSize, SetDataOptions.Discard);

                var primitiveCount = Helper.GetPrimitiveCount(entry.PrimitiveType, entry.IndexCount);
                graphics.Indices = indexBuffer;
                graphics.DrawIndexedPrimitives(entry.PrimitiveType, 0, entry.StartVertex, entry.VertexCount, entry.StartIndex, primitiveCount);
            }
            else
            {
                var primitiveCount = Helper.GetPrimitiveCount(entry.PrimitiveType, entry.VertexCount);
                graphics.DrawPrimitives(entry.PrimitiveType, entry.StartVertex, primitiveCount);
            }

            material.EndApply(context);
        }