Skip to content

Commit

Permalink
Renderer: Fixed FOV (95°) for player weapon models
Browse files Browse the repository at this point in the history
The cvar "rend-model-fov" specifies the FOV for weapon models, which is separate from the rest of the view. This alleviates issues with weapon models not being drawn as the author intended.
  • Loading branch information
skyjake committed May 1, 2019
1 parent 64739f0 commit 5831dd3
Show file tree
Hide file tree
Showing 9 changed files with 32 additions and 59 deletions.
6 changes: 1 addition & 5 deletions doomsday/apps/client/include/gl/gl_main.h
Expand Up @@ -124,11 +124,7 @@ void GL_TotalRestore();
*/
void GL_Init2DState();

//void GL_SwitchTo3DState(dd_bool push_state) //, viewport_t const *port, viewdata_t const *viewData);

//void GL_Restore2DState(int step, viewport_t const *port, viewdata_t const *viewData);

void GL_ProjectionMatrix();
void GL_ProjectionMatrix(bool useFixedFov = false /* psprites use fixed FOV */);

de::Rangef GL_DepthClipRange();

Expand Down
2 changes: 2 additions & 0 deletions doomsday/apps/client/include/render/modelrenderer.h
Expand Up @@ -38,6 +38,8 @@ struct vispsprite_t;

namespace render { class ModelLoader; }

extern float weaponFixedFOV; // cvar

/**
* The model renderer: draws 3D models representing map objects and psprites.
*
Expand Down
4 changes: 3 additions & 1 deletion doomsday/apps/client/include/render/rend_main.h
Expand Up @@ -182,8 +182,10 @@ de::Vector3d Rend_EyeOrigin();
/**
* Returns the projection matrix that is used for rendering the current frame's
* 3D portions.
*
* @param fixedFov If non-zero, overrides the user's FOV with a fixed value.
*/
de::Matrix4f Rend_GetProjectionMatrix();
de::Matrix4f Rend_GetProjectionMatrix(float fixedFov = 0.f);

#define Rend_PointDist2D(c) (abs((vOrigin.z-(c)[VY])*viewsidex - (vOrigin.x-(c)[VX])*viewsidey))

Expand Down
6 changes: 2 additions & 4 deletions doomsday/apps/client/src/gl/gl_main.cpp
Expand Up @@ -383,15 +383,13 @@ Rangef GL_DepthClipRange()
return Rangef(glNearClip, glFarClip);
}

void GL_ProjectionMatrix()
void GL_ProjectionMatrix(bool useFixedFov)
{
DENG2_ASSERT_IN_RENDER_THREAD();
DENG_ASSERT_GL_CONTEXT_ACTIVE();

// Actually shift the player viewpoint
// We'd like to have a left-handed coordinate system.
DGL_MatrixMode(DGL_PROJECTION);
DGL_LoadMatrix(Rend_GetProjectionMatrix().values());
DGL_LoadMatrix(Rend_GetProjectionMatrix(useFixedFov ? weaponFixedFOV : 0.f).values());
}

void GL_SetupFogFromMapInfo(Record const *mapInfo)
Expand Down
13 changes: 9 additions & 4 deletions doomsday/apps/client/src/render/modelrenderer.cpp
Expand Up @@ -41,6 +41,8 @@ using namespace de;

static int constexpr MAX_LIGHTS = 4;

float weaponFixedFOV = 95.f;

DENG2_PIMPL(ModelRenderer)
, DENG2_OBSERVES(render::ModelLoader, NewProgram)
{
Expand Down Expand Up @@ -167,10 +169,13 @@ DENG2_PIMPL(ModelRenderer)
modelToLocal = modelToLocal * (*preModelToLocal);
}

Matrix4f const localToWorld =
Matrix4f::translate(origin) *
Matrix4f::scale(aspectCorrect); // Inverse aspect correction.
Matrix4f const localToScreen = Viewer_Matrix() * localToWorld;
const Matrix4f localToWorld = Matrix4f::translate(origin) *
Matrix4f::scale(aspectCorrect); // Inverse aspect correction.

const Matrix4f viewProj = Rend_GetProjectionMatrix(weaponFixedFOV) *
ClientApp::renderSystem().uViewMatrix().toMatrix4f();

const Matrix4f localToScreen = viewProj * localToWorld;

uWorldMatrix = localToWorld * modelToLocal;

Expand Down
48 changes: 8 additions & 40 deletions doomsday/apps/client/src/render/r_main.cpp
Expand Up @@ -30,6 +30,7 @@

#include "dd_def.h" // finesine
#include "clientapp.h"
#include "gl/gl_main.h"
#include "render/billboard.h"
#include "render/modelrenderer.h"
#include "render/r_main.h"
Expand Down Expand Up @@ -250,38 +251,10 @@ static void setupModelParamsForVisPSprite(vissprite_t &vis, vispsprite_t const &

void Rend_Draw3DPlayerSprites()
{
// Setup the modelview matrix.
GL_ProjectionMatrix(true /* fixed FOV for psprites */);
Rend_ModelViewMatrix(false /* don't apply view angle rotation */);

bool first = true;
#if 0
std::unique_ptr<GLFramebuffer::AlternativeBuffer> altDepth;

static bool altDepthSupported = true;
/**
* @todo It appears that at least with the Intel OpenGL drivers on macOS, somebody is
* leaking texture allocations behind the scenes. Unless there is a bug in
* GLFramebuffer (which is entirely possible), it is not such a great idea to switch
* around the attachments of an FBO. It should be a better approach to create a
* persistent second FBO that shares the color attachment but uses an alternative
* depth/stencil attachment.
*/

if (altDepthSupported)
{
try
{
altDepth.reset(new GLFramebuffer::AlternativeBuffer
(GLState::current().target(), GLFramebuffer::DepthStencil));
}
catch (...)
{
// The FBO doesn't support an alternative depth target.
// We will not try again...
altDepthSupported = false;
}
}
#endif

// Draw HUD vissprites.
for (vispsprite_t const &spr : visPSprites)
Expand All @@ -293,17 +266,9 @@ void Rend_Draw3DPlayerSprites()
if (first)
{
first = false;
/*if (altDepth && altDepth->init())
{
// Clear the depth before first use.
altDepth->target().clear(GLFramebuffer::DepthStencil);
}
else*/
{
// As a fallback, just clear the depth buffer so models don't clip
// into walls.
GLState::current().target().clear(GLFramebuffer::Depth);
}

// Clear the depth buffer so models don't clip into walls.
GLState::current().target().clear(GLFramebuffer::Depth);
}

if (spr.type == VPSPR_MODEL)
Expand All @@ -321,4 +286,7 @@ void Rend_Draw3DPlayerSprites()
.render(lit, viewPlayer->publicData().mo);
}
}

// Restore normal projection matrix.
GL_ProjectionMatrix(false);
}
4 changes: 2 additions & 2 deletions doomsday/apps/client/src/render/rend_main.cpp
Expand Up @@ -559,14 +559,14 @@ void Rend_ModelViewMatrix(bool inWorldSpace)
Rend_GetModelViewMatrix(DoomsdayApp::players().indexOf(viewPlayer), inWorldSpace).values());
}

Matrix4f Rend_GetProjectionMatrix()
Matrix4f Rend_GetProjectionMatrix(float fixedFov)
{
if (fixedView)
{
return fixedView->projectionMatrix;
}

const dfloat fov = Rend_FieldOfView();
const dfloat fov = (fixedFov > 0 ? fixedFov : Rend_FieldOfView());
const Vector2f size = R_Console3DViewRect(displayPlayer).size();
yfov = vrCfg().verticalFieldOfView(fov, size);
const Rangef clip = GL_DepthClipRange();
Expand Down
2 changes: 1 addition & 1 deletion doomsday/apps/client/src/render/rend_model.cpp
Expand Up @@ -127,8 +127,8 @@ void Rend_ModelRegister()
C_VAR_FLOAT("rend-model-lod", &rend_model_lod, CVF_NO_MAX, 0, 0);
C_VAR_INT ("rend-model-mirror-hud", &mirrorHudModels, 0, 0, 1);
C_VAR_FLOAT("rend-model-spin-speed", &modelSpinSpeed, CVF_NO_MAX | CVF_NO_MIN, 0, 0);
//C_VAR_INT ("rend-model-shiny-multitex", &modelShinyMultitex, 0, 0, 1);
C_VAR_FLOAT("rend-model-shiny-strength", &modelShinyFactor, 0, 0, 10);
C_VAR_FLOAT("rend-model-fov", &weaponFixedFOV, 0, 0, 180);
}

void Rend_ModelInit()
Expand Down
6 changes: 4 additions & 2 deletions doomsday/apps/client/src/render/viewports.cpp
Expand Up @@ -859,8 +859,10 @@ static void setupPlayerSprites()
spr->data.model.pitchAngleOffset =
(32 - spr->psp->pos[1]) * weaponOffsetScale * weaponOffsetScaleY / 1000.0f;
// Is the FOV shift in effect?
if(weaponFOVShift > 0 && Rend_FieldOfView() > 90)
spr->data.model.pitchAngleOffset -= weaponFOVShift * (Rend_FieldOfView() - 90) / 90;
if (weaponFOVShift > 0 && weaponFixedFOV > 90)
{
spr->data.model.pitchAngleOffset -= weaponFOVShift * (weaponFixedFOV - 90) / 90;
}
// Real rotation angles.
spr->data.model.yaw =
viewData->current.angle() / (dfloat) ANGLE_MAX *-360 + spr->data.model.yawAngleOffset + 90;
Expand Down

0 comments on commit 5831dd3

Please sign in to comment.