在 XNA 中使用 CreateOrthographicOffCenter

发布于 2024-09-05 08:40:27 字数 178 浏览 11 评论 0原文

我正在尝试弄清楚如何在 XNA 中绘制图形,其他人建议了这一点。 但在我尝试使用这个之前...

如果我创建并使用这个相机,并将 LEFT,TOP 设置为 0 且 WIDTH=256 和 HEIGHT=240,我渲染到屏幕上的任何内容都将使用这些坐标?那么一个宽度和高度为1的盒子,如果设置为0,0会占用0,0到1,1的空间吗?

I'm trying to figure out how to draw graphics in XNA, and someone else suggested this.
But before I attempt to use this...

If I create and use this camera, and set LEFT,TOP to 0 and WIDTH=256 and HEIGHT=240, anything I render to the screen will use these coordinates? So a box with a width and height of 1, if set to 0,0 will take up space from 0,0 to 1,1?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

白况 2024-09-12 08:40:28

您引用的函数是:Matrix.CreateOrthographicOffCenter(left, right, Bottom, top, zNearPlane, zFarPlane)

这将返回一个投影矩阵,可用于将世界空间中的点转换为投影空间中的点。

投影空间从视口左下角的 (-1,-1) 到右上角的 (1,1)。这是 GPU 在光栅化时实际工作的坐标空间。

世界空间是你想要的任何东西。

假设您使用 Matrix.CreateOrthographicOffCenter(0, 256, 240, 0, -10, 10) 创建了一个矩阵,并使用该矩阵作为 BasicEffect 的投影矩阵来绘制一个模型立方体。假设立方体模型以原点为中心,尺寸为 1(长、宽和高)。

除了 basicEffect.Projection 之外,您还可以设置 basicEffect.View = Matrix.Identity (因为我们不需要额外的相机转换)和 basicEffect.World = Matrix.CreateTranslation(0.5f, 0.5f, 0) 平移模型,使其存在于世界空间中的 (0,0) 到 (1,1) 之间。然后使用该 BasicEffect 绘制模型。

立方体的顶面(正交投影意味着没有透视)将绘制在视口的左上角。它将占据视口宽度的 1/256 和高度的 1/240(另请参见 GraphicsDevice.Viewport)。

(PS:我不记得背面剔除是如何受到这种投影的影响的。如果你什么也没看到,请尝试将其关闭或切换缠绕顺序。)


现在,话虽如此 - 我从你的其他问题中得到了一个感觉(和事实上,您想要制作一个正交矩阵),您想要进行 2D 精灵工作。 BasicEffect 主要是为进行 3D 工作而设计的(尽管如果您制作自己的顶点着色器(不推荐用于精灵),您将需要一个投影矩阵)。

您可能想要使用 XNA 的 SpriteBatch - 尤其是因为它针对绘制精灵进行了大量优化。 SpriteBatch.Begin 将采用 Matrix transformMatrix 作为参数。这相当于上面的世界和视图矩阵,而不是投影矩阵。

SpriteBatch 假设您的世界空间与客户端空间相同(左上角是 (0,0),宽度和高度是视口的大小)并为您处理投影。 (实际上它比这更高级 - 它会为您应用偏移量,以便精灵像素与屏幕像素对齐。)

如果您想绘制精灵,使世界在视口中显示为 256 单位宽和 240 单位高,您可以将这样的矩阵传递给 SpriteBatch.Begin

Matrix.CreateScale(viewport.Width / 256f, viewport.Height / 240f, 1f)

值得注意的是,在新的XNA 4.0 您可以 使用 SpriteBatch 使用自定义顶点着色器进行绘制,因此您可以使用任意世界视图项目矩阵。

The function you are referring to is: Matrix.CreateOrthographicOffCenter(left, right, bottom, top, zNearPlane, zFarPlane).

This returns a projection matrix that can be used to transform a point in world space to a point in projection space.

Projection space goes from (-1,-1) in the bottom left corner of the viewport to (1,1) in the top right corner. This is the coordinate space that the GPU actually works in when rasterising.

World space is whatever you want it to be.

So let's say you create a matrix with Matrix.CreateOrthographicOffCenter(0, 256, 240, 0, -10, 10), and you used that matrix as your projection matrix with BasicEffect to draw a model of a cube. Let's say the model of the cube is centered at the origin and is of size 1 (length, width and height).

As well as basicEffect.Projection, you would set basicEffect.View = Matrix.Identity (because we don't want an additional camera transformation) and basicEffect.World = Matrix.CreateTranslation(0.5f, 0.5f, 0) to translate your model so that it exists from (0,0) to (1,1) in world space. Then draw your model using that BasicEffect.

The top face of your cube (orthographic projection means that there is no perspective) will be drawn at the top left corner of the viewport. It will take up 1/256th of the width and 1/240th of the height of the viewport (see also GraphicsDevice.Viewport).

(PS: I can't remember how backface culling is affected by this kind of projection. If you see nothing try turning it off or switching the winding order.)


Now, this being said - I get a sense from your other questions (and the fact you want to make an orthographic matrix) that you want to do 2D sprite work. BasicEffect is designed primarily for doing 3D work (although if you make your own vertex shader, not recommended for sprites, you will need a projection matrix).

You probably want to use XNA's SpriteBatch - not least of all because it's heavily optimised for drawing sprites. SpriteBatch.Begin will take a Matrix transformMatrix as an argument. This is equivalent to the World and View matrix, above, not the Projection matrix.

SpriteBatch assumes your world space is the same as client space (top left is (0,0), width and height are the size of the viewport) and handles the projection for you. (Actually it is more advanced than this - it will apply an offset for you so that sprite pixels line up with screen pixels.)

If you want to draw sprites so that world appears 256 units wide and 240 units high in the viewport, you could pass a matrix like this to SpriteBatch.Begin:

Matrix.CreateScale(viewport.Width / 256f, viewport.Height / 240f, 1f)

It is worth noting that in the new XNA 4.0 you can use SpriteBatch to draw with custom vertex shaders and so you may use arbitrary world-view-project matrices.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文