XNA 4.0: 2D相机Y和X方向错误
本文关键字:方向 错误 相机 2D XNA | 更新日期: 2023-09-27 18:06:07
所以我知道有一些关于为XNA构建2D相机的问题/答案,但是人们似乎只是乐于发布他们的代码而没有解释。我在寻找更多的解释我做错了什么。
首先,我理解了整个World -> View -> Projection -> Screen的转换。
我的目标是有一个相机对象在视口的中心,当相机的位置向上移动时,它关联到在视口中向上移动,当它向右移动时,它关联到在视口中向右移动。
我很难实现这个功能,因为视口的Y值是颠倒的。
//In Camera Class
private void UpdateViewTransform()
{
//My thinking here was that I would create a projection matrix to center the camera and then flip the Y axis appropriately
Matrix proj = Matrix.CreateTranslation(new Vector3(_viewport.Width * 0.5f, _viewport.Height * 0.5f, 0)) *
Matrix.CreateScale(new Vector3(1f, -1f, 1f));
//Here is the camera Matrix. I have to give the Inverse of this matrix to the Spritebatch I believe since I want to go from World Coordinates to Camera Coordinates
_viewMatrix = Matrix.CreateRotationZ(_rotation) *
Matrix.CreateScale(new Vector3(_zoom, _zoom, 1.0f)) *
Matrix.CreateTranslation(_position.X, _position.Y, 0.0f);
_viewMatrix = proj * _viewMatrix;
}
有人能帮助我理解我如何构建我的视图转换传递到SpriteBatch,这样我就能实现我所寻找的。
编辑
这作为一个转换似乎工作,但我不确定为什么。有没有人能帮我解释一下?
Matrix proj = Matrix.CreateTranslation(new Vector3(_viewport.Width * 0.5f, _viewport.Height * 0.5f, 0));
_viewMatrix = Matrix.CreateRotationZ(_rotation) *
Matrix.CreateScale(new Vector3(_zoom, _zoom, 1.0f)) *
Matrix.CreateTranslation(-1 * _position.X, _position.Y, 0.0f);
_viewMatrix = proj * _viewMatrix;
我之前已经建立了一个光线追踪器,所以我应该理解你的理解,我的困惑在于它是2D的事实,SpriteBatch隐藏了它正在做的事情。谢谢!法
如果你用比例矩阵翻转Y轴上的所有内容,这意味着你正在翻转SpriteBatch
正在绘制的模型(纹理四边形)。这意味着你还必须改变你的绕线顺序(即:背面剔除解释为你正在绘制面向相机的三角形的背面,所以它剔除它们,所以你必须改变它使用的规则)。
默认情况下,SpriteBatch
使用RasterizerState.CullCounterClockwise
。当你调用SpriteBatch.Begin
时,你需要传入RasterizerState.CullClockwise
。
当然,Begin
是你传递变换矩阵的地方。
我没有仔细检查你的矩阵操作-尽管我怀疑顺序是错误的。我建议您创建一个非常简单的测试应用程序,并一次构建一个转换。
我与XNA进行了很多斗争,试图让它像我以前使用过的其他引擎一样……我的建议是,不值得…只要使用XNA标准,并使用矩阵辅助方法来创建您的视角/Viewport矩阵。
所以在逻辑上思考之后,我能够推导出适当的变换。我将在这里概述这些步骤,以防有人想要真正的分解:
理解什么是相机转换或视图转换是很重要的。视图转换通常是从坐标相对到相机到世界空间坐标所需要的。视图变换的逆过程将创建一个相对于相机的世界坐标!
创建视图矩阵
- 应用相机旋转。我们只在Z轴上做,因为这是一个2D相机。
- 应用相机的变换。这是有意义的,因为我们想要的世界坐标是相机坐标和相对于相机的物体的和。
- 您可能注意到我将Y分量乘以-1。这是为了增加摄像机的Y位置与向上移动相关联,因为屏幕的Y值指向向下。
- 应用相机的变焦
现在矩阵的逆将做世界坐标->视图坐标。
我还选择将相机居中置于屏幕中央,因此我包含了一个预先附加的翻译。
Matrix proj = Matrix.CreateTranslation(new Vector3(_viewport.Width * 0.5f, _viewport.Height * 0.5f, 0));
_viewMatrix = Matrix.CreateRotationZ(moveComponent.Rotation) *
Matrix.CreateTranslation(moveComponent.Position.X, -1 * moveComponent.Position.Y, 0.0f) *
Matrix.CreateScale(new Vector3(zoomComponent.Zoom, zoomComponent.Zoom, 1.0f));
_viewMatrix = proj * Matrix.Invert(_viewMatrix);