From 5831dd321773fb8b53d639a92a07c06c186feac3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaakko=20Kera=CC=88nen?= Date: Wed, 1 May 2019 11:16:22 +0300 Subject: [PATCH] =?UTF-8?q?Renderer:=20Fixed=20FOV=20(95=C2=B0)=20for=20pl?= =?UTF-8?q?ayer=20weapon=20models?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- doomsday/apps/client/include/gl/gl_main.h | 6 +-- .../client/include/render/modelrenderer.h | 2 + .../apps/client/include/render/rend_main.h | 4 +- doomsday/apps/client/src/gl/gl_main.cpp | 6 +-- .../apps/client/src/render/modelrenderer.cpp | 13 +++-- doomsday/apps/client/src/render/r_main.cpp | 48 ++++--------------- doomsday/apps/client/src/render/rend_main.cpp | 4 +- .../apps/client/src/render/rend_model.cpp | 2 +- doomsday/apps/client/src/render/viewports.cpp | 6 ++- 9 files changed, 32 insertions(+), 59 deletions(-) diff --git a/doomsday/apps/client/include/gl/gl_main.h b/doomsday/apps/client/include/gl/gl_main.h index 95c74adfc6..66deb4d8b7 100644 --- a/doomsday/apps/client/include/gl/gl_main.h +++ b/doomsday/apps/client/include/gl/gl_main.h @@ -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(); diff --git a/doomsday/apps/client/include/render/modelrenderer.h b/doomsday/apps/client/include/render/modelrenderer.h index ec8edf1095..ce72cf7dd0 100644 --- a/doomsday/apps/client/include/render/modelrenderer.h +++ b/doomsday/apps/client/include/render/modelrenderer.h @@ -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. * diff --git a/doomsday/apps/client/include/render/rend_main.h b/doomsday/apps/client/include/render/rend_main.h index 80927f3ee0..ee7d44384e 100644 --- a/doomsday/apps/client/include/render/rend_main.h +++ b/doomsday/apps/client/include/render/rend_main.h @@ -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)) diff --git a/doomsday/apps/client/src/gl/gl_main.cpp b/doomsday/apps/client/src/gl/gl_main.cpp index 208152890d..2b6ce667bc 100644 --- a/doomsday/apps/client/src/gl/gl_main.cpp +++ b/doomsday/apps/client/src/gl/gl_main.cpp @@ -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) diff --git a/doomsday/apps/client/src/render/modelrenderer.cpp b/doomsday/apps/client/src/render/modelrenderer.cpp index 8b922aec9b..ea6f8e8adf 100644 --- a/doomsday/apps/client/src/render/modelrenderer.cpp +++ b/doomsday/apps/client/src/render/modelrenderer.cpp @@ -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) { @@ -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; diff --git a/doomsday/apps/client/src/render/r_main.cpp b/doomsday/apps/client/src/render/r_main.cpp index 69c87c7399..da817a32d6 100644 --- a/doomsday/apps/client/src/render/r_main.cpp +++ b/doomsday/apps/client/src/render/r_main.cpp @@ -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" @@ -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 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) @@ -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) @@ -321,4 +286,7 @@ void Rend_Draw3DPlayerSprites() .render(lit, viewPlayer->publicData().mo); } } + + // Restore normal projection matrix. + GL_ProjectionMatrix(false); } diff --git a/doomsday/apps/client/src/render/rend_main.cpp b/doomsday/apps/client/src/render/rend_main.cpp index ec73667623..86364bb284 100644 --- a/doomsday/apps/client/src/render/rend_main.cpp +++ b/doomsday/apps/client/src/render/rend_main.cpp @@ -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(); diff --git a/doomsday/apps/client/src/render/rend_model.cpp b/doomsday/apps/client/src/render/rend_model.cpp index 1229736da7..7330f35c39 100644 --- a/doomsday/apps/client/src/render/rend_model.cpp +++ b/doomsday/apps/client/src/render/rend_model.cpp @@ -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() diff --git a/doomsday/apps/client/src/render/viewports.cpp b/doomsday/apps/client/src/render/viewports.cpp index e5f821cab6..6fe0068576 100644 --- a/doomsday/apps/client/src/render/viewports.cpp +++ b/doomsday/apps/client/src/render/viewports.cpp @@ -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;