pouët.net

aspect ratios / displays / resolutions etc.

category: general [glöplog]
i think now that we've gone past the mark where you'd just say "my demo is 1024x768 and your screen better be 4:3" there's suddenly a lot of config/adjusment shit coming our way.

as this new demo is the first one that's not just a fixedres thing (5 years ago you still could i guess) and i havent done any renderer configs for pc games as to date... (and on consoles its luckily a bit easier)

i wonder how everyone deals with this. i currently do the following, but i'm a bit hazy if it's ok..

- demo has a preferred res / aspect ratio
- in windowed mode, one just uses the preferred res and doesnt do any aspect compensation
- in fullscreen mode, an arbitrary resolution can be selected and an aspect ratio that befits your screen/beamer target whatever -- i then find out on which axis i need to adjust to get a viewport that has the right aspect ratio on the actual output res/aspect combo

code probably says more.

Code: m_nativeVP.Width = xRes; // <- xres/yres is the selected full res m_nativeVP.Height = yRes; m_nativeVP.X = 0; m_nativeVP.Y = 0; m_nativeVP.MaxZ = 1.f; m_nativeVP.MinZ = 0.f; float xAdjust, yAdjust; const float aspectDiff = g_aspectRatio - g_displayAspectRatio; if (aspectDiff >= 0.f) { yAdjust = 1.f - aspectDiff; xAdjust = 1.f; } else { yAdjust = 1.f; xAdjust = 1.f + aspectDiff; } const uint xResAdj = (uint) ((float) xRes * xAdjust); const uint yResAdj = (uint) ((float) yRes * yAdjust); m_fullVP.Width = xRes; m_fullVP.Height = yResAdj; m_fullVP.X = (xRes - xResAdj) >> 1; m_fullVP.Y = (yRes - yResAdj) >> 1; m_fullVP.MaxZ = 1.f; m_fullVP.MinZ = 0.f; m_quarterVP = m_fullVP; m_quarterVP.Width >>= 1; m_quarterVP.Height >>= 1;


in windowed mode i just make the g_aspectratio and g_displayaspectratio match so no correction is done -- n fullscreen g_aspectratio is set by the demo (or derived from it's preferred 'virtual' res) and g_displayaspectratio is selected by the user.

this works.

but what does a 16:10 dell monitor do actually when i tell my videocard to go 640x480 fullscreen?

just wonderning how everyone does this.
added on the 2008-08-15 15:21:33 by superplek superplek
Quote:
but what does a 16:10 dell monitor do actually when i tell my videocard to go 640x480 fullscreen?


Depends if the computer has fixed aspect ratio scaling enabled or not. Best thing to do in my opinion is assume that pixels are square.
and that would effectively make you have to do what?
added on the 2008-08-15 15:45:45 by superplek superplek
640x480 at 16:10 will stretch the image to cover the whole screen (usually).

In this topic, there is something I'm missing I think. Because as far as I know, you can get what's the user resolution. If the resolution is 1920x1200, then you know it's 16:10, so if aspect ratio of the resolution the user is selecting doesn't match with the current one, you know if you have to distort your camera or not.

It may be some scenario I'm not aware of, because I still don't understand why most of the demo groups still make you chose the aspect ratio, and users usually have the aspect ratio a little bit over their heads and (in case of ASD) they always force 16:9, just for the sake of it.

But you can say that maybe the user is using a 4:3 resolution while on a 16:10 screen, well, true, but I guess that's the users fault.
added on the 2008-08-15 15:46:19 by mrdoob mrdoob
(just tried 640x480, told 'em my monitor was 16:10 and the adjustment flopped, lets debug :-))
added on the 2008-08-15 15:47:24 by superplek superplek
the most confusing part comes with laptops because they come with stretch AND squarepixels modes, so...
added on the 2008-08-15 15:50:06 by Gargaj Gargaj
Code: void CApp::SetAspectRatio(float ax, float ay) { aspect=ax/ay; U32 w, h; CDevice::Get()->GetWindowSize(&w, &h); S32 num=(S32)(w/(U32)ax)-(S32)(h/(U32)ay); vp.MinZ=0.f; vp.MaxZ=1.f; if(num==1) { vp.X=vp.Y=0; vp.Width=w; vp.Height=h; } else { if(num<1) { vp.Width=w; vp.X=0; vp.Height=(U32)((((float)h)*((float)ay/(float)ax))/(((float)h)/((float)w))); vp.Y=(h-vp.Height)/2; }else{ vp.Height=h; vp.Y=0; vp.Width=(U32)((((float)w)*((float)ax/(float)ay))/(((float)w)/((float)h))); vp.X=(w-vp.Width)/2; } } }


That's some old code I used. User picks a resolution, you specify the aspect ratio and that code will add black backs as appropriate. I'm fairly sure it's robust.
looks good.
added on the 2008-08-15 15:52:44 by superplek superplek
What is exactly the problem when you just always assume 16/9 and just add black bars on the top and bottom of the screen if is 16:10 or 4:3? Maybe I am just too stupid to see the problem...
m_fullVP.Width = xRes; should be
m_fullVP.Width = xResAdj;

works.

but pete's solution is obviously simpler. the user selected aspect ratio adds something in that for ex you can want 640x480 rendering, user selects 640x480 on his 16:10 display (and picks 16:10 aspect ratio)

then it actually squashes it and puts bars on the sides so you still get a 4:3 picture.
added on the 2008-08-15 15:56:39 by superplek superplek
portrait mode, anyone? :)
added on the 2008-08-15 16:09:45 by havoc havoc
(and by 'you want 640x480 rendering i meant to say you want 4:3)
added on the 2008-08-15 16:13:37 by superplek superplek
Dunno if it would work on pc (i use osx), or if it's a particularly good way to work, but it works for me.

I render the demo to a texture, at 16x10 ratio (which most mac screens are at), get the aspect ratio from the rendering destination, and use that to scale the final output. You can set it to fill the screen width or height, depending on the target aspect ratio, so that it can be cropped for 4:3 or rendered with black bars (depends on the demo and if there's much going on in the sides).

An added benefit is if you run in windowed mode, the demo will resize itself nicely to fit the window so you can allow the window to be freely resized. If you drag the window to another screen with different aspect, it'll adjust itself to fit too.
added on the 2008-08-15 16:16:23 by psonice psonice
Rob's suggestion is what i do. I always render to a 16:9 rendertarget, which i render to the framebuffer at the desirable height (depending on aspect).
added on the 2008-08-15 16:17:05 by quisten quisten
Please, remember the 5:4 resolutions! (like 1280x1024)
added on the 2008-08-15 16:18:00 by texel texel
Using a rendertarget is wasteful when you can just adjust the viewport, and probably counts out AA on old-ish cards?
thats a detail and completely hardware dependent.

texel: in my situation, 5:4 would work fine :) it's selectable.
added on the 2008-08-15 16:26:55 by superplek superplek
The problem about finding out what real physical aspect a given resolution has on the user's screen is: It's impossible.

In 99% of cases you can query the desktop resolution and blindly assume that this is the native resolution of the display and you've got square pixels, and that choosing this exact resolution for the demo will at least not look "wronger" than everything else the user stares at all the time.

BUT: Using this aspect ratio with other resolutions is dangerous. Because the GPU as well as the display itself are cmopletely free to scale non-native resolutions as they wish. Both of them might stretch to full screen or they might perform an aspect ratio preserving stretch (resulting in automatic lack bars) or not stretch at all.

And the worst thing is: At least under Windows XP you're completely out of luck if you want to find out what's happening. There's exactly NO API or combinations thereof that will yield the correct result.

So what I did (and what went into eg. Masagin/FR+Neuro and theBeauty/Einklang) was:
- present combobox will all supported resolutions of the primary display device, and default to current resolution of said device
- present another combobox for aspect ratio, consisting of "Auto" (default, assumes square pixels and does xRes/yRes as display aspect), 4:3, 5:4, 16:9, 16:10 plus all other aspect ratios that you might get from the enumerated resolutions (for people who have turned their monitors 90° etc)

So in said 99% of cases simply clicking "ok" works, albeit admittedly somewhat GPU heavy if people have big monitors ;). And well, for all other resolutions it's a maximum of two clicks, and hopefully the viewer has seen enough demos so far to know which two.
added on the 2008-08-15 16:29:45 by kb_ kb_
what about non-square-pixel modes? (like 720*576 ie. TV displays)
added on the 2008-08-15 16:33:15 by havoc havoc
adapting the viewport may hurt the original design of the demo, so adding black bars is the safest and easiest way imho.

that's a different story with games, adapting the viewport is a must, gta4 on the 360 did the job very well when i switched from a 4:3 to a 16:10 screen, no black bars, fullscreen baby, and the game experience was way better with a wider viewport, specially to avoid stupid drivers who respect road lights ;)
added on the 2008-08-15 16:33:26 by Zest Zest
havoc: that's why you let the user set the resolution and aspect ratio independently if he is inclined to. Setting 720x576 and then 4:3 would work. Or 16:9 if you want to go anamorphic ;)

As said, there's exactly no way to do this fully automatically.
added on the 2008-08-15 16:36:04 by kb_ kb_
i feel i'm on the right track. good idea about that current res as default/auto thing kb.
added on the 2008-08-15 16:39:05 by superplek superplek
exactly what kb said. better to let people choose than try and over-guess. although making the defaults actually work on the user's system is useful.

using a rendertarget to do it is a bad idea all round. there are various benefits to using the backbuffer for most of the rendering - like aa and tile regions.
besides that, you should be able to get exactly the right result using a viewport, and not waste the memory and copying cost. also, scaling the rendertarget a bit looks rough.

the one annoyance about these bars and so on is it does have the side effect of cocking up reads to the vpos in pixel shaders - it doesnt take viewport settings into account so you have to fix that yourself.
added on the 2008-08-15 16:42:08 by smash smash
Quote:
adapting the viewport may hurt the original design of the demo, so adding black bars is the safest and easiest way imho.


No it won't because you would only ever have a viewport in the shape you want it (ie. you choose an specific aspect ratio for your demo).
Quote:
cocking up reads to the vpos in pixel shaders


first of all, congratulations for remembering that one can actually say 'cocking up'. second of all, 'reads to the vpos'?
added on the 2008-08-15 16:44:45 by superplek superplek

login