So I have a pixel art based game that is designed for a 320x180 resolution. and is scaled up to the largest multiple that would fit within the viewport.
So a viewport of 925x522 will have a “gameport” of 640x360. The next multiple would be 940x540 and that’s too big so we stop at 640x360 and use black bars to center the gameport in the viewport.
This is what that looks like
This strategy works fine when the viewport is pretty close to the gameport. But as you can see for viewports of this size it doesn’t quite work well enough for my taste. Ideally I’d like the gameport to not be so much smaller than the viewport.
This is what I have for drawing the 640x360 gameport to the main buffer/viewport.
void DrawToMainBuffer()
{
Graphics.GraphicsDevice.SetRenderTarget(null);
Graphics.GraphicsDevice.Clear(Color.Black);
spriteBatch.Begin(
sortMode: SpriteSortMode.Immediate,
samplerState: SamplerState.PointClamp,
transformMatrix: Camera.ViewportTransformation,
blendState: BlendState.AlphaBlend
);
spriteBatch.Draw(
texture: gameportRenderTarget,
destinationRectangle: new Rectangle(
Gameport.X,
Gameport.Y,
Gameport.Width,
Gameport.Height
),
color: Color.White
);
spriteBatch.End();
}
I’ve seen other games, like Celeste, that will scale the game to the actual viewport. So I know there must be a way to do this, I just don’t know how.
One thing I’m trying is scaling the gameport up one additional multiple and then in the spritebatch draw call I’m scaling up the rendertarget/texture to fit the viewport. My results are not what I want though. With the LinearClamp sampler state the result is a little blurry. With the PointClamp sampler state it distorts the pixels a bit.
Blurry pixel art?
This is how I’m doing that
void DrawToMainBuffer()
{
Graphics.GraphicsDevice.SetRenderTarget(null);
Graphics.GraphicsDevice.Clear(Color.Black);
spriteBatch.Begin(
sortMode: SpriteSortMode.Immediate,
samplerState: SamplerState.LinearClamp,
transformMatrix: Camera.ViewportTransformation,
blendState: BlendState.AlphaBlend
);
float factor = (float)ViewportDimensions.X / (float)Gameport.Width;
// Draw gameport to screen
spriteBatch.Draw(
texture: gameportRenderTarget,
position: new Vector2(
(ViewportDimensions.X - (Gameport.Width * factor)) / 2f,
(ViewportDimensions.Y - (Gameport.Height * factor)) / 2f
),
sourceRectangle: null,
color: Color.White,
rotation: 0f,
origin: new Vector2(0, 0),
scale: new Vector2(factor, factor),
effects: SpriteEffects.None,
layerDepth: 0f
);
spriteBatch.End();
}
I feel like I’m pretty close, but at the same time I’m moving outside of my knowledge with this stuff so I really have no idea what to do. Does anyone have any tips for me?
Thanks!