diff --git a/src/material.cpp b/src/material.cpp
index 61f28a5..c2070e2 100644
--- a/src/material.cpp
+++ b/src/material.cpp
@@ -62,6 +62,10 @@ RenderableMaterial::RenderableMaterial(Qt3DCore::QNode *parent, VertexShaderType
shader3->setGeometryShaderCode(
Qt3DRender::QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/shaders/line_tesselator.geom"))));
break;
+ case (GeometryShaderType::LineStipple):
+ shader3->setGeometryShaderCode(
+ Qt3DRender::QShaderProgram::loadSource(QUrl(QStringLiteral("qrc:/shaders/shaders/line_stipple.geom"))));
+ break;
default:
throw(std::runtime_error("Unhandled geometry shader type.\n"));
}
@@ -122,4 +126,4 @@ void RenderableMaterial::setSpecular(QColor specular)
{
specular_ = specular;
specularParameter_->setValue(specular_);
-}
\ No newline at end of file
+}
diff --git a/src/material.h b/src/material.h
index 04977de..e593118 100644
--- a/src/material.h
+++ b/src/material.h
@@ -19,7 +19,8 @@ class RenderableMaterial : public Qt3DRender::QMaterial
enum class GeometryShaderType
{
None,
- LineTesselator
+ LineTesselator,
+ LineStipple
};
// Fragment Shader Types
enum class FragmentShaderType
@@ -56,4 +57,4 @@ class RenderableMaterial : public Qt3DRender::QMaterial
// Set specular colour component
void setSpecular(QColor specular);
};
-} // namespace Mildred
\ No newline at end of file
+} // namespace Mildred
diff --git a/src/shaders.qrc b/src/shaders.qrc
index ac06ea9..7663dd7 100644
--- a/src/shaders.qrc
+++ b/src/shaders.qrc
@@ -6,5 +6,6 @@
shaders/phongpervertex.frag
shaders/monochrome.frag
shaders/line_tesselator.geom
+ shaders/line_stipple.geom
diff --git a/src/shaders/line_stipple.geom b/src/shaders/line_stipple.geom
new file mode 100644
index 0000000..38f942c
--- /dev/null
+++ b/src/shaders/line_stipple.geom
@@ -0,0 +1,79 @@
+#version 330
+
+layout(lines) in;
+layout(triangle_strip, max_vertices = 4) out;
+
+// Input Vertex Data
+in worldData
+{
+ vec3 position;
+ vec3 normal;
+ vec4 color;
+}
+vertices[];
+
+// Output Fragment Data
+out fragData
+{
+ vec3 position;
+ vec3 normal;
+ vec4 color;
+}
+frag;
+
+uniform vec2 viewportSize;
+uniform float lineWidth = 1.5;
+
+// Copy clip distances for specified input vertex
+void applyClipping(int inVertexID)
+{
+ gl_ClipDistance[0] = gl_in[inVertexID].gl_ClipDistance[0];
+ gl_ClipDistance[1] = gl_in[inVertexID].gl_ClipDistance[1];
+ gl_ClipDistance[2] = gl_in[inVertexID].gl_ClipDistance[2];
+ gl_ClipDistance[3] = gl_in[inVertexID].gl_ClipDistance[3];
+ gl_ClipDistance[4] = gl_in[inVertexID].gl_ClipDistance[4];
+ gl_ClipDistance[5] = gl_in[inVertexID].gl_ClipDistance[5];
+}
+
+void main()
+{
+ vec4 p1 = gl_in[0].gl_Position;
+ vec4 p2 = gl_in[1].gl_Position;
+
+ vec2 dir = normalize((p2.xy - p1.xy) * viewportSize);
+ vec2 offset = vec2(-dir.y, dir.x) * lineWidth / viewportSize;
+
+ // Emit the four corners of our two triangles
+ gl_Position = p1 + vec4(offset.xy * p1.w, 0.0, 0.0);
+ applyClipping(0);
+ frag.position = vec3(gl_Position);
+ frag.color = vertices[0].color;
+ frag.normal = vertices[1].normal;
+ EmitVertex();
+ gl_Position = p1 - vec4(offset.xy * p1.w, 0.0, 0.0);
+ applyClipping(0);
+ frag.position = vec3(gl_Position);
+ frag.color = vertices[0].color;
+ frag.normal = vertices[0].normal;
+ EmitVertex();
+ gl_Position = p2 + vec4(offset.xy * p2.w, 0.0, 0.0);
+ applyClipping(1);
+ frag.position = vec3(gl_Position);
+ frag.color = vertices[1].color;
+ frag.normal = vertices[1].normal;
+ EmitVertex();
+ gl_Position = p2 - vec4(offset.xy * p2.w, 0.0, 0.0);
+ applyClipping(1);
+ frag.position = vec3(gl_Position);
+ frag.color = vertices[1].color;
+ frag.normal = vertices[1].normal;
+
+ // To view line-stipple output, remove comment bars (//) from the following two lines
+ //gl_Position = p1 + vec4(offset.xy * p1.w, 0.0, 0.0);
+ //applyClipping(0);
+
+ EmitVertex();
+
+ EndPrimitive();
+
+}
diff --git a/src/widget.cpp b/src/widget.cpp
index bde20f9..fbe1df9 100644
--- a/src/widget.cpp
+++ b/src/widget.cpp
@@ -195,7 +195,7 @@ Data1DEntity *MildredWidget::addData1D(std::string_view tag)
// Add a material
auto *material = createMaterial(entity, RenderableMaterial::VertexShaderType::ClippedToDataVolume,
- RenderableMaterial::GeometryShaderType::LineTesselator,
+ RenderableMaterial::GeometryShaderType::LineStipple,
RenderableMaterial::FragmentShaderType::PerVertexPhong);
entity->setDataMaterial(material);
entity->setErrorMaterial(material);
@@ -214,4 +214,4 @@ DisplayGroup *MildredWidget::addDisplayGroup()
auto newGroup = displayGroups_.emplace_back(std::make_shared());
return newGroup.get();
-}
\ No newline at end of file
+}