From 2842719a9d6f385852d90c0046b90e694be8f818 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Fri, 19 Jan 2024 02:10:39 +0000 Subject: Add rail network render test --- test/test-render.cpp | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/test/test-render.cpp b/test/test-render.cpp index 41731dd..19261fe 100644 --- a/test/test-render.cpp +++ b/test/test-render.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -158,4 +159,46 @@ BOOST_AUTO_TEST_CASE(terrain) Texture::save(outImage, "/tmp/terrain.tga"); } +BOOST_AUTO_TEST_CASE(railnet) +{ + SceneRenderer ss {size, output}; + ss.camera.setView({0, 0, 10000}, glm::normalize(glm::vec3 {1, 1, -0.5F})); + + class TestRail : public SceneProvider { + RailLinks net; + + public: + TestRail() + { + net.addLinksBetween({10000, 10000, 0}, {100000, 100000, 0}); + } + + void + content(const SceneShader & shader) const override + { + net.render(shader); + } + + void + environment(const SceneShader &, const SceneRenderer & sr) const override + { + sr.setAmbientLight({0.1, 0.1, 0.1}); + sr.setDirectionalLight({1, 1, 1}, south + down, *this); + } + + void + lights(const SceneShader &) const override + { + } + + void + shadows(const ShadowMapper &) const override + { + } + }; + + ss.render(TestRail {}); + Texture::save(outImage, "/tmp/railnet.tga"); +} + BOOST_AUTO_TEST_SUITE_END(); -- cgit v1.2.3 From 1e43d23ae40282ef9c4047c77b7994527ee95b38 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sat, 20 Jan 2024 12:57:55 +0000 Subject: Add mail rail network to render test, include curves --- test/test-render.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/test-render.cpp b/test/test-render.cpp index 19261fe..cc2bba2 100644 --- a/test/test-render.cpp +++ b/test/test-render.cpp @@ -170,7 +170,11 @@ BOOST_AUTO_TEST_CASE(railnet) public: TestRail() { - net.addLinksBetween({10000, 10000, 0}, {100000, 100000, 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 -- cgit v1.2.3 From a6e28fe377b41500d6ce3e0a9a4d6e6288d97f61 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Wed, 17 Jan 2024 01:08:54 +0000 Subject: Copy render vital link data to vertex buffer --- game/network/network.h | 13 ++++++++++--- game/network/network.impl.h | 40 ++++++++++++++++++++-------------------- game/network/rail.cpp | 31 ++++++++++++++++++++----------- game/network/rail.h | 26 +++++++++++++++++++++----- test/test-network.cpp | 40 ++++++++++++++++++++++++++-------------- 5 files changed, 97 insertions(+), 53 deletions(-) diff --git a/game/network/network.h b/game/network/network.h index fa311ac..12c006c 100644 --- a/game/network/network.h +++ b/game/network/network.h @@ -1,5 +1,6 @@ #pragma once +#include "gfx/gl/instanceVertices.h" #include "link.h" #include #include @@ -58,7 +59,13 @@ protected: std::shared_ptr texture; }; -template class NetworkOf : public Network, public Renderable { +template class NetworkLinkHolder { + friend LinkType; + mutable InstanceVertices vertices; +}; + +template +class NetworkOf : public Network, public Renderable, public NetworkLinkHolder... { protected: using Network::Network; @@ -75,7 +82,7 @@ public: requires std::is_base_of_v { const auto node1 = candidateNodeAt(a).first, node2 = candidateNodeAt(b).first; - return std::make_shared(node1, node2, std::forward(params)...); + return std::make_shared(*this, node1, node2, std::forward(params)...); } template @@ -84,7 +91,7 @@ public: requires std::is_base_of_v { const auto node1 = nodeAt(a), node2 = nodeAt(b); - auto l {links.template create(node1, node2, std::forward(params)...)}; + auto l {links.template create(*this, node1, node2, std::forward(params)...)}; joinLinks(l); return l; } diff --git a/game/network/network.impl.h b/game/network/network.impl.h index f9595ed..c1f079d 100644 --- a/game/network/network.impl.h +++ b/game/network/network.impl.h @@ -2,9 +2,9 @@ #include #include -template +template void -NetworkOf::render(const SceneShader & shader) const +NetworkOf::render(const SceneShader & shader) const { if constexpr (std::is_base_of_v) { shader.absolute.use(); @@ -13,18 +13,18 @@ NetworkOf::render(const SceneShader & shader) const } } -template +template void -NetworkOf::joinLinks(const Link::Ptr & l) const +NetworkOf::joinLinks(const Link::Ptr & l) const { for (const auto & ol : links.objects) { Network::joinLinks(l, ol); } } -template +template Link::Ptr -NetworkOf::intersectRayLinks(const Ray & ray) const +NetworkOf::intersectRayLinks(const Ray & ray) const { // Click link if (const auto link = std::find_if(links.objects.begin(), links.objects.end(), @@ -37,9 +37,9 @@ NetworkOf::intersectRayLinks(const Ray & ray) const return {}; } -template +template float -NetworkOf::findNodeDirection(Node::AnyCPtr n) const +NetworkOf::findNodeDirection(Node::AnyCPtr n) const { for (const auto & l : links.objects) { for (const auto & e : l->ends) { @@ -52,16 +52,16 @@ NetworkOf::findNodeDirection(Node::AnyCPtr n) const throw std::runtime_error("Node exists but couldn't find it"); } -template +template Link::CCollection -NetworkOf::candidateStraight(GlobalPosition3D n1, GlobalPosition3D n2) +NetworkOf::candidateStraight(GlobalPosition3D n1, GlobalPosition3D n2) { return {candidateLink(n1, n2)}; } -template +template Link::CCollection -NetworkOf::candidateJoins(GlobalPosition3D start, GlobalPosition3D end) +NetworkOf::candidateJoins(GlobalPosition3D start, GlobalPosition3D end) { if (glm::length(RelativePosition3D(start - end)) < 2000.F) { return {}; @@ -73,24 +73,24 @@ NetworkOf::candidateJoins(GlobalPosition3D start, GlobalPosition3D end) return {candidateLink(c1s, c1e, c1c), candidateLink(c2s, c2e, c2c)}; } -template +template Link::CCollection -NetworkOf::candidateExtend(GlobalPosition3D start, GlobalPosition3D end) +NetworkOf::candidateExtend(GlobalPosition3D start, GlobalPosition3D end) { const auto [cstart, cend, centre] = genCurveDef(start, end, findNodeDirection(candidateNodeAt(start).first)); return {candidateLink(cstart, cend, centre)}; } -template +template Link::CCollection -NetworkOf::addStraight(GlobalPosition3D n1, GlobalPosition3D n2) +NetworkOf::addStraight(GlobalPosition3D n1, GlobalPosition3D n2) { return {addLink(n1, n2)}; } -template +template Link::CCollection -NetworkOf::addJoins(GlobalPosition3D start, GlobalPosition3D end) +NetworkOf::addJoins(GlobalPosition3D start, GlobalPosition3D end) { if (glm::length(RelativePosition3D(start - end)) < 2000.F) { return {}; @@ -101,9 +101,9 @@ NetworkOf::addJoins(GlobalPosition3D start, GlobalPosition3D end) return {addLink(c1s, c1e, c1c), addLink(c2s, c2e, c2c)}; } -template +template Link::CCollection -NetworkOf::addExtend(GlobalPosition3D start, GlobalPosition3D end) +NetworkOf::addExtend(GlobalPosition3D start, GlobalPosition3D end) { const auto [cstart, cend, centre] = genCurveDef(start, end, findNodeDirection(nodeAt(start))); return {addLink(cstart, cend, centre)}; diff --git a/game/network/rail.cpp b/game/network/rail.cpp index 79aaf97..3d29ea5 100644 --- a/game/network/rail.cpp +++ b/game/network/rail.cpp @@ -13,12 +13,12 @@ #include #include -template class NetworkOf; +template class NetworkOf; constexpr auto RAIL_CROSSSECTION_VERTICES {5U}; constexpr Size3D RAIL_HEIGHT {0, 0, 250.F}; -RailLinks::RailLinks() : NetworkOf {"rails.jpg"} { } +RailLinks::RailLinks() : NetworkOf {"rails.jpg"} { } void RailLinks::tick(TickDuration) @@ -117,15 +117,20 @@ round_sleepers(const float v) return round_frac(v, sleepers); } -RailLinkStraight::RailLinkStraight(const Node::Ptr & a, const Node::Ptr & b) : RailLinkStraight(a, b, b->pos - a->pos) +RailLinkStraight::RailLinkStraight( + NetworkLinkHolder & instances, const Node::Ptr & a, const Node::Ptr & b) : + RailLinkStraight(instances, a, b, b->pos - a->pos) { } -RailLinkStraight::RailLinkStraight(Node::Ptr a, Node::Ptr b, const RelativePosition3D & diff) : - Link({std::move(a), vector_yaw(diff)}, {std::move(b), vector_yaw(-diff)}, glm::length(diff)) +RailLinkStraight::RailLinkStraight( + NetworkLinkHolder & instances, Node::Ptr a, Node::Ptr b, const RelativePosition3D & diff) : + Link({std::move(a), vector_yaw(diff)}, {std::move(b), vector_yaw(-diff)}, glm::length(diff)), + instance {instances.vertices.acquire( + ends[0].node->pos, ends[1].node->pos, flat_orientation(diff), round_sleepers(length / 2.F))} { if (glGenVertexArrays) { - std::vector vertices; + std::vector<::Vertex> vertices; vertices.reserve(2 * railCrossSection.size()); const auto len = round_sleepers(length / 2000.F); const glm::mat3 trans {flat_orientation(diff)}; @@ -139,15 +144,19 @@ RailLinkStraight::RailLinkStraight(Node::Ptr a, Node::Ptr b, const RelativePosit } } -RailLinkCurve::RailLinkCurve(const Node::Ptr & a, const Node::Ptr & b, GlobalPosition2D c) : - RailLinkCurve(a, b, c || a->pos.z, {c || 0, a->pos, b->pos}) +RailLinkCurve::RailLinkCurve( + NetworkLinkHolder & instances, const Node::Ptr & a, const Node::Ptr & b, GlobalPosition2D c) : + RailLinkCurve(instances, a, b, c || a->pos.z, {c || 0, a->pos, b->pos}) { } -RailLinkCurve::RailLinkCurve(const Node::Ptr & a, const Node::Ptr & b, GlobalPosition3D c, const Arc arc) : +RailLinkCurve::RailLinkCurve(NetworkLinkHolder & instances, const Node::Ptr & a, const Node::Ptr & b, + GlobalPosition3D c, const Arc arc) : Link({a, normalize(arc.first + half_pi)}, {b, normalize(arc.second - half_pi)}, glm::length(RelativePosition3D(a->pos - c)) * arc_length(arc)), - LinkCurve {c, glm::length(RelativePosition3D(ends[0].node->pos - c)), arc} + LinkCurve {c, glm::length(RelativePosition3D(ends[0].node->pos - c)), arc}, + instance {instances.vertices.acquire(ends[0].node->pos, ends[1].node->pos, c, round_sleepers(length / 2.F))} + { if (glGenVertexArrays) { const auto & e0p {ends[0].node->pos}; @@ -157,7 +166,7 @@ RailLinkCurve::RailLinkCurve(const Node::Ptr & a, const Node::Ptr & b, GlobalPos const auto step {RelativePosition3D {arc_length(arc), e1p.z - e0p.z, slength / 1000.F} / segs}; auto segCount = static_cast(std::lround(segs)) + 1; - std::vector vertices; + std::vector<::Vertex> vertices; vertices.reserve(segCount * railCrossSection.size()); for (RelativePosition3D swing = {arc.first, centreBase.z - e0p.z, 0.F}; segCount; swing += step, --segCount) { const auto t { diff --git a/game/network/rail.h b/game/network/rail.h index 986b0aa..e06568f 100644 --- a/game/network/rail.h +++ b/game/network/rail.h @@ -40,23 +40,39 @@ protected: RailLink::~RailLink() = default; +class RailLinks; + class RailLinkStraight : public RailLink, public LinkStraight { public: - RailLinkStraight(const Node::Ptr &, const Node::Ptr &); + RailLinkStraight(NetworkLinkHolder &, const Node::Ptr &, const Node::Ptr &); + + struct Vertex { + GlobalPosition3D a, b; + glm::mat2 rotation; + float textureRepeats; + }; private: - RailLinkStraight(Node::Ptr, Node::Ptr, const RelativePosition3D & diff); + RailLinkStraight(NetworkLinkHolder &, Node::Ptr, Node::Ptr, const RelativePosition3D & diff); + InstanceVertices::InstanceProxy instance; }; class RailLinkCurve : public RailLink, public LinkCurve { public: - RailLinkCurve(const Node::Ptr &, const Node::Ptr &, GlobalPosition2D); + RailLinkCurve(NetworkLinkHolder &, const Node::Ptr &, const Node::Ptr &, GlobalPosition2D); + + struct Vertex { + GlobalPosition3D a, b, c; + float textureRepeats; + }; private: - RailLinkCurve(const Node::Ptr &, const Node::Ptr &, GlobalPosition3D, const Arc); + RailLinkCurve( + NetworkLinkHolder &, const Node::Ptr &, const Node::Ptr &, GlobalPosition3D, const Arc); + InstanceVertices::InstanceProxy instance; }; -class RailLinks : public NetworkOf, public WorldObject { +class RailLinks : public NetworkOf, public WorldObject { public: RailLinks(); diff --git a/test/test-network.cpp b/test/test-network.cpp index 0274b00..dbc184d 100644 --- a/test/test-network.cpp +++ b/test/test-network.cpp @@ -23,25 +23,37 @@ BOOST_GLOBAL_FIXTURE(ApplicationBase); BOOST_GLOBAL_FIXTURE(TestMainWindow); -struct TestLink : public LinkStraight { - TestLink(const Node::Ptr & a, const Node::Ptr & b) : TestLink {a, b, (a->pos - b->pos)} { } +struct TestLinkS; - TestLink(Node::Ptr a, Node::Ptr b, RelativePosition2D l) : +struct TestLink : public virtual Link { + using StraightLink = TestLinkS; + using CurveLink = TestLinkS; +}; + +struct TestLinkS : public TestLink, public LinkStraight { + TestLinkS(NetworkLinkHolder & network, const Node::Ptr & a, const Node::Ptr & b) : + TestLinkS {network, a, b, (a->pos - b->pos)} + { + } + + TestLinkS(NetworkLinkHolder &, Node::Ptr a, Node::Ptr b, RelativePosition2D l) : Link {{std::move(a), 0}, {std::move(b), pi}, glm::length(l)} { } - TestLink(Node::Ptr a, Node::Ptr b, float l) : Link {{std::move(a), 0}, {std::move(b), pi}, l} { } + struct Vertex { }; - using StraightLink = TestLink; - using CurveLink = TestLink; + TestLinkS(NetworkLinkHolder &, Node::Ptr a, Node::Ptr b, float l) : + Link {{std::move(a), 0}, {std::move(b), pi}, l} + { + } }; constexpr GlobalPosition3D p000 {0, 0, 0}, p100 {10000, 0, 0}, p200 {20000, 0, 0}, p300 {30000, 0, 0}; constexpr GlobalPosition3D p110 {10000, 10000, 0}; -struct TestNetwork : public NetworkOf { - TestNetwork() : NetworkOf {RESDIR "rails.jpg"} +struct TestNetwork : public NetworkOf { + TestNetwork() : NetworkOf {RESDIR "rails.jpg"} { // 0 1 2 // p000 <-> p100 <-> p200 <-> p300 @@ -49,12 +61,12 @@ struct TestNetwork : public NetworkOf { // \ 5 / // 3 | 4 // \-> p110 <-/ - addLink(p000, p100, 1.F); - addLink(p100, p200, 1.F); - addLink(p200, p300, 1.F); - addLink(p000, p110, 2.F); - addLink(p200, p110, 2.F); - addLink(p100, p110, 1.F); + addLink(p000, p100, 1.F); + addLink(p100, p200, 1.F); + addLink(p200, p300, 1.F); + addLink(p000, p110, 2.F); + addLink(p200, p110, 2.F); + addLink(p100, p110, 1.F); } }; -- cgit v1.2.3 From c7af64b7061c59c987958d0830838f1c05caeb29 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Fri, 19 Jan 2024 00:23:56 +0000 Subject: Render rail network using new shaders Non-functional, totally unimplemented at this stage --- game/network/network.h | 3 +-- game/network/network.impl.h | 11 ----------- game/network/rail.cpp | 22 ++++++++++++++++++++-- game/network/rail.h | 1 + gfx/gl/sceneShader.cpp | 17 ++++++++++++----- gfx/gl/sceneShader.h | 1 + gfx/gl/shaders/network.fs | 6 ++++++ gfx/gl/shaders/networkCurve.gs | 9 +++++++++ gfx/gl/shaders/networkCurve.vs | 20 ++++++++++++++++++++ gfx/gl/shaders/networkStraight.gs | 15 +++++++++++++++ gfx/gl/shaders/networkStraight.vs | 20 ++++++++++++++++++++ test/test-network.cpp | 5 +++++ 12 files changed, 110 insertions(+), 20 deletions(-) create mode 100644 gfx/gl/shaders/network.fs create mode 100644 gfx/gl/shaders/networkCurve.gs create mode 100644 gfx/gl/shaders/networkCurve.vs create mode 100644 gfx/gl/shaders/networkStraight.gs create mode 100644 gfx/gl/shaders/networkStraight.vs diff --git a/game/network/network.h b/game/network/network.h index 12c006c..49322f9 100644 --- a/game/network/network.h +++ b/game/network/network.h @@ -60,6 +60,7 @@ protected: }; template class NetworkLinkHolder { +protected: friend LinkType; mutable InstanceVertices vertices; }; @@ -105,8 +106,6 @@ public: [[nodiscard]] float findNodeDirection(Node::AnyCPtr) const override; - void render(const SceneShader &) const override; - protected: Link::CCollection addJoins(); }; diff --git a/game/network/network.impl.h b/game/network/network.impl.h index c1f079d..ff29088 100644 --- a/game/network/network.impl.h +++ b/game/network/network.impl.h @@ -2,17 +2,6 @@ #include #include -template -void -NetworkOf::render(const SceneShader & shader) const -{ - if constexpr (std::is_base_of_v) { - shader.absolute.use(); - texture->bind(); - links.apply(&Renderable::render, shader); - } -} - template void NetworkOf::joinLinks(const Link::Ptr & l) const diff --git a/game/network/rail.cpp b/game/network/rail.cpp index 3d29ea5..9766851 100644 --- a/game/network/rail.cpp +++ b/game/network/rail.cpp @@ -127,7 +127,7 @@ RailLinkStraight::RailLinkStraight( NetworkLinkHolder & instances, Node::Ptr a, Node::Ptr b, const RelativePosition3D & diff) : Link({std::move(a), vector_yaw(diff)}, {std::move(b), vector_yaw(-diff)}, glm::length(diff)), instance {instances.vertices.acquire( - ends[0].node->pos, ends[1].node->pos, flat_orientation(diff), round_sleepers(length / 2.F))} + ends[0].node->pos, ends[1].node->pos, flat_orientation(diff), round_sleepers(length / 2000.F))} { if (glGenVertexArrays) { std::vector<::Vertex> vertices; @@ -155,7 +155,7 @@ RailLinkCurve::RailLinkCurve(NetworkLinkHolder & instances, const Link({a, normalize(arc.first + half_pi)}, {b, normalize(arc.second - half_pi)}, glm::length(RelativePosition3D(a->pos - c)) * arc_length(arc)), LinkCurve {c, glm::length(RelativePosition3D(ends[0].node->pos - c)), arc}, - instance {instances.vertices.acquire(ends[0].node->pos, ends[1].node->pos, c, round_sleepers(length / 2.F))} + instance {instances.vertices.acquire(ends[0].node->pos, ends[1].node->pos, c, round_sleepers(length / 2000.F))} { if (glGenVertexArrays) { @@ -185,3 +185,21 @@ RailLink::vehiclePositionOffset() const { return RAIL_HEIGHT; } + +void +RailLinks::render(const SceneShader & shader) const +{ + auto renderType = [](auto & v, auto & s) { + if (auto count = v.size()) { + s.use(); + glBindBuffer(GL_VERTEX_ARRAY, v.bufferName()); + glDrawArrays(GL_POINTS, 0, static_cast(count)); + } + }; + if (!links.objects.empty()) { + texture->bind(); + renderType(NetworkLinkHolder::vertices, shader.networkStraight); + renderType(NetworkLinkHolder::vertices, shader.networkCurve); + glBindBuffer(GL_VERTEX_ARRAY, 0); + } +} diff --git a/game/network/rail.h b/game/network/rail.h index e06568f..5191b90 100644 --- a/game/network/rail.h +++ b/game/network/rail.h @@ -77,6 +77,7 @@ public: RailLinks(); std::shared_ptr addLinksBetween(GlobalPosition3D start, GlobalPosition3D end); + void render(const SceneShader &) const override; private: void tick(TickDuration elapsed) override; diff --git a/gfx/gl/sceneShader.cpp b/gfx/gl/sceneShader.cpp index 1b3b27c..146e642 100644 --- a/gfx/gl/sceneShader.cpp +++ b/gfx/gl/sceneShader.cpp @@ -1,14 +1,19 @@ #include "sceneShader.h" #include #include +#include #include #include #include +#include +#include #include #include #include #include #include +#include +#include #include #include #include @@ -21,15 +26,17 @@ SceneShader::SceneShader() : basicInst {dynamicPointInst_vs, material_fs}, landmass {fixedPoint_vs, landmass_fs}, absolute {fixedPoint_vs, material_fs}, spotLightInst {spotLight_vs, spotLight_gs, spotLight_fs}, - pointLightInst {pointLight_vs, pointLight_gs, pointLight_fs} + pointLightInst {pointLight_vs, pointLight_gs, pointLight_fs}, + networkStraight {networkStraight_vs, networkStraight_gs, network_fs}, + networkCurve {networkCurve_vs, networkCurve_gs, network_fs} { } void SceneShader::setViewProjection(const GlobalPosition3D & viewPoint, const glm::mat4 & viewProjection) const { - for (const auto & prog : std::initializer_list { - &basic, &basicInst, &water, &landmass, &absolute, &pointLightInst, &spotLightInst}) { + for (const auto & prog : std::initializer_list {&basic, &basicInst, &water, &landmass, + &absolute, &pointLightInst, &spotLightInst, &networkStraight, &networkCurve}) { prog->setViewProjection(viewPoint, viewProjection); } } @@ -37,8 +44,8 @@ SceneShader::setViewProjection(const GlobalPosition3D & viewPoint, const glm::ma void SceneShader::setViewPort(const ViewPort & viewPort) const { - for (const auto & prog : std::initializer_list { - &basic, &basicInst, &water, &landmass, &absolute, &pointLightInst, &spotLightInst}) { + for (const auto & prog : std::initializer_list {&basic, &basicInst, &water, &landmass, + &absolute, &pointLightInst, &spotLightInst, &networkStraight, &networkCurve}) { prog->setViewPort(viewPort); } } diff --git a/gfx/gl/sceneShader.h b/gfx/gl/sceneShader.h index 813c1bf..c86d157 100644 --- a/gfx/gl/sceneShader.h +++ b/gfx/gl/sceneShader.h @@ -57,6 +57,7 @@ public: BasicProgram basic; WaterProgram water; AbsolutePosProgram basicInst, landmass, absolute, spotLightInst, pointLightInst; + AbsolutePosProgram networkStraight, networkCurve; void setViewProjection(const GlobalPosition3D & viewPoint, const glm::mat4 & viewProjection) const; void setViewPort(const ViewPort & viewPort) const; diff --git a/gfx/gl/shaders/network.fs b/gfx/gl/shaders/network.fs new file mode 100644 index 0000000..d427da2 --- /dev/null +++ b/gfx/gl/shaders/network.fs @@ -0,0 +1,6 @@ +#version 330 core + +void +main() +{ +} diff --git a/gfx/gl/shaders/networkCurve.gs b/gfx/gl/shaders/networkCurve.gs new file mode 100644 index 0000000..cf70b6e --- /dev/null +++ b/gfx/gl/shaders/networkCurve.gs @@ -0,0 +1,9 @@ +#version 330 core + +layout(points) in; +layout(triangle_strip, max_vertices = 255) out; + +void +main() +{ +} diff --git a/gfx/gl/shaders/networkCurve.vs b/gfx/gl/shaders/networkCurve.vs new file mode 100644 index 0000000..b4324d6 --- /dev/null +++ b/gfx/gl/shaders/networkCurve.vs @@ -0,0 +1,20 @@ +#version 330 core + +layout(location = 0) in ivec3 v_apos; +layout(location = 1) in ivec3 v_bpos; +layout(location = 2) in ivec3 v_centre; +layout(location = 3) in float v_reps; + +uniform mat4 viewProjection; + +flat out ivec3 apos; +flat out ivec3 bpos; +flat out mat2 rot; +flat out float reps; +flat out float dist; + +void +main() +{ + dist = viewProjection[0][0]; +} diff --git a/gfx/gl/shaders/networkStraight.gs b/gfx/gl/shaders/networkStraight.gs new file mode 100644 index 0000000..c2bfe3f --- /dev/null +++ b/gfx/gl/shaders/networkStraight.gs @@ -0,0 +1,15 @@ +#version 330 core + +flat in ivec3 apos[]; +flat in ivec3 bpos[]; +flat in mat2 rot[]; +flat in float reps[]; +flat in float dist[]; + +layout(points) in; +layout(triangle_strip, max_vertices = 20) out; + +void +main() +{ +} diff --git a/gfx/gl/shaders/networkStraight.vs b/gfx/gl/shaders/networkStraight.vs new file mode 100644 index 0000000..025ae8f --- /dev/null +++ b/gfx/gl/shaders/networkStraight.vs @@ -0,0 +1,20 @@ +#version 330 core + +layout(location = 0) in ivec3 v_apos; +layout(location = 1) in ivec3 v_bpos; +layout(location = 2) in mat2 v_rot; +layout(location = 4) in float v_reps; + +uniform mat4 viewProjection; + +flat out ivec3 apos; +flat out ivec3 bpos; +flat out mat2 rot; +flat out float reps; +flat out float dist; + +void +main() +{ + dist = viewProjection[0][0]; +} diff --git a/test/test-network.cpp b/test/test-network.cpp index dbc184d..df61b94 100644 --- a/test/test-network.cpp +++ b/test/test-network.cpp @@ -68,6 +68,11 @@ struct TestNetwork : public NetworkOf { addLink(p200, p110, 2.F); addLink(p100, p110, 1.F); } + + void + render(const SceneShader &) const override + { + } }; const auto VALID_NODES = boost::unit_test::data::make({ -- cgit v1.2.3 From 538af692b66e67dfa4f347cc9ddd784a36f9a991 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sat, 20 Jan 2024 01:23:53 +0000 Subject: Update network with vertex array --- game/network/network.h | 5 ++++- game/network/rail.cpp | 37 +++++++++++++++++++++++++++++-------- game/network/rail.h | 3 +++ test/test-network.cpp | 2 ++ 4 files changed, 38 insertions(+), 9 deletions(-) diff --git a/game/network/network.h b/game/network/network.h index 49322f9..5725360 100644 --- a/game/network/network.h +++ b/game/network/network.h @@ -60,8 +60,11 @@ protected: }; template class NetworkLinkHolder { -protected: +public: + // Implemented per LinkType to configure vao + NetworkLinkHolder(); friend LinkType; + glVertexArray vao; mutable InstanceVertices vertices; }; diff --git a/game/network/rail.cpp b/game/network/rail.cpp index 9766851..efe4e2d 100644 --- a/game/network/rail.cpp +++ b/game/network/rail.cpp @@ -186,20 +186,41 @@ RailLink::vehiclePositionOffset() const return RAIL_HEIGHT; } -void -RailLinks::render(const SceneShader & shader) const +template<> NetworkLinkHolder::NetworkLinkHolder() +{ + VertexArrayObject {vao} + .addAttribs( + vertices.bufferName()); +} + +template<> NetworkLinkHolder::NetworkLinkHolder() { - auto renderType = [](auto & v, auto & s) { - if (auto count = v.size()) { + VertexArrayObject {vao} + .addAttribs(vertices.bufferName()); +} + +namespace { + template + void + renderType(const NetworkLinkHolder & n, auto & s) + { + if (auto count = n.vertices.size()) { s.use(); - glBindBuffer(GL_VERTEX_ARRAY, v.bufferName()); + glBindVertexArray(n.vao); glDrawArrays(GL_POINTS, 0, static_cast(count)); } }; +} + +void +RailLinks::render(const SceneShader & shader) const +{ if (!links.objects.empty()) { texture->bind(); - renderType(NetworkLinkHolder::vertices, shader.networkStraight); - renderType(NetworkLinkHolder::vertices, shader.networkCurve); - glBindBuffer(GL_VERTEX_ARRAY, 0); + renderType(*this, shader.networkStraight); + renderType(*this, shader.networkCurve); + glBindVertexArray(0); } } diff --git a/game/network/rail.h b/game/network/rail.h index 5191b90..b6a9ebe 100644 --- a/game/network/rail.h +++ b/game/network/rail.h @@ -72,6 +72,9 @@ private: InstanceVertices::InstanceProxy instance; }; +template<> NetworkLinkHolder::NetworkLinkHolder(); +template<> NetworkLinkHolder::NetworkLinkHolder(); + class RailLinks : public NetworkOf, public WorldObject { public: RailLinks(); diff --git a/test/test-network.cpp b/test/test-network.cpp index df61b94..174e2a5 100644 --- a/test/test-network.cpp +++ b/test/test-network.cpp @@ -52,6 +52,8 @@ struct TestLinkS : public TestLink, public LinkStraight { constexpr GlobalPosition3D p000 {0, 0, 0}, p100 {10000, 0, 0}, p200 {20000, 0, 0}, p300 {30000, 0, 0}; constexpr GlobalPosition3D p110 {10000, 10000, 0}; +template<> NetworkLinkHolder::NetworkLinkHolder() = default; + struct TestNetwork : public NetworkOf { TestNetwork() : NetworkOf {RESDIR "rails.jpg"} { -- cgit v1.2.3 From 7f852de673bb687c5721c6a74367278f8ba62f56 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sat, 20 Jan 2024 12:05:53 +0000 Subject: Implement complete network straight part shader --- gfx/gl/shaders/network.fs | 11 +++++++++++ gfx/gl/shaders/networkStraight.gs | 38 +++++++++++++++++++++++++++++++++++++- gfx/gl/shaders/networkStraight.vs | 8 ++++++-- 3 files changed, 54 insertions(+), 3 deletions(-) diff --git a/gfx/gl/shaders/network.fs b/gfx/gl/shaders/network.fs index d427da2..e7d15b3 100644 --- a/gfx/gl/shaders/network.fs +++ b/gfx/gl/shaders/network.fs @@ -1,6 +1,17 @@ #version 330 core +#extension GL_ARB_shading_language_420pack : enable + +include(`materialOut.glsl') +in vec3 rposition; +in vec2 texCoord; + +layout(binding = 0) uniform sampler2D texture0; +uniform ivec3 viewPoint; void main() { + gPosition = ivec4(viewPoint + rposition, 0); + gNormal = vec4(0, 0, 1, 1); + gAlbedoSpec = texture(texture0, texCoord); } diff --git a/gfx/gl/shaders/networkStraight.gs b/gfx/gl/shaders/networkStraight.gs index c2bfe3f..ccd456a 100644 --- a/gfx/gl/shaders/networkStraight.gs +++ b/gfx/gl/shaders/networkStraight.gs @@ -1,5 +1,14 @@ #version 330 core +const float RAIL_HEIGHT = 250; +const vec3[] profile = vec3[]( // + vec3(-1900.F, 0.F, 0.F), // + vec3(-608.F, 0.F, RAIL_HEIGHT), // + vec3(0, 0.F, RAIL_HEIGHT * .7F), // + vec3(608.F, 0.F, RAIL_HEIGHT), // + vec3(1900.F, 0.F, 0.F)); +const float[profile.length()] texturePos = float[](0, 0.34, 0.5, 0.65, 1); + flat in ivec3 apos[]; flat in ivec3 bpos[]; flat in mat2 rot[]; @@ -7,9 +16,36 @@ flat in float reps[]; flat in float dist[]; layout(points) in; -layout(triangle_strip, max_vertices = 20) out; +layout(triangle_strip, max_vertices = 10) out; + +uniform mat4 viewProjection; +uniform ivec3 viewPoint; + +uniform int clipDistance = 5000000; +uniform int flatDistance = 1000000; + +out vec2 texCoord; +out vec3 rposition; + +void +doEnd(const ivec3 end, int v, float texY) +{ + rposition = vec3(rot[0] * profile[v].xy, profile[v].z); + ivec3 vpos = end + ivec3(rposition); + gl_Position = viewProjection * vec4(vpos - viewPoint, 1); + texCoord = vec2(texturePos[v], texY); + EmitVertex(); +} void main() { + if (dist[0] < clipDistance) { + int vstep = (dist[0] < flatDistance) ? 1 : profile.length() - 1; + for (int v = 0; v < profile.length(); v += vstep) { + doEnd(bpos[0], v, reps[0]); + doEnd(apos[0], v, 0); + } + EndPrimitive(); + } } diff --git a/gfx/gl/shaders/networkStraight.vs b/gfx/gl/shaders/networkStraight.vs index 025ae8f..a0fa437 100644 --- a/gfx/gl/shaders/networkStraight.vs +++ b/gfx/gl/shaders/networkStraight.vs @@ -5,7 +5,7 @@ layout(location = 1) in ivec3 v_bpos; layout(location = 2) in mat2 v_rot; layout(location = 4) in float v_reps; -uniform mat4 viewProjection; +uniform ivec3 viewPoint; flat out ivec3 apos; flat out ivec3 bpos; @@ -16,5 +16,9 @@ flat out float dist; void main() { - dist = viewProjection[0][0]; + apos = v_apos; + bpos = v_bpos; + rot = v_rot; + reps = v_reps; + dist = min(distance(viewPoint, v_apos), distance(viewPoint, v_bpos)); } -- cgit v1.2.3 From d1d1a4e349f18cd36406f75170dad87fbad2722a Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sat, 20 Jan 2024 13:00:49 +0000 Subject: Common code between straight/curve network geometry shaders --- gfx/gl/shaders/networkCommon.glsl | 41 +++++++++++++++++++++++++++++++++++++++ gfx/gl/shaders/networkCurve.gs | 10 ++++++++++ gfx/gl/shaders/networkCurve.vs | 10 +++++----- gfx/gl/shaders/networkStraight.gs | 38 ++---------------------------------- 4 files changed, 58 insertions(+), 41 deletions(-) create mode 100644 gfx/gl/shaders/networkCommon.glsl diff --git a/gfx/gl/shaders/networkCommon.glsl b/gfx/gl/shaders/networkCommon.glsl new file mode 100644 index 0000000..2639eb1 --- /dev/null +++ b/gfx/gl/shaders/networkCommon.glsl @@ -0,0 +1,41 @@ +const float RAIL_HEIGHT = 250; +const vec3[] profile = vec3[]( // + vec3(-1900.F, 0.F, 0.F), // + vec3(-608.F, 0.F, RAIL_HEIGHT), // + vec3(0, 0.F, RAIL_HEIGHT * .7F), // + vec3(608.F, 0.F, RAIL_HEIGHT), // + vec3(1900.F, 0.F, 0.F)); +const float[profile.length()] texturePos = float[](0, 0.34, 0.5, 0.65, 1); + +uniform mat4 viewProjection; +uniform ivec3 viewPoint; + +uniform float clipDistance = 5000000; +uniform float flatDistance = 1000000; + +out vec2 texCoord; +out vec3 rposition; + +void +doVertex(const ivec3 end, const int v, const float texY, const mat2 rot) +{ + rposition = vec3(rot * profile[v].xy, profile[v].z); + ivec3 vpos = end + ivec3(rposition); + gl_Position = viewProjection * vec4(vpos - viewPoint, 1); + texCoord = vec2(texturePos[v], texY); + EmitVertex(); +} + +void +doSeg(const float dist, const ivec3 apos, const ivec3 bpos, const float atexY, const float btexY, const mat2 arot, + const mat2 brot) +{ + if (dist < clipDistance) { + int vstep = (dist < flatDistance) ? 1 : profile.length() - 1; + for (int v = 0; v < profile.length(); v += vstep) { + doVertex(bpos, v, btexY, brot); + doVertex(apos, v, atexY, arot); + } + EndPrimitive(); + } +} diff --git a/gfx/gl/shaders/networkCurve.gs b/gfx/gl/shaders/networkCurve.gs index cf70b6e..c504df3 100644 --- a/gfx/gl/shaders/networkCurve.gs +++ b/gfx/gl/shaders/networkCurve.gs @@ -1,9 +1,19 @@ #version 330 core +flat in ivec3 apos[]; +flat in ivec3 bpos[]; +flat in ivec3 cpos[]; +flat in float reps[]; + layout(points) in; layout(triangle_strip, max_vertices = 255) out; +const mat2 rot = mat2(1); + +include(`networkCommon.glsl') + void main() { + doSeg(0, apos[0], bpos[0], 0.f, reps[0], rot, rot); } diff --git a/gfx/gl/shaders/networkCurve.vs b/gfx/gl/shaders/networkCurve.vs index b4324d6..d083765 100644 --- a/gfx/gl/shaders/networkCurve.vs +++ b/gfx/gl/shaders/networkCurve.vs @@ -5,16 +5,16 @@ layout(location = 1) in ivec3 v_bpos; layout(location = 2) in ivec3 v_centre; layout(location = 3) in float v_reps; -uniform mat4 viewProjection; - flat out ivec3 apos; flat out ivec3 bpos; -flat out mat2 rot; +flat out ivec3 cpos; flat out float reps; -flat out float dist; void main() { - dist = viewProjection[0][0]; + apos = v_apos; + bpos = v_bpos; + cpos = v_centre; + reps = v_reps; } diff --git a/gfx/gl/shaders/networkStraight.gs b/gfx/gl/shaders/networkStraight.gs index ccd456a..51df5fb 100644 --- a/gfx/gl/shaders/networkStraight.gs +++ b/gfx/gl/shaders/networkStraight.gs @@ -1,14 +1,5 @@ #version 330 core -const float RAIL_HEIGHT = 250; -const vec3[] profile = vec3[]( // - vec3(-1900.F, 0.F, 0.F), // - vec3(-608.F, 0.F, RAIL_HEIGHT), // - vec3(0, 0.F, RAIL_HEIGHT * .7F), // - vec3(608.F, 0.F, RAIL_HEIGHT), // - vec3(1900.F, 0.F, 0.F)); -const float[profile.length()] texturePos = float[](0, 0.34, 0.5, 0.65, 1); - flat in ivec3 apos[]; flat in ivec3 bpos[]; flat in mat2 rot[]; @@ -17,35 +8,10 @@ flat in float dist[]; layout(points) in; layout(triangle_strip, max_vertices = 10) out; - -uniform mat4 viewProjection; -uniform ivec3 viewPoint; - -uniform int clipDistance = 5000000; -uniform int flatDistance = 1000000; - -out vec2 texCoord; -out vec3 rposition; - -void -doEnd(const ivec3 end, int v, float texY) -{ - rposition = vec3(rot[0] * profile[v].xy, profile[v].z); - ivec3 vpos = end + ivec3(rposition); - gl_Position = viewProjection * vec4(vpos - viewPoint, 1); - texCoord = vec2(texturePos[v], texY); - EmitVertex(); -} +include(`networkCommon.glsl') void main() { - if (dist[0] < clipDistance) { - int vstep = (dist[0] < flatDistance) ? 1 : profile.length() - 1; - for (int v = 0; v < profile.length(); v += vstep) { - doEnd(bpos[0], v, reps[0]); - doEnd(apos[0], v, 0); - } - EndPrimitive(); - } + doSeg(dist[0], apos[0], bpos[0], 0.f, reps[0], rot[0], rot[0]); } -- cgit v1.2.3 From a19011b730ac6d770e3b42cde3a10961495a417d Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sat, 20 Jan 2024 20:10:12 +0000 Subject: Implement basic network curve part shader --- game/network/rail.cpp | 7 +++--- game/network/rail.h | 1 + gfx/gl/shaders/networkCommon.glsl | 45 ++++++++++++++++++++++----------------- gfx/gl/shaders/networkCurve.gs | 29 ++++++++++++++++++++++++- gfx/gl/shaders/networkCurve.vs | 6 ++++++ gfx/gl/shaders/networkStraight.vs | 6 +++--- 6 files changed, 68 insertions(+), 26 deletions(-) diff --git a/game/network/rail.cpp b/game/network/rail.cpp index efe4e2d..46c129b 100644 --- a/game/network/rail.cpp +++ b/game/network/rail.cpp @@ -155,8 +155,8 @@ RailLinkCurve::RailLinkCurve(NetworkLinkHolder & instances, const Link({a, normalize(arc.first + half_pi)}, {b, normalize(arc.second - half_pi)}, glm::length(RelativePosition3D(a->pos - c)) * arc_length(arc)), LinkCurve {c, glm::length(RelativePosition3D(ends[0].node->pos - c)), arc}, - instance {instances.vertices.acquire(ends[0].node->pos, ends[1].node->pos, c, round_sleepers(length / 2000.F))} - + instance {instances.vertices.acquire(ends[0].node->pos, ends[1].node->pos, c, round_sleepers(length / 2000.F), + half_pi - arc.first, half_pi - arc.second)} { if (glGenVertexArrays) { const auto & e0p {ends[0].node->pos}; @@ -198,7 +198,8 @@ template<> NetworkLinkHolder::NetworkLinkHolder() { VertexArrayObject {vao} .addAttribs(vertices.bufferName()); + &RailLinkCurve::Vertex::c, &RailLinkCurve::Vertex::textureRepeats, &RailLinkCurve::Vertex::aangle, + &RailLinkCurve::Vertex::bangle>(vertices.bufferName()); } namespace { diff --git a/game/network/rail.h b/game/network/rail.h index b6a9ebe..39dfdc9 100644 --- a/game/network/rail.h +++ b/game/network/rail.h @@ -64,6 +64,7 @@ public: struct Vertex { GlobalPosition3D a, b, c; float textureRepeats; + float aangle, bangle; }; private: diff --git a/gfx/gl/shaders/networkCommon.glsl b/gfx/gl/shaders/networkCommon.glsl index 2639eb1..e1811bc 100644 --- a/gfx/gl/shaders/networkCommon.glsl +++ b/gfx/gl/shaders/networkCommon.glsl @@ -16,26 +16,33 @@ uniform float flatDistance = 1000000; out vec2 texCoord; out vec3 rposition; -void -doVertex(const ivec3 end, const int v, const float texY, const mat2 rot) +float +segDist(const ivec3 a, const ivec3 b) { - rposition = vec3(rot * profile[v].xy, profile[v].z); - ivec3 vpos = end + ivec3(rposition); - gl_Position = viewProjection * vec4(vpos - viewPoint, 1); - texCoord = vec2(texturePos[v], texY); - EmitVertex(); + return min(distance(viewPoint, a), distance(viewPoint, b)); } -void -doSeg(const float dist, const ivec3 apos, const ivec3 bpos, const float atexY, const float btexY, const mat2 arot, - const mat2 brot) -{ - if (dist < clipDistance) { - int vstep = (dist < flatDistance) ? 1 : profile.length() - 1; - for (int v = 0; v < profile.length(); v += vstep) { - doVertex(bpos, v, btexY, brot); - doVertex(apos, v, atexY, arot); +ifelse( + TYPE, .gs, + // Begin: Geometry shader only function + void doVertex(const ivec3 end, const int v, const float texY, const mat2 rot) { + rposition = vec3(rot * profile[v].xy, profile[v].z); + ivec3 vpos = end + ivec3(rposition); + gl_Position = viewProjection * vec4(vpos - viewPoint, 1); + texCoord = vec2(texturePos[v], texY); + EmitVertex(); } - EndPrimitive(); - } -} + + void doSeg(const float dist, const ivec3 apos, const ivec3 bpos, const float atexY, const float btexY, + const mat2 arot, const mat2 brot) { + if (dist < clipDistance) { + int vstep = (dist < flatDistance) ? 1 : profile.length() - 1; + for (int v = 0; v < profile.length(); v += vstep) { + doVertex(bpos, v, btexY, brot); + doVertex(apos, v, atexY, arot); + } + EndPrimitive(); + } + } + // End: Geometry shader only function +) diff --git a/gfx/gl/shaders/networkCurve.gs b/gfx/gl/shaders/networkCurve.gs index c504df3..82d8c59 100644 --- a/gfx/gl/shaders/networkCurve.gs +++ b/gfx/gl/shaders/networkCurve.gs @@ -4,6 +4,8 @@ flat in ivec3 apos[]; flat in ivec3 bpos[]; flat in ivec3 cpos[]; flat in float reps[]; +flat in float aangle[]; +flat in float bangle[]; layout(points) in; layout(triangle_strip, max_vertices = 255) out; @@ -12,8 +14,33 @@ const mat2 rot = mat2(1); include(`networkCommon.glsl') +mat2 +getRot(float angle) +{ + return mat2(cos(angle), sin(angle), -sin(angle), cos(angle)); +} + void main() { - doSeg(0, apos[0], bpos[0], 0.f, reps[0], rot, rot); + float segs = floor(255 / (profile.length() * 2)); + float radius = distance(cpos[0], apos[0]); + vec3 arcstep = vec3((bangle[0] - aangle[0]), // angle + reps[0], // texture + (bpos[0].z - apos[0].z)) // height + / segs; + + ivec3 prevPos = apos[0]; + mat2 prevRot = getRot(aangle[0]); + float prevTex = 0; + for (vec3 arc = arcstep; arc.y < reps[0] - 0.01; arc += arcstep) { + mat2 rot = getRot(arc.x + aangle[0]); + ivec3 pos = cpos[0] + ivec3(rot * vec2(radius, 0), arc.z); + float tex = arc.y; + doSeg(segDist(prevPos, pos), pos, prevPos, tex, prevTex, rot, prevRot); + prevPos = pos; + prevRot = rot; + prevTex = tex; + } + doSeg(segDist(prevPos, bpos[0]), bpos[0], prevPos, reps[0], prevTex, getRot(bangle[0]), prevRot); } diff --git a/gfx/gl/shaders/networkCurve.vs b/gfx/gl/shaders/networkCurve.vs index d083765..6c56e93 100644 --- a/gfx/gl/shaders/networkCurve.vs +++ b/gfx/gl/shaders/networkCurve.vs @@ -4,11 +4,15 @@ layout(location = 0) in ivec3 v_apos; layout(location = 1) in ivec3 v_bpos; layout(location = 2) in ivec3 v_centre; layout(location = 3) in float v_reps; +layout(location = 4) in float v_aangle; +layout(location = 5) in float v_bangle; flat out ivec3 apos; flat out ivec3 bpos; flat out ivec3 cpos; flat out float reps; +flat out float aangle; +flat out float bangle; void main() @@ -17,4 +21,6 @@ main() bpos = v_bpos; cpos = v_centre; reps = v_reps; + aangle = v_aangle; + bangle = v_bangle; } diff --git a/gfx/gl/shaders/networkStraight.vs b/gfx/gl/shaders/networkStraight.vs index a0fa437..55f9c4f 100644 --- a/gfx/gl/shaders/networkStraight.vs +++ b/gfx/gl/shaders/networkStraight.vs @@ -5,14 +5,14 @@ layout(location = 1) in ivec3 v_bpos; layout(location = 2) in mat2 v_rot; layout(location = 4) in float v_reps; -uniform ivec3 viewPoint; - flat out ivec3 apos; flat out ivec3 bpos; flat out mat2 rot; flat out float reps; flat out float dist; +include(`networkCommon.glsl') + void main() { @@ -20,5 +20,5 @@ main() bpos = v_bpos; rot = v_rot; reps = v_reps; - dist = min(distance(viewPoint, v_apos), distance(viewPoint, v_bpos)); + dist = segDist(v_apos, v_bpos); } -- cgit v1.2.3 From 35a9f035963458156c719dc16f4073b8244d66eb Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sat, 20 Jan 2024 23:27:01 +0000 Subject: Pass curve link radius, no recalculate, its constant --- game/network/rail.cpp | 4 ++-- game/network/rail.h | 2 +- gfx/gl/shaders/networkCurve.gs | 4 ++-- gfx/gl/shaders/networkCurve.vs | 3 +++ 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/game/network/rail.cpp b/game/network/rail.cpp index 46c129b..b500006 100644 --- a/game/network/rail.cpp +++ b/game/network/rail.cpp @@ -156,7 +156,7 @@ RailLinkCurve::RailLinkCurve(NetworkLinkHolder & instances, const glm::length(RelativePosition3D(a->pos - c)) * arc_length(arc)), LinkCurve {c, glm::length(RelativePosition3D(ends[0].node->pos - c)), arc}, instance {instances.vertices.acquire(ends[0].node->pos, ends[1].node->pos, c, round_sleepers(length / 2000.F), - half_pi - arc.first, half_pi - arc.second)} + half_pi - arc.first, half_pi - arc.second, radius)} { if (glGenVertexArrays) { const auto & e0p {ends[0].node->pos}; @@ -199,7 +199,7 @@ template<> NetworkLinkHolder::NetworkLinkHolder() VertexArrayObject {vao} .addAttribs(vertices.bufferName()); + &RailLinkCurve::Vertex::bangle, &RailLinkCurve::Vertex::radius>(vertices.bufferName()); } namespace { diff --git a/game/network/rail.h b/game/network/rail.h index 39dfdc9..a95ba04 100644 --- a/game/network/rail.h +++ b/game/network/rail.h @@ -64,7 +64,7 @@ public: struct Vertex { GlobalPosition3D a, b, c; float textureRepeats; - float aangle, bangle; + float aangle, bangle, radius; }; private: diff --git a/gfx/gl/shaders/networkCurve.gs b/gfx/gl/shaders/networkCurve.gs index 82d8c59..d373c0c 100644 --- a/gfx/gl/shaders/networkCurve.gs +++ b/gfx/gl/shaders/networkCurve.gs @@ -6,6 +6,7 @@ flat in ivec3 cpos[]; flat in float reps[]; flat in float aangle[]; flat in float bangle[]; +flat in float radius[]; layout(points) in; layout(triangle_strip, max_vertices = 255) out; @@ -24,7 +25,6 @@ void main() { float segs = floor(255 / (profile.length() * 2)); - float radius = distance(cpos[0], apos[0]); vec3 arcstep = vec3((bangle[0] - aangle[0]), // angle reps[0], // texture (bpos[0].z - apos[0].z)) // height @@ -35,7 +35,7 @@ main() float prevTex = 0; for (vec3 arc = arcstep; arc.y < reps[0] - 0.01; arc += arcstep) { mat2 rot = getRot(arc.x + aangle[0]); - ivec3 pos = cpos[0] + ivec3(rot * vec2(radius, 0), arc.z); + ivec3 pos = cpos[0] + ivec3(rot * vec2(radius[0], 0), arc.z); float tex = arc.y; doSeg(segDist(prevPos, pos), pos, prevPos, tex, prevTex, rot, prevRot); prevPos = pos; diff --git a/gfx/gl/shaders/networkCurve.vs b/gfx/gl/shaders/networkCurve.vs index 6c56e93..f51bb87 100644 --- a/gfx/gl/shaders/networkCurve.vs +++ b/gfx/gl/shaders/networkCurve.vs @@ -6,6 +6,7 @@ layout(location = 2) in ivec3 v_centre; layout(location = 3) in float v_reps; layout(location = 4) in float v_aangle; layout(location = 5) in float v_bangle; +layout(location = 6) in float v_radius; flat out ivec3 apos; flat out ivec3 bpos; @@ -13,6 +14,7 @@ flat out ivec3 cpos; flat out float reps; flat out float aangle; flat out float bangle; +flat out float radius; void main() @@ -23,4 +25,5 @@ main() reps = v_reps; aangle = v_aangle; bangle = v_bangle; + radius = v_radius; } -- cgit v1.2.3 From d392262db761f66b43589c7e7ce4accef4330154 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sun, 21 Jan 2024 01:31:16 +0000 Subject: Fix includes in test glCtxtBhvr --- test/test-glContextBhvr.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/test-glContextBhvr.cpp b/test/test-glContextBhvr.cpp index 26b45d9..ec5cc21 100644 --- a/test/test-glContextBhvr.cpp +++ b/test/test-glContextBhvr.cpp @@ -1,10 +1,9 @@ #define BOOST_TEST_MODULE test_glcontextbehaviour - -#include "testHelpers.h" #include #include #include +#include #include #include -- cgit v1.2.3 From d4ae68b6ba5211c7bc11a52951c466c5050ae377 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sun, 21 Jan 2024 01:34:10 +0000 Subject: String view/constexpr Shader instances Gonna need more constexpr stuff and strstr/strlen aren't that --- gfx/gl/shader.cpp | 5 ++++- gfx/gl/shader.h | 6 ++---- lib/embed-glsl.cpp.m4 | 9 +++------ lib/strlen.h | 14 -------------- 4 files changed, 9 insertions(+), 25 deletions(-) delete mode 100644 lib/strlen.h diff --git a/gfx/gl/shader.cpp b/gfx/gl/shader.cpp index 5f83b83..285c2c3 100644 --- a/gfx/gl/shader.cpp +++ b/gfx/gl/shader.cpp @@ -7,7 +7,10 @@ Shader::ShaderRef Shader::compile() const { ShaderRef shader {type}; - glShaderSource(shader, 1, &text, &len); + auto source = [&shader](auto text, GLint len) { + glShaderSource(shader, 1, &text, &len); + }; + source(text.data(), static_cast(text.length())); glCompileShader(shader); CheckShaderError(shader, GL_COMPILE_STATUS, false, "Error compiling shader!"); diff --git a/gfx/gl/shader.h b/gfx/gl/shader.h index cff2281..cc1bbc0 100644 --- a/gfx/gl/shader.h +++ b/gfx/gl/shader.h @@ -2,20 +2,18 @@ #include #include -#include #include class Shader { public: using ShaderRef = glRef; - constexpr Shader(const GLchar * text, GLint len, GLuint type) : text {text}, len {len}, type {type} { } + constexpr Shader(const GLchar * text, GLuint type) : text {text}, type {type} { } [[nodiscard]] ShaderRef compile() const; static void CheckShaderError(GLuint shader, GLuint flag, bool isProgram, std::string_view errorMessage); private: - const GLchar * text; - GLint len; + const std::basic_string_view text; GLuint type; }; diff --git a/lib/embed-glsl.cpp.m4 b/lib/embed-glsl.cpp.m4 index 60fb56b..9fe0b41 100644 --- a/lib/embed-glsl.cpp.m4 +++ b/lib/embed-glsl.cpp.m4 @@ -1,12 +1,9 @@ changecom() dnl // NAME #include "gfx/gl/shader.h" -#include "lib/strlen.h" #include "substr(TYPE,1)-NAME.h" #include - constexpr const GLchar * src {R"GLSL-EMBED(dnl -include(SOURCE))GLSL-EMBED"}; -constexpr auto len {constexpr_strlen(src)}; - -const Shader NAME`_'substr(TYPE,1) { src, len, GLTYPE }; +constexpr Shader NAME`_'substr(TYPE,1) { + R"GLSL-EMBED(dnl + include(SOURCE))GLSL-EMBED", GLTYPE }; diff --git a/lib/strlen.h b/lib/strlen.h deleted file mode 100644 index 2090d25..0000000 --- a/lib/strlen.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include -#include - -constexpr auto -constexpr_strlen(const GLchar * const s) -{ - std::size_t ch {}; - while (s[ch]) { - ch++; - } - return ch; -} -- cgit v1.2.3 From 28c23d2f55b7c8036a348849f90abe133c2226b8 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sun, 21 Jan 2024 02:33:02 +0000 Subject: Include ctre submodule --- .gitmodules | 3 +++ thirdparty/ctre | 1 + 2 files changed, 4 insertions(+) create mode 160000 thirdparty/ctre diff --git a/.gitmodules b/.gitmodules index 0ce5431..6332369 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "thirdparty/glad"] path = thirdparty/glad url = https://github.com/Dav1dde/glad +[submodule "thirdparty/ctre"] + path = thirdparty/ctre + url = https://github.com/hanickadot/compile-time-regular-expressions diff --git a/thirdparty/ctre b/thirdparty/ctre new file mode 160000 index 0000000..b3d7788 --- /dev/null +++ b/thirdparty/ctre @@ -0,0 +1 @@ +Subproject commit b3d7788b559e34d985c8530c3e0e7260b67505a6 -- cgit v1.2.3 From 979c226bdcd7904db5bd23dfbf526de4c040f436 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sun, 21 Jan 2024 02:39:30 +0000 Subject: Look for and replace GL_XXX with fixed string --- gfx/gl/shader.cpp | 11 ++++++++++- gfx/gl/shader.h | 7 ++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/gfx/gl/shader.cpp b/gfx/gl/shader.cpp index 285c2c3..b57dcd4 100644 --- a/gfx/gl/shader.cpp +++ b/gfx/gl/shader.cpp @@ -10,7 +10,16 @@ Shader::compile() const auto source = [&shader](auto text, GLint len) { glShaderSource(shader, 1, &text, &len); }; - source(text.data(), static_cast(text.length())); + if (lookups) { + std::basic_string textMod {text}; + for (const auto & match : ctre::range(textMod)) { + textMod.replace(match.begin(), match.end(), "255"); + } + source(textMod.c_str(), static_cast(textMod.length())); + } + else { + source(text.data(), static_cast(text.length())); + } glCompileShader(shader); CheckShaderError(shader, GL_COMPILE_STATUS, false, "Error compiling shader!"); diff --git a/gfx/gl/shader.h b/gfx/gl/shader.h index cc1bbc0..c6b45af 100644 --- a/gfx/gl/shader.h +++ b/gfx/gl/shader.h @@ -3,12 +3,16 @@ #include #include #include +#include class Shader { public: using ShaderRef = glRef; - constexpr Shader(const GLchar * text, GLuint type) : text {text}, type {type} { } + constexpr Shader(const GLchar * text, GLuint type) : + text {text}, type {type}, lookups {ctre::search(this->text)} + { + } [[nodiscard]] ShaderRef compile() const; static void CheckShaderError(GLuint shader, GLuint flag, bool isProgram, std::string_view errorMessage); @@ -16,4 +20,5 @@ public: private: const std::basic_string_view text; GLuint type; + bool lookups; }; -- cgit v1.2.3 From 2368cde54675f39e9b5a99880124503b3ae391e1 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sun, 21 Jan 2024 03:01:44 +0000 Subject: Replace tokens found with values from getIntegerv --- gfx/gl/shader.cpp | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/gfx/gl/shader.cpp b/gfx/gl/shader.cpp index b57dcd4..0f75817 100644 --- a/gfx/gl/shader.cpp +++ b/gfx/gl/shader.cpp @@ -1,8 +1,24 @@ #include "shader.h" +#include #include #include #include +namespace { + auto + getInt(GLenum e) + { + GLint i {}; + glGetIntegerv(e, &i); + return std::to_string(i); + } + + using LookUpFunction = std::string (*)(GLenum); + constexpr std::array, 1> LOOKUPS {{ + {"GL_MAX_GEOMETRY_OUTPUT_VERTICES", GL_MAX_GEOMETRY_OUTPUT_VERTICES, getInt}, + }}; +} + Shader::ShaderRef Shader::compile() const { @@ -13,7 +29,14 @@ Shader::compile() const if (lookups) { std::basic_string textMod {text}; for (const auto & match : ctre::range(textMod)) { - textMod.replace(match.begin(), match.end(), "255"); + if (const auto lookup = std::find_if(LOOKUPS.begin(), LOOKUPS.end(), + [&match](const auto & lookup) { + return std::get(lookup) == match; + }); + lookup != LOOKUPS.end()) { + const auto & [name, pname, getFunction] = *lookup; + textMod.replace(match.begin(), match.end(), getFunction(pname)); + } } source(textMod.c_str(), static_cast(textMod.length())); } -- cgit v1.2.3 From 7ce3368e918b085ef8894fb7aa68e36b07984b1d Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sun, 21 Jan 2024 03:04:57 +0000 Subject: Use symbol GL_MAX_GEOMETRY_OUTPUT_VERTICES to lookup the implementation limit at runtime --- gfx/gl/shaders/networkCurve.gs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gfx/gl/shaders/networkCurve.gs b/gfx/gl/shaders/networkCurve.gs index d373c0c..326e8b6 100644 --- a/gfx/gl/shaders/networkCurve.gs +++ b/gfx/gl/shaders/networkCurve.gs @@ -9,7 +9,7 @@ flat in float bangle[]; flat in float radius[]; layout(points) in; -layout(triangle_strip, max_vertices = 255) out; +layout(triangle_strip, max_vertices = GL_MAX_GEOMETRY_OUTPUT_VERTICES) out; const mat2 rot = mat2(1); @@ -24,7 +24,7 @@ getRot(float angle) void main() { - float segs = floor(255 / (profile.length() * 2)); + float segs = floor(GL_MAX_GEOMETRY_OUTPUT_VERTICES / (profile.length() * 2)); vec3 arcstep = vec3((bangle[0] - aangle[0]), // angle reps[0], // texture (bpos[0].z - apos[0].z)) // height -- cgit v1.2.3 From fb3e42e2d13138865d5eb40a0f65ef14e67f995b Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sun, 21 Jan 2024 03:27:01 +0000 Subject: Dynamic number of segments into curve render Simpler formula than the old one, neither scientific, needs to tests to demonstrate a decent result for whatever formula we use. --- gfx/gl/shaders/networkCurve.gs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gfx/gl/shaders/networkCurve.gs b/gfx/gl/shaders/networkCurve.gs index 326e8b6..619625f 100644 --- a/gfx/gl/shaders/networkCurve.gs +++ b/gfx/gl/shaders/networkCurve.gs @@ -24,7 +24,8 @@ getRot(float angle) void main() { - float segs = floor(GL_MAX_GEOMETRY_OUTPUT_VERTICES / (profile.length() * 2)); + float segs = clamp( + round(reps[0] * radius[0] / 1000), 4, floor(GL_MAX_GEOMETRY_OUTPUT_VERTICES / (profile.length() * 2))); vec3 arcstep = vec3((bangle[0] - aangle[0]), // angle reps[0], // texture (bpos[0].z - apos[0].z)) // height -- cgit v1.2.3 From 80ff7597e0d6b083d1ad4c7c7b758379de69786d Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Sun, 21 Jan 2024 03:36:03 +0000 Subject: Remove the old custom mesh per network link rendering --- game/network/rail.cpp | 65 +++------------------------------------------------ game/network/rail.h | 8 +------ 2 files changed, 4 insertions(+), 69 deletions(-) diff --git a/game/network/rail.cpp b/game/network/rail.cpp index b500006..216ec1c 100644 --- a/game/network/rail.cpp +++ b/game/network/rail.cpp @@ -1,17 +1,9 @@ #include "rail.h" #include "network.h" -#include -#include -#include -#include -#include #include // IWYU pragma: keep -#include -#include -#include -#include -#include -#include +#include +#include +#include template class NetworkOf; @@ -81,24 +73,6 @@ RailLinks::addLinksBetween(GlobalPosition3D start, GlobalPosition3D end) return addLink(start, end, centre.first); } -Mesh::Ptr -RailLink::defaultMesh(const std::span vertices) -{ - std::vector indices; - for (auto n = RAIL_CROSSSECTION_VERTICES; n < vertices.size(); n += 1) { - indices.push_back(n - RAIL_CROSSSECTION_VERTICES); - indices.push_back(n); - } - - return std::make_unique(vertices, indices, GL_TRIANGLE_STRIP); -} - -void -RailLink::render(const SceneShader &) const -{ - mesh->Draw(); -} - constexpr const std::array, RAIL_CROSSSECTION_VERTICES> railCrossSection {{ // ___________ // _/ \_ @@ -129,19 +103,6 @@ RailLinkStraight::RailLinkStraight( instance {instances.vertices.acquire( ends[0].node->pos, ends[1].node->pos, flat_orientation(diff), round_sleepers(length / 2000.F))} { - if (glGenVertexArrays) { - std::vector<::Vertex> vertices; - vertices.reserve(2 * railCrossSection.size()); - const auto len = round_sleepers(length / 2000.F); - const glm::mat3 trans {flat_orientation(diff)}; - for (auto ei : {1U, 0U}) { - for (const auto & rcs : railCrossSection) { - const auto m {ends[ei].node->pos + GlobalPosition3D(trans * rcs.first)}; - vertices.emplace_back(m, TextureRelCoord {rcs.second, len * static_cast(ei)}, up); - } - } - mesh = defaultMesh(vertices); - } } RailLinkCurve::RailLinkCurve( @@ -158,26 +119,6 @@ RailLinkCurve::RailLinkCurve(NetworkLinkHolder & instances, const instance {instances.vertices.acquire(ends[0].node->pos, ends[1].node->pos, c, round_sleepers(length / 2000.F), half_pi - arc.first, half_pi - arc.second, radius)} { - if (glGenVertexArrays) { - const auto & e0p {ends[0].node->pos}; - const auto & e1p {ends[1].node->pos}; - const auto slength = round_sleepers(length / 2.F); - const auto segs = std::round(slength / std::pow(radius, 0.7F)); - const auto step {RelativePosition3D {arc_length(arc), e1p.z - e0p.z, slength / 1000.F} / segs}; - - auto segCount = static_cast(std::lround(segs)) + 1; - std::vector<::Vertex> vertices; - vertices.reserve(segCount * railCrossSection.size()); - for (RelativePosition3D swing = {arc.first, centreBase.z - e0p.z, 0.F}; segCount; swing += step, --segCount) { - const auto t { - glm::rotate(half_pi - swing.x, up) * glm::translate(RelativePosition3D {radius, 0.F, swing.y})}; - for (const auto & rcs : railCrossSection) { - const auto m {centreBase + GlobalPosition3D(t * (rcs.first || 1.F))}; - vertices.emplace_back(m, TextureRelCoord {rcs.second, swing.z}, up); - } - } - mesh = defaultMesh(vertices); - } } RelativePosition3D diff --git a/game/network/rail.h b/game/network/rail.h index a95ba04..c8effef 100644 --- a/game/network/rail.h +++ b/game/network/rail.h @@ -2,13 +2,11 @@ #include "chronology.h" #include "game/worldobject.h" -#include "gfx/models/mesh.h" #include "gfx/renderable.h" #include "link.h" #include "network.h" #include #include -#include #include class SceneShader; @@ -19,7 +17,7 @@ struct Arc; class RailLinkStraight; class RailLinkCurve; -class RailLink : public virtual Link, public Renderable { +class RailLink : public virtual Link { public: RailLink() = default; inline ~RailLink() override = 0; @@ -27,15 +25,11 @@ public: using StraightLink = RailLinkStraight; using CurveLink = RailLinkCurve; - void render(const SceneShader &) const override; NO_COPY(RailLink); NO_MOVE(RailLink); protected: [[nodiscard]] RelativePosition3D vehiclePositionOffset() const override; - [[nodiscard]] static Mesh::Ptr defaultMesh(const std::span vertices); - - Mesh::Ptr mesh; }; RailLink::~RailLink() = default; -- cgit v1.2.3 From 903e959080837d1f15e8689f095624cccfc3ceda Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Mon, 22 Jan 2024 01:45:01 +0000 Subject: Add missing support for glUniform simple span of numbers --- lib/gl_traits.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/gl_traits.h b/lib/gl_traits.h index 2d3d85d..dcbe04e 100644 --- a/lib/gl_traits.h +++ b/lib/gl_traits.h @@ -125,6 +125,15 @@ glUniform(GLint location, std::span> v) (*gl_traits::glUniformvFunc[L - 1])(location, static_cast(v.size()), glm::value_ptr(v.front())); } +template +void +glUniform(GLint location, std::span v) +{ + static_assert( + requires { gl_traits::glUniformvFunc; }, "Has glUnformNTv"); + (*gl_traits::glUniformvFunc.front())(location, static_cast(v.size()), v.data()); +} + template void glUniform(GLint location, const glm::mat & v) -- cgit v1.2.3 From 961f69d8cda0364c04ec98efc70a6f21e0a091e6 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Mon, 22 Jan 2024 02:25:47 +0000 Subject: Bind the network profile in as uniforms Makes the network shaders generic to network type --- game/network/rail.cpp | 24 ++++++++++++++---------- gfx/gl/sceneShader.cpp | 17 +++++++++++++++++ gfx/gl/sceneShader.h | 14 ++++++++++++-- gfx/gl/shaders/networkCommon.glsl | 17 ++++++----------- gfx/gl/shaders/networkCurve.gs | 2 +- 5 files changed, 50 insertions(+), 24 deletions(-) diff --git a/game/network/rail.cpp b/game/network/rail.cpp index 216ec1c..176a704 100644 --- a/game/network/rail.cpp +++ b/game/network/rail.cpp @@ -73,16 +73,20 @@ RailLinks::addLinksBetween(GlobalPosition3D start, GlobalPosition3D end) return addLink(start, end, centre.first); } -constexpr const std::array, RAIL_CROSSSECTION_VERTICES> railCrossSection {{ - // ___________ - // _/ \_ - // left to right - {{-1900.F, 0.F, 0.F}, 0.F}, - {{-608.F, 0.F, RAIL_HEIGHT.z}, .34F}, - {{0, 0.F, RAIL_HEIGHT.z * .7F}, .5F}, - {{608.F, 0.F, RAIL_HEIGHT.z}, .66F}, - {{1900.F, 0.F, 0.F}, 1.F}, +constexpr const std::array railCrossSection {{ + {-1900.F, 0.F, 0.F}, + {-608.F, 0.F, RAIL_HEIGHT.z}, + {0, 0.F, RAIL_HEIGHT.z * .7F}, + {608.F, 0.F, RAIL_HEIGHT.z}, + {1900.F, 0.F, 0.F}, }}; +constexpr const std::array railTexturePos { + 0.F, + .34F, + .5F, + .66F, + 1.F, +}; constexpr auto sleepers {5.F}; // There are 5 repetitions of sleepers in the texture inline auto @@ -149,7 +153,7 @@ namespace { renderType(const NetworkLinkHolder & n, auto & s) { if (auto count = n.vertices.size()) { - s.use(); + s.use(railCrossSection, railTexturePos); glBindVertexArray(n.vao); glDrawArrays(GL_POINTS, 0, static_cast(count)); } diff --git a/gfx/gl/sceneShader.cpp b/gfx/gl/sceneShader.cpp index 146e642..bc64a88 100644 --- a/gfx/gl/sceneShader.cpp +++ b/gfx/gl/sceneShader.cpp @@ -86,6 +86,23 @@ SceneShader::BasicProgram::use(Location const & location) const setModel(location); } +template +SceneShader::NetworkProgram::NetworkProgram(S &&... s) : + AbsolutePosProgram {std::forward(s)...}, profileLoc {*this, "profile"}, texturePosLoc {*this, "texturePos"}, + profileLengthLoc {*this, "profileLength"} +{ +} + +void +SceneShader::NetworkProgram::use( + const std::span profile, const std::span texturePos) const +{ + Program::use(); + glUniform(profileLoc, profile); + glUniform(texturePosLoc, texturePos); + glUniform(profileLengthLoc, static_cast(profile.size())); +} + SceneShader::WaterProgram::WaterProgram() : SceneProgram {water_vs, water_fs}, waveLoc {*this, "waves"} { } void diff --git a/gfx/gl/sceneShader.h b/gfx/gl/sceneShader.h index c86d157..8621442 100644 --- a/gfx/gl/sceneShader.h +++ b/gfx/gl/sceneShader.h @@ -3,6 +3,7 @@ #include "config/types.h" #include "program.h" #include +#include class Location; @@ -41,8 +42,17 @@ class SceneShader { using SceneProgram::SceneProgram; }; - class WaterProgram : public SceneProgram { + class NetworkProgram : public AbsolutePosProgram { public: + template explicit NetworkProgram(S &&...); + + void use(const std::span, const std::span) const; + + private: + RequiredUniformLocation profileLoc, texturePosLoc, profileLengthLoc; + }; + + class WaterProgram : public SceneProgram { public: WaterProgram(); void use(float waveCycle) const; @@ -57,7 +67,7 @@ public: BasicProgram basic; WaterProgram water; AbsolutePosProgram basicInst, landmass, absolute, spotLightInst, pointLightInst; - AbsolutePosProgram networkStraight, networkCurve; + NetworkProgram networkStraight, networkCurve; void setViewProjection(const GlobalPosition3D & viewPoint, const glm::mat4 & viewProjection) const; void setViewPort(const ViewPort & viewPort) const; diff --git a/gfx/gl/shaders/networkCommon.glsl b/gfx/gl/shaders/networkCommon.glsl index e1811bc..7b55cad 100644 --- a/gfx/gl/shaders/networkCommon.glsl +++ b/gfx/gl/shaders/networkCommon.glsl @@ -1,11 +1,6 @@ -const float RAIL_HEIGHT = 250; -const vec3[] profile = vec3[]( // - vec3(-1900.F, 0.F, 0.F), // - vec3(-608.F, 0.F, RAIL_HEIGHT), // - vec3(0, 0.F, RAIL_HEIGHT * .7F), // - vec3(608.F, 0.F, RAIL_HEIGHT), // - vec3(1900.F, 0.F, 0.F)); -const float[profile.length()] texturePos = float[](0, 0.34, 0.5, 0.65, 1); +uniform vec3[10] profile; +uniform float[10] texturePos; +uniform uint profileLength; uniform mat4 viewProjection; uniform ivec3 viewPoint; @@ -25,7 +20,7 @@ segDist(const ivec3 a, const ivec3 b) ifelse( TYPE, .gs, // Begin: Geometry shader only function - void doVertex(const ivec3 end, const int v, const float texY, const mat2 rot) { + void doVertex(const ivec3 end, const uint v, const float texY, const mat2 rot) { rposition = vec3(rot * profile[v].xy, profile[v].z); ivec3 vpos = end + ivec3(rposition); gl_Position = viewProjection * vec4(vpos - viewPoint, 1); @@ -36,8 +31,8 @@ ifelse( void doSeg(const float dist, const ivec3 apos, const ivec3 bpos, const float atexY, const float btexY, const mat2 arot, const mat2 brot) { if (dist < clipDistance) { - int vstep = (dist < flatDistance) ? 1 : profile.length() - 1; - for (int v = 0; v < profile.length(); v += vstep) { + uint vstep = (dist < flatDistance) ? 1u : profileLength - 1u; + for (uint v = 0u; v < profileLength; v += vstep) { doVertex(bpos, v, btexY, brot); doVertex(apos, v, atexY, arot); } diff --git a/gfx/gl/shaders/networkCurve.gs b/gfx/gl/shaders/networkCurve.gs index 619625f..7cb6c42 100644 --- a/gfx/gl/shaders/networkCurve.gs +++ b/gfx/gl/shaders/networkCurve.gs @@ -25,7 +25,7 @@ void main() { float segs = clamp( - round(reps[0] * radius[0] / 1000), 4, floor(GL_MAX_GEOMETRY_OUTPUT_VERTICES / (profile.length() * 2))); + round(reps[0] * radius[0] / 1000), 4, floor(uint(GL_MAX_GEOMETRY_OUTPUT_VERTICES) / (profileLength * 2u))); vec3 arcstep = vec3((bangle[0] - aangle[0]), // angle reps[0], // texture (bpos[0].z - apos[0].z)) // height -- cgit v1.2.3 From 8391c63472641c67f59723d0a6706efff6fb17d4 Mon Sep 17 00:00:00 2001 From: Dan Goodliffe Date: Tue, 23 Jan 2024 23:50:46 +0000 Subject: Fix network population of position in gBuffer Adds some rails to the basic test highlighting broken shadows --- gfx/gl/shaders/network.fs | 2 +- gfx/gl/shaders/networkCommon.glsl | 6 +++--- test/test-render.cpp | 4 ++++ 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/gfx/gl/shaders/network.fs b/gfx/gl/shaders/network.fs index e7d15b3..4e347b4 100644 --- a/gfx/gl/shaders/network.fs +++ b/gfx/gl/shaders/network.fs @@ -11,7 +11,7 @@ uniform ivec3 viewPoint; void main() { - gPosition = ivec4(viewPoint + rposition, 0); + gPosition = ivec4(viewPoint + rposition, 1); gNormal = vec4(0, 0, 1, 1); gAlbedoSpec = texture(texture0, texCoord); } diff --git a/gfx/gl/shaders/networkCommon.glsl b/gfx/gl/shaders/networkCommon.glsl index 7b55cad..0bc3c1c 100644 --- a/gfx/gl/shaders/networkCommon.glsl +++ b/gfx/gl/shaders/networkCommon.glsl @@ -21,9 +21,9 @@ ifelse( TYPE, .gs, // Begin: Geometry shader only function void doVertex(const ivec3 end, const uint v, const float texY, const mat2 rot) { - rposition = vec3(rot * profile[v].xy, profile[v].z); - ivec3 vpos = end + ivec3(rposition); - gl_Position = viewProjection * vec4(vpos - viewPoint, 1); + ivec3 vpos = end + ivec3(rot * profile[v].xy, profile[v].z); + rposition = vpos - viewPoint; + gl_Position = viewProjection * vec4(rposition, 1); texCoord = vec2(texturePos[v], texY); EmitVertex(); } diff --git a/test/test-render.cpp b/test/test-render.cpp index cc2bba2..6c20a23 100644 --- a/test/test-render.cpp +++ b/test/test-render.cpp @@ -25,6 +25,7 @@ class TestScene : public SceneProvider { const RailVehicleClassPtr brush47rvc = std::dynamic_pointer_cast( AssetFactory::loadXML(RESDIR "/brush47.xml")->assets.at("brush-47")); std::shared_ptr train1, train2; + RailLinks rail; Terrain terrain {[]() { auto gd = std::make_shared(GeoData::createFlat({0, 0}, {1000000, 1000000}, 1)); @@ -42,6 +43,8 @@ public: train2->location.setPosition({52000, 30000, 2000}); train2->bogies.front().setPosition(train2->bogies.front().position() + train2->location.position()); train2->bogies.back().setPosition(train2->bogies.back().position() + train2->location.position()); + rail.addLinksBetween({42000, 50000, 1000}, {65000, 50000, 1000}); + rail.addLinksBetween({65000, 50000, 1000}, {75000, 45000, 2000}); } void @@ -49,6 +52,7 @@ public: { terrain.render(shader); brush47rvc->render(shader); + rail.render(shader); } void -- cgit v1.2.3