public void Draw(Skeleton skeleton) { float[] vertices = this.vertices; var drawOrder = skeleton.DrawOrder; var drawOrderItems = skeleton.DrawOrder.Items; float skeletonR = skeleton.R, skeletonG = skeleton.G, skeletonB = skeleton.B, skeletonA = skeleton.A; for (int i = 0, n = drawOrder.Count; i < n; i++) { Slot slot = drawOrderItems[i]; Attachment attachment = slot.Attachment; if (attachment is RegionAttachment) { RegionAttachment regionAttachment = (RegionAttachment)attachment; BlendState blend = slot.Data.BlendMode == BlendMode.additive ? BlendState.Additive : defaultBlendState; if (device.BlendState != blend) { End(); device.BlendState = blend; } MeshItem item = batcher.NextItem(4, 6); item.triangles = quadTriangles; VertexPositionColorTexture[] itemVertices = item.vertices; AtlasRegion region = (AtlasRegion)regionAttachment.RendererObject; item.texture = (Texture2D)region.page.rendererObject; Color color; float a = skeletonA * slot.A * regionAttachment.A; if (premultipliedAlpha) { color = new Color( skeletonR * slot.R * regionAttachment.R * a, skeletonG * slot.G * regionAttachment.G * a, skeletonB * slot.B * regionAttachment.B * a, a); } else { color = new Color( skeletonR * slot.R * regionAttachment.R, skeletonG * slot.G * regionAttachment.G, skeletonB * slot.B * regionAttachment.B, a); } itemVertices[TL].Color = color; itemVertices[BL].Color = color; itemVertices[BR].Color = color; itemVertices[TR].Color = color; regionAttachment.ComputeWorldVertices(slot.Bone, vertices); itemVertices[TL].Position.X = vertices[RegionAttachment.X1]; itemVertices[TL].Position.Y = vertices[RegionAttachment.Y1]; itemVertices[TL].Position.Z = 0; itemVertices[BL].Position.X = vertices[RegionAttachment.X2]; itemVertices[BL].Position.Y = vertices[RegionAttachment.Y2]; itemVertices[BL].Position.Z = 0; itemVertices[BR].Position.X = vertices[RegionAttachment.X3]; itemVertices[BR].Position.Y = vertices[RegionAttachment.Y3]; itemVertices[BR].Position.Z = 0; itemVertices[TR].Position.X = vertices[RegionAttachment.X4]; itemVertices[TR].Position.Y = vertices[RegionAttachment.Y4]; itemVertices[TR].Position.Z = 0; float[] uvs = regionAttachment.UVs; itemVertices[TL].TextureCoordinate.X = uvs[RegionAttachment.X1]; itemVertices[TL].TextureCoordinate.Y = uvs[RegionAttachment.Y1]; itemVertices[BL].TextureCoordinate.X = uvs[RegionAttachment.X2]; itemVertices[BL].TextureCoordinate.Y = uvs[RegionAttachment.Y2]; itemVertices[BR].TextureCoordinate.X = uvs[RegionAttachment.X3]; itemVertices[BR].TextureCoordinate.Y = uvs[RegionAttachment.Y3]; itemVertices[TR].TextureCoordinate.X = uvs[RegionAttachment.X4]; itemVertices[TR].TextureCoordinate.Y = uvs[RegionAttachment.Y4]; } else if (attachment is MeshAttachment) { MeshAttachment mesh = (MeshAttachment)attachment; int vertexCount = mesh.Vertices.Length; if (vertices.Length < vertexCount) { vertices = new float[vertexCount]; } mesh.ComputeWorldVertices(slot, vertices); int[] triangles = mesh.Triangles; MeshItem item = batcher.NextItem(vertexCount, triangles.Length); item.triangles = triangles; AtlasRegion region = (AtlasRegion)mesh.RendererObject; item.texture = (Texture2D)region.page.rendererObject; Color color; float a = skeletonA * slot.A * mesh.A; if (premultipliedAlpha) { color = new Color( skeletonR * slot.R * mesh.R * a, skeletonG * slot.G * mesh.G * a, skeletonB * slot.B * mesh.B * a, a); } else { color = new Color( skeletonR * slot.R * mesh.R, skeletonG * slot.G * mesh.G, skeletonB * slot.B * mesh.B, a); } float[] uvs = mesh.UVs; VertexPositionColorTexture[] itemVertices = item.vertices; for (int ii = 0, v = 0; v < vertexCount; ii++, v += 2) { itemVertices[ii].Color = color; itemVertices[ii].Position.X = vertices[v]; itemVertices[ii].Position.Y = vertices[v + 1]; itemVertices[ii].Position.Z = 0; itemVertices[ii].TextureCoordinate.X = uvs[v]; itemVertices[ii].TextureCoordinate.Y = uvs[v + 1]; } } else if (attachment is WeightedMeshAttachment) { WeightedMeshAttachment mesh = (WeightedMeshAttachment)attachment; int vertexCount = mesh.UVs.Length; if (vertices.Length < vertexCount) { vertices = new float[vertexCount]; } mesh.ComputeWorldVertices(slot, vertices); int[] triangles = mesh.Triangles; MeshItem item = batcher.NextItem(vertexCount, triangles.Length); item.triangles = triangles; AtlasRegion region = (AtlasRegion)mesh.RendererObject; item.texture = (Texture2D)region.page.rendererObject; Color color; float a = skeletonA * slot.A * mesh.A; if (premultipliedAlpha) { color = new Color( skeletonR * slot.R * mesh.R * a, skeletonG * slot.G * mesh.G * a, skeletonB * slot.B * mesh.B * a, a); } else { color = new Color( skeletonR * slot.R * mesh.R, skeletonG * slot.G * mesh.G, skeletonB * slot.B * mesh.B, a); } float[] uvs = mesh.UVs; VertexPositionColorTexture[] itemVertices = item.vertices; for (int ii = 0, v = 0; v < vertexCount; ii++, v += 2) { itemVertices[ii].Color = color; itemVertices[ii].Position.X = vertices[v]; itemVertices[ii].Position.Y = vertices[v + 1]; itemVertices[ii].Position.Z = 0; itemVertices[ii].TextureCoordinate.X = uvs[v]; itemVertices[ii].TextureCoordinate.Y = uvs[v + 1]; } } } }
public void Draw(Skeleton skeleton) { var drawOrder = skeleton.DrawOrder; var drawOrderItems = skeleton.DrawOrder.Items; float skeletonR = skeleton.R, skeletonG = skeleton.G, skeletonB = skeleton.B, skeletonA = skeleton.A; for (int i = 0, n = drawOrder.Count; i < n; i++) { Slot slot = drawOrderItems[i]; RegionAttachment regionAttachment = slot.Attachment as RegionAttachment; if (regionAttachment != null) { BlendState blendState = new BlendState(); Blend blendSrc; Blend blendDst; if (premultipliedAlpha) { blendState.AlphaBlendFunction = BlendState.AlphaBlend.AlphaBlendFunction; blendState.BlendFactor = BlendState.AlphaBlend.BlendFactor; blendState.ColorBlendFunction = BlendState.AlphaBlend.ColorBlendFunction; blendState.ColorWriteChannels = BlendState.AlphaBlend.ColorWriteChannels; blendState.ColorWriteChannels1 = BlendState.AlphaBlend.ColorWriteChannels1; blendState.ColorWriteChannels2 = BlendState.AlphaBlend.ColorWriteChannels2; blendState.ColorWriteChannels3 = BlendState.AlphaBlend.ColorWriteChannels3; blendState.MultiSampleMask = BlendState.AlphaBlend.MultiSampleMask; } else { blendState.AlphaBlendFunction = BlendState.NonPremultiplied.AlphaBlendFunction; blendState.BlendFactor = BlendState.NonPremultiplied.BlendFactor; blendState.ColorBlendFunction = BlendState.NonPremultiplied.ColorBlendFunction; blendState.ColorWriteChannels = BlendState.NonPremultiplied.ColorWriteChannels; blendState.ColorWriteChannels1 = BlendState.NonPremultiplied.ColorWriteChannels1; blendState.ColorWriteChannels2 = BlendState.NonPremultiplied.ColorWriteChannels2; blendState.ColorWriteChannels3 = BlendState.NonPremultiplied.ColorWriteChannels3; blendState.MultiSampleMask = BlendState.NonPremultiplied.MultiSampleMask; } switch (slot.Data.BlendMode) { case BlendMode.additive: blendState = BlendState.Additive; break; case BlendMode.multiply: blendSrc = BlendXna.GetXNABlend(BlendXna.GL_DST_COLOR); blendDst = BlendXna.GetXNABlend(BlendXna.GL_ONE_MINUS_SRC_ALPHA); blendState.ColorSourceBlend = blendSrc; blendState.AlphaSourceBlend = blendSrc; blendState.ColorDestinationBlend = blendDst; blendState.AlphaDestinationBlend = blendDst; break; case BlendMode.screen: blendSrc = BlendXna.GetXNABlend(premultipliedAlpha ? BlendXna.GL_ONE : BlendXna.GL_SRC_ALPHA); blendDst = BlendXna.GetXNABlend(BlendXna.GL_ONE_MINUS_SRC_COLOR); blendState.ColorSourceBlend = blendSrc; blendState.AlphaSourceBlend = blendSrc; blendState.ColorDestinationBlend = blendDst; blendState.AlphaDestinationBlend = blendDst; break; default: blendState = defaultBlendState; break; } if (device.BlendState != blendState) { End(); device.BlendState = blendState; } RegionItem item = batcher.NextItem(); AtlasRegion region = (AtlasRegion)regionAttachment.RendererObject; item.texture = (Texture2D)region.page.rendererObject; Color color; float a = skeletonA * slot.A; if (premultipliedAlpha) { color = new Color(skeletonR * slot.R * a, skeletonG * slot.G * a, skeletonB * slot.B * a, a); } else { color = new Color(skeletonR * slot.R, skeletonG * slot.G, skeletonB * slot.B, a); } item.vertexTL.Color = color; item.vertexBL.Color = color; item.vertexBR.Color = color; item.vertexTR.Color = color; float[] vertices = this.vertices; regionAttachment.ComputeWorldVertices(slot.Bone, vertices); item.vertexTL.Position.X = vertices[RegionAttachment.X1]; item.vertexTL.Position.Y = vertices[RegionAttachment.Y1]; item.vertexTL.Position.Z = 0; item.vertexBL.Position.X = vertices[RegionAttachment.X2]; item.vertexBL.Position.Y = vertices[RegionAttachment.Y2]; item.vertexBL.Position.Z = 0; item.vertexBR.Position.X = vertices[RegionAttachment.X3]; item.vertexBR.Position.Y = vertices[RegionAttachment.Y3]; item.vertexBR.Position.Z = 0; item.vertexTR.Position.X = vertices[RegionAttachment.X4]; item.vertexTR.Position.Y = vertices[RegionAttachment.Y4]; item.vertexTR.Position.Z = 0; float[] uvs = regionAttachment.UVs; item.vertexTL.TextureCoordinate.X = uvs[RegionAttachment.X1]; item.vertexTL.TextureCoordinate.Y = uvs[RegionAttachment.Y1]; item.vertexBL.TextureCoordinate.X = uvs[RegionAttachment.X2]; item.vertexBL.TextureCoordinate.Y = uvs[RegionAttachment.Y2]; item.vertexBR.TextureCoordinate.X = uvs[RegionAttachment.X3]; item.vertexBR.TextureCoordinate.Y = uvs[RegionAttachment.Y3]; item.vertexTR.TextureCoordinate.X = uvs[RegionAttachment.X4]; item.vertexTR.TextureCoordinate.Y = uvs[RegionAttachment.Y4]; } } }