I have a UI system which consist of a tree of individual elements starting at a Root element, and rendering down through the tree for as many elements that exist. The transform of a parent affects all its children, so that position / scale / etc is relative to the parent instead of absolute screen space values.
Here is the Render function for an individual element:
public void Render( SpriteBatch spriteBatch, Matrix parentTransform, float parentAlpha )
float alpha = parentAlpha * this.Alpha;
Matrix transform = Matrix.CreateTranslation( X, Y, Depth ) * Matrix.CreateRotationZ( MathHelper.ToRadians( ZRotation ) );
transform *= parentTransform;
Vector3 pos = transform.Translation;
// Fixes some odd behavior with how SpriteBatch handles rendering rectangles with origin values
Rectangle elementRect = new Rectangle( (int)pos.X, (int)pos.Y, (int)Width, (int)Height );
Rectangle destRect = new Rectangle( elementRect.X + elementRect.Width / 2, elementRect.Y + elementRect.Height / 2, elementRect.Width, elementRect.Height );
Vector2 originOffset = new Vector2( _Image.Width / 2, _Image.Height / 2 );
spriteBatch.Draw( _Image, destRect, new Rectangle( 0, 0, _Image.Width, _Image.Height ), ColorMod * alpha, MathHelper.ToRadians( ZRotation ), originOffset, SpriteEffects.None, pos.Z );
for ( int childNum = 0; childNum < _Children.Count; ++childNum )
_Children[childNum].Render( spriteBatch, transform, alpha );
Things are already working well for the translation, but as you can probably see there is an issue with the rotation value due to the fact that it is affecting the position of the Rectangle as being applied as the rotation value in the actual Draw call.
I'm wondering if anyone has a better way of handling this? The simple solution would be to just pass a distinct rotation value down the tree instead of applying it into the transform Matrix, but the issue there lies with the fact that I'll run into this exact same issue when I go to add Scale as something that affects down the tree. In addition, at some point I'm going to optimize these by moving these calculations out of render and into the Update function, and it would be nice to be able to keep track of just the one transform matrix instead of a running position, rotation, and scale value.
I suspect the answer will be just to abandon SpriteBatch and just render everything as textured quads. Then there won't be any issue with this Matrix approach as I just apply the running transform matrix to the verts. However, I wanted to see if anyone had any other answers before I do the refactor.