qzdoom/src/rendering/gl/renderer/gl_scene.cpp

121 lines
4.2 KiB
C++
Raw Normal View History

//
//---------------------------------------------------------------------------
//
// 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/
//
//--------------------------------------------------------------------------
//
/*
** gl_scene.cpp
** manages the rendering of the player's view
**
*/
2020-04-10 20:10:49 +00:00
#include "gl_system.h"
#include "gi.h"
#include "m_png.h"
#include "doomstat.h"
#include "r_data/r_interpolate.h"
#include "r_utility.h"
#include "d_player.h"
#include "hwrenderer/dynlights/hw_dynlightdata.h"
#include "hwrenderer/utility/hw_clock.h"
#include "hwrenderer/data/flatvertices.h"
#include "hwrenderer/dynlights/hw_lightbuffer.h"
#include "hwrenderer/utility/hw_cvars.h"
#include "hwrenderer/data/hw_viewpointbuffer.h"
#include "hwrenderer/scene/hw_clipper.h"
#include "hwrenderer/scene/hw_portal.h"
#include "hwrenderer/utility/hw_vrmodes.h"
//-----------------------------------------------------------------------------
//
// Renders one viewpoint in a scene
//
//-----------------------------------------------------------------------------
sector_t* RenderViewpoint(FRenderViewpoint& mainvp, AActor* camera, IntRect* bounds, float fov, float ratio, float fovratio, bool mainview, bool toscreen)
{
auto& RenderState = *screen->RenderState();
R_SetupFrame(mainvp, r_viewwindow, camera);
if (mainview && toscreen)
screen->UpdateShadowMap();
// Update the attenuation flag of all light defaults for each viewpoint.
// This function will only do something if the setting differs.
FLightDefaults::SetAttenuationForLevel(!!(camera->Level->flags3 & LEVEL3_ATTENUATE));
// Render (potentially) multiple views for stereo 3d
// 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);
const int eyeCount = vrmode->mEyeCount;
screen->FirstEye();
for (int eye_ix = 0; eye_ix < eyeCount; ++eye_ix)
{
const auto& eye = vrmode->mEyes[eye_ix];
2018-06-03 11:59:40 +00:00
screen->SetViewportRects(bounds);
if (mainview) // Bind the scene frame buffer and turn on draw buffers used by ssao
{
bool useSSAO = (gl_ssao != 0);
screen->SetSceneRenderTarget(useSSAO);
RenderState.SetPassType(useSSAO ? GBUFFER_PASS : NORMAL_PASS);
RenderState.EnableDrawBuffers(RenderState.GetPassDrawBufferCount(), true);
}
auto di = HWDrawInfo::StartDrawInfo(mainvp.ViewLevel, nullptr, mainvp, nullptr);
auto& vp = di->Viewpoint;
2018-10-29 09:21:52 +00:00
di->Set3DViewport(RenderState);
di->SetViewArea();
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)
// Stereo mode specific perspective projection
di->VPUniforms.mProjectionMatrix = eye.GetProjection(fov, ratio, fovratio);
// Stereo mode specific viewpoint adjustment
vp.Pos += eye.GetViewShift(vp.HWAngles.Yaw.Degrees);
di->SetupView(RenderState, vp.Pos.X, vp.Pos.Y, vp.Pos.Z, false, false);
2018-06-22 19:44:53 +00:00
di->ProcessScene(toscreen);
if (mainview)
{
PostProcess.Clock();
if (toscreen) di->EndDrawScene(mainvp.sector, RenderState); // do not call this for camera textures.
if (RenderState.GetPassType() == GBUFFER_PASS) // Turn off ssao draw buffers
{
RenderState.SetPassType(NORMAL_PASS);
RenderState.EnableDrawBuffers(1);
}
screen->PostProcessScene(false, cm, [&]() { di->DrawEndScene2D(mainvp.sector, RenderState); });
PostProcess.Unclock();
}
di->EndDrawInfo();
if (eyeCount - eye_ix > 1)
screen->NextEye(eyeCount);
}
return mainvp.sector;
}