I am writing sprite batching based on VertexArray. Idea is, that every sprite instead of being drawn with Draw method is converted to VertexArray and merged with global VertexArray assigned to sprites atlas texture.
With this technique, I've got only one Draw call per sprites atlas texture.
I want my resulting VertexArray to support sprite Rotation and Scale. I know that there is Sprite.TransformPoint method, but it includes also Sprite position, so I cant use it.
Here is my approach to do this task manualy. Is my approach good or it can be done simplier?
public static VertexArray CreateVertexArrayFromSprite
(this Sprite sprite
) { VertexArray vertices
= new VertexArray
(PrimitiveType
.Quads); IntRect currentRect
= sprite
.TextureRect; Vector2f currentPos
= sprite
.Position; float rotation
= sprite
.Rotation; Vector2f scale
= sprite
.Scale; // Calculate the rotated and scaled vertices of the quad manually Vertex
[] quad
= new Vertex
[4]; quad
[0] = new Vertex
(new Vector2f
(currentPos
.X, currentPos
.Y),
new Vector2f
(currentRect
.Left, currentRect
.Top)); quad
[1] = new Vertex
(new Vector2f
(currentPos
.X + currentRect
.Width, currentPos
.Y),
new Vector2f
(currentRect
.Left + currentRect
.Width, currentRect
.Top)); quad
[2] = new Vertex
(new Vector2f
(currentPos
.X + currentRect
.Width, currentPos
.Y + currentRect
.Height),
new Vector2f
(currentRect
.Left + currentRect
.Width, currentRect
.Top + currentRect
.Height)); quad
[3] = new Vertex
(new Vector2f
(currentPos
.X, currentPos
.Y + currentRect
.Height),
new Vector2f
(currentRect
.Left, currentRect
.Top + currentRect
.Height)); // Apply rotation and scale manually Vector2f rotationCenter
= new Vector2f
(currentPos
.X + currentRect
.Width / 2, currentPos
.Y + currentRect
.Height / 2); for (int i
= 0; i
< 4; i
++) { quad
[i
].Position = RotateAndScalePoint
(quad
[i
].Position, rotationCenter, rotation
); quad
[i
].Position = new Vector2f
(quad
[i
].Position.X * scale
.X, quad
[i
].Position.Y * scale
.Y); } // Add the quad to the VertexArray vertices
.Append(quad
[0]); vertices
.Append(quad
[1]); vertices
.Append(quad
[2]); vertices
.Append(quad
[3]); return vertices
; } // Helper method to rotate and scale a point around a center private static Vector2f RotateAndScalePoint
(Vector2f point, Vector2f center,
float rotation
) { float cosTheta
= (float)Math
.Cos(Math
.PI * rotation
/ 180.0); float sinTheta
= (float)Math
.Sin(Math
.PI * rotation
/ 180.0); float translatedX
= point
.X - center
.X; float translatedY
= point
.Y - center
.Y; float rotatedX
= translatedX
* cosTheta
- translatedY
* sinTheta
; float rotatedY
= translatedX
* sinTheta
+ translatedY
* cosTheta
; return new Vector2f
(rotatedX
+ center
.X, rotatedY
+ center
.Y); }