2016-09-14 18:01:13 +00:00
|
|
|
//
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
// Copyright(C) 2004-2016 Christoph Oelckers
|
|
|
|
// All rights reserved.
|
|
|
|
//
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU Lesser General Public License as published by
|
|
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
|
|
// (at your option) any later version.
|
|
|
|
//
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU Lesser General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU Lesser General Public License
|
|
|
|
// along with this program. If not, see http://www.gnu.org/licenses/
|
|
|
|
//
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
//
|
2013-06-23 07:49:34 +00:00
|
|
|
/*
|
|
|
|
** gl_scene.cpp
|
|
|
|
** manages the rendering of the player's view
|
|
|
|
**
|
|
|
|
*/
|
|
|
|
|
2018-05-16 21:34:52 +00:00
|
|
|
#include "gl_load/gl_system.h"
|
2013-06-23 07:49:34 +00:00
|
|
|
#include "gi.h"
|
|
|
|
#include "m_png.h"
|
|
|
|
#include "doomstat.h"
|
|
|
|
#include "g_level.h"
|
|
|
|
#include "r_data/r_interpolate.h"
|
|
|
|
#include "r_utility.h"
|
|
|
|
#include "d_player.h"
|
|
|
|
#include "p_effect.h"
|
|
|
|
#include "sbar.h"
|
|
|
|
#include "po_man.h"
|
|
|
|
#include "p_local.h"
|
2016-09-23 23:47:44 +00:00
|
|
|
#include "serializer.h"
|
2017-01-08 17:45:30 +00:00
|
|
|
#include "g_levellocals.h"
|
2018-10-27 20:04:13 +00:00
|
|
|
#include "r_data/models/models.h"
|
2018-04-16 07:02:48 +00:00
|
|
|
#include "hwrenderer/dynlights/hw_dynlightdata.h"
|
2018-10-27 20:04:13 +00:00
|
|
|
#include "hwrenderer/utility/hw_clock.h"
|
|
|
|
#include "hwrenderer/data/flatvertices.h"
|
2013-06-23 07:49:34 +00:00
|
|
|
|
2018-10-28 14:09:33 +00:00
|
|
|
#include "hwrenderer/dynlights/hw_lightbuffer.h"
|
2018-05-16 21:21:21 +00:00
|
|
|
#include "gl_load/gl_interface.h"
|
2013-06-23 07:49:34 +00:00
|
|
|
#include "gl/system/gl_framebuffer.h"
|
2018-06-30 13:24:13 +00:00
|
|
|
#include "gl/system/gl_debug.h"
|
2018-04-25 18:33:55 +00:00
|
|
|
#include "hwrenderer/utility/hw_cvars.h"
|
2013-06-23 07:49:34 +00:00
|
|
|
#include "gl/renderer/gl_renderstate.h"
|
2016-07-26 19:27:02 +00:00
|
|
|
#include "gl/renderer/gl_renderbuffers.h"
|
2018-10-28 12:26:47 +00:00
|
|
|
#include "hwrenderer/data/hw_viewpointbuffer.h"
|
2018-04-23 20:18:13 +00:00
|
|
|
#include "hwrenderer/scene/hw_clipper.h"
|
2018-06-23 11:25:23 +00:00
|
|
|
#include "hwrenderer/scene/hw_portal.h"
|
2018-06-24 11:39:14 +00:00
|
|
|
#include "hwrenderer/utility/hw_vrmodes.h"
|
2018-10-24 22:25:55 +00:00
|
|
|
#include "gl/renderer/gl_renderer.h"
|
2013-06-23 07:49:34 +00:00
|
|
|
|
|
|
|
//==========================================================================
|
|
|
|
//
|
|
|
|
// CVARs
|
|
|
|
//
|
|
|
|
//==========================================================================
|
|
|
|
CVAR(Bool, gl_texture, true, 0)
|
|
|
|
CVAR(Bool, gl_no_skyclear, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
|
|
|
CVAR(Float, gl_mask_threshold, 0.5f,CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
|
|
|
CVAR(Float, gl_mask_sprite_threshold, 0.5f,CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
|
|
|
|
|
|
|
EXTERN_CVAR (Bool, cl_capfps)
|
|
|
|
EXTERN_CVAR (Bool, r_deathcamera)
|
2017-07-09 17:01:34 +00:00
|
|
|
EXTERN_CVAR (Float, r_visibility)
|
2017-07-30 14:44:49 +00:00
|
|
|
EXTERN_CVAR (Bool, r_drawvoxels)
|
2013-06-23 07:49:34 +00:00
|
|
|
|
|
|
|
|
2018-10-29 12:56:17 +00:00
|
|
|
namespace OpenGLRenderer
|
|
|
|
{
|
|
|
|
|
2013-06-23 07:49:34 +00:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
// gl_drawscene - this function renders the scene from the current
|
2018-04-01 20:26:57 +00:00
|
|
|
// viewpoint, including mirrors and skyboxes and other portals
|
2018-10-24 05:49:06 +00:00
|
|
|
// It is assumed that the HWPortal::EndFrame returns with the
|
2013-06-23 07:49:34 +00:00
|
|
|
// stencil, z-buffer and the projection matrix intact!
|
|
|
|
//
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
2018-10-29 11:54:10 +00:00
|
|
|
void FGLRenderer::DrawScene(HWDrawInfo *di, int drawmode)
|
2013-06-23 07:49:34 +00:00
|
|
|
{
|
|
|
|
static int recursion=0;
|
2016-09-24 18:09:40 +00:00
|
|
|
static int ssao_portals_available = 0;
|
2018-10-29 11:54:10 +00:00
|
|
|
const auto &vp = di->Viewpoint;
|
2013-06-23 07:49:34 +00:00
|
|
|
|
2016-10-22 19:35:49 +00:00
|
|
|
bool applySSAO = false;
|
2016-10-21 22:09:06 +00:00
|
|
|
if (drawmode == DM_MAINVIEW)
|
2016-10-22 19:35:49 +00:00
|
|
|
{
|
|
|
|
ssao_portals_available = gl_ssao_portals;
|
|
|
|
applySSAO = true;
|
|
|
|
}
|
2016-10-21 22:09:06 +00:00
|
|
|
else if (drawmode == DM_OFFSCREEN)
|
2016-10-22 19:35:49 +00:00
|
|
|
{
|
2016-10-21 22:09:06 +00:00
|
|
|
ssao_portals_available = 0;
|
2016-10-22 19:35:49 +00:00
|
|
|
}
|
2017-03-11 16:20:06 +00:00
|
|
|
else if (drawmode == DM_PORTAL && ssao_portals_available > 0)
|
2016-10-22 19:35:49 +00:00
|
|
|
{
|
|
|
|
applySSAO = true;
|
|
|
|
ssao_portals_available--;
|
|
|
|
}
|
2013-06-23 07:49:34 +00:00
|
|
|
|
2018-06-19 21:16:22 +00:00
|
|
|
if (vp.camera != nullptr)
|
2016-06-18 10:14:20 +00:00
|
|
|
{
|
2018-06-19 21:16:22 +00:00
|
|
|
ActorRenderFlags savedflags = vp.camera->renderflags;
|
2018-10-29 11:54:10 +00:00
|
|
|
di->CreateScene();
|
2018-06-19 21:16:22 +00:00
|
|
|
vp.camera->renderflags = savedflags;
|
2016-06-18 10:14:20 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-10-29 11:54:10 +00:00
|
|
|
di->CreateScene();
|
2016-06-18 10:14:20 +00:00
|
|
|
}
|
2013-06-23 07:49:34 +00:00
|
|
|
|
2018-10-28 21:58:35 +00:00
|
|
|
glDepthMask(true);
|
2018-10-29 11:54:10 +00:00
|
|
|
if (!gl_no_skyclear) screen->mPortalState->RenderFirstSkyPortal(recursion, di, gl_RenderState);
|
2018-10-28 21:58:35 +00:00
|
|
|
|
2018-10-29 11:54:10 +00:00
|
|
|
di->RenderScene(gl_RenderState);
|
2013-06-23 07:49:34 +00:00
|
|
|
|
2016-10-22 19:35:49 +00:00
|
|
|
if (applySSAO && gl_RenderState.GetPassType() == GBUFFER_PASS)
|
2016-09-21 00:04:56 +00:00
|
|
|
{
|
2016-10-21 22:09:06 +00:00
|
|
|
gl_RenderState.EnableDrawBuffers(1);
|
2018-10-29 11:54:10 +00:00
|
|
|
GLRenderer->AmbientOccludeScene(di->VPUniforms.mProjectionMatrix.get()[5]);
|
2018-07-28 17:01:04 +00:00
|
|
|
glViewport(screen->mSceneViewport.left, screen->mSceneViewport.top, screen->mSceneViewport.width, screen->mSceneViewport.height);
|
2017-03-12 11:03:54 +00:00
|
|
|
GLRenderer->mBuffers->BindSceneFB(true);
|
2016-10-21 22:09:06 +00:00
|
|
|
gl_RenderState.EnableDrawBuffers(gl_RenderState.GetPassDrawBufferCount());
|
2016-09-21 00:04:56 +00:00
|
|
|
gl_RenderState.Apply();
|
2018-10-29 11:54:10 +00:00
|
|
|
screen->mViewpoints->Bind(gl_RenderState, di->vpIndex);
|
2016-09-21 00:04:56 +00:00
|
|
|
}
|
2016-09-03 02:29:50 +00:00
|
|
|
|
2018-04-01 20:26:57 +00:00
|
|
|
// Handle all portals after rendering the opaque objects but before
|
2013-06-23 07:49:34 +00:00
|
|
|
// doing all translucent stuff
|
|
|
|
recursion++;
|
2018-10-29 11:54:10 +00:00
|
|
|
screen->mPortalState->EndFrame(di, gl_RenderState);
|
2013-06-23 07:49:34 +00:00
|
|
|
recursion--;
|
2018-10-29 11:54:10 +00:00
|
|
|
di->RenderTranslucent(gl_RenderState);
|
2013-06-23 07:49:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
// Renders one viewpoint in a scene
|
|
|
|
//
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
2018-06-20 10:57:41 +00:00
|
|
|
sector_t * FGLRenderer::RenderViewpoint (FRenderViewpoint &mainvp, AActor * camera, IntRect * bounds, float fov, float ratio, float fovratio, bool mainview, bool toscreen)
|
2018-06-20 08:47:03 +00:00
|
|
|
{
|
2018-06-19 21:16:22 +00:00
|
|
|
R_SetupFrame (mainvp, r_viewwindow, camera);
|
2014-12-31 11:04:55 +00:00
|
|
|
|
2019-01-11 18:53:30 +00:00
|
|
|
if (mainview && toscreen)
|
|
|
|
UpdateShadowMap();
|
2019-01-04 14:51:59 +00:00
|
|
|
|
2018-06-20 08:47:03 +00:00
|
|
|
// Render (potentially) multiple views for stereo 3d
|
2018-06-24 11:39:14 +00:00
|
|
|
// Fixme. The view offsetting should be done with a static table and not require setup of the entire render state for the mode.
|
|
|
|
auto vrmode = VRMode::GetVRMode(mainview && toscreen);
|
|
|
|
for (int eye_ix = 0; eye_ix < vrmode->mEyeCount; ++eye_ix)
|
2015-10-31 00:51:35 +00:00
|
|
|
{
|
2018-06-24 11:39:14 +00:00
|
|
|
const auto &eye = vrmode->mEyes[eye_ix];
|
2018-06-03 11:59:40 +00:00
|
|
|
screen->SetViewportRects(bounds);
|
2018-06-30 13:24:13 +00:00
|
|
|
|
|
|
|
if (mainview) // Bind the scene frame buffer and turn on draw buffers used by ssao
|
|
|
|
{
|
|
|
|
FGLDebug::PushGroup("MainView");
|
|
|
|
|
|
|
|
bool useSSAO = (gl_ssao != 0);
|
|
|
|
mBuffers->BindSceneFB(useSSAO);
|
|
|
|
gl_RenderState.SetPassType(useSSAO ? GBUFFER_PASS : NORMAL_PASS);
|
|
|
|
gl_RenderState.EnableDrawBuffers(gl_RenderState.GetPassDrawBufferCount());
|
|
|
|
gl_RenderState.Apply();
|
|
|
|
}
|
|
|
|
|
2018-05-21 20:04:29 +00:00
|
|
|
|
2018-10-29 11:54:10 +00:00
|
|
|
auto di = HWDrawInfo::StartDrawInfo(nullptr, mainvp, nullptr);
|
2018-06-24 11:39:14 +00:00
|
|
|
auto &vp = di->Viewpoint;
|
2018-10-29 09:21:52 +00:00
|
|
|
|
|
|
|
di->Set3DViewport(gl_RenderState);
|
2018-05-21 20:04:29 +00:00
|
|
|
di->SetViewArea();
|
2018-06-19 21:16:22 +00:00
|
|
|
auto cm = di->SetFullbrightFlags(mainview ? vp.camera->player : nullptr);
|
|
|
|
di->Viewpoint.FieldOfView = fov; // Set the real FOV for the current scene (it's not necessarily the same as the global setting in r_viewpoint)
|
2018-05-21 20:04:29 +00:00
|
|
|
|
2015-10-31 00:51:35 +00:00
|
|
|
// Stereo mode specific perspective projection
|
2018-06-24 11:39:14 +00:00
|
|
|
di->VPUniforms.mProjectionMatrix = eye.GetProjection(fov, ratio, fovratio);
|
|
|
|
// Stereo mode specific viewpoint adjustment
|
|
|
|
vp.Pos += eye.GetViewShift(vp.HWAngles.Yaw.Degrees);
|
2018-10-28 21:20:51 +00:00
|
|
|
di->SetupView(gl_RenderState, vp.Pos.X, vp.Pos.Y, vp.Pos.Z, false, false);
|
2018-06-22 19:44:53 +00:00
|
|
|
|
2018-10-29 11:54:10 +00:00
|
|
|
// std::function until this can be done better in a cross-API fashion.
|
|
|
|
di->ProcessScene(toscreen, [&](HWDrawInfo *di, int mode) {
|
|
|
|
DrawScene(di, mode);
|
|
|
|
});
|
2018-04-29 09:00:34 +00:00
|
|
|
|
2018-06-16 07:37:01 +00:00
|
|
|
if (mainview)
|
2016-07-29 19:31:20 +00:00
|
|
|
{
|
2018-09-02 09:34:18 +00:00
|
|
|
PostProcess.Clock();
|
2018-10-29 08:58:37 +00:00
|
|
|
if (toscreen) di->EndDrawScene(mainvp.sector, gl_RenderState); // do not call this for camera textures.
|
2018-06-30 13:24:13 +00:00
|
|
|
|
|
|
|
if (gl_RenderState.GetPassType() == GBUFFER_PASS) // Turn off ssao draw buffers
|
|
|
|
{
|
|
|
|
gl_RenderState.SetPassType(NORMAL_PASS);
|
|
|
|
gl_RenderState.EnableDrawBuffers(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
mBuffers->BlitSceneToTexture(); // Copy the resulting scene to the current post process texture
|
|
|
|
|
|
|
|
FGLDebug::PopGroup(); // MainView
|
|
|
|
|
2018-10-29 08:58:37 +00:00
|
|
|
PostProcessScene(cm, [&]() { di->DrawEndScene2D(mainvp.sector, gl_RenderState); });
|
2018-09-02 09:34:18 +00:00
|
|
|
PostProcess.Unclock();
|
2016-07-29 19:31:20 +00:00
|
|
|
}
|
2018-06-19 21:16:22 +00:00
|
|
|
di->EndDrawInfo();
|
2018-06-24 11:39:14 +00:00
|
|
|
if (vrmode->mEyeCount > 1)
|
2018-06-20 10:57:41 +00:00
|
|
|
mBuffers->BlitToEyeTexture(eye_ix);
|
2015-10-31 00:51:35 +00:00
|
|
|
}
|
2013-06-23 07:49:34 +00:00
|
|
|
|
|
|
|
interpolator.RestoreInterpolations ();
|
2018-06-20 08:47:03 +00:00
|
|
|
return mainvp.sector;
|
2013-06-23 07:49:34 +00:00
|
|
|
}
|
|
|
|
|
2018-10-29 12:56:17 +00:00
|
|
|
}
|