It’s actually quite difficult to write a good tiled map renderer that works perfectly in all situations. We’ve already been through a few iterations on this renderer and it’s already much better than some previous attempts.
Honestly, I don’t know how to make it perfect at all zoom levels.
You could always try and write your own renderer. There have been a few ideas over the years for different types of renderers, each with their own pros and cons. It’s a tricky balance between memory consumption, rendering quality and frame rate performance. Depending on your requirements you might be able to get something that works better for your situation.
With the existing renderer though, probably not.The only thing I can think of that might help is to try and clamp your zoom levels to ones that work well for your game. It should render perfectly at multiples of 2 and it’ll probably work okay at some other ones. You’ll just have to play with it and see.
They are at the same distance number of rectangles (as the squares/pixels are a little deformed) between the 2 so its seems ok without that level of zoom (impossible to zoom it on my phone )
You have the same problem as depicted here
I think you need to take into account the aspect ratio when zooming to keep the pixels as squares all of the same size. And even like that it may not be perfect
Just render like you normally would, but in front of the drawing code set your render target using GraphicsDevice.SetRenderTarget. After rendering unset the RT so you draw to the back buffer again by calling SetRenderTarget with argument null. You can use SpriteBatch to draw your Render Target to the back buffer. Make sure to pass a Point sampling state to SpriteBatch.Begin to get proper upscaling (no interpolation between pixels).
Declare a RenderTarget2D with the native resolution you want, for me, it was 320x240. (Don’t do this in the Draw loop or the Update Loop, do this before that): PresentationParameters pp = Graphics.GraphicsDevice.PresentationParameters; _renderTarget = new RenderTarget2D(Graphics.GraphicsDevice, 320, 240, false, SurfaceFormat.Color, DepthFormat.None, pp.MultiSampleCount, RenderTargetUsage.DiscardContents);
Before you begin to draw anything in the Draw loop, change the RenderTarget2D of the GraphicsDevice: GraphicsDevice.SetRenderTarget(_renderTarget); GraphicsDevice.Clear(Color.Transparent); GraphicsDevice.BlendState = BlendState.AlphaBlend; GraphicsDevice.SamplerStates = SamplerState.PointClamp; GraphicsDevice.RasterizerState = RasterizerState.CullNone;
Draw what you need
After you have finish to draw your game, reset the RenderTarget of the GraphicsDevice: GraphicsDevice.SetRenderTarget(null); GraphicsDevice.Clear(Color.CornflowerBlue); //I do this to have a background color
Now you have a “Texture” of your “entire game”, simply draw it at the scale you want, here I put 640x480 (be sure the scaling is consistant if you want Perfect Pixel): SpriteBatch.Begin(samplerState: SamplerState.PointClamp); SpriteBatch.Draw(_renderTarget, destinationRectangle: new Rectangle(0, 0, 640, 480), color: Color.White); SpriteBatch.End();
NOTE for Mongame.Extended.Tiled:
If you have a instantiate your Camera2D with a ViewportAdapter, be sure to that it’s a DefaultViewportAdapter and not a BoxingViewportAdapter or ScalingViewportAdapter, these two seems to change the Viewport when the Window Size change (if somebody can help with that, it will be nice, but for now, it’s work with DefaultViewportAdapter)