From 4cf2493cfd7628a0af8e07d482bf2ee881788331 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 18 Mar 2021 14:49:36 +0100 Subject: [PATCH] set up the entry point for the renderer. --- source/CMakeLists.txt | 1 + source/build/src/engine.cpp | 4 +- source/core/rendering/hw_entrypoint.cpp | 328 ++++++++++++++++++++ source/core/rendering/render.cpp | 5 +- source/core/rendering/render.h | 3 +- source/core/rendering/scene/hw_drawinfo.cpp | 24 +- source/core/rendering/scene/hw_drawinfo.h | 5 +- source/glbackend/glbackend.h | 6 - 8 files changed, 341 insertions(+), 35 deletions(-) create mode 100644 source/core/rendering/hw_entrypoint.cpp diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 7c20121a2..90245b5d0 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -1071,6 +1071,7 @@ set (PCH_SOURCES core/statusbar2.cpp core/gi.cpp + core/rendering/hw_entrypoint.cpp core/rendering/scene/hw_clipper.cpp core/rendering/scene/hw_walls.cpp core/rendering/render.cpp diff --git a/source/build/src/engine.cpp b/source/build/src/engine.cpp index 6c3981a0b..d2c6383e2 100644 --- a/source/build/src/engine.cpp +++ b/source/build/src/engine.cpp @@ -913,6 +913,7 @@ void set_globalang(fixed_t const ang) // EXTERN_CVAR(Int, gl_fogmode) CVAR(Bool, testnewrenderer, true, 0) +CVAR(Bool, testnewinterface, true, 0) int32_t renderDrawRoomsQ16(int32_t daposx, int32_t daposy, int32_t daposz, fixed_t daang, fixed_t dahoriz, int16_t dacursectnum) @@ -980,7 +981,8 @@ int32_t renderDrawRoomsQ16(int32_t daposx, int32_t daposy, int32_t daposz, else { vec3_t pos = { daposx, daposy, daposz }; - render_drawrooms(pos, globalcursectnum, daang, dahoriz, rollang, r_fov, false, false); + if (!testnewinterface) render_drawrooms_(pos, globalcursectnum, daang, dahoriz, rollang, r_fov, false, false); + else render_drawrooms(pos, globalcursectnum, daang, dahoriz, rollang, false, false); } return inpreparemirror; diff --git a/source/core/rendering/hw_entrypoint.cpp b/source/core/rendering/hw_entrypoint.cpp new file mode 100644 index 000000000..ce3c8e765 --- /dev/null +++ b/source/core/rendering/hw_entrypoint.cpp @@ -0,0 +1,328 @@ +// +//--------------------------------------------------------------------------- +// +// 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 +** +*/ + +#include "gi.h" +#include "build.h" +#include "v_draw.h" +//#include "a_dynlight.h" +#include "v_video.h" +#include "m_png.h" +//#include "doomstat.h" +//#include "r_data/r_interpolate.h" +//#include "r_utility.h" +//#include "d_player.h" +#include "i_time.h" +#include "hw_dynlightdata.h" +#include "hw_clock.h" +#include "flatvertices.h" +//#include "v_palette.h" +//#include "d_main.h" + +#include "hw_renderstate.h" +#include "hw_lightbuffer.h" +#include "hw_cvars.h" +#include "hw_viewpointbuffer.h" +#include "hw_clipper.h" +//#include "hwrenderer/scene/hw_portal.h" +#include "hw_vrmodes.h" +//#include "g_levellocals.h" + +#include "hw_drawstructs.h" +#include "hw_drawlist.h" +#include "hw_drawinfo.h" +#include "gamecvars.h" + +EXTERN_CVAR(Bool, cl_capfps) +bool NoInterpolateView; + + +#if 0 +void CollectLights(FLevelLocals* Level) +{ + IShadowMap* sm = &screen->mShadowMap; + int lightindex = 0; + + // Todo: this should go through the blockmap in a spiral pattern around the player so that closer lights are preferred. + for (auto light = Level->lights; light; light = light->next) + { + IShadowMap::LightsProcessed++; + if (light->shadowmapped && light->IsActive() && lightindex < 1024) + { + IShadowMap::LightsShadowmapped++; + + light->mShadowmapIndex = lightindex; + sm->SetLight(lightindex, (float)light->X(), (float)light->Y(), (float)light->Z(), light->GetRadius()); + lightindex++; + } + else + { + light->mShadowmapIndex = 1024; + } + + } + + for (; lightindex < 1024; lightindex++) + { + sm->SetLight(lightindex, 0, 0, 0, 0); + } +} +#endif + + +//----------------------------------------------------------------------------- +// +// Renders one viewpoint in a scene +// +//----------------------------------------------------------------------------- + +void RenderViewpoint(FRenderViewpoint& mainvp, IntRect* bounds, float fov, float ratio, float fovratio, bool mainview, bool toscreen) +{ + auto& RenderState = *screen->RenderState(); + + /* + if (mainview && toscreen) + { + screen->SetAABBTree(camera->Level->aabbTree); + screen->mShadowMap.SetCollectLights([=] { + CollectLights(camera->Level); + }); + screen->UpdateShadowMap(); + } + */ + + // 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]; + 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(nullptr, mainvp, nullptr); + auto& vp = di->Viewpoint; + vp = mainvp; + + di->Set3DViewport(RenderState); + float flash = 1.f; + 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); + + di->ProcessScene(toscreen); + + if (mainview) + { + PostProcess.Clock(); + if (toscreen) di->EndDrawScene(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_DEFAULT, flash, [&]() { }); + PostProcess.Unclock(); + } + di->EndDrawInfo(); + if (eyeCount - eye_ix > 1) + screen->NextEye(eyeCount); + } +} + +//=========================================================================== +// +// Set up the view point. +// +//=========================================================================== + +FRenderViewpoint SetupView(vec3_t& position, int sectnum, fixed_t q16angle, fixed_t q16horizon, float rollang) +{ + FRenderViewpoint r_viewpoint{}; + r_viewpoint.SectNum = sectnum; + r_viewpoint.Pos = { position.x / 16.f, position.y / -16.f, position.z / -256.f }; + r_viewpoint.HWAngles.Yaw = -90.f + q16ang(q16angle).asdeg(); + r_viewpoint.HWAngles.Pitch = -HorizToPitch(q16horizon); + r_viewpoint.HWAngles.Roll = rollang; + r_viewpoint.FieldOfView = (float)r_fov; + r_viewpoint.RotAngle = q16ang(q16angle).asbam(); + return r_viewpoint; +} + + +void DoWriteSavePic(FileWriter* file, uint8_t* scr, int width, int height, bool upsidedown) +{ + int pixelsize = 1; + + int pitch = width * pixelsize; + if (upsidedown) + { + scr += ((height - 1) * width * pixelsize); + pitch *= -1; + } + + M_CreatePNG(file, scr, nullptr, SS_RGB, width, height, pitch, vid_gamma); +} + +//=========================================================================== +// +// Render the view to a savegame picture +// +//=========================================================================== + +#if 0 +void WriteSavePic(player_t* player, FileWriter* file, int width, int height) +{ + IntRect bounds; + bounds.left = 0; + bounds.top = 0; + bounds.width = width; + bounds.height = height; + auto& RenderState = *screen->RenderState(); + + // we must be sure the GPU finished reading from the buffer before we fill it with new data. + screen->WaitForCommands(false); + + // Switch to render buffers dimensioned for the savepic + screen->SetSaveBuffers(true); + screen->ImageTransitionScene(true); + + hw_ClearFakeFlat(); + RenderState.SetVertexBuffer(screen->mVertexData); + screen->mVertexData->Reset(); + screen->mLights->Clear(); + screen->mViewpoints->Clear(); + + // This shouldn't overwrite the global viewpoint even for a short time. + FRenderViewpoint savevp; + sector_t* viewsector = RenderViewpoint(savevp, players[consoleplayer].camera, &bounds, r_viewpoint.FieldOfView.Degrees, 1.6f, 1.6f, true, false); + RenderState.EnableStencil(false); + RenderState.SetNoSoftLightLevel(); + + int numpixels = width * height; + uint8_t* scr = (uint8_t*)M_Malloc(numpixels * 3); + screen->CopyScreenToBuffer(width, height, scr); + + DoWriteSavePic(file, SS_RGB, scr, width, height, viewsector, screen->FlipSavePic()); + M_Free(scr); + + // Switch back the screen render buffers + screen->SetViewportRects(nullptr); + screen->SetSaveBuffers(false); +} +#endif + +//=========================================================================== +// +// Renders the main view +// +//=========================================================================== + +static void CheckTimer(FRenderState &state, uint64_t ShaderStartTime) +{ + // if firstFrame is not yet initialized, initialize it to current time + // if we're going to overflow a float (after ~4.6 hours, or 24 bits), re-init to regain precision + if ((state.firstFrame == 0) || (screen->FrameTime - state.firstFrame >= 1 << 24) || ShaderStartTime >= state.firstFrame) + state.firstFrame = screen->FrameTime; +} + + +void render_drawrooms(vec3_t& position, int sectnum, fixed_t q16angle, fixed_t q16horizon, float rollang, bool mirror, bool planemirror) +{ + int retsec = 0; + auto RenderState = screen->RenderState(); + RenderState->SetVertexBuffer(screen->mVertexData); + screen->mVertexData->Reset(); + + FRenderViewpoint r_viewpoint = SetupView(position, sectnum, q16angle, q16horizon, rollang); + iter_dlightf = iter_dlight = draw_dlight = draw_dlightf = 0; + + checkBenchActive(); + + // reset statistics counters + ResetProfilingData(); + + // Get this before everything else + if (cl_capfps) r_viewpoint.TicFrac = 1.; + else r_viewpoint.TicFrac = I_GetTimeFrac(); + + screen->mLights->Clear(); + screen->mViewpoints->Clear(); + + // NoInterpolateView should have no bearing on camera textures, but needs to be preserved for the main view below. + bool saved_niv = NoInterpolateView; + NoInterpolateView = false; + + // Shader start time does not need to be handled per level. Just use the one from the camera to render from. + CheckTimer(*RenderState, 0/*ShaderStartTime*/); + // prepare all camera textures that have been used in the last frame. + // This must be done for all levels, not just the primary one! + /* + Level->canvasTextureInfo.UpdateAll([&](AActor* camera, FCanvasTexture* camtex, double fov) + { + screen->RenderTextureView(camtex, [=](IntRect& bounds) + { + FRenderViewpoint texvp; + float ratio = camtex->aspectRatio; + RenderViewpoint(texvp, camera, &bounds, fov, ratio, ratio, false, false); + }); + }); + } + */ + NoInterpolateView = saved_niv; + + // now render the main view + float fovratio; + float ratio = ActiveRatio(windowxy2.x - windowxy1.x + 1, windowxy2.y - windowxy1.y); + if (ratio >= 1.33f) + { + fovratio = 1.33f; + } + else + { + fovratio = ratio; + } + + screen->ImageTransitionScene(true); // Only relevant for Vulkan. + + RenderViewpoint(r_viewpoint, NULL, r_viewpoint.FieldOfView.Degrees, ratio, fovratio, true, true); + All.Unclock(); +} diff --git a/source/core/rendering/render.cpp b/source/core/rendering/render.cpp index d982b6dbe..e7eaf5772 100644 --- a/source/core/rendering/render.cpp +++ b/source/core/rendering/render.cpp @@ -14,6 +14,7 @@ #include "v_video.h" #include "flatvertices.h" #include "gamefuncs.h" +#include "hw_drawinfo.h" angle_t FrustumAngle(float ratio, float fov, float pitch) { @@ -579,7 +580,7 @@ static void SetViewMatrix(const FRotator& angles, float vx, float vy, float vz, using namespace Newrender; -void render_drawrooms(vec3_t& position, int sectnum, fixed_t q16angle, fixed_t q16horizon, float rollang, float fov, bool mirror, bool planemirror) +void render_drawrooms_(vec3_t& position, int sectnum, fixed_t q16angle, fixed_t q16horizon, float rollang, float fov, bool mirror, bool planemirror) { GLInterface.ClearDepth(); GLInterface.EnableBlend(false); @@ -608,7 +609,7 @@ void render_drawrooms(vec3_t& position, int sectnum, fixed_t q16angle, fixed_t q angle_t rotang = q16ang(q16angle).asbam(); clipper.SafeAddClipRangeRealAngles(rotang + fa, rotang - fa); - BunchDrawer drawer(clipper, position.vec2); + Newrender::BunchDrawer drawer(clipper, position.vec2); drawer.RenderScene(sectnum); diff --git a/source/core/rendering/render.h b/source/core/rendering/render.h index b92958f07..8c2da2cf2 100644 --- a/source/core/rendering/render.h +++ b/source/core/rendering/render.h @@ -1,5 +1,6 @@ #pragma once #include "build.h" -void render_drawrooms(vec3_t& position, int sectnum, fixed_t q16angle, fixed_t q16horizon, float rollang, float fov, bool mirror, bool planemirror); +void render_drawrooms(vec3_t& position, int sectnum, fixed_t q16angle, fixed_t q16horizon, float rollang, bool mirror, bool planemirror); +void render_drawrooms_(vec3_t& position, int sectnum, fixed_t q16angle, fixed_t q16horizon, float rollang, float fov, bool mirror, bool planemirror); diff --git a/source/core/rendering/scene/hw_drawinfo.cpp b/source/core/rendering/scene/hw_drawinfo.cpp index c92c421a2..e99897852 100644 --- a/source/core/rendering/scene/hw_drawinfo.cpp +++ b/source/core/rendering/scene/hw_drawinfo.cpp @@ -447,7 +447,7 @@ void HWDrawInfo::RenderPortal(HWPortal *p, FRenderState &state, bool usestencil) //----------------------------------------------------------------------------- -void HWDrawInfo::EndDrawScene(sectortype * viewsector, FRenderState &state) +void HWDrawInfo::EndDrawScene(FRenderState &state) { state.EnableFog(false); @@ -472,28 +472,6 @@ void HWDrawInfo::EndDrawScene(sectortype * viewsector, FRenderState &state) state.SetScissor(0, 0, -1, -1); } -void HWDrawInfo::DrawEndScene2D(sectortype * viewsector, FRenderState &state) -{ - //const bool renderHUDModel = IsHUDModelForPlayerAvailable(players[consoleplayer].camera->player); - auto vrmode = VRMode::GetVRMode(true); - - HWViewpointUniforms vp = VPUniforms; - vp.mViewMatrix.loadIdentity(); - vp.mProjectionMatrix = vrmode->GetHUDSpriteProjection(); - screen->mViewpoints->SetViewpoint(state, &vp); - state.EnableDepthTest(false); - state.EnableMultisampling(false); - - //DrawPlayerSprites(false, state); - - state.SetNoSoftLightLevel(); - - // Restore standard rendering state - state.SetRenderStyle(STYLE_Translucent); - state.ResetColor(); - state.EnableTexture(true); - state.SetScissor(0, 0, -1, -1); -} //----------------------------------------------------------------------------- // diff --git a/source/core/rendering/scene/hw_drawinfo.h b/source/core/rendering/scene/hw_drawinfo.h index 8c0182e36..ac7eda6a0 100644 --- a/source/core/rendering/scene/hw_drawinfo.h +++ b/source/core/rendering/scene/hw_drawinfo.h @@ -39,6 +39,8 @@ struct FRenderViewpoint FRotator HWAngles; FAngle FieldOfView; angle_t RotAngle; + int SectNum; + double TicFrac; }; //========================================================================== // @@ -164,8 +166,7 @@ public: void RenderScene(FRenderState &state); void RenderTranslucent(FRenderState &state); void RenderPortal(HWPortal *p, FRenderState &state, bool usestencil); - void EndDrawScene(sectortype * viewsector, FRenderState &state); - void DrawEndScene2D(sectortype * viewsector, FRenderState &state); + void EndDrawScene(FRenderState &state); void Set3DViewport(FRenderState &state); void ProcessScene(bool toscreen); diff --git a/source/glbackend/glbackend.h b/source/glbackend/glbackend.h index 44a41cbdd..518a7503e 100644 --- a/source/glbackend/glbackend.h +++ b/source/glbackend/glbackend.h @@ -21,12 +21,6 @@ class F2DDrawer; struct palette_t; extern int xdim, ydim; -enum -{ - DM_MAINVIEW, - DM_OFFSCREEN -}; - class PaletteManager { IHardwareTexture* palettetextures[256] = {};