diff options
| -rw-r--r-- | application/resviewer.cpp | 21 | ||||
| -rw-r--r-- | gfx/gl/sceneProvider.h | 4 | ||||
| -rw-r--r-- | gfx/gl/sceneRenderer.cpp | 11 | ||||
| -rw-r--r-- | gfx/gl/sceneRenderer.h | 2 | ||||
| -rw-r--r-- | test/test-assetFactory.cpp | 15 | ||||
| -rw-r--r-- | test/test-geoData.cpp | 14 | ||||
| -rw-r--r-- | test/test-render.cpp | 69 | ||||
| -rw-r--r-- | ui/gameMainWindow.cpp | 13 | ||||
| -rw-r--r-- | ui/gameMainWindow.h | 1 |
9 files changed, 102 insertions, 48 deletions
diff --git a/application/resviewer.cpp b/application/resviewer.cpp index 0e34c05..68c2316 100644 --- a/application/resviewer.cpp +++ b/application/resviewer.cpp @@ -44,9 +44,9 @@ private: void render() override { - const auto & [camFrust, lightFrust] = preFrame(gameState->environment->getSunPos()); + SceneRenderer::preFrame(*this, gameState->environment->getSunPos()); SceneRenderer::render(*this); - controls(camFrust, lightFrust); + controls(); } void @@ -90,12 +90,12 @@ private: } void - controls(const Frustum & camFrust, const Frustum & lightFrust) + controls() { if (ImGui::Begin("Resource view")) { ImGui::SetWindowSize({}); fileSelection(); - assetSelection(camFrust, lightFrust); + assetSelection(); } ImGui::End(); @@ -131,7 +131,7 @@ private: } void - assetSelection(const Frustum & camFrust, const Frustum & lightFrust) + assetSelection() { if (!gameState->assets.empty()) { ImGui::BeginListBox("Asset"); @@ -142,7 +142,6 @@ private: selectedAssetId = asset.first; selectedAsset = renderable; location = asset.second->createAt(position); - renderable->preFrame(camFrust, lightFrust); } } } @@ -151,6 +150,14 @@ private: } void + forEachRenderable(const RenderableProcessor & func) const override + { + if (selectedAsset) { + func(selectedAsset); + } + } + + void content(const SceneShader & sceneShader, const Frustum & frustum) const override { gameState->terrain->render(sceneShader, frustum); @@ -186,7 +193,7 @@ private: std::filesystem::file_time_type fileTime; const std::filesystem::path * selectedFile {}; std::string selectedAssetId; - const Renderable * selectedAsset {}; + Renderable * selectedAsset {}; Location position {.pos = {0, 0, TERRAIN_HEIGHT}, .rot = {}}; std::any location; Angle cameraAngle {0.F}; diff --git a/gfx/gl/sceneProvider.h b/gfx/gl/sceneProvider.h index f6b7009..e69885a 100644 --- a/gfx/gl/sceneProvider.h +++ b/gfx/gl/sceneProvider.h @@ -1,11 +1,13 @@ #pragma once +#include <functional> #include <special_members.h> class SceneRenderer; class ShadowMapper; class SceneShader; class Frustum; +class Renderable; class SceneProvider { public: @@ -13,6 +15,8 @@ public: virtual ~SceneProvider() = default; DEFAULT_MOVE_COPY(SceneProvider); + using RenderableProcessor = std::function<void(Renderable *)>; + virtual void forEachRenderable(const RenderableProcessor &) 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; diff --git a/gfx/gl/sceneRenderer.cpp b/gfx/gl/sceneRenderer.cpp index d005dfa..c1ec987 100644 --- a/gfx/gl/sceneRenderer.cpp +++ b/gfx/gl/sceneRenderer.cpp @@ -4,6 +4,7 @@ #include <gfx/gl/shaders/directionalLight-frag.h> #include <gfx/gl/shaders/lighting-frag.h> #include <gfx/gl/shaders/lighting-vert.h> +#include <gfx/renderable.h> #include <glm/gtc/type_ptr.hpp> static constexpr const std::array<const glm::i8vec4, 4> displayVAOdata {{ @@ -77,10 +78,14 @@ SceneRenderer::resize(ScreenAbsCoord newSize) shader.setViewPort({0, 0, size.x, size.y}); } -std::pair<const Frustum &, const Frustum &> -SceneRenderer::preFrame(const LightDirection & lightDirection) +void +SceneRenderer::preFrame(const SceneProvider & scene, const LightDirection lightDirection) { - return {camera, shadowMapper.preFrame(lightDirection, camera)}; + glDebugScope _ {output}; + const auto lightView = shadowMapper.preFrame(lightDirection, camera); + scene.forEachRenderable([&lightView, this](Renderable * renderable) { + renderable->preFrame(camera, lightView); + }); } void diff --git a/gfx/gl/sceneRenderer.h b/gfx/gl/sceneRenderer.h index 2ec8057..d6f5dd1 100644 --- a/gfx/gl/sceneRenderer.h +++ b/gfx/gl/sceneRenderer.h @@ -17,8 +17,8 @@ public: void resize(ScreenAbsCoord size); + void preFrame(const SceneProvider & scene, LightDirection lightDirection); void render(const SceneProvider &) const; - std::pair<const Frustum &, const Frustum &> preFrame(const LightDirection &); void setAmbientLight(const RGB & colour) const; void setDirectionalLight(const RGB & colour, const LightDirection & direction, const SceneProvider &) const; diff --git a/test/test-assetFactory.cpp b/test/test-assetFactory.cpp index ff38369..8dbe53d 100644 --- a/test/test-assetFactory.cpp +++ b/test/test-assetFactory.cpp @@ -69,16 +69,21 @@ namespace { } void - render(float dist) + forEachRenderable(const RenderableProcessor & func) const override { - sceneRenderer.camera.setView({-dist, dist * 1.2F, dist * 1.2F}, south + east + down); - const auto & [camFrust, lightFrust] = sceneRenderer.preFrame({{0.9, 0.5}}); for (const auto & [assetId, asset] : gameState.assets) { if (const auto renderable = asset.getAs<Renderable>()) { - renderable->preFrame(camFrust, lightFrust); + func(renderable); } } - gameState.world.apply<Renderable>(&Renderable::preFrame, camFrust, lightFrust); + gameState.world.apply<Renderable>(func); + } + + void + render(float dist) + { + sceneRenderer.camera.setView({-dist, dist * 1.2F, dist * 1.2F}, south + east + down); + sceneRenderer.preFrame(*this, {{0.9, 0.5}}); sceneRenderer.render(*this); } diff --git a/test/test-geoData.cpp b/test/test-geoData.cpp index b3a6ad4..80d3a08 100644 --- a/test/test-geoData.cpp +++ b/test/test-geoData.cpp @@ -256,14 +256,20 @@ BOOST_DATA_TEST_CASE(Deform, loadFixtureJson<DeformTerrainData>("geoData/deform/ TestRenderOutput tro {{640, 480}}; struct TestTerrain : public SceneProvider { - explicit TestTerrain(GeoData geoData) : terrain(std::move(geoData)) { } + explicit TestTerrain(GeoData geoData) : terrain(std::make_shared<Terrain>(std::move(geoData))) { } - const Terrain terrain; + std::shared_ptr<Terrain> terrain; + + void + forEachRenderable(const RenderableProcessor & func) const override + { + func(terrain.get()); + } void content(const SceneShader & shader, const Frustum & frustum) const override { - terrain.render(shader, frustum); + terrain->render(shader, frustum); } void @@ -281,7 +287,7 @@ BOOST_DATA_TEST_CASE(Deform, loadFixtureJson<DeformTerrainData>("geoData/deform/ void shadows(const ShadowMapper & shadowMapper, const Frustum & frustum) const override { - terrain.shadows(shadowMapper, frustum); + terrain->shadows(shadowMapper, frustum); } }; diff --git a/test/test-render.cpp b/test/test-render.cpp index ac71276..da7d572 100644 --- a/test/test-render.cpp +++ b/test/test-render.cpp @@ -30,12 +30,12 @@ namespace { class TestScene : public SceneProvider { RailVehicleClassPtr brush47rvc; std::shared_ptr<RailVehicle> train1, train2; - RailLinks rail; + std::shared_ptr<RailLinks> rail = std::make_shared<RailLinks>(); std::shared_ptr<Environment> env = std::make_shared<Environment>(); std::shared_ptr<Terrain> terrain = std::make_shared<Terrain>(GeoData::createFlat({0, 0}, {1000000, 1000000}, 1)); - Water water {terrain}; + std::shared_ptr<Water> water = std::make_shared<Water>(terrain); public: TestScene() @@ -69,16 +69,29 @@ namespace { .rot = {0, rotationDistribution(randomdev), 0}}); } } - rail.addLinksBetween({42000, 50000, 1000}, {65000, 50000, 1000}); - rail.addLinksBetween({65000, 50000, 1000}, {75000, 45000, 2000}); + rail->addLinksBetween({42000, 50000, 1000}, {65000, 50000, 1000}); + rail->addLinksBetween({65000, 50000, 1000}, {75000, 45000, 2000}); + } + + void + forEachRenderable(const RenderableProcessor & func) const override + { + func(terrain.get()); + func(water.get()); + func(rail.get()); + std::ranges::for_each(gameState->assets, [&func](const auto & asset) { + if (const auto renderable = asset.second.template getAs<const Renderable>()) { + func(renderable); + } + }); } void content(const SceneShader & shader, const Frustum & frustum) const override { terrain->render(shader, frustum); - water.render(shader, frustum); - rail.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 = asset.second.template getAs<const Renderable>()) { renderable->render(shader, frustum); @@ -162,13 +175,7 @@ BOOST_AUTO_TEST_CASE(Basic) TestSceneRenderer renderer {size, output}; renderer.camera.setView({-10000, -10000, 60000}, glm::normalize(glm::vec3 {1, 1, -0.5F})); const TestScene scene; - const auto & [camFrust, lightFrust] = renderer.preFrame(gameState.environment->getSunPos()); - for (const auto & [assetId, asset] : gameState.assets) { - if (const auto renderable = asset.getAs<Renderable>()) { - renderable->preFrame(camFrust, lightFrust); - } - } - gameState.world.apply<Renderable>(&Renderable::preFrame, camFrust, lightFrust); + renderer.preFrame(scene, gameState.environment->getSunPos()); renderer.render(scene); renderer.saveBuffers(ANALYSIS_DIRECTORY / "basic"); Texture::save(outImage, (ANALYSIS_DIRECTORY / "basic/final.tga").c_str()); @@ -182,13 +189,20 @@ BOOST_AUTO_TEST_CASE(TerrainSD19) class TestTerrain : public SceneProvider { std::shared_ptr<Terrain> terrain = std::make_shared<Terrain>(GeoData::loadFromAsciiGrid(FIXTURESDIR "height/SD19.asc")); - Water water {terrain}; + std::shared_ptr<Water> water = std::make_shared<Water>(terrain); + + void + forEachRenderable(const RenderableProcessor & func) const override + { + func(terrain.get()); + func(water.get()); + } void content(const SceneShader & shader, const Frustum & frustum) const override { terrain->render(shader, frustum); - water.render(shader, frustum); + water->render(shader, frustum); } void @@ -210,8 +224,9 @@ BOOST_AUTO_TEST_CASE(TerrainSD19) } }; - renderer.preFrame(gameState.environment->getSunPos()); - renderer.render(TestTerrain {}); + TestTerrain testTerrain; + renderer.preFrame(testTerrain, gameState.environment->getSunPos()); + renderer.render(testTerrain); Texture::save(outImage, (ANALYSIS_DIRECTORY / "terrain.tga").c_str()); } @@ -221,22 +236,28 @@ BOOST_AUTO_TEST_CASE(RailNetwork) renderer.camera.setView({0, 0, 10000}, glm::normalize(glm::vec3 {1, 1, -0.5F})); class TestRail : public SceneProvider { - RailLinks net; + std::shared_ptr<RailLinks> net = std::make_shared<RailLinks>(); public: TestRail() { - net.addLinksBetween({20000, 10000, 0}, {100000, 100000, 0}); - net.addLinksBetween({20000, 10000, 0}, {10000, 10000, 0}); - net.addLinksBetween({10000, 20000, 0}, {100000, 120000, 0}); - net.addLinksBetween({10000, 20000, 0}, {10000, 10000, 0}); - net.addLinksBetween({100000, 100000, 0}, {100000, 120000, 0}); + net->addLinksBetween({20000, 10000, 0}, {100000, 100000, 0}); + net->addLinksBetween({20000, 10000, 0}, {10000, 10000, 0}); + net->addLinksBetween({10000, 20000, 0}, {100000, 120000, 0}); + net->addLinksBetween({10000, 20000, 0}, {10000, 10000, 0}); + net->addLinksBetween({100000, 100000, 0}, {100000, 120000, 0}); + } + + void + forEachRenderable(const RenderableProcessor & func) const override + { + func(net.get()); } void content(const SceneShader & shader, const Frustum & frustum) const override { - net.render(shader, frustum); + net->render(shader, frustum); } void diff --git a/ui/gameMainWindow.cpp b/ui/gameMainWindow.cpp index 9f224a2..056dac3 100644 --- a/ui/gameMainWindow.cpp +++ b/ui/gameMainWindow.cpp @@ -83,15 +83,20 @@ GameMainWindow::handleInput(const SDL_Event & event) } void -GameMainWindow::render() +GameMainWindow::forEachRenderable(const RenderableProcessor & func) const { - const auto & [camFrust, lightFrust] = SceneRenderer::preFrame(gameState->environment->getSunPos()); for (const auto & [assetId, asset] : gameState->assets) { if (const auto renderable = asset.getAs<Renderable>()) { - renderable->preFrame(camFrust, lightFrust); + func(renderable); } } - gameState->world.apply<const Renderable>(&Renderable::preFrame, camFrust, lightFrust); + gameState->world.apply<Renderable>(func); +} + +void +GameMainWindow::render() +{ + SceneRenderer::preFrame(*this, gameState->environment->getSunPos()); SceneRenderer::render(*this); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); diff --git a/ui/gameMainWindow.h b/ui/gameMainWindow.h index 71b6314..015bb2b 100644 --- a/ui/gameMainWindow.h +++ b/ui/gameMainWindow.h @@ -14,6 +14,7 @@ public: private: bool handleInput(const SDL_Event &) override; + void forEachRenderable(const RenderableProcessor & func) const override; void content(const SceneShader &, const Frustum &) const override; void environment(const SceneShader &, const SceneRenderer &) const override; void lights(const SceneShader &) const override; |
