我是 XNA 的新手,希望在其上开发一个轻量级 2D 引擎,并将实体组织成父子层次结构。在绘制子项时我会想到矩阵,因为它们的位置、旋转和缩放取决于其父项。
如果我使用SpriteBatch.Begin()
,我的矩形可以在屏幕上绘制,但是当我将它们更改为:
this.DrawingMatrix = Matrix.Identity;
this.SpriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.LinearClamp, DepthStencilState.None, RasterizerState.CullClockwise, null, this.DrawingMatrix);
不再绘制任何内容。我什至尝试了 new Matrix()
或 Matrix.CreateTranslation(0, 0, 0)
for DrawingMatrix
。
我的第一个问题是:为什么它不起作用?我没有使用任何相机或视口(viewport)。
其次,在绘制实体之前,我调用 PreDraw
来转换矩阵(然后我将在 PostDraw
处重置为原始状态):
protected virtual void PreDraw(Engine pEngine)
{
pEngine.DrawingMatrix *=
Matrix.CreateTranslation(this.X, this.Y, 0) *
Matrix.CreateScale(this.ScaleX, this.ScaleY, 1) *
Matrix.CreateRotationZ(this.Rotation);
}
请澄清以上代码的更正。我需要的不是在原点缩放,而是在 ScaleCenterX 和 ScaleCenterY 处缩放,如何实现这一点?
添加:这是我的引擎绘制过程的示例:
调用这些代码:
this.DrawingMatrix = Matrix.CreateTranslation(0, 0, 0); this.SpriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.LinearClamp, DepthStencilState.None, RasterizerState.CullClockwise, null, this.DrawingMatrix);
调用
PreDraw()
,其中:protected virtual void PreDraw(Engine pEngine) { pEngine.DrawingMatrix *= Matrix.CreateTranslation(this.X, this.Y, 0) * Matrix.CreateScale(this.ScaleX, this.ScaleY, 1) * Matrix.CreateRotationZ(this.Rotation); }
例如,在我的
Rect
类中调用Draw()
:protected override void Draw(Engine pEngine) { pEngine.SpriteBatch.Draw(pEngine.RectangleTexture, new Rectangle(0, 0, (int)this.Width, (int)this.Height), new Rectangle(0, 0, 1, 1), this.Color); }
如果我用 this.SpriteBatch.Begin()
替换上面的 Begin
代码,矩形就会正确绘制,所以我猜这是因为矩阵的原因。
最佳答案
第一个问题是一个简单的错误:SpriteBatch
的默认值为 CullCounterClockwise
,但您指定了 CullClockwise
导致所有 Sprite 恢复- 脸部剔除。如果您只想使用默认渲染状态,则可以传递 null
- 无需显式指定它们。
(如果您使用负比例,则需要更改剔除模式。)
要回答你的第二个问题:你需要翻译“向后”以将缩放原点(你的 ScaleCenterX 和 ScaleCenterY )放置在世界原点 (0,0) 。变换总是发生在 (0,0) 附近。所以通常的顺序是:将 Sprite 原点平移回世界原点,缩放,旋转,平移以将 Sprite 原点放置在所需的世界位置。
此外,我希望您的 PostDraw
没有应用反向转换(您听起来就像是这样)。这很可能会导致精度问题。您应该保存并恢复矩阵。
关于algorithm - 如何正确使用SpriteBatch的变换矩阵?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14229986/