xna矩阵相机2d在使用点钳时有额外的像素

时间:2014-01-08 05:02:40

标签: c# matrix xna sprite monogame

我有一个在矩阵上编程的相机,但是当用矩阵设置比例时,精灵有时变得模糊,我使用点钳,因为我希望它们显示像素化。如果我将缩放写入精灵的绘制方法,它就可以正常工作。我有代码所以矩阵如下:

this._transform = Matrix.CreateTranslation(
new Vector3( -( this._position.X * 100 ), -(this._position.Y * 100), 0 ) ) *
Matrix.CreateRotationZ( this._rotation ) *
Matrix.CreateScale( this._worldSize.Z, this._worldSize.Z, 1f ) *
Matrix.CreateTranslation( new Vector3( this._atlas.GetViewport().GetViewportWidth() * 0.5f, this._atlas.GetViewport().GetViewportHeight() * 0.5f, 0 ) );

我的绘图代码带有注释掉的手动缩放。

float zoomLevel = camera.GetWorldViewSize().Z;
Rectangle viewPosition = new Rectangle();
Vector2 viewWorldPosition = new Vector2( worldPosition.position.X, worldPosition.position.Y );
viewPosition.X = (int)(( Math.Round( viewWorldPosition.X ) ) /* + ( viewWorldPosition.X * zoomLevel ) */ );
viewPosition.Y = (int)(( viewWorldPosition.Y ) /* + ( viewWorldPosition.Y * zoomLevel ) */ );
viewPosition.Y = -viewPosition.Y;
viewPosition.X -= (int)( ( drawSettings.spritePosition.Width * drawSettings.anchor.X ) /* * zoomLevel */ );
viewPosition.Y -= (int)( ( drawSettings.spritePosition.Height * drawSettings.anchor.Y ) /* * zoomLevel */ );
viewPosition.Width = (int)( drawSettings.spritePosition.Width /* * zoomLevel */ );
viewPosition.Height = (int)( drawSettings.spritePosition.Height /* * zoomLevel */ );
spriteBatch.Draw(
  drawSettings.image.GetTexture(),
  viewPosition,
  drawSettings.spritePosition,
  drawSettings.imageTint,
  0,
  Vector2.Zero,
  drawSettings.flip,
  (float)( this._drawDepth.zIndex / 1000 )
);

我已经读过,这可能是因为当xna绘制放大的精灵时因插值而引起的。有没有办法解决这个问题,我尝试了几次尝试。我在精灵批量创建中有以下内容

GraphicsDevice.SamplerStates[0].MaxAnisotropy = 0;
GraphicsDevice.SamplerStates[0].Filter = TextureFilter.Point;

我还使用以下参数设置了图形设备。

graphics = new GraphicsDeviceManager( this );
graphics.SynchronizeWithVerticalRetrace = true;
graphics.PreferMultiSampling = false;
graphics.CreateDevice();
Core.Application.graphicsDevice = graphics.GraphicsDevice;
graphics.IsFullScreen = false;
graphics.GraphicsDevice.PresentationParameters.IsFullScreen = false;
graphics.GraphicsDevice.PresentationParameters.BackBufferFormat = SurfaceFormat.Color;
graphics.GraphicsDevice.PresentationParameters.MultiSampleCount = 0;
graphics.GraphicsDevice.PresentationParameters.RenderTargetUsage = RenderTargetUsage.DiscardContents; 
graphics.GraphicsDevice.PresentationParameters.PresentationInterval = PresentInterval.Immediate;
graphics.GraphicsDevice.PresentationParameters.DepthStencilFormat = DepthFormat.Depth24Stencil8;
graphics.GraphicsDevice.PresentationParameters.BackBufferWidth = graphics.PreferredBackBufferWidth;
graphics.GraphicsDevice.PresentationParameters.BackBufferHeight = graphics.PreferredBackBufferHeight;
graphics.GraphicsDevice.Viewport = new Microsoft.Xna.Framework.Graphics.Viewport( 0, 0, graphics.PreferredBackBufferWidth, graphics.PreferredBackBufferHeight );

我会尝试任何帮助,以及我将使用的任何建议。我想使用矩阵进行缩放,因为它使数学更容易阅读,而不是在代码中。如果不可能,我按照我的描述进行手动变焦工作。

我无法提出任何有关此问题的图片,但我可以参考其他有类似问题的图片,因为问题的性质会让图片变得非常困难。

Another person having a similar issue unresolved from awhile ago.

1 个答案:

答案 0 :(得分:0)

在GraphicsDevice上手动设置SamplerStates对SpriteBatch没有好处,因为一旦调用了End()调用,就会在你的精灵发出绘制调用之前立即覆盖它和其他几个GraphicsDevice状态(假设你'不用立即渲染。)

将您想要的状态作为SamplerState对象传递给SpriteBatch的Begin()重载之一。有现成的SamplerState.PointClamp,您也可以创建自己的。

如果您想自己在开始/结束对中设置或更改SamplerState(或混合,深度模板或光栅化器状态),则必须使用立即模式,该模式在Begin调用时仅设置一次图形状态。但是你会对你画的每个精灵都进行一次平局调用。