所以我知道有关于为XNA构建2D相机的一些问题/答案,但是人们似乎很乐意在没有解释的情况下发布他们的代码。 我正在寻找更多关于我做错的解释。
首先,我了解整个世界 - >查看 - >投影 - >屏幕转换。
我的目标是让一个相机对象以视口的中心为中心,当相机的位置向上移动时,它与在视口中向上移动相关,当它向右移动时,它关联在视口中向右移动
我在实现该功能时遇到困难,因为视口的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正在隐藏它对我的影响。 谢谢! 法里德
答案 0 :(得分:2)
如果使用比例矩阵翻转Y轴上的所有内容,则表示您正在翻转SpriteBatch
正在绘制的模型(纹理四边形)。这意味着您还必须更改您的上弦顺序(即:背面剔除是解释您正在绘制面向相机的三角形的背面,因此它会剔除它们,因此您必须更改它使用的规则)。
默认情况下,SpriteBatch
使用RasterizerState.CullCounterClockwise
。当您致电SpriteBatch.Begin
时,您需要传递RasterizerState.CullClockwise
。
当然,Begin
是传递转换矩阵的地方。
我没有仔细检查过你的矩阵操作 - 尽管我怀疑订单是不正确的。我建议您创建一个非常简单的测试应用程序,并一次构建一个转换。
答案 1 :(得分:1)
我和XNA进行了很多努力,试图让它像我之前使用过的其他引擎一样...我的推荐, 它不值得 ...只需使用XNA标准并使用Matrix辅助方法创建Perspective / Viewport矩阵。
答案 2 :(得分:0)
因此,在思考逻辑后,我能够推断出正确的转换。 我将概述这里的步骤,任何人都想要真正的细分:
了解什么是相机转换或视图转换非常重要。 视图转换通常是从坐标相对到您的相机到世界空间坐标所需的。然后,视图转换的反转将构成相对于相机的世界坐标!
创建视图矩阵
现在矩阵的逆矩阵将做世界坐标 - >查看Cordinates。
我还选择将相机放在屏幕中央,因此我添加了预先附加的翻译。
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);