【问题标题】:XNA stretching and filling 2D and 3D contentXNA 拉伸和填充 2D 和 3D 内容
【发布时间】:2011-02-20 16:46:52
【问题描述】:

我在这里写出了我的问题的详细描述:

http://www.codebot.org/articles/?doc=9574

我的问题的基本要点是让 XNA 表现得像我的 OpenGL 应用程序一样的最佳方式是什么,因为我希望根据我设计的比例而不是实际窗口大小。

进一步的信息,这个问题与不同的窗口或视口大小有关。在我以前的 OpenGL 应用程序中,我允许用户在窗口模式和全屏模式之间切换,并且我还允许调整窗口大小。我在使用 XNA 时遇到的问题是处理不同的全屏和窗口大小。在 OpenGL 中,我会检测窗口何时调整大小并调整视口,以便视野始终固定为分辨率纵横比。我还将使用 glOrtho 函数创建一个固定分辨率的 2D 投影图。

我使用 SpriteBatch 和 SpriteFont 完成的 XNA 示例,文本和精灵似乎以屏幕像素呈现。也就是说,所有的 2D 输出都是用方形像素渲染的,没有拉伸。在我的 XNA 应用程序中,我宁愿它们拉伸以按照我设计的比例填充窗口。我的问题是,2D 和 3D 拉伸和填充,就像我在 OpenGL 中所做的那样,最好在 XNA 中完成?

【问题讨论】:

  • 为了方便起见,您能否编辑您的问题以包含您博客文章中的更多详细信息?

标签: c# xna


【解决方案1】:

对于使用BasicEffect3D 内容(以及其他实现IEffectMatrices 的效果,如here 所述),您可以使用适当的成员来设置您喜欢的世界、视图和投影矩阵.

那么在你的 OpenGL 代码中你有这个:

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(FieldOfView, Width / Height, 1, 1000);

在XNA中相当于是在效果上设置一个投影矩阵,像这样:

effect.Projection = Matrix.CreatePerspectiveFieldOfView(
        FieldOfView, Width / Height, 1, 1000);

现在,对于 2D。以下是您在 OpenGL 中可能拥有的内容:

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, width, height, 0, 0, 1);

如果您使用效果(即使使用SpriteBatch,如here 所解释的那样),基本思想与使用 3D 相同:

effect.Projection = Matrix.CreateOrthographicOffCenter(
        0, width, height, 0, 0, 1);

现在,如果您使用的是SpriteBatch没有自定义效果(如果您实际上不需要自定义效果,我会推荐这个),您必须记住,默认情况下,SpriteBatch 使用的投影相当于:

effect.Projection = Matrix.CreateTranslation(-0.5f, -0.5f, 0)
        * Matrix.CreateOrthographicOffCenter(0,
        GraphicsDevice.Viewport.Width,
        GraphicsDevice.Viewport.Height, 0, 0, 1);

它给出了一个“客户空间”(左上角是 (0,0))坐标系,与像素中心对齐。

如果你想调整那个空间,你可以传入一个变换矩阵到SpriteBatch.Begin (this overload)。

所以为了获得你想要的效果(固定数量的世界单位出现在屏幕上,无论屏幕大小),你可以通过这个转换来抵消来自客户端空间的内置投影:

Matrix.CreateScale(GraphicsDevice.Viewport.Width / 640f,
        GraphicsDevice.Viewport.Height / 480f, 1f);

(假设您希望您的可见世界空间为 640 x 480。)


我建议您查看XNA's Matrix on MSDN 的文档,看看您可以创建什么样的矩阵。

【讨论】:

  • 好的,谢谢。我不得不扭转你的分裂。应该是:Matrix.CreateScale((float)GraphicsDevice.Viewport.Width / 640f, (float)GraphicsDevice.Viewport.Height / 480f, 1f);
【解决方案2】:

对于 2D 绘图,我将此添加到我的 LoadContent() 方法中,其中效果是我的 Game 类中的私有字段...

effect = new BasicEffect(GraphicsDevice)
{
  TextureEnabled = true,
  VertexColorEnabled = true
};

然后在我的 Draw() 方法中添加这个 ...

effect.Projection = Matrix.CreateTranslation(-0.5f, -0.5f, 0) * 
  Matrix.CreateOrthographicOffCenter(0, 640, 480, 0, 0, 1);
batch.Begin(0, null, null, null, RasterizerState.CullNone, effect); 

它似乎工作正常。现在,在调整窗口大小时,2D 图像和字体可以正确缩放。您建议不要使用自定义效果。创建一个 BasicEffect 的实例是你的意思,还是你的意思是别的?那就是我看不到如何在不使用效果实例的情况下创建自定义项目矩阵。

【讨论】:

  • SpriteBatch.Begin 的最后一个参数,在其形式中指定了所有参数 (MSDN),是一个转换(不是投影)矩阵。我会使用它,而不是创建一个 BasicEffect。只需传递null 即可获得效果。
猜你喜欢
  • 2010-11-23
  • 1970-01-01
  • 1970-01-01
  • 2016-02-14
  • 2015-11-19
  • 1970-01-01
  • 2019-10-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多