0
votes

I have a camera that is programmed on a matrix, however when setting the scale with the matrix the sprites render blurry sometimes, I am using point clamp as I want them to show pixelation. If I write the zoom into the draw method for the sprite it works just fine. I have the code so the matrix as follows:

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 ) );

And my draw code with the commented out manual zoom.

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 )
);

I have read that this can because caused because of the interpolation when xna draws a zoomed in sprite. Is there a way to turn this off, I have tried several attempts. I have the following in the sprite batch creation

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

I also have the graphics device setup with the following params.

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 );

Any help I will try, and any advice I will use. I would like to use the matrix for the zoom because it makes the math easier to read and not in the code. If it is not possible I do have manual zoom working as I described.

I cannot put any images up about this but I can refer to others with similar issues because of nature of the issue getting a pictures would be very hard.

Another person having a similar issue unresolved from awhile ago.

1

1 Answers

0
votes

Setting SamplerStates on GraphicsDevice manually does no good with SpriteBatch, because that and several other GraphicsDevice states are going to be overwritten once the End() call is invoked, immediately before issuing the draw call(s) for your sprites (assuming you're not rendering with Immediate).

Pass in your desired state as a SamplerState object to one of SpriteBatch's Begin() overloads. There is the ready-available SamplerState.PointClamp, or you can create your own.

If you want to set or change the SamplerState (or blend, depth stencil, or rasterizer states) within the Begin/End pair yourself, then you must use Immediate mode, which sets the graphics state just once at the Begin call. But you'll incur a draw call on every sprite you draw.