Skip to content

Commit

Permalink
Draw dashed lines in screenspace
Browse files Browse the repository at this point in the history
Use hardware interpolation to calculate dashinng.
Closes #29, #31
  • Loading branch information
hlorus committed May 11, 2022
1 parent a1329e3 commit 6621fb9
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 35 deletions.
38 changes: 4 additions & 34 deletions class_defines.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,6 @@ def is_dirty(self, value):

@property
def _shader(self):
dashed = self.is_dashed()
if dashed:
return Shaders.dashed_uniform_color_3d()

if self.is_point():
return Shaders.uniform_color_3d()
return Shaders.uniform_color_line_3d()
Expand Down Expand Up @@ -221,11 +217,10 @@ def draw(self, context):
col = self.color(context)
shader.uniform_float("color", col)

if self.is_dashed():
shader.uniform_float("u_Scale", 20)
bgl.glLineWidth(self.line_width)
if not self.is_point():
shader.uniform_bool("dashed", (self.is_dashed(), ))

elif not self.is_point():
if not self.is_point():
viewport = [context.area.width, context.area.height]
shader.uniform_float("Viewport", viewport)
shader.uniform_float("thickness", self.line_width)
Expand All @@ -251,6 +246,7 @@ def draw_id(self, context):
viewport = [context.area.width, context.area.height]
shader.uniform_float("Viewport", viewport)
shader.uniform_float("thickness", self.line_width_select)
shader.uniform_bool("dashed", (False, ))

batch.draw(shader)
gpu.shader.unbind()
Expand Down Expand Up @@ -423,11 +419,6 @@ def update(self):
coords = (p1, p2)

kwargs = {"pos": coords}

if self.is_dashed():
arc_lengths = (0.0, (p2 - p1).length)
kwargs["arcLength"] = arc_lengths

self._batch = batch_for_shader(
self._shader, "LINES", kwargs
)
Expand Down Expand Up @@ -842,10 +833,6 @@ def update(self):
coords = (p1, p2)

kwargs = {"pos": coords}
if self.is_dashed():
arc_lengths = (0.0, (p2 - p1).length)
kwargs["arcLength"] = arc_lengths

self._batch = batch_for_shader(self._shader, "LINES", kwargs)
self.is_dirty = False

Expand Down Expand Up @@ -1054,16 +1041,6 @@ def update(self):
coords = [(mat @ Vector((*co, 0)))[:] for co in coords]

kwargs = {"pos": coords}

if self.is_dashed():
r = self.radius
a = self.angle
length = r * angle
v_count = len(coords)
step = length / v_count
arc_lengths = [i * step for i in range(v_count)]
kwargs["arcLength"] = arc_lengths

self._batch = batch_for_shader(self._shader, "LINE_STRIP", kwargs)
self.is_dirty = False

Expand Down Expand Up @@ -1220,13 +1197,6 @@ def update(self):
coords = [(mat @ Vector((*co, 0)))[:] for co in coords]

kwargs = {"pos": coords}
if self.is_dashed():
U = math.pi * self.radius * 2
v_count = len(coords)
step = U / v_count
arc_lengths = [i * step for i in range(v_count)]
kwargs["arcLength"] = arc_lengths

self._batch = batch_for_shader(self._shader, "LINE_STRIP", kwargs)
self.is_dirty = False

Expand Down
41 changes: 40 additions & 1 deletion shaders.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,42 @@ class Shaders:
uniform mat4 ModelViewProjectionMatrix;
in vec3 pos;
vec4 project = ModelViewProjectionMatrix * vec4(pos, 1.0);
void main() {
gl_Position = project;
}
'''
base_fragment_shader_3d = '''
uniform vec4 color;
uniform float dash_width = 10.0;
uniform float dash_factor = 0.40;
uniform vec2 Viewport;
uniform bool dashed = false;
noperspective in vec2 stipple_pos;
flat in vec2 stipple_start;
out vec4 fragColor;
void main() {
fragColor = color;
float aspect = Viewport.x/Viewport.y;
float distance_along_line = distance(stipple_pos, stipple_start);
float normalized_distance = fract(distance_along_line / dash_width);
if (dashed == true) {
if (normalized_distance <= dash_factor) {
discard;
}
else {
fragColor = color;
}
}
else {
fragColor = color;
}
}
'''

Expand Down Expand Up @@ -56,6 +81,10 @@ def uniform_color_line_3d(cls):
uniform vec2 Viewport;
uniform float thickness = float(0.1);
/* We leverage hardware interpolation to compute distance along the line. */
noperspective out vec2 stipple_pos; /* In screen space */
flat out vec2 stipple_start; /* In screen space */
out vec2 mTexCoord;
out float alpha;
float aspect = Viewport.x/Viewport.y;
Expand Down Expand Up @@ -110,6 +139,16 @@ def uniform_color_line_3d(cls):
mTexCoord = texCoords[i];
gl_Position = coords[i];
alpha = lineAlpha;
vec4 stipple_base;
if (i < 2) {
stipple_base = vec4(ssp1*p1.w,p1.z,p1.w);
}
else {
stipple_base = vec4(ssp2*p2.w, p2.z, p2.w);
}
stipple_start = stipple_pos = Viewport * 0.5 * (stipple_base.xy / stipple_base.w);
EmitVertex();
}
EndPrimitive();
Expand Down

0 comments on commit 6621fb9

Please sign in to comment.