XNA拉伸和填充2D和3D内容

时间:2011-02-20 16:46:52

标签: c# xna

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

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

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

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

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

2 个答案:

答案 0 :(得分:1)

对于使用BasicEffect 3D 内容(以及here所解释的实施IEffectMatrices的其他效果),您可以使用相应的成员来设置您的世界,查看和你喜欢的投影矩阵。

那么在你的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.Beginthis overload)。

因此,为了获得您所追求的效果(屏幕上显示固定数量的世界单位,无论屏幕大小如何),您都可以通过此转换来反击来自客户空间的内置投影:< / p>

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

(假设你希望你的可见世界空间是640乘480.)


我建议您查看XNA's Matrix on MSDN的文档,了解您可以创建哪种矩阵。

答案 1 :(得分:0)

对于2D绘图,我将其添加到我的LoadContent()方法中,其中effect是我的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的实例你的意思,还是你的意思?这就是我没有看到如何在不使用效果实例的情况下创建自定义项目矩阵。