summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2024-01-20 20:10:12 +0000
committerDan Goodliffe <dan@randomdan.homeip.net>2024-01-20 20:10:12 +0000
commita19011b730ac6d770e3b42cde3a10961495a417d (patch)
treea3d1e4de3c709167d226725ddd768a9ecd662ff5
parentCommon code between straight/curve network geometry shaders (diff)
downloadilt-a19011b730ac6d770e3b42cde3a10961495a417d.tar.bz2
ilt-a19011b730ac6d770e3b42cde3a10961495a417d.tar.xz
ilt-a19011b730ac6d770e3b42cde3a10961495a417d.zip
Implement basic network curve part shader
-rw-r--r--game/network/rail.cpp7
-rw-r--r--game/network/rail.h1
-rw-r--r--gfx/gl/shaders/networkCommon.glsl45
-rw-r--r--gfx/gl/shaders/networkCurve.gs29
-rw-r--r--gfx/gl/shaders/networkCurve.vs6
-rw-r--r--gfx/gl/shaders/networkStraight.vs6
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<RailLinkCurve> & 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<RailLinkCurve>::NetworkLinkHolder()
{
VertexArrayObject {vao}
.addAttribs<RailLinkCurve::Vertex, &RailLinkCurve::Vertex::a, &RailLinkCurve::Vertex::b,
- &RailLinkCurve::Vertex::c, &RailLinkCurve::Vertex::textureRepeats>(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);
}