我是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)
或DrawingMatrix
。
我的第一个问题是:为什么它不起作用?我不使用任何相机或视口。
其次,在绘制实体之前,我调用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);
使用is:
调用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);
}
例如,在我的Draw()
课程中调用Rect
:
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);
}
如果我将上述Begin
代码替换为this.SpriteBatch.Begin()
,则会正确绘制矩形,因此我猜这是因为矩阵。
答案 0 :(得分:4)
第一个问题是一个简单的错误:SpriteBatch
的默认值为CullCounterClockwise
,但您已指定CullClockwise
导致所有精灵被剔除。如果您只想使用默认渲染状态,则可以传递null
- 您无需明确指定它们。
(如果使用负刻度,则需要更改剔除模式。)
要回答您的第二个问题:您需要翻译“返回”以将缩放原点(您的ScaleCenterX
和ScaleCenterY
)放置在世界原点(0,0)。转换总是发生在(0,0)附近。通常顺序是:将精灵原点转换回世界原点,缩放,旋转,平移以将精灵原点放置在所需的世界位置。
另外,我希望你的PostDraw
没有应用反向转换(你让它听起来像它一样)。这很可能会导致精确度问题。您应该保存并恢复矩阵。