10 thoughts on “Resolution Independent 2D Rendering in XNA 4”
Jackie
This code works great for drawing simple background images, but I cannot get this to work inside the “XNA Game State Management” sample, where each screen is capable of drawing additional textures besides background images. When I use the Resolution code inside the “Gameplay” screen to draw a simple rectangle texture in the center of the screen(with position coordinates set at center of screen and origin set halfway through texture), it’s never centered at any resolution.
Hi Jackie. It’s hard to diagnose the issue without seeing how you’ve implemented it. You say it’s not centered, so where is it? Is it way off? Is it close? Can you provide a screenshot?
OK, all of my new year’s events are out of the way, so I’m back. My textures were created in Gimp using 1280×720 resolution. When I implement the resolution code where SetVirtualResolution(1280,720) and SetResolution(1280,720, false), everything works fine so far.
Inside game constructor Screenshot
Inside gameplayscreen Screenshot
Screenshot result Screenshot ).
When I change SetResolution() to SetResolution(800,600,false), the white rectangle resizes to fit an 800×600 screen, but it’s not centered in the middle of screen anymore. It’s as if instead of drawing the rectangle from the center, it draws the rectangle from the bottom right.
Result Screenshot ).
The only thing changed were the parameters in SetResolution().
Hi Jackie. How are you establishing the ’tile’ object’s position? What’s the ’tile.Draw’ method look like? From the code you’ve provided, I can’t really see anything wrong with it.
Jackie
Gameplayscreen.cs contains a tile object. Inside gameplayscreen’s constructor tile gets instantiated, taking in a Vector2 at the center of the screen Vector2(ScreenWidth/2, ScreenHeigth/2)) and I set tile’s position to that. Tile’s origin is Vector2(texture.Width/2, texture.Height/2).
It doesn’t seem to make a difference whether I place the Resolution draw code inside gameplayscreen.cs’s draw() or tile.cs’s Draw(). All i can think of now is reassigning tile’s position and origin right before draw or mulitplying position by some number to recenter it.
How is `ScreenWidth` and `ScreenHeight` determined? They should be based on the virtual resolution and not the actual rendered resolution. For example, I have a title screen image that is centered by using the following properties:
VirtualViewport is defined as: new Viewport(0, 0, _VWidth, _VHeight);
_VWidth and _VHeight are private members of the Resolution class that get adjusted when you call SetVirtualResolution.
You should always position your elements based on the VirtualViewport (which never changes). The user can adjust the rendered resolution (as you’ve done by changing to 800×600), but as long as you render based on the constant virtual resolution, your positioning should be correct. Please confirm if you are using ScreenWidth and ScreenHeight based on the virtual viewport.
Jackie
That was it! After I set the rendered resolution, i set variables screen_width and screen_height to equal the rendered resolution, not the virtual resolution. So, did you just create some public properties in Resolution.cs to return the virtual resolutions?
jskiles1Post author
I’m really glad that handled it. Yes, my Resolution class exposes the VirtualWidth and VirtualHeight as public properties. Feel free to contact me for more help.
This code works great for drawing simple background images, but I cannot get this to work inside the “XNA Game State Management” sample, where each screen is capable of drawing additional textures besides background images. When I use the Resolution code inside the “Gameplay” screen to draw a simple rectangle texture in the center of the screen(with position coordinates set at center of screen and origin set halfway through texture), it’s never centered at any resolution.
Hi Jackie. It’s hard to diagnose the issue without seeing how you’ve implemented it. You say it’s not centered, so where is it? Is it way off? Is it close? Can you provide a screenshot?
OK, all of my new year’s events are out of the way, so I’m back. My textures were created in Gimp using 1280×720 resolution. When I implement the resolution code where SetVirtualResolution(1280,720) and SetResolution(1280,720, false), everything works fine so far.
Inside game constructor Screenshot
Inside gameplayscreen Screenshot
Screenshot result Screenshot ).
When I change SetResolution() to SetResolution(800,600,false), the white rectangle resizes to fit an 800×600 screen, but it’s not centered in the middle of screen anymore. It’s as if instead of drawing the rectangle from the center, it draws the rectangle from the bottom right.
Result Screenshot ).
The only thing changed were the parameters in SetResolution().
Error on first screenshot link:
Inside Game constructor
Hi Jackie. How are you establishing the ’tile’ object’s position? What’s the ’tile.Draw’ method look like? From the code you’ve provided, I can’t really see anything wrong with it.
Gameplayscreen.cs contains a tile object. Inside gameplayscreen’s constructor tile gets instantiated, taking in a Vector2 at the center of the screen Vector2(ScreenWidth/2, ScreenHeigth/2)) and I set tile’s position to that. Tile’s origin is Vector2(texture.Width/2, texture.Height/2).
It doesn’t seem to make a difference whether I place the Resolution draw code inside gameplayscreen.cs’s draw() or tile.cs’s Draw(). All i can think of now is reassigning tile’s position and origin right before draw or mulitplying position by some number to recenter it.
Screenshot
How is `ScreenWidth` and `ScreenHeight` determined? They should be based on the virtual resolution and not the actual rendered resolution. For example, I have a title screen image that is centered by using the following properties:
Resolution.VirtualViewport.Height
Resolution.VirtualViewport.Width
VirtualViewport is defined as: new Viewport(0, 0, _VWidth, _VHeight);
_VWidth and _VHeight are private members of the Resolution class that get adjusted when you call SetVirtualResolution.
You should always position your elements based on the VirtualViewport (which never changes). The user can adjust the rendered resolution (as you’ve done by changing to 800×600), but as long as you render based on the constant virtual resolution, your positioning should be correct. Please confirm if you are using ScreenWidth and ScreenHeight based on the virtual viewport.
That was it! After I set the rendered resolution, i set variables screen_width and screen_height to equal the rendered resolution, not the virtual resolution. So, did you just create some public properties in Resolution.cs to return the virtual resolutions?
I’m really glad that handled it. Yes, my Resolution class exposes the VirtualWidth and VirtualHeight as public properties. Feel free to contact me for more help.
Pingback: Resolution Independent 2D Rendering in SDL2 | Pseudorandom Discussion Generator