Skip to content

Commit

Permalink
Renderer: Automatically adjust FOV for view aspect ratio
Browse files Browse the repository at this point in the history
The FOV angle is now interpreted to be the horizontal FOV angle for
a view with 4:3 aspect ratio (matching the original DOOM). For wider
or narrower views, the FOV is increased accordingly, making it
independent of view width.

This fixes the problem of inappropriately low FOV angles with 16:9
or 16:10 displays.
  • Loading branch information
skyjake committed Sep 4, 2013
1 parent 5dad337 commit 27c79db
Show file tree
Hide file tree
Showing 6 changed files with 22 additions and 12 deletions.
4 changes: 3 additions & 1 deletion doomsday/client/include/render/rend_main.h
Expand Up @@ -42,7 +42,7 @@ class Map;
#define SHADOW_SURFACE_LUMINOSITY_ATTRIBUTION_MIN (.05f)

DENG_EXTERN_C coord_t vOrigin[3];
DENG_EXTERN_C float vang, vpitch, fieldOfView, yfov;
DENG_EXTERN_C float vang, vpitch, yfov;
DENG_EXTERN_C float viewsidex, viewsidey;
DENG_EXTERN_C float fogColor[4];

Expand Down Expand Up @@ -91,6 +91,8 @@ void Rend_Shutdown();
void Rend_Reset();
void Rend_RenderMap(de::Map &map);

float Rend_FieldOfView();

/**
* @param useAngles @c true= Apply viewer angle rotation.
*/
Expand Down
2 changes: 1 addition & 1 deletion doomsday/client/src/gl/gl_main.cpp
Expand Up @@ -588,7 +588,7 @@ void GL_ProjectionMatrix()

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(yfov = fieldOfView / aspect, aspect, glNearClip, glFarClip);
gluPerspective(yfov = Rend_FieldOfView() / aspect, aspect, glNearClip, glFarClip);

// We'd like to have a left-handed coordinate system.
glScalef(1, 1, -1);
Expand Down
12 changes: 7 additions & 5 deletions doomsday/client/src/network/net_demo.cpp
Expand Up @@ -349,7 +349,7 @@ boolean Demo_BeginPlayback(const char* fileName)
lookdirDelta = 0;
demoFrameZ = 1;
demoZ = 0;
startFOV = fieldOfView;
startFOV = 95; //Rend_FieldOfView();
demoStartTic = DEMOTIC;
memset(posDelta, 0, sizeof(posDelta));
// Start counting frames from here.
Expand All @@ -375,7 +375,7 @@ void Demo_StopPlayback(void)
playback = false;
lzClose(playdemo);
playdemo = 0;
fieldOfView = startFOV;
//fieldOfView = startFOV;
Net_StopGame();

/*
Expand Down Expand Up @@ -455,7 +455,7 @@ void Demo_WriteLocalCamera(int plrNum)
mobj_t* mo = ddpl->mo;
fixed_t x, y, z;
byte flags;
boolean incfov = (writeInfo[plrNum].fov != fieldOfView);
boolean incfov = false; //(writeInfo[plrNum].fov != fieldOfView);
const viewdata_t* viewData = R_ViewData(plrNum);

if(!mo)
Expand Down Expand Up @@ -487,11 +487,11 @@ void Demo_WriteLocalCamera(int plrNum)
Writer_WriteInt16(msgWriter, mo->angle /*ddpl->clAngle*/ >> 16); /* $unifiedangles */
Writer_WriteInt16(msgWriter, ddpl->lookDir / 110 * DDMAXSHORT /* $unifiedangles */);
// Field of view is optional.
if(incfov)
/*if(incfov)
{
Writer_WriteInt16(msgWriter, fieldOfView / 180 * DDMAXSHORT);
writeInfo[plrNum].fov = fieldOfView;
}
}*/
Msg_End();
Net_SendBuffer(plrNum, SPF_DONT_SEND);
}
Expand Down Expand Up @@ -544,8 +544,10 @@ void Demo_ReadLocalCamera(void)
dlook = Reader_ReadInt16(msgReader) * 110.0f / DDMAXSHORT;

// FOV included?
/*
if(flags & LCAMF_FOV)
fieldOfView = Reader_ReadInt16(msgReader) * 180.0f / DDMAXSHORT;
*/

if(intertics == 1 || demoFrameZ == 1)
{
Expand Down
6 changes: 3 additions & 3 deletions doomsday/client/src/render/r_main.cpp
Expand Up @@ -1024,8 +1024,8 @@ void R_SetupPlayerSprites()
spr->data.model.pitchAngleOffset =
(32 - psp->pos[VY]) * weaponOffsetScale * weaponOffsetScaleY / 1000.0f;
// Is the FOV shift in effect?
if(weaponFOVShift > 0 && fieldOfView > 90)
spr->data.model.pitchAngleOffset -= weaponFOVShift * (fieldOfView - 90) / 90;
if(weaponFOVShift > 0 && Rend_FieldOfView() > 90)
spr->data.model.pitchAngleOffset -= weaponFOVShift * (Rend_FieldOfView() - 90) / 90;
// Real rotation angles.
spr->data.model.yaw =
viewData->current.angle / (float) ANGLE_MAX *-360 + spr->data.model.yawAngleOffset + 90;
Expand Down Expand Up @@ -1130,7 +1130,7 @@ DENG_EXTERN_C void R_RenderPlayerView(int num)
GL_DrawFilter();
}

Vignette_Render(&vd->window, fieldOfView);
Vignette_Render(&vd->window, Rend_FieldOfView());

// Now we can show the viewPlayer's mobj again.
if(!(player->shared.flags & DDPF_CHASECAM))
Expand Down
8 changes: 7 additions & 1 deletion doomsday/client/src/render/rend_main.cpp
Expand Up @@ -323,6 +323,12 @@ void Rend_Reset()
}
}

float Rend_FieldOfView()
{
float const widescreenCorrection = float(viewpw)/float(viewph) / (4.f / 3.f);
return widescreenCorrection * fieldOfView;
}

void Rend_ModelViewMatrix(bool useAngles)
{
viewdata_t const *viewData = R_ViewData(viewPlayer - ddPlayers);
Expand Down Expand Up @@ -2559,7 +2565,7 @@ void Rend_RenderMap(Map &map)
if(vpitch <= 90 - yfov / 2 && vpitch >= -90 + yfov / 2)
{
float a = de::abs(vpitch) / (90 - yfov / 2);
binangle_t startAngle = binangle_t(BANG_45 * fieldOfView / 90) * (1 + a);
binangle_t startAngle = binangle_t(BANG_45 * Rend_FieldOfView() / 90) * (1 + a);
binangle_t angLen = BANG_180 - startAngle;

binangle_t viewside = (viewData->current.angle >> (32 - BAMS_BITS)) + startAngle;
Expand Down
2 changes: 1 addition & 1 deletion doomsday/client/src/render/rend_model.cpp
Expand Up @@ -1009,7 +1009,7 @@ static void Mod_RenderSubModel(uint number, rendmodelparams_t const *parm)
// Determine the suitable LOD.
if(mdl->info.numLODs > 1 && rend_model_lod != 0)
{
float lodFactor = rend_model_lod * DENG_WINDOW->width() / 640.0f / (fieldOfView / 90.0f);
float lodFactor = rend_model_lod * DENG_WINDOW->width() / 640.0f / (Rend_FieldOfView() / 90.0f);
if(!FEQUAL(lodFactor, 0))
lodFactor = 1 / lodFactor;

Expand Down

0 comments on commit 27c79db

Please sign in to comment.