private unsafe void PopulateVertex( Sprite *sprite, Texture <T> texture, Vertex2D *tl, Vertex2D *tr, Vertex2D *bl, Vertex2D *br) { var w = (sprite->Size.X > 0 ? sprite->Size.X : texture.Width) * sprite->Scale.X; var h = (sprite->Size.Y > 0 ? sprite->Size.Y : texture.Height) * sprite->Scale.Y; var x = sprite->Position.X - sprite->Origin.X * w; var y = sprite->Position.Y - sprite->Origin.Y * h; tl->Position.X = x; tl->Position.Y = y; tl->Color = sprite->Color.Bgra; tl->TextureCoordinate.X = texture.UvLeft; tl->TextureCoordinate.Y = texture.UvTop; tr->Position.X = x + w; tr->Position.Y = y; tr->Color = sprite->Color.Bgra; tr->TextureCoordinate.X = texture.UvRight; tr->TextureCoordinate.Y = texture.UvTop; bl->Position.X = x; bl->Position.Y = y + h; bl->Color = sprite->Color.Bgra; bl->TextureCoordinate.X = texture.UvLeft; bl->TextureCoordinate.Y = texture.UvBottom; br->Position.X = x + w; br->Position.Y = y + h; br->Color = sprite->Color.Bgra; br->TextureCoordinate.X = texture.UvRight; br->TextureCoordinate.Y = texture.UvBottom; }
private unsafe void PopulateVertexWithRotationAndTransform( Sprite *sprite, Texture <T> texture, Vertex2D *tl, Vertex2D *tr, Vertex2D *bl, Vertex2D *br, Matrix3x2 transform) { var w = (sprite->Size.X > 0 ? sprite->Size.X : texture.Width) * sprite->Scale.X; var h = (sprite->Size.Y > 0 ? sprite->Size.Y : texture.Height) * sprite->Scale.Y; var x = sprite->Position.X; var y = sprite->Position.Y; var dx = -sprite->Origin.X * w; var dy = -sprite->Origin.Y * h; var radius = MathHelper.ToRadius(sprite->Rotation); var cos = Math.Cos(radius); var sin = Math.Sin(radius); tl->Position.X = (float)(x + dx * cos - dy * sin); tl->Position.Y = (float)(y + dx * sin + dy * cos); tl->Color = sprite->Color.Bgra; tl->TextureCoordinate.X = texture.UvLeft; tl->TextureCoordinate.Y = texture.UvTop; tr->Position.X = (float)(x + (dx + w) * cos - dy * sin); tr->Position.Y = (float)(y + (dx + w) * sin + dy * cos); tr->Color = sprite->Color.Bgra; tr->TextureCoordinate.X = texture.UvRight; tr->TextureCoordinate.Y = texture.UvTop; bl->Position.X = (float)(x + dx * cos - (dy + h) * sin); bl->Position.Y = (float)(y + dx * sin + (dy + h) * cos); bl->Color = sprite->Color.Bgra; bl->TextureCoordinate.X = texture.UvLeft; bl->TextureCoordinate.Y = texture.UvBottom; br->Position.X = (float)(x + (dx + w) * cos - (dy + h) * sin); br->Position.Y = (float)(y + (dx + w) * sin + (dy + h) * cos); br->Color = sprite->Color.Bgra; br->TextureCoordinate.X = texture.UvRight; br->TextureCoordinate.Y = texture.UvBottom; tl->Position = Vector2.Transform(tl->Position, transform); tr->Position = Vector2.Transform(tr->Position, transform); bl->Position = Vector2.Transform(bl->Position, transform); br->Position = Vector2.Transform(br->Position, transform); }
private unsafe void PopulateVertexWithRotation( Sprite *sprite, Texture texture, Vertex *tl, Vertex *tr, Vertex *bl, Vertex *br) { var w = (sprite->Size.X > 0 ? sprite->Size.X : texture.Width) * sprite->Scale.X; var h = (sprite->Size.Y > 0 ? sprite->Size.Y : texture.Height) * sprite->Scale.Y; var x = sprite->Position.X; var y = sprite->Position.Y; var dx = -sprite->Origin.X * w; var dy = -sprite->Origin.Y * h; var radius = MathHelper.ToRadius(sprite->Rotation); var cos = Math.Cos(radius); var sin = Math.Sin(radius); tl->Position.X = (float)(x + dx * cos - dy * sin); tl->Position.Y = (float)(y + dx * sin + dy * cos); tl->Color = sprite->Color.Bgra; tl->TextureCoordinate.X = texture.Left; tl->TextureCoordinate.Y = texture.Top; tr->Position.X = (float)(x + (dx + w) * cos - dy * sin); tr->Position.Y = (float)(y + (dx + w) * sin + dy * cos); tr->Color = sprite->Color.Bgra; tr->TextureCoordinate.X = texture.Right; tr->TextureCoordinate.Y = texture.Top; bl->Position.X = (float)(x + dx * cos - (dy + h) * sin); bl->Position.Y = (float)(y + dx * sin + (dy + h) * cos); bl->Color = sprite->Color.Bgra; bl->TextureCoordinate.X = texture.Left; bl->TextureCoordinate.Y = texture.Bottom; br->Position.X = (float)(x + (dx + w) * cos - (dy + h) * sin); br->Position.Y = (float)(y + (dx + w) * sin + (dy + h) * cos); br->Color = sprite->Color.Bgra; br->TextureCoordinate.X = texture.Right; br->TextureCoordinate.Y = texture.Bottom; }
private unsafe void PopulateVertexWithTransform( Sprite *sprite, Texture texture, Vertex *tl, Vertex *tr, Vertex *bl, Vertex *br, Matrix3x2 transform) { var w = (sprite->Size.X > 0 ? sprite->Size.X : texture.Width) * sprite->Scale.X; var h = (sprite->Size.Y > 0 ? sprite->Size.Y : texture.Height) * sprite->Scale.Y; var x = sprite->Position.X - sprite->Origin.X * w; var y = sprite->Position.Y - sprite->Origin.Y * h; tl->Position.X = x; tl->Position.Y = y; tl->Color = sprite->Color.Bgra; tl->TextureCoordinate.X = texture.Left; tl->TextureCoordinate.Y = texture.Top; tr->Position.X = x + w; tr->Position.Y = y; tr->Color = sprite->Color.Bgra; tr->TextureCoordinate.X = texture.Right; tr->TextureCoordinate.Y = texture.Top; bl->Position.X = x; bl->Position.Y = y + h; bl->Color = sprite->Color.Bgra; bl->TextureCoordinate.X = texture.Left; bl->TextureCoordinate.Y = texture.Bottom; br->Position.X = x + w; br->Position.Y = y + h; br->Color = sprite->Color.Bgra; br->TextureCoordinate.X = texture.Right; br->TextureCoordinate.Y = texture.Bottom; tl->Position = Vector2.Transform(tl->Position, transform); tr->Position = Vector2.Transform(tr->Position, transform); bl->Position = Vector2.Transform(bl->Position, transform); br->Position = Vector2.Transform(br->Position, transform); }
public unsafe void Draw(Matrix4x4 projection, Slice <Sprite> sprites, Slice <Matrix3x2>?transforms = null) { if (sprites.Length <= 0) { return; } if (sprites.Length * 4 > _vertexData.Length) { Array.Resize(ref _vertexData, sprites.Length * 4); } fixed(ushort *pIndex = QuadListIndexData.GetIndices(sprites.Length)) fixed(Vertex2D * pVertex = _vertexData) fixed(Sprite * pSprite = &sprites.Items[sprites.Begin]) { var vertexCount = 0; var drawing = false; var isTransparent = false; var previousTexture = (Texture <T>)null; Vertex2D *vertex = pVertex; Sprite * sprite = pSprite; for (var i = 0; i < sprites.Length; i++) { var currentTexture = _textureFactory.GetTexture(sprite->Texture); if (currentTexture == null) { continue; } if (previousTexture == null) { previousTexture = currentTexture; } else if (!_equaltyComparer.Equals(currentTexture.PlatformTexture, previousTexture.PlatformTexture)) { if (!drawing) { drawing = true; BeginDraw(ref projection, pIndex, sprites.Length * 6); } Draw(pVertex, vertexCount, previousTexture.PlatformTexture, isTransparent); vertexCount = 0; vertex = pVertex; previousTexture = currentTexture; isTransparent = false; } var isSpriteTransparent = currentTexture.IsTransparent || sprite->Color.IsTransparent; isTransparent |= isSpriteTransparent; if (sprite->Rotation == 0) { if (transforms == null) { PopulateVertex(sprite, currentTexture, vertex++, vertex++, vertex++, vertex++); } else { PopulateVertexWithTransform(sprite, currentTexture, vertex++, vertex++, vertex++, vertex++, transforms.Value[i]); } } else { if (transforms == null) { PopulateVertexWithRotation(sprite, currentTexture, vertex++, vertex++, vertex++, vertex++); } else { PopulateVertexWithRotationAndTransform(sprite, currentTexture, vertex++, vertex++, vertex++, vertex++, transforms.Value[i]); } } vertexCount += 4; sprite++; } if (vertexCount > 0) { if (!drawing) { drawing = true; BeginDraw(ref projection, pIndex, sprites.Length * 6); } Draw(pVertex, vertexCount, previousTexture.PlatformTexture, isTransparent); } if (drawing) { EndDraw(); } } }
public unsafe void Draw(Matrix4x4 projection, Slice <Sprite> sprites, Slice <Matrix3x2>?transforms = null, Slice <int>?indices = null) { var spriteCount = (indices != null ? indices.Value.Count : sprites.Count); if (spriteCount <= 0) { return; } EnsureBufferCapacity(spriteCount); fixed(Vertex *pVertex = vertexData) fixed(ushort *pIndex = indexData) fixed(Sprite * pSprite = &sprites.Items[sprites.Begin]) { var vertexCount = 0; var drawing = false; var isTransparent = false; var previousTexture = (Texture)null; Vertex *vertex = pVertex; Sprite *sprite = pSprite; for (var i = 0; i < spriteCount; i++) { var iIndexed = i; if (indices != null) { iIndexed = indices.Value[i]; Debug.Assert(iIndexed >= 0 && iIndexed < sprites.Count); sprite = pSprite + iIndexed; } var currentTexture = textureFactory.GetTexture(sprite->Texture); if (currentTexture == null) { continue; } if (previousTexture == null) { previousTexture = currentTexture; } else if (currentTexture.PlatformTexture != previousTexture.PlatformTexture) { if (!drawing) { drawing = true; PlatformBeginDraw(ref projection); } PlatformDraw( pVertex, pIndex, vertexCount, vertexCount / 4 * 6, previousTexture.PlatformTexture, isTransparent); vertexCount = 0; vertex = pVertex; previousTexture = currentTexture; isTransparent = false; } var isSpriteTransparent = currentTexture.IsTransparent || sprite->Color.IsTransparent; isTransparent |= isSpriteTransparent; if (sprite->Rotation == 0) { if (transforms == null) { PopulateVertex(sprite, currentTexture, vertex++, vertex++, vertex++, vertex++); } else { PopulateVertexWithTransform(sprite, currentTexture, vertex++, vertex++, vertex++, vertex++, transforms.Value[iIndexed]); } } else { if (transforms == null) { PopulateVertexWithRotation(sprite, currentTexture, vertex++, vertex++, vertex++, vertex++); } else { PopulateVertexWithRotationAndTransform(sprite, currentTexture, vertex++, vertex++, vertex++, vertex++, transforms.Value[iIndexed]); } } vertexCount += 4; if (indices == null) { sprite++; } } if (vertexCount > 0) { if (!drawing) { drawing = true; PlatformBeginDraw(ref projection); } PlatformDraw( pVertex, pIndex, vertexCount, vertexCount / 4 * 6, previousTexture.PlatformTexture, isTransparent); } if (drawing) { PlatformEndDraw(); } } }