Index | FAQ | Search | Memberlist | Usergroups | Profile | Log in to check your private messages | Log in | Register

Re: Fixes for widescreen displays (Part 2: 3D)

| Inside3d Forums Forum Index -> Programming Tutorials

View previous topic :: View next topic
Author | Message
--- | ---
mh Joined: 12 Jan 2008 Posts: 909 |

Posted: Fri Dec 19, 2008 12:15 am Post subject: Re: Fixes for widescreen displays (Part 2: 3D) |

mh wrote:
OK, I posted parts of this one on QuakeSrc back in the day, but it didn't survive the Great Catastrophe, so here it is again in improved, debugged and 2008 form. If you've ever played Quake on a widescreen display, you'll have noticed that while the width is correct, the top and bottom of the 3D views is cut off. You can obviously fix this by setting the value of the fov cvar to something higher (102 worked well for me), but you shouldn't have to. You'll also have noticed that the console, status bar pictures and menus are stretched. These two tutorials will resolve all of that.
The first one we're going to do is the 2D stuff, but before I even start anything...
BEGIN DISCLAIMER
Some people may feel that a wider FOV is cheating. I'm taking the viewpoint that as Quake lets you set the FOV anyway, there is no cheating involved, at least beyond what's possible with normal Quake. Server administrators should propose a protocol extension that requires servers to examine FOV settings and enforce them on clients if there are any bad feelings about this.
END DISCLAIMER

Here we go again.
This one is even easier than the last, as it all revolves around the SCR_CalcRefdef and CalcFov functions in gl_screen.c; so let's jump right in.
The first thing we do is replace CalcFov with these two:

Code:
float SCR_CalcFovX (float fov_y, float width, float height) { float a; float y; // bound, don't crash
if (fov_y < 1) fov_y = 1;
if (fov_y > 179) fov_y = 179;
y = height / tan (fov_y / 360 * M_PI);
a = atan (width / y);
a = a * 360 / M_PI;
return a;
}
float SCR_CalcFovY (float fov_x, float width, float height)
{
float a;
float x;
// bound, don't crash
if (fov_x < 1) fov_x = 1;
if (fov_x > 179) fov_x = 179;
x = width / tan (fov_x / 360 * M_PI);
a = atan (height / x);
a = a * 360 / M_PI;
return a;
}

The second one (SCR_CalcFovY) is the exact same as the old CalcFov, but with the Sys_Error removed. If you look closely, you'll actually notice that both are the same function - you just flip width and height - but I prefer to keep them separate so that it's more obvious what's going on.
Speaking of obvious, all we're doing here is calculating an X FOV from a given Y FOV and vice-versa.
Now we need to actually use them, so pop this code into SCR_CalcRefdef. Again, I've given the line just before and after so you'll know where to insert it:

Code:
r_refdef.fov_x = scr_fov.value; // calculate y fov as if the screen was 640 x 432; this ensures that the top and bottom // don't get clipped off if we have a widescreen display r_refdef.fov_y = SCR_CalcFovY (r_refdef.fov_x, 640, 432); // now recalculate fov_x so that it's correctly proportioned for fov_y
r_refdef.fov_x = SCR_CalcFovX (r_refdef.fov_y, r_refdef.vrect.width, r_refdef.vrect.height);
scr_vrect = r_refdef.vrect;

That's literally it. We calculate the y fov (which is used for our projection matrix and frustum culling) as if the screen was 640 x 432, which seems as bit weird (why not 480?), but was chosen as Quake's "intended aspect ratio" (i.e. running at 640 x 480 with a full status bar showing), thus ensuring that we get a consistent vertical field of view, irrespective of the screen's resolution. Then we recalculate the horizontal field of view to get the extra stuff at the sides.
This code, by the way, will work for any aspect ratio - there's no need to check for a widescreen display aspect as part of it. However, you might notice that if you have a display that's narrower than 4:3 you'll start losing stuff at the sides. Fortunately, this is rarer, and even at the only common resolution it affects (1280 x 1024) there's no dramatic loss.
We really should fix that too, though, but that's a project for another day!
_________________
DirectQ Engine - New release 1.8.666a, 9th August 2010
MHQuake Blog (General)
Direct3D 8 Quake Engines

Back to top |

mh Joined: 12 Jan 2008 Posts: 909 |

Posted: Sun Dec 21, 2008 4:23 pm Post subject: |

There's a part 3 to come here, by the way - fixing what happens when you play at a fullscreen resolution that's not the same aspect as your monitor. _________________ DirectQ Engine - New release 1.8.666a, 9th August 2010 MHQuake Blog (General) Direct3D 8 Quake Engines

Back to top |

Team Xlink Joined: 25 Jun 2009 Posts: 320 |

Posted: Mon Apr 26, 2010 11:48 pm Post subject: |

mh wrote:
There's a part 3 to come here, by the way - fixing what happens when you play at a fullscreen resolution that's not the same aspect as your monitor.

This set has been very useful, but I cannot find part 3.
_________________

Anonymous wrote:
if it works, it works. if it doesn't, HAHAHA!

Back to top |

mh Joined: 12 Jan 2008 Posts: 909 |

Posted: Thu May 06, 2010 12:20 pm Post subject: |

I can't even remember if I ever did it! _________________ DirectQ Engine - New release 1.8.666a, 9th August 2010 MHQuake Blog (General) Direct3D 8 Quake Engines

Back to top |

Display posts from previous:

| Inside3d Forums Forum Index -> Programming Tutorials | All times are GMT
Page 1 of 1

Jump to:

You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

Powered by phpBB © 2004 phpBB Group