Aspect ratios

Miscellaneous Forums/General Discussion/Aspect ratios

I'm having a mental blockage when it comes to working out aspect ratio scaling factors.

I'm generating some on-the-fly graphics in order to be resolution independant and aspect ratio aware. The nominal resolution I'm starting with is 640x480.

So, no aspect ratio correction is needed for a 640x480, 800x600, 1280x960 or 1600x1200 screen.

For 1920x1080 (which is a 16:9 aspect) I apply a 16/9 scaling factor for x coordinates, which looks almost right.

Here's some code to illistrate (if not demonstrate) what I'm doing:

' Kludge...
Global main:config = config.start()
main.screenwidth = 1920
main.screenheight = 1080
main.screenaspect = 16.0/9.0
main.screencenterx = main.screenwidth/2
main.screencentery = main.screenheight/2
main.screendepth = 32
main.scalex = (main.screenwidth/640) * (1/main.screenaspect)
main.scaley = (main.screenheight/480)

**EDIT* What I'm looking for is a little formula that lets me vary the main.screenaspect modifier to give correct looking results for widescreen displays and also 5:4 displays (TFT's that do 1280x1024).

I'm going for a cuppa now, if anyone has any ideas on how to accomplish this little task, I would be most grateful :)

Sounds like a computational nightmare, you should use one of my modules! I think the projection matrix mod would do the trick quite nicely. And yes you can do widescreen stuff, it'll even re-compute the mouseX and mouseY for you.

If I understand what you are after it's a variable that's used to rescale all x/y positions when displayed right?

Keeping the X & Y scale independant will automatically fix the aspect ratio.
baseResolutionX=640
baseResolutionY=480
ScaleX# = graphicswidth()/baseResolutionX
ScaleY# = graphicsheight()/baseResolutionY
Aspect# = scaleX/scaleY

Or have a completely miss-understood?

@Indie: Sounds useful, thanks. Generating proportional graphics is not as simple a task as I initially thought.

Where do I find the module?

Sounds like a computational nightmare, you should use one of my modules!


I found that funny. Not a bad idea, but for some reason that line by itself is just funny. It's worse 'cause I already say that sort of thing.

Banshee: Like I said, I'm having a mental block :)

Your idea works unless your display is other than 4:3 aspect. Your code scales the graphics to the right size whether you choose 640x480 or 1600x1200. Choose 1920x1080 and everything looks squished :-(

why just not bother with funny resolutions?

I found that funny. Not a bad idea, but for some reason that line by itself is just funny. It's worse 'cause I already say that sort of thing.

Yeah me too, sort of an "in-joke" right now :)

email me and I'll send you the module :D

Grey: 1680x1050, 1920x1080, 1900x1200 and even 2560x1600 are on the upward sloping side of popularity. Best to start catering for them now rather than later. There are also in increasing number of people with a PC in their living room. Let's not forget the potential for Xbox Live versions of your games (OK, maybe a pipe-dream for me, but hey :) ).

You can't just continue to assume everyone playing your game is sat in front of a legacy 4:3 aspect display.

I'm just about starting to build a library of routines etc, soemthing you chaps have already done and worn the t-shirt for. I know what I want to acheive and I know, essentially, the steps I need to take to get there. There's no point in me not implementing delta-time, because I don't know how powerful a user's PC is. Why should I not implement aspect awareness?

**EDIT** I sometimes run my 19" CRT in 1920x1080 with the screen height squished down to simulate a widescreen display (when watching HDTV films). First chance I get to own a widescreen 1920x1080 or 1920x1200 display, I'm taking it :) Prices of those lovely Dell TFT's will come down eventually...

Widescreen was the worst thing that happened to television, I cannot believe we're repeating the mistake with computers.

I dont mind the aspect ratio, it's the multiple standards that bother me.

I'm not sure what the code I posted is not doing. You've got positional X/Y scaled to the base resolution and a aspect ratio for modifying the width of graphics if you want to squish them, ignore that if you dont.

The alternative is to make widescreen players have vertical black bars, or horizontal bars for traditional displays.

Or you could detect for a widescreen and add an extra information panel on the side.

Adding a config option to select between the various aspect ratios is probably what I will do. It's been too long a day for me to be able to concentrate on this any further. I'll pick this up again in the week (work permitting).

I'm sure I'll come up with something after I've slept on the problem. If I come up with an elegant solution, I will share it.

Thanks for your help folks :)

oops didn't realise they were wide screen, sorry shoulda read more. Thought they were jsut those slightly non-standard resolutions you used to get in Quake etc.

Widescreen was the worst thing that happened to television
ABSOLUTELY NOT TRUE

Acutally, I just overcame this obstacle in a recent game I wrote......

What I did for the on screen gfx (say a gui), was to have a view object. Everything was linked to a certain view, that way, it obeys that view's properties.

In addition, rather than placing things at an absolute position, simply place them at a percentage of the screen. This way, regardless of the resolution, the position will always be the same.

Simplified version of code:
Type View
	Field X,Y
	Field W,H
End Type

Function View_Create.View(ThisAspectRatio# = .75)
	Local This.View
	This					=New View
	This\W					=GraphicsWidth()
	This\H					=GraphicsHeight()
	ThisScreenAspect#			=Float(GraphicsHeight())/GraphicsWidth()
	if ThisScreenAspect# >ThisAspectRatio then ;Height is bigger (possibly a tablet)
		This\H					=This\W * ThisAspectRatio
	elseif ThisScreenAspect# < ThisAspectRatio then ;Width is Bigger (Wide Screen)
		This\W					=This\H / ThisAspectRatio
	endif
	This\X					=(GraphicsWidth() / 2 ) - (This\W / 2 )
	This\Y					=(GraphicsHeight() / 2 ) - (This\H / 2 )
	Return(This)	
End Function


What this does, is create a view with a needed apsect ratio, and then center it. For every GUI gadget I create, I simply pass in its view, and it does it's positioning based on that.

To keep all Gadgets at the same spot, regardless of resolution, I create them as a percentage position of the view rather than an absolute.

More Simplified Code:
Type Gadget
	Field X,Y
	Field W,H
	Field View
End Type

Function Gadget_Create.Gadget( ThisView.View, ThisX#, ThisY#, ThisW#, ThisH# )
	Local This.Gadget
	if ThisView <> null then
		This				=New Gadget
		This\View			=ThisView
		This\X				=This\View\X + ((ThisX * .01) * This\View\W)
		This\Y				=This\View\Y + ((ThisY * .01) * This\View\H)
		This\W				=(ThisW * .01) * This\View\W
		This\H				=(ThisH * .01) * This\View\H
		Return(This)
	endif
end Function


So putting the above into practice:
MyView.View 			=View_Create()
MyGadget.Gadget		=Gadget_Create(MyView, 20,20,40,40)


This will create a view, so I can keep the same aspect ratio for any res.

Then this creates a gadget using percentages of the view width. This gadget will be placed 20% accross the view, 20% down the view, and will be 40% of the width of the view, and 40% of the height of the view.

The functions do the converting to the ACTUAL pixal locations, so when I write the drawing function for the gadget, I just place it at gad\x,gad\y. The view converted it for me.

Or, am I way off base in the question?

@DarkHalf, that's the computational nightmare I was talking about. What you are doing there is a massive overhead, especailly when both DirectX and OpenGL can do it for FREE.

Sort still on topic..
Why do I keep seeing screen ratios written as 16:9 when it should be 4:3????

16:9 is widescreen format.

yeah malice either your maths has gone wrong or you need to elaborate a bit.

What you are doing there is a massive overhead, especailly when both DirectX and OpenGL can do it for FREE


It's not over head when its a needed operation.

How can DirectX and Opengl do this for free?

. No more time to waste .

So how does one do that in blitz3d? I dont see any projection matrix commands that allow me to change the aspect ratio and have everything stay the way I put it....

The matrix is your view of the world.
Ah, I see, Neo. :P

. No more time to waste .

Hurrrummmm. This projection matrix malarkey is what I be needing, methinks.

Having had an overnight mull of the problem, it seems to be broken down into a few classes:

1) Aspect correction
This is where a normally square(ish) 4:3 resolution is being displayed on a 16:9 aspect screen. This is generally the case for standard definition TV. What looked like a circle on a normal TV is now a wide ellipse. So, you need to correct the aspect manually in software.

2) Aspect awareness
You've actually got a wide-aspect resolution (1920x1080 for instance) and you are displaying it on a wide-aspect screen. You don't need to draw anything differently. You do need to be aware of the extra screen area though. Having a wider display can alter the way you might want to introduce certain game elements, or the layout of a GUI.

3) Resolution independance
Either you're not using bitmapped graphics or you are willing to upscale (and soften the appearance of) some bitmapped graphics or downscale high-res bitmapped graphics.

The last option could be tricky and depends on how important the clarity of the bitmap is. You don't want to lose essential information that the player needs to see just because of a downscaling artifact on your user's 640x480 screen.

The first option limits the creativity and appearance of your graphics unless you are prepared to spend an inordinate amount of time creating complex vector graphics. There is the option of creating rules for drawing a large version of a graphic using standard Line/Oval/Rect commands, grabbing it as an image and then downscaling (i.e. anti-aliasing). This is the option I'm heading for.

Upscaling bitmapped gfx looks cheap (IMHO) and is not at all desirable.

I'm going to try and concentrate on the gameplay aspect of my project before I start implementing nice technical things. I will try and keep in mind though that at some point my game is going to be played at 2560x1600 on a Dell 30" TFT as well as a 640x480 14" CRT and 720x576 PAL widescreen TV.