/// <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); }
/// <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 }
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); }