diff options
-rw-r--r-- | application/main.cpp | 8 | ||||
-rw-r--r-- | game/gamestate.h | 4 | ||||
-rw-r--r-- | game/terrain.cpp | 54 | ||||
-rw-r--r-- | game/terrain.h | 13 | ||||
-rw-r--r-- | test/test-geoData.cpp | 10 | ||||
-rw-r--r-- | test/test-render.cpp | 20 | ||||
-rw-r--r-- | ui/editNetwork.cpp | 8 | ||||
-rw-r--r-- | ui/gameMainSelector.cpp | 4 |
8 files changed, 54 insertions, 67 deletions
diff --git a/application/main.cpp b/application/main.cpp index db42a63..2c0d96f 100644 --- a/application/main.cpp +++ b/application/main.cpp @@ -38,12 +38,10 @@ public: int run() { - geoData = std::make_shared<GeoData>(GeoData::loadFromAsciiGrid("test/fixtures/height/SD19.asc")); - windows.create<MainWindow>(DISPLAY_WIDTH, DISPLAY_HEIGHT)->setContent<GameMainWindow>(); - world.create<Terrain>(geoData); - world.create<Water>(geoData); + terrain = world.create<Terrain>(GeoData::loadFromAsciiGrid("test/fixtures/height/SD19.asc")); + world.create<Water>(terrain); assets = AssetFactory::loadAll("res"); { @@ -89,7 +87,7 @@ public: for (auto y = 491100000; y < 491130000; y += 5000) { world.create<Plant>(std::dynamic_pointer_cast<Foliage>(assets.at(std::format("Tree-{:#02}-{}", treeDistribution(randomdev), treeVariantDistribution(randomdev)))), - Location {geoData->positionAt({{x + positionOffsetDistribution(randomdev), + Location {terrain->positionAt({{x + positionOffsetDistribution(randomdev), y + positionOffsetDistribution(randomdev)}}), {0, rotationDistribution(randomdev), 0}}); } diff --git a/game/gamestate.h b/game/gamestate.h index 892aa69..189417d 100644 --- a/game/gamestate.h +++ b/game/gamestate.h @@ -6,7 +6,7 @@ #include <special_members.h> class WorldObject; -class GeoData; +class Terrain; class Environment; class GameState { @@ -17,7 +17,7 @@ public: NO_COPY(GameState); Collection<WorldObject> world; - std::shared_ptr<GeoData> geoData; + std::shared_ptr<Terrain> terrain; std::shared_ptr<Environment> environment; AssetFactory::Assets assets; }; diff --git a/game/terrain.cpp b/game/terrain.cpp index c834379..786b9b0 100644 --- a/game/terrain.cpp +++ b/game/terrain.cpp @@ -1,6 +1,5 @@ #include "terrain.h" #include "game/geoData.h" -#include "gfx/models/texture.h" #include <algorithm> #include <cstddef> #include <gfx/gl/sceneShader.h> @@ -15,12 +14,7 @@ #include <utility> #include <vector> -static constexpr RGB openSurface {-1}; - -Terrain::Terrain(std::shared_ptr<GeoData> tm) : geoData {std::move(tm)}, grass {std::make_shared<Texture>("grass.png")} -{ - generateMeshes(); -} +static constexpr RGB OPEN_SURFACE {-1}; template<> VertexArrayObject & @@ -35,38 +29,34 @@ Terrain::generateMeshes() { meshes.removeAll(); std::vector<unsigned int> indices; - indices.reserve(geoData->n_faces() * 3); + indices.reserve(n_faces() * 3); std::vector<Vertex> vertices; - vertices.reserve(geoData->n_vertices()); - std::map<std::pair<GeoData::VertexHandle, const Surface *>, size_t> vertexIndex; - std::for_each(geoData->vertices_sbegin(), geoData->vertices_end(), - [this, &vertexIndex, &vertices](const GeoData::VertexHandle v) { - std::for_each(geoData->vf_begin(v), geoData->vf_end(v), - [&vertexIndex, v, this, &vertices](const GeoData::FaceHandle f) { - const auto surface = geoData->getSurface(f); - if (const auto vertexIndexRef = vertexIndex.emplace(std::make_pair(v, surface), 0); - vertexIndexRef.second) { - vertexIndexRef.first->second = vertices.size(); + vertices.reserve(n_vertices()); + std::map<std::pair<VertexHandle, const Surface *>, size_t> vertexIndex; + std::ranges::for_each(this->vertices(), [this, &vertexIndex, &vertices](const auto vertex) { + std::ranges::for_each(vf_range(vertex), [&vertexIndex, vertex, this, &vertices](const auto face) { + const auto * const surface = getSurface(face); + if (const auto vertexIndexRef = vertexIndex.emplace(std::make_pair(vertex, surface), 0); + vertexIndexRef.second) { + vertexIndexRef.first->second = vertices.size(); - vertices.emplace_back(geoData->point(v), geoData->normal(v), - surface ? surface->colorBias : openSurface); - } - }); - }); - std::for_each( - geoData->faces_sbegin(), geoData->faces_end(), [this, &vertexIndex, &indices](const GeoData::FaceHandle f) { - std::transform(geoData->fv_begin(f), geoData->fv_end(f), std::back_inserter(indices), - [&vertexIndex, f, this](const GeoData::VertexHandle v) { - return vertexIndex[std::make_pair(v, geoData->getSurface(f))]; - }); - }); + vertices.emplace_back(point(vertex), normal(vertex), surface ? surface->colorBias : OPEN_SURFACE); + } + }); + }); + std::ranges::for_each(faces(), [this, &vertexIndex, &indices](const auto face) { + std::ranges::transform( + fv_range(face), std::back_inserter(indices), [&vertexIndex, face, this](const auto vertex) { + return vertexIndex[std::make_pair(vertex, getSurface(face))]; + }); + }); meshes.create<MeshT<Vertex>>(vertices, indices); } void Terrain::tick(TickDuration) { - if (const auto newGeneration = geoData->getGeneration(); newGeneration != geoGeneration) { + if (const auto newGeneration = getGeneration(); newGeneration != geoGeneration) { generateMeshes(); geoGeneration = newGeneration; } @@ -77,9 +67,7 @@ Terrain::render(const SceneShader & shader) const { shader.landmass.use(); grass->bind(); - // glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); meshes.apply(&Mesh::Draw); - // glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } void diff --git a/game/terrain.h b/game/terrain.h index c9d09fe..7464bdd 100644 --- a/game/terrain.h +++ b/game/terrain.h @@ -4,17 +4,19 @@ #include "collection.h" #include "config/types.h" #include "game/worldobject.h" +#include "geoData.h" #include "gfx/models/mesh.h" #include "gfx/models/texture.h" #include "gfx/renderable.h" -#include <memory> class SceneShader; -class GeoData; -class Terrain : public WorldObject, public Renderable { +class Terrain : public GeoData, public WorldObject, public Renderable { public: - explicit Terrain(std::shared_ptr<GeoData>); + template<typename... P> explicit Terrain(P &&... params) : GeoData {std::forward<P>(params)...} + { + generateMeshes(); + } void render(const SceneShader & shader) const override; void shadows(const ShadowMapper &) const override; @@ -30,8 +32,7 @@ public: private: void generateMeshes(); - std::shared_ptr<GeoData> geoData; Collection<MeshT<Vertex>, false> meshes; - Texture::Ptr grass; + Texture::Ptr grass = std::make_shared<Texture>("grass.png"); size_t geoGeneration {}; }; diff --git a/test/test-geoData.cpp b/test/test-geoData.cpp index dbf5f29..4979327 100644 --- a/test/test-geoData.cpp +++ b/test/test-geoData.cpp @@ -244,15 +244,13 @@ BOOST_DATA_TEST_CASE(deform, loadFixtureJson<DeformTerrainData>("geoData/deform/ { Surface surface; surface.colorBias = RGB {0, 0, 1}; - auto gd = std::make_shared<GeoData>(GeoData::createFlat({0, 0}, {1000000, 1000000}, 100)); - BOOST_CHECK_NO_THROW(gd->setHeights(points, {.surface = &surface})); ApplicationBase ab; TestMainWindow tmw; TestRenderOutput tro {{640, 480}}; struct TestTerrain : public SceneProvider { - explicit TestTerrain(std::shared_ptr<GeoData> gd) : terrain(std::move(gd)) { } + explicit TestTerrain(GeoData gd) : terrain(std::move(gd)) { } const Terrain terrain; @@ -281,7 +279,11 @@ BOOST_DATA_TEST_CASE(deform, loadFixtureJson<DeformTerrainData>("geoData/deform/ } }; - TestTerrain t {gd}; + TestTerrain t {[&points, &surface]() { + auto gd = GeoData::createFlat({0, 0}, {1000000, 1000000}, 100); + BOOST_CHECK_NO_THROW(gd.setHeights(points, {.surface = &surface})); + return gd; + }()}; SceneRenderer ss {tro.size, tro.output}; std::for_each(cams.begin(), cams.end(), [&ss, &t, &tro](const auto & cam) { ss.camera.setView(cam.first.first, glm::normalize(cam.first.second)); diff --git a/test/test-render.cpp b/test/test-render.cpp index 3966f28..3c453bd 100644 --- a/test/test-render.cpp +++ b/test/test-render.cpp @@ -30,11 +30,10 @@ class TestScene : public SceneProvider { RailVehicleClassPtr brush47rvc; std::shared_ptr<RailVehicle> train1, train2; RailLinks rail; - std::shared_ptr<GeoData> gd = std::make_shared<GeoData>(GeoData::createFlat({0, 0}, {1000000, 1000000}, 1)); std::shared_ptr<Environment> env = std::make_shared<Environment>(); - Terrain terrain {gd}; - Water water {gd}; + std::shared_ptr<Terrain> terrain = std::make_shared<Terrain>(GeoData::createFlat({0, 0}, {1000000, 1000000}, 1)); + Water water {terrain}; public: TestScene() @@ -71,7 +70,7 @@ public: void content(const SceneShader & shader) const override { - terrain.render(shader); + terrain->render(shader); water.render(shader); rail.render(shader); std::ranges::for_each(gameState->assets, [&shader](const auto & asset) { @@ -95,7 +94,7 @@ public: void shadows(const ShadowMapper & shadowMapper) const override { - terrain.shadows(shadowMapper); + terrain->shadows(shadowMapper); std::ranges::for_each(gameState->assets, [&shadowMapper](const auto & asset) { if (const auto renderable = std::dynamic_pointer_cast<const Renderable>(asset.second)) { renderable->shadows(shadowMapper); @@ -167,15 +166,14 @@ BOOST_AUTO_TEST_CASE(terrain) ss.camera.setView({310000000, 490000000, 600000}, glm::normalize(glm::vec3 {1, 1, -0.5F})); class TestTerrain : public SceneProvider { - std::shared_ptr<GeoData> gd - = std::make_shared<GeoData>(GeoData::loadFromAsciiGrid(FIXTURESDIR "height/SD19.asc")); - Terrain terrain {gd}; - Water water {gd}; + std::shared_ptr<Terrain> terrain + = std::make_shared<Terrain>(GeoData::loadFromAsciiGrid(FIXTURESDIR "height/SD19.asc")); + Water water {terrain}; void content(const SceneShader & shader) const override { - terrain.render(shader); + terrain->render(shader); water.render(shader); } @@ -194,7 +192,7 @@ BOOST_AUTO_TEST_CASE(terrain) void shadows(const ShadowMapper & shadowMapper) const override { - terrain.shadows(shadowMapper); + terrain->shadows(shadowMapper); } }; diff --git a/ui/editNetwork.cpp b/ui/editNetwork.cpp index 50d049d..c4c0297 100644 --- a/ui/editNetwork.cpp +++ b/ui/editNetwork.cpp @@ -4,7 +4,7 @@ #include "builders/straight.h" #include "text.h" #include <game/gamestate.h> -#include <game/geoData.h> +#include <game/terrain.h> #include <gfx/gl/sceneShader.h> #include <gfx/models/texture.h> @@ -26,7 +26,7 @@ bool EditNetwork::click(const SDL_MouseButtonEvent & e, const Ray<GlobalPosition3D> & ray) { if (builder && (e.button == SDL_BUTTON_LEFT || e.button == SDL_BUTTON_MIDDLE)) { - builder->click(network, gameState->geoData.get(), e, ray); + builder->click(network, gameState->terrain.get(), e, ray); return true; } return false; @@ -36,7 +36,7 @@ bool EditNetwork::move(const SDL_MouseMotionEvent & e, const Ray<GlobalPosition3D> & ray) { if (builder) { - builder->move(network, gameState->geoData.get(), e, ray); + builder->move(network, gameState->terrain.get(), e, ray); } return false; } @@ -70,7 +70,7 @@ EditNetwork::Builder::setHeightsFor(Network * network, const Link::CCollection & const auto width = network->getBaseWidth(); for (const auto & link : links) { - gameState->geoData->setHeights(link->getBase(width), opts); + gameState->terrain->setHeights(link->getBase(width), opts); } } diff --git a/ui/gameMainSelector.cpp b/ui/gameMainSelector.cpp index 5bef48d..e9642ec 100644 --- a/ui/gameMainSelector.cpp +++ b/ui/gameMainSelector.cpp @@ -4,8 +4,8 @@ #include "ui/uiComponent.h" #include <SDL2/SDL.h> #include <game/gamestate.h> -#include <game/geoData.h> #include <game/selectable.h> +#include <game/terrain.h> #include <game/worldobject.h> // IWYU pragma: keep #include <gfx/gl/camera.h> #include <optional> @@ -83,7 +83,7 @@ GameMainSelector::defaultClick(const Ray<GlobalPosition3D> & ray) const auto & ref = *selected.base()->get(); clicked = typeid(ref).name(); } - else if (const auto pos = gameState->geoData->intersectRay(ray)) { + else if (const auto pos = gameState->terrain->intersectRay(ray)) { clicked = streamed_string(*pos); } else { |