summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--application/resviewer.cpp21
-rw-r--r--gfx/gl/sceneProvider.h4
-rw-r--r--gfx/gl/sceneRenderer.cpp11
-rw-r--r--gfx/gl/sceneRenderer.h2
-rw-r--r--test/test-assetFactory.cpp15
-rw-r--r--test/test-geoData.cpp14
-rw-r--r--test/test-render.cpp69
-rw-r--r--ui/gameMainWindow.cpp13
-rw-r--r--ui/gameMainWindow.h1
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;