From 625b78bba16dcbbe97fa84bbf8f2273472d79ade Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Thu, 6 Mar 2025 00:25:22 +0000 Subject: Pass frustum into render functions Support for culling objects outside the view frustum --- game/network/rail.cpp | 2 +- game/network/rail.h | 2 +- game/scenary/foliage.cpp | 2 +- game/scenary/foliage.h | 2 +- game/scenary/illuminator.cpp | 2 +- game/scenary/illuminator.h | 2 +- game/terrain.cpp | 2 +- game/terrain.h | 2 +- game/vehicles/railVehicleClass.cpp | 2 +- game/vehicles/railVehicleClass.h | 2 +- game/water.cpp | 2 +- game/water.h | 2 +- gfx/gl/sceneProvider.h | 3 ++- gfx/gl/sceneRenderer.cpp | 2 +- gfx/renderable.h | 3 ++- test/test-assetFactory.cpp | 4 ++-- test/test-geoData.cpp | 4 ++-- test/test-network.cpp | 2 +- test/test-render.cpp | 22 +++++++++++----------- ui/editNetwork.cpp | 8 ++++---- ui/editNetwork.h | 4 ++-- ui/gameMainSelector.cpp | 6 +++--- ui/gameMainSelector.h | 4 ++-- ui/gameMainWindow.cpp | 8 ++++---- ui/gameMainWindow.h | 2 +- ui/worldOverlay.h | 3 ++- 26 files changed, 51 insertions(+), 48 deletions(-) diff --git a/game/network/rail.cpp b/game/network/rail.cpp index d7de231..2a18b9a 100644 --- a/game/network/rail.cpp +++ b/game/network/rail.cpp @@ -166,7 +166,7 @@ namespace { } void -RailLinks::render(const SceneShader & shader) const +RailLinks::render(const SceneShader & shader, const Frustum &) const { if (!links.objects.empty()) { texture->bind(); diff --git a/game/network/rail.h b/game/network/rail.h index fa64eda..4aef9e3 100644 --- a/game/network/rail.h +++ b/game/network/rail.h @@ -75,7 +75,7 @@ public: RailLinks(); std::shared_ptr addLinksBetween(GlobalPosition3D start, GlobalPosition3D end); - void render(const SceneShader &) const override; + void render(const SceneShader &, const Frustum &) const override; [[nodiscard]] const Surface * getBaseSurface() const override; [[nodiscard]] RelativeDistance getBaseWidth() const override; diff --git a/game/scenary/foliage.cpp b/game/scenary/foliage.cpp index a0ec576..c1bf9b9 100644 --- a/game/scenary/foliage.cpp +++ b/game/scenary/foliage.cpp @@ -29,7 +29,7 @@ Foliage::updateStencil(const ShadowStenciller & ss) const } void -Foliage::render(const SceneShader & shader) const +Foliage::render(const SceneShader & shader, const Frustum &) const { if (const auto count = instances.size()) { shader.basicInst.use(); diff --git a/game/scenary/foliage.h b/game/scenary/foliage.h index 5da63f0..422c7aa 100644 --- a/game/scenary/foliage.h +++ b/game/scenary/foliage.h @@ -24,7 +24,7 @@ public: }; mutable InstanceVertices instances; - void render(const SceneShader &) const override; + void render(const SceneShader &, const Frustum &) const override; void shadows(const ShadowMapper &) const override; void updateStencil(const ShadowStenciller &) const override; glTexture shadowStencil = ShadowStenciller::createStencilTexture(256, 256); diff --git a/game/scenary/illuminator.cpp b/game/scenary/illuminator.cpp index e3810ec..f1a02b2 100644 --- a/game/scenary/illuminator.cpp +++ b/game/scenary/illuminator.cpp @@ -59,7 +59,7 @@ Illuminator::postLoad() } void -Illuminator::render(const SceneShader & shader) const +Illuminator::render(const SceneShader & shader, const Frustum &) const { if (const auto count = instances.size()) { shader.basicInst.use(); diff --git a/game/scenary/illuminator.h b/game/scenary/illuminator.h index 44bd583..47ce337 100644 --- a/game/scenary/illuminator.h +++ b/game/scenary/illuminator.h @@ -45,7 +45,7 @@ public: mutable InstanceVertices instances; mutable InstanceVertices instancesSpotLight; mutable InstanceVertices instancesPointLight; - void render(const SceneShader &) const override; + void render(const SceneShader &, const Frustum &) const override; void lights(const SceneShader &) const override; protected: diff --git a/game/terrain.cpp b/game/terrain.cpp index f7de6fd..ee7dfa4 100644 --- a/game/terrain.cpp +++ b/game/terrain.cpp @@ -97,7 +97,7 @@ Terrain::afterChange() } void -Terrain::render(const SceneShader & shader) const +Terrain::render(const SceneShader & shader, const Frustum &) const { grass->bind(); const auto chunkBySurface = std::views::chunk_by([](const auto & itr1, const auto & itr2) { diff --git a/game/terrain.h b/game/terrain.h index f5b1b32..66887ed 100644 --- a/game/terrain.h +++ b/game/terrain.h @@ -16,7 +16,7 @@ public: generateMeshes(); } - void render(const SceneShader & shader) const override; + void render(const SceneShader & shader, const Frustum &) const override; void shadows(const ShadowMapper &) const override; void tick(TickDuration) override; diff --git a/game/vehicles/railVehicleClass.cpp b/game/vehicles/railVehicleClass.cpp index 34c1359..179b570 100644 --- a/game/vehicles/railVehicleClass.cpp +++ b/game/vehicles/railVehicleClass.cpp @@ -33,7 +33,7 @@ RailVehicleClass::postLoad() } void -RailVehicleClass::render(const SceneShader & shader) const +RailVehicleClass::render(const SceneShader & shader, const Frustum &) const { if (const auto count = static_cast(instances.size())) { if (texture) { diff --git a/game/vehicles/railVehicleClass.h b/game/vehicles/railVehicleClass.h index 88f08c5..2c1fd2b 100644 --- a/game/vehicles/railVehicleClass.h +++ b/game/vehicles/railVehicleClass.h @@ -14,7 +14,7 @@ class Location; class RailVehicleClass : public Renderable, public Asset { public: - void render(const SceneShader & shader) const override; + void render(const SceneShader & shader, const Frustum &) const override; void shadows(const ShadowMapper & shadowMapper) const override; struct LocationVertex { diff --git a/game/water.cpp b/game/water.cpp index f720e3e..94a8596 100644 --- a/game/water.cpp +++ b/game/water.cpp @@ -102,7 +102,7 @@ Water::tick(TickDuration dur) } void -Water::render(const SceneShader & shader) const +Water::render(const SceneShader & shader, const Frustum &) const { shader.water.use(waveCycle); water->bind(); diff --git a/game/water.h b/game/water.h index ba46703..f9fe080 100644 --- a/game/water.h +++ b/game/water.h @@ -16,7 +16,7 @@ class Water : public WorldObject, public Renderable { public: explicit Water(std::shared_ptr); - void render(const SceneShader & shader) const override; + void render(const SceneShader & shader, const Frustum &) const override; void tick(TickDuration) override; float waveCycle {0.F}; diff --git a/gfx/gl/sceneProvider.h b/gfx/gl/sceneProvider.h index f5e8e99..93b384f 100644 --- a/gfx/gl/sceneProvider.h +++ b/gfx/gl/sceneProvider.h @@ -5,6 +5,7 @@ class SceneRenderer; class ShadowMapper; class SceneShader; +class Frustum; class SceneProvider { public: @@ -12,7 +13,7 @@ public: virtual ~SceneProvider() = default; DEFAULT_MOVE_COPY(SceneProvider); - virtual void content(const SceneShader &) const = 0; + virtual void content(const SceneShader &, const Frustum &) const = 0; virtual void environment(const SceneShader &, const SceneRenderer &) const; virtual void lights(const SceneShader &) const = 0; virtual void shadows(const ShadowMapper &) const; diff --git a/gfx/gl/sceneRenderer.cpp b/gfx/gl/sceneRenderer.cpp index b2a7d78..188c4fd 100644 --- a/gfx/gl/sceneRenderer.cpp +++ b/gfx/gl/sceneRenderer.cpp @@ -71,7 +71,7 @@ SceneRenderer::render(const SceneProvider & scene) const glEnable(GL_DEPTH_TEST); glClearColor(0, 0, 0, 1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - scene.content(shader); + scene.content(shader, camera); // Environment pass - // * ambient - clears illumination texture - see setAmbientLight diff --git a/gfx/renderable.h b/gfx/renderable.h index 83522e3..9fbeccd 100644 --- a/gfx/renderable.h +++ b/gfx/renderable.h @@ -3,6 +3,7 @@ #include class SceneShader; +class Frustum; class ShadowMapper; class ShadowStenciller; @@ -12,7 +13,7 @@ public: virtual ~Renderable() = default; DEFAULT_MOVE_COPY(Renderable); - virtual void render(const SceneShader & shader) const = 0; + virtual void render(const SceneShader & shader, const Frustum &) const = 0; virtual void lights(const SceneShader & shader) const; virtual void shadows(const ShadowMapper & shadowMapper) const; diff --git a/test/test-assetFactory.cpp b/test/test-assetFactory.cpp index 6036721..02f0202 100644 --- a/test/test-assetFactory.cpp +++ b/test/test-assetFactory.cpp @@ -38,10 +38,10 @@ public: } void - content(const SceneShader & shader) const override + content(const SceneShader & shader, const Frustum & frustum) const override { shader.basic.use(Location {{0, 0, 0}, {0, 0, 0}}); - objects.apply(&Renderable::render, shader); + objects.apply(&Renderable::render, shader, frustum); } void diff --git a/test/test-geoData.cpp b/test/test-geoData.cpp index 2332513..fb8b5c5 100644 --- a/test/test-geoData.cpp +++ b/test/test-geoData.cpp @@ -255,9 +255,9 @@ BOOST_DATA_TEST_CASE(deform, loadFixtureJson("geoData/deform/ const Terrain terrain; void - content(const SceneShader & shader) const override + content(const SceneShader & shader, const Frustum & frustum) const override { - terrain.render(shader); + terrain.render(shader, frustum); } void diff --git a/test/test-network.cpp b/test/test-network.cpp index e7419b5..51fea8b 100644 --- a/test/test-network.cpp +++ b/test/test-network.cpp @@ -70,7 +70,7 @@ struct TestNetwork : public NetworkOf { } void - render(const SceneShader &) const override + render(const SceneShader &, const Frustum &) const override { } diff --git a/test/test-render.cpp b/test/test-render.cpp index 3c453bd..080e635 100644 --- a/test/test-render.cpp +++ b/test/test-render.cpp @@ -68,14 +68,14 @@ public: } void - content(const SceneShader & shader) const override + content(const SceneShader & shader, const Frustum & frustum) const override { - terrain->render(shader); - water.render(shader); - rail.render(shader); - std::ranges::for_each(gameState->assets, [&shader](const auto & asset) { + terrain->render(shader, frustum); + water.render(shader, frustum); + rail.render(shader, frustum); + std::ranges::for_each(gameState->assets, [&shader, &frustum](const auto & asset) { if (const auto renderable = std::dynamic_pointer_cast(asset.second)) { - renderable->render(shader); + renderable->render(shader, frustum); } }); } @@ -171,10 +171,10 @@ BOOST_AUTO_TEST_CASE(terrain) Water water {terrain}; void - content(const SceneShader & shader) const override + content(const SceneShader & shader, const Frustum & frustum) const override { - terrain->render(shader); - water.render(shader); + terrain->render(shader, frustum); + water.render(shader, frustum); } void @@ -219,9 +219,9 @@ BOOST_AUTO_TEST_CASE(railnet) } void - content(const SceneShader & shader) const override + content(const SceneShader & shader, const Frustum & frustum) const override { - net.render(shader); + net.render(shader, frustum); } void diff --git a/ui/editNetwork.cpp b/ui/editNetwork.cpp index c4c0297..2887491 100644 --- a/ui/editNetwork.cpp +++ b/ui/editNetwork.cpp @@ -48,19 +48,19 @@ EditNetwork::handleInput(const SDL_Event & e, const UIComponent::Position & pare } void -EditNetwork::render(const SceneShader & shader) const +EditNetwork::render(const SceneShader & shader, const Frustum & frustum) const { if (builder) { blue.bind(); shader.absolute.use(); - builder->render(shader); + builder->render(shader, frustum); } } void -EditNetwork::Builder::render(const SceneShader & shader) const +EditNetwork::Builder::render(const SceneShader & shader, const Frustum & frustum) const { - candidateLinks.apply(&Renderable::render, shader); + candidateLinks.apply(&Renderable::render, shader, frustum); } void diff --git a/ui/editNetwork.h b/ui/editNetwork.h index 2ae467d..ae887bd 100644 --- a/ui/editNetwork.h +++ b/ui/editNetwork.h @@ -18,7 +18,7 @@ public: bool click(const SDL_MouseButtonEvent & e, const Ray &) override; bool move(const SDL_MouseMotionEvent & e, const Ray &) override; bool handleInput(const SDL_Event & e, const UIComponent::Position &) override; - void render(const SceneShader &) const override; + void render(const SceneShader &, const Frustum &) const override; void render(const UIShader & shader, const UIComponent::Position & pos) const override; using NetworkClickPos = std::variant; @@ -26,7 +26,7 @@ public: class Builder { public: virtual ~Builder() = default; - virtual void render(const SceneShader & shader) const; + virtual void render(const SceneShader & shader, const Frustum &) const; virtual std::string hint() const = 0; virtual void click(Network *, const GeoData *, const SDL_MouseButtonEvent &, const Ray &) = 0; virtual void move(Network *, const GeoData *, const SDL_MouseMotionEvent &, const Ray &) = 0; diff --git a/ui/gameMainSelector.cpp b/ui/gameMainSelector.cpp index a817f69..23ae8c0 100644 --- a/ui/gameMainSelector.cpp +++ b/ui/gameMainSelector.cpp @@ -33,10 +33,10 @@ GameMainSelector::render(const UIShader & shader, const Position & parentPos) co } void -GameMainSelector::render(const SceneShader & shader) const +GameMainSelector::render(const SceneShader & shader, const Frustum & frustum) const { if (target) { - target->render(shader); + target->render(shader, frustum); } } @@ -115,6 +115,6 @@ GameMainSelector::Component::render(const UIShader &, const UIComponent::Positio } void -GameMainSelector::Component::render(const SceneShader &) const +GameMainSelector::Component::render(const SceneShader &, const Frustum &) const { } diff --git a/ui/gameMainSelector.h b/ui/gameMainSelector.h index ccf0fa0..e715823 100644 --- a/ui/gameMainSelector.h +++ b/ui/gameMainSelector.h @@ -24,13 +24,13 @@ public: virtual bool move(const SDL_MouseMotionEvent &, const Ray &); virtual bool handleInput(const SDL_Event &, const Position & pos); virtual void render(const UIShader & shader, const Position & pos) const; - virtual void render(const SceneShader &) const; + virtual void render(const SceneShader &, const Frustum &) const; }; GameMainSelector(const Camera * c, ScreenAbsCoord size); void render(const UIShader & shader, const Position & pos) const override; - void render(const SceneShader & shader) const override; + void render(const SceneShader & shader, const Frustum &) const override; bool handleInput(const SDL_Event & e, const Position &) override; diff --git a/ui/gameMainWindow.cpp b/ui/gameMainWindow.cpp index c53300b..3403afa 100644 --- a/ui/gameMainWindow.cpp +++ b/ui/gameMainWindow.cpp @@ -54,15 +54,15 @@ GameMainWindow::render() const } void -GameMainWindow::content(const SceneShader & shader) const +GameMainWindow::content(const SceneShader & shader, const Frustum & frustum) const { for (const auto & [id, asset] : gameState->assets) { if (const auto r = std::dynamic_pointer_cast(asset)) { - r->render(shader); + r->render(shader, frustum); } } - gameState->world.apply(&Renderable::render, shader); - uiComponents.apply(&WorldOverlay::render, shader); + gameState->world.apply(&Renderable::render, shader, frustum); + uiComponents.apply(&WorldOverlay::render, shader, frustum); } void diff --git a/ui/gameMainWindow.h b/ui/gameMainWindow.h index fcbd135..112d23b 100644 --- a/ui/gameMainWindow.h +++ b/ui/gameMainWindow.h @@ -17,7 +17,7 @@ public: void render() const override; private: - void content(const SceneShader &) const override; + void content(const SceneShader &, const Frustum &) const override; void environment(const SceneShader &, const SceneRenderer &) const override; void lights(const SceneShader &) const override; void shadows(const ShadowMapper &) const override; diff --git a/ui/worldOverlay.h b/ui/worldOverlay.h index 18fab3f..a0f3b65 100644 --- a/ui/worldOverlay.h +++ b/ui/worldOverlay.h @@ -1,9 +1,10 @@ #pragma once class SceneShader; +class Frustum; class WorldOverlay { public: virtual ~WorldOverlay() = default; - virtual void render(const SceneShader &) const = 0; + virtual void render(const SceneShader &, const Frustum &) const = 0; }; -- cgit v1.2.3