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