From da0a46fb6f31e92ef8df1b9fbdfdfaa9f0309e33 Mon Sep 17 00:00:00 2001 From: codereader Date: Thu, 27 Jan 2022 06:00:55 +0100 Subject: [PATCH] #5893: Add separate entry point to RenderSystem for drawing the scene in lighting mode. --- include/irender.h | 26 +++++ radiant/camera/CamWnd.cpp | 40 +++++-- .../rendersystem/LightingModeRenderResult.h | 22 ++++ .../rendersystem/OpenGLRenderSystem.cpp | 109 +++++++++++++----- radiantcore/rendersystem/OpenGLRenderSystem.h | 11 ++ tools/msvc/DarkRadiantCore.vcxproj | 1 + tools/msvc/DarkRadiantCore.vcxproj.filters | 3 + 7 files changed, 171 insertions(+), 41 deletions(-) create mode 100644 radiantcore/rendersystem/LightingModeRenderResult.h diff --git a/include/irender.h b/include/irender.h index 5374e5710a..dcb80221d8 100644 --- a/include/irender.h +++ b/include/irender.h @@ -2,6 +2,7 @@ #include "imodule.h" #include "ivolumetest.h" +#include "irenderview.h" #include "iwindingrenderer.h" #include "igeometryrenderer.h" #include "isurfacerenderer.h" @@ -627,6 +628,16 @@ enum class ColourShaderType CameraAndOrthoview, }; +class IRenderResult +{ +public: + using Ptr = std::shared_ptr; + + virtual ~IRenderResult() {} + + virtual std::string toString() = 0; +}; + /** * \brief * The main interface for the backend renderer. @@ -726,6 +737,21 @@ class RenderSystem const Vector3& viewer, const VolumeTest& volume) = 0; + /** + * Render the scene based on the light-entity interactions. + * All the active lights and entities must have added themselves + * to this rendersystem at this point, using addEntity(). + * + * \param globalFlagsMask + * The mask of render flags which are permitted during this render pass. Any + * render flag which is 0 in this mask will not be enabled during rendering, + * even if the particular shader requests it. + * + * \returns A result object which can be used to display a statistics summary. + */ + virtual IRenderResult::Ptr renderLitScene(RenderStateFlags globalFlagsMask, + const render::IRenderView& view) = 0; + virtual void realise() = 0; virtual void unrealise() = 0; diff --git a/radiant/camera/CamWnd.cpp b/radiant/camera/CamWnd.cpp index 525da8d3ac..4eb1e4380c 100644 --- a/radiant/camera/CamWnd.cpp +++ b/radiant/camera/CamWnd.cpp @@ -784,6 +784,8 @@ void CamWnd::Cam_Draw() | RENDER_POLYGONSTIPPLE; } + IRenderResult::Ptr result; + // Main scene render { _renderer->prepare(); @@ -802,12 +804,20 @@ void CamWnd::Cam_Draw() i.second->render(GlobalRenderSystem(), *_renderer, _view); } - // Back end (submit to shaders and do the actual render) - _renderer->submitToShaders( - getCameraSettings()->getRenderMode() == RENDER_MODE_LIGHTING - ); - GlobalRenderSystem().render(RenderViewType::Camera, allowedRenderFlags, - _camera->getModelView(), _camera->getProjection(), _view.getViewer(), _view); + if (getCameraSettings()->getRenderMode() == RENDER_MODE_LIGHTING) + { + // Lit mode + result = GlobalRenderSystem().renderLitScene(allowedRenderFlags, _view); + } + else + { + // Back end (submit to shaders and do the actual render) + _renderer->submitToShaders( + getCameraSettings()->getRenderMode() == RENDER_MODE_LIGHTING + ); + GlobalRenderSystem().render(RenderViewType::Camera, allowedRenderFlags, + _camera->getModelView(), _camera->getProjection(), _view.getViewer(), _view); + } _renderer->cleanup(); } @@ -876,11 +886,19 @@ void CamWnd::Cam_Draw() // Render the stats and timing text. This may include culling stats in // debug builds. glRasterPos3f(4.0f, static_cast(_camera->getDeviceHeight()) - 4.0f, 0.0f); - std::string statString = _view.getCullStats(); - if (!statString.empty()) - statString += " | "; - statString += _renderStats.getStatString(); - _glFont->drawString(statString); + + if (result) + { + _glFont->drawString(result->toString()); + } + else + { + std::string statString = _view.getCullStats(); + if (!statString.empty()) + statString += " | "; + statString += _renderStats.getStatString(); + _glFont->drawString(statString); + } drawTime(); diff --git a/radiantcore/rendersystem/LightingModeRenderResult.h b/radiantcore/rendersystem/LightingModeRenderResult.h new file mode 100644 index 0000000000..2031f0b7a0 --- /dev/null +++ b/radiantcore/rendersystem/LightingModeRenderResult.h @@ -0,0 +1,22 @@ +#pragma once + +#include "irender.h" +#include "fmt/format.h" + +namespace render +{ + +class LightingModeRenderResult : + public IRenderResult +{ +public: + std::size_t visibleLights = 0; + std::size_t skippedLights = 0; + + std::string toString() override + { + return fmt::format("Lights: {0} of {1}", visibleLights, skippedLights); + } +}; + +} diff --git a/radiantcore/rendersystem/OpenGLRenderSystem.cpp b/radiantcore/rendersystem/OpenGLRenderSystem.cpp index 9589dcc9df..723335c579 100644 --- a/radiantcore/rendersystem/OpenGLRenderSystem.cpp +++ b/radiantcore/rendersystem/OpenGLRenderSystem.cpp @@ -11,6 +11,7 @@ #include "backend/BuiltInShader.h" #include "backend/ColourShader.h" #include "debugging/debugging.h" +#include "LightingModeRenderResult.h" #include @@ -161,26 +162,10 @@ ShaderPtr OpenGLRenderSystem::capture(ColourShaderType type, const Colour4& colo }); } -/* - * Render all states in the ShaderCache along with their renderables. This - * is where the actual OpenGL rendering starts. - */ -void OpenGLRenderSystem::render(RenderViewType renderViewType, - RenderStateFlags globalstate, - const Matrix4& modelview, - const Matrix4& projection, - const Vector3& viewer, - const VolumeTest& view) +void OpenGLRenderSystem::beginRendering(OpenGLState& state) { glPushAttrib(GL_ALL_ATTRIB_BITS); - // Set the projection and modelview matrices - glMatrixMode(GL_PROJECTION); - glLoadMatrixd(projection); - - glMatrixMode(GL_MODELVIEW); - glLoadMatrixd(modelview); - // global settings that are not set in renderstates glFrontFace(GL_CW); glCullFace(GL_BACK); @@ -204,18 +189,13 @@ void OpenGLRenderSystem::render(RenderViewType renderViewType, glDisableVertexAttribArrayARB(c_attr_Binormal); } - if (globalstate & RENDER_TEXTURE_2D) { - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - } - - // Construct default OpenGL state - OpenGLState current; + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // Set up initial GL state. This MUST MATCH the defaults in the OpenGLState // object, otherwise required state changes may not occur. - glLineStipple(current.m_linestipple_factor, - current.m_linestipple_pattern); + glLineStipple(state.m_linestipple_factor, + state.m_linestipple_pattern); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glDisable(GL_LIGHTING); glDisable(GL_TEXTURE_2D); @@ -243,14 +223,47 @@ void OpenGLRenderSystem::render(RenderViewType renderViewType, glDisable(GL_POLYGON_OFFSET_FILL); // greebo: otherwise tiny gap lines between brushes are visible glBindTexture(GL_TEXTURE_2D, 0); - glColor4f(1,1,1,1); - glDepthFunc(current.getDepthFunc()); + glColor4f(1, 1, 1, 1); + glDepthFunc(state.getDepthFunc()); glAlphaFunc(GL_ALWAYS, 0); glLineWidth(1); glPointSize(1); glHint(GL_FOG_HINT, GL_NICEST); glDisable(GL_FOG); +} + +void OpenGLRenderSystem::setupViewMatrices(const Matrix4& modelview, const Matrix4& projection) +{ + // Set the projection and modelview matrices + glMatrixMode(GL_PROJECTION); + glLoadMatrixd(projection); + + glMatrixMode(GL_MODELVIEW); + glLoadMatrixd(modelview); +} + +void OpenGLRenderSystem::finishRendering() +{ + glPopAttrib(); +} + +/* + * Render all states in the ShaderCache along with their renderables. This + * is where the actual OpenGL rendering starts. + */ +void OpenGLRenderSystem::render(RenderViewType renderViewType, + RenderStateFlags globalstate, + const Matrix4& modelview, + const Matrix4& projection, + const Vector3& viewer, + const VolumeTest& view) +{ + // Construct default OpenGL state + OpenGLState current; + beginRendering(current); + + setupViewMatrices(modelview, projection); // Iterate over the sorted mapping between OpenGLStates and their // OpenGLShaderPasses (containing the renderable geometry), and render the @@ -269,6 +282,44 @@ void OpenGLRenderSystem::render(RenderViewType renderViewType, pair.second->clearRenderables(); } + renderText(); + + finishRendering(); +} + +IRenderResult::Ptr OpenGLRenderSystem::renderLitScene(RenderStateFlags globalFlagsMask, + const IRenderView& view) +{ + auto result = std::make_shared(); + + // Construct default OpenGL state + OpenGLState current; + beginRendering(current); + setupViewMatrices(view.GetModelview(), view.GetProjection()); + + std::size_t visibleLights = 0; + + // Gather all visible lights and render the surfaces touched by them + for (const auto& light : _lights) + { + if (view.TestAABB(light->lightAABB()) == VOLUME_OUTSIDE) + { + result->skippedLights++; + continue; + } + + result->visibleLights++; + + // TODO: Insert rendering code here + } + + finishRendering(); + + return result; +} + +void OpenGLRenderSystem::renderText() +{ // Render all text glDisable(GL_DEPTH_TEST); @@ -276,8 +327,6 @@ void OpenGLRenderSystem::render(RenderViewType renderViewType, { textRenderer->render(); } - - glPopAttrib(); } void OpenGLRenderSystem::realise() diff --git a/radiantcore/rendersystem/OpenGLRenderSystem.h b/radiantcore/rendersystem/OpenGLRenderSystem.h index 7fd86f60ad..d0cbeb281b 100644 --- a/radiantcore/rendersystem/OpenGLRenderSystem.h +++ b/radiantcore/rendersystem/OpenGLRenderSystem.h @@ -76,6 +76,8 @@ class OpenGLRenderSystem final const Matrix4& projection, const Vector3& viewer, const VolumeTest& view) override; + IRenderResult::Ptr renderLitScene(RenderStateFlags globalFlagsMask, + const IRenderView& view) override; void realise() override; void unrealise() override; @@ -120,6 +122,15 @@ class OpenGLRenderSystem final void shutdownModule() override; private: + // Set up initial GL states, will push all attrib states + void beginRendering(OpenGLState& state); + + // Will pop attrib states + void finishRendering(); + + void setupViewMatrices(const Matrix4& modelview, const Matrix4& projection); + void renderText(); + ShaderPtr capture(const std::string& name, const std::function& createShader); }; diff --git a/tools/msvc/DarkRadiantCore.vcxproj b/tools/msvc/DarkRadiantCore.vcxproj index 9c3ede07b1..1bdd2d9ab3 100644 --- a/tools/msvc/DarkRadiantCore.vcxproj +++ b/tools/msvc/DarkRadiantCore.vcxproj @@ -999,6 +999,7 @@ + diff --git a/tools/msvc/DarkRadiantCore.vcxproj.filters b/tools/msvc/DarkRadiantCore.vcxproj.filters index 5bcdfafd5d..8f23c317b2 100644 --- a/tools/msvc/DarkRadiantCore.vcxproj.filters +++ b/tools/msvc/DarkRadiantCore.vcxproj.filters @@ -2292,5 +2292,8 @@ src\rendersystem\backend + + src\rendersystem + \ No newline at end of file