Wide Screen Monitor Stretching

BlitzMax Forums/BlitzMax Programming/Wide Screen Monitor Stretching

The forum is locked. These are the original blitzbasic.com forums, kept so they can still be read. No new topics, replies or edits can be made here. To join in, head over to the Blitz3D+ forums.

What you're aiming to do in preserving an aspect ratio, is to preserve your game graphics to be in the same *proportions* that they were in when you designed them, ie so that no matter what resolution you are in and no matter what size things get stretched to, visually the width and height of the graphic is in exactly the same proportion so all your circles still look like circles and your squares don't become rectangles, etc. That's what you're aiming for.

So it slightly depends, to begin with, in what resolution you create your source graphics. If you do all your design in a 4:3 screen format then you need to take that aspect ratio into account when deciding whether stretching needs to occur in order to maintain proportion. You might, for example, develop your graphics in an app running on a 1440x900 widescreen 10:9 display and then try running your game in a 1024x768 4:3 aspect. Obviously, by default, this would make your graphics stretch out in an unwanted way. And vice versa, if you create gfx in 4:3 and display at 16:9 then obviously they will stretch. What you are trying to compensate for is the *difference between* the graphic's native aspect ratio and the ratio of the display.

If you made for example a title screen that is 800x600 in 4:3 aspect, and the user wants to run in widescreen 16:9, then to maintain proportion you're going to have to have black bars at the sides of the screen. Since the 800x600 mode's pixel aspect ratio (shape) is the same as for the widescreen mode, this is pretty easy to do - just draw the graphic in the center of the display and no more changes are needed.

See, if you have a widescreen display in 16:9 and you display a 1024x768 mode on it, which is non-stretched, the 1024x768 mode will show at 4:3 aspect ratio. But if they choose a stretched mode which stretches out the 1024 across the whole display, then now you have a problem because the aspect ratio of the *pixels* has changed - they've become elongated and the number of pixels across the screen is now out of proportion to the *physical width* of space that it takes up on the display. This is where you need to know the physical dimension or aspect ratio of the display mode. If you know how much physical space it takes up you can adjust your aspect.

The projection matrix basically creates an elongated rectangular camera in 16:9 mode rather than one in 4:3 mode so that instead of the left and right edges of the screen being, say, -1 and 1 in world coordinates, they'd be something like -1.2 and 1.2, so the graphics at -1 or 1 are in the right position and not all the way to the edge of the screen. It means that all drawing/texturing etc will be automatically `sampled` at a higher horizontal resolution.

This stuff can really get quite complicated. In the most ideal situation you would know the physical dimensions of how much screen space a given display modes consumes, regardless of whather that is all of the available hardware screen space or not, so that you can then determine what the aspect ratio really is to the user, and so that you can then adjust your internal aspect ratio to keep the right proportions.

The way I figured it, there are three scenarios for types of screen resolution.

1) The resolutions are proportional to each other, so a 1024x768 mode leaves black stripes at the sides on a 1440x960 widescreen display. Aspect ratio is kind-of automatically maintained because the hardware manufacturers made sure the aspects between multiple modes are in proportion. These modes need a projection matrix that creates a `wider camera` for wider modes, ie the camera size is directly related to the aspect ratio.

2) The resolutions are not proportional because the all use the same physical amount of screen space, ie 1024x768 gets stretched out horizontally to use all available `pixels` that the hardware display can show. The physical aspect ratio is the same for each display mode but the amount of pixels within that screen space varies, so needs projection matrix adjustment in software - the camera size needs to be dynamic to scale from the physical screen size to the number of pixels within that area.

3) The user (or hardware) has adjusted each display mode differently to use different amounts of physical screen space, as well as having who knows what amount of pixels to fill that space. This happens on crt monitors more than lcd screens and basically is because the monitor has adjustments to change the size and shape of what is displayed. So any resolution, even if it's some basic 1024x768 can get all stretched about so that it's not, technically, actually at exactly a 4:3 ratio. The width might be a bit wider, or the height might be stretched. These kind of modes are the difficult ones, where they could have all sorts of wierd resolutions like 1280x256 on the Amiga (super hi-res) which was at a 4:3 ratio. Even if the o/s could tell you the default aspect ratio of that display it would not be able to tell you the monitor's adjustments to the size/position/scale of the output, so who the heck knows what the user is seeing or in what aspect. In this situation you need to adjust the projection matrix dynamically but probably would only be accurate if you can get the user to tell you the physical measurements of the display mode (ie get a ruler out and measure it).

In some of these situations, maybe the best solution would be to provide some kind of in-game `tweaking` of the resolution, ie changes to the projection matrix, so the user can stretch out what is displayed (perhaps within reasonable limits) to get `what looks to them` to be the right proportions. A sort of `calibration` screen or some key you press to adjust it, just like if you had on-screen controls on your monitor to adjust these. You could also ask the user whether all their screen modes fill the whole display, but then you're getting technical. The user shouldn't have to do things that the software should do automatically.

One further tip is that you can *usually* detect `common` aspect ratios by dividing the width by the height, in pixels. Then if this boils down to being like 4:3 or 16:10 or whatever, you can identify that mode as that aspect ratio. But you still don't know for sure that you have accurate information. I know some people are grouping display modes by aspect ratio, or hiding modes that don't seem to have a 4:3 ratio ie just the 640x480 800x600 1024x768 etc modes show and no widescreen stuff.

While you can see what the desktop resolution is not everyone uses their highest or native resolution for the desktop display. It is unreliable. You also can't always depend on the number of pixels being displayed horizontally or vertically matching up with or being a multiple of the aspect ratio. You could have more pixels in the same amount of physical screen space, in either of the dimensions separately. PixelWidth/PixelHeight is not accurate enough.

Unfortunately there is no totally automated solution without making some decisions on behalf of the user. BlitzMax cannot detect aspect ratios and probably neither can the o/s properly, unless maybe the driver can provide some details, but I doubt the driver can tell you if the user stretched their display manually.

What you're left with is trying to come up with as close an approximation as possible, to cover most of the situations and provide enough options that things can be tweaked if they are off.