I'm trying to make a 2D engine for XNA with SpriteBatch. My object unit is Entity, which can include other Entities as its children. However, when drawing them, the rotation and scaling stacking do not work well.
Here is my Entity code:
protected virtual void PreDraw(Engine pEngine)
{
pEngine.PushMatrix();
{ // Transform Matrix
// Translate
pEngine.DrawingMatrix *= Matrix.CreateTranslation(this.X, this.Y, 0);
{ // Scale
float translateX = this.ScaleCenterY + this.X;
float translateY = this.ScaleCenterX + this.Y;
pEngine.DrawingMatrix *= Matrix.CreateTranslation(-translateX, -translateY, 0);
pEngine.DrawingMatrix *= Matrix.CreateScale(this.ScaleX, this.ScaleY, 0);
pEngine.DrawingMatrix *= Matrix.CreateTranslation(translateX, translateY, 0);
}
{ // Rotation
float translateX = this.RotationCenterX + this.X;
float translateY = this.RotationCenterY + this.Y;
pEngine.DrawingMatrix *= Matrix.CreateTranslation(-translateX, -translateY, 0);
pEngine.DrawingMatrix *= Matrix.CreateRotationZ(MathHelper.ToRadians(this.Rotation));
pEngine.DrawingMatrix *= Matrix.CreateTranslation(translateX, translateY, 0);
}
}
}
protected virtual void Draw(Engine pEngine) { }
protected virtual void PostDraw(Engine pEngine)
{
pEngine.PopMatrix();
}
I will implement some primitive entities by overridding Draw method. Here is my Drawing call, and the Draw implementation for Rectangle, and the StartDrawing in the Engine:
Managed Draw call every drawing:
public void ManagedDraw(Engine pEngine)
{
if (!this.Visible) return;
{ // Perform Drawing
this.PreDraw(pEngine);
int childIndex = 0;
// Underlay Children
while (childIndex < this.Children.Count && this.Children[childIndex].Z < 0)
{
this.Children[childIndex].ManagedDraw(pEngine);
childIndex++;
}
// Draw Self
this.Draw(pEngine);
// Overlay Children
for (; childIndex < this.Children.Count; childIndex++)
{
this.Children[childIndex].ManagedDraw(pEngine);
}
this.PostDraw(pEngine);
}
}
** Draw implementation of Rectable**:
protected override void Draw(Engine pEngine)
{
pEngine.StartDrawing();
pEngine.SpriteBatch.Draw(pEngine.RectangleTexture, new Rectangle(0, 0, (int)this.Width, (int)this.Height), new Rectangle(0, 0, 1, 1), this.Color);
pEngine.StopDrawing();
}
Start Drawing of Engine:
public void StartDrawing()
{
this.SpriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.LinearClamp, DepthStencilState.None, null, null, this.DrawingMatrix);
}
Here is one example of my failure, where the parent has Rotation of 30, while the children has none, but it should be in the center of the parent (red) rectangle:

Please give me the problem with above Drawing Matrix. What should I do to achieve the stacking?