I have been at this game of trial-and-error for days now. I cannot find a consistent method to calculate the respective mouse position in my game world after the calculations are done to stretch the game's render view to the current resolution. I've seen other, similar questions and answers on this site, but after looking at them long and hard, I can't translate the answers to my project.
I'm using XNA. First, I render everything to a RenderTarget2D at a resolution of 800x600. Then I render said RenderTarget to the screen by calculating it's size and location through a method that returns a Rectangle:
public Rectangle CalculateRenderTargetPosition()
{
Rectangle rec;
Single preferredAspect = Globals.RenderSize.Width / (Single)Globals.RenderSize.Height;
Single outputAspect = Globals.WindowSize.Width / (Single)Globals.WindowSize.Height;
if (outputAspect <= preferredAspect)
{
// output is taller than it is wider, bars on top/bottom
Int32 presentHeight = (Int32)((Globals.WindowSize.Width / preferredAspect) + 0.5f);
Int32 barHeight = (Globals.WindowSize.Height - presentHeight) / 2;
rec = new Rectangle(0, barHeight, Globals.WindowSize.Width, presentHeight);
}
else
{
// output is wider than it is tall, bars left/right
Int32 presentWidth = (Int32)((Globals.WindowSize.Height * preferredAspect) + 0.5f);
Int32 barWidth = (Globals.WindowSize.Width - presentWidth) / 2;
rec = new Rectangle(barWidth, 0, presentWidth, Globals.WindowSize.Height);
}
return rec;
}
The Camera's position is rendered during rendering to the RenderTarget2D through a Matrix in the SpriteBatch.Draw method, so there's nothing weird going on there. The Camera itself works fine at any resolution.
After days of guesswork, this is the closest method I've got:
Rectangle r = Globals.Draw.CalculateRenderTargetPosition();
MouseState ms = Mouse.GetState();
Single aspect = Globals.WindowSize.Width / (Single)Globals.WindowSize.Height;
Single pmx = (ms.X - r.X);
Single pmy = (ms.Y - r.Y);
Single mx = (pmx == 0 ? pmx : pmx / aspect);
Single my = (pmy == 0 ? pmy : pmy / aspect);
Vector2 pos = Vector2.Transform(new Vector2(mx, my),
Matrix.Invert(Globals.Camera.GetViewMatrix()));
Globals.RelativeMousePosition = new Vector2(pos.X, pos.Y);
Even if this is almost close enough, it's still off. I don't know if there's some magical Matrix method I don't know about or if I just suck at math.