diff --git a/src/screencast_keys/compat/bglx.py b/src/screencast_keys/compat/bglx.py index 8858d65..bd1a2af 100644 --- a/src/screencast_keys/compat/bglx.py +++ b/src/screencast_keys/compat/bglx.py @@ -12,6 +12,19 @@ GL_TRIANGLE_FAN = 6 GL_QUADS = 4 + +def primitive_mode_is_line(mode): + return mode in [GL_LINES, GL_LINE_STRIP, GL_LINE_LOOP] + + +def is_shader_supported(shader_name): + try: + gpu.shader.from_builtin(shader_name) + return True + except ValueError: + return False + + class InternalData: __inst = None __lock = Lock() @@ -86,6 +99,8 @@ def glLineWidth(width): inst = InternalData.get_instance() inst.set_line_width(width) + bgl.glLineWidth(width) + def glColor3f(r, g, b): inst = InternalData.get_instance() @@ -156,12 +171,23 @@ def glEnd(): if len(tex_coords) == 0: shader = gpu.shader.from_builtin('2D_UNIFORM_COLOR') else: - #shader = gpu.shader.from_builtin('2D_IMAGE') vert_shader, frag_shader = _get_transparency_shader() shader = gpu.types.GPUShader(vert_shader, frag_shader) + elif inst.get_dims() == 3: + if len(tex_coords) == 0: + if primitive_mode_is_line(inst.get_prim_mode()): + if is_shader_supported('3D_POLYLINE_UNIFORM_COLOR'): + shader = gpu.shader.from_builtin('3D_POLYLINE_UNIFORM_COLOR') + else: + shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR') + else: + shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR') + else: + raise NotImplemented("Texture is not supported in get_dims() == 3") else: raise NotImplemented("get_dims() != 2") + if len(tex_coords) == 0: data = { "pos": coords, @@ -211,6 +237,9 @@ def glEnd(): shader.uniform_float("modelViewMatrix", gpu.matrix.get_model_view_matrix()) shader.uniform_float("projectionMatrix", gpu.matrix.get_projection_matrix()) shader.uniform_int("image", 0) + if (primitive_mode_is_line(inst.get_prim_mode()) and + is_shader_supported('3D_POLYLINE_UNIFORM_COLOR')): + shader.uniform_float("lineWidth", inst.get_line_width()) shader.uniform_float("color", color) batch.draw(shader) @@ -223,6 +252,12 @@ def glVertex2f(x, y): inst.set_dims(2) +def glVertex3f(x, y, z): + inst = InternalData.get_instance() + inst.add_vert([x, y, z]) + inst.set_dims(3) + + def glTexCoord2f(u, v): inst = InternalData.get_instance() inst.add_tex_coord([u, v]) diff --git a/src/screencast_keys/ops.py b/src/screencast_keys/ops.py index 9ea2a1b..018d112 100644 --- a/src/screencast_keys/ops.py +++ b/src/screencast_keys/ops.py @@ -55,7 +55,7 @@ def draw_mouse(x, y, w, h, left_pressed, right_pressed, middle_pressed, color, - round_radius, fill=False, fill_color=None): + round_radius, fill=False, fill_color=None, line_thickness=1): mouse_body = [x, y, w, h/2] left_mouse_button = [x, y + h/2, w/3, h/2] @@ -68,12 +68,14 @@ def draw_mouse(x, y, w, h, left_pressed, right_pressed, middle_pressed, color, mouse_body[2], mouse_body[3], round_radius, fill=True, color=fill_color, - round_corner=[True, True, False, False]) + round_corner=[True, True, False, False], + line_thickness=line_thickness) draw_rounded_box(mouse_body[0], mouse_body[1], mouse_body[2], mouse_body[3], round_radius, fill=False, color=color, - round_corner=[True, True, False, False]) + round_corner=[True, True, False, False], + line_thickness=line_thickness) # Left button. if fill: @@ -81,18 +83,21 @@ def draw_mouse(x, y, w, h, left_pressed, right_pressed, middle_pressed, color, left_mouse_button[2], left_mouse_button[3], round_radius / 2, fill=True, color=fill_color, - round_corner=[False, False, False, True]) + round_corner=[False, False, False, True], + line_thickness=line_thickness) draw_rounded_box(left_mouse_button[0], left_mouse_button[1], left_mouse_button[2], left_mouse_button[3], round_radius / 2, fill=False, color=color, - round_corner=[False, False, False, True]) + round_corner=[False, False, False, True], + line_thickness=line_thickness) if left_pressed: draw_rounded_box(left_mouse_button[0], left_mouse_button[1], left_mouse_button[2], left_mouse_button[3], round_radius / 2, fill=True, color=color, - round_corner=[False, False, False, True]) + round_corner=[False, False, False, True], + line_thickness=line_thickness) # Middle button. if fill: @@ -100,18 +105,21 @@ def draw_mouse(x, y, w, h, left_pressed, right_pressed, middle_pressed, color, middle_mouse_button[2], middle_mouse_button[3], round_radius / 2, fill=True, color=fill_color, - round_corner=[False, False, False, False]) + round_corner=[False, False, False, False], + line_thickness=line_thickness) draw_rounded_box(middle_mouse_button[0], middle_mouse_button[1], middle_mouse_button[2], middle_mouse_button[3], round_radius / 2, fill=False, color=color, - round_corner=[False, False, False, False]) + round_corner=[False, False, False, False], + line_thickness=line_thickness) if middle_pressed: draw_rounded_box(middle_mouse_button[0], middle_mouse_button[1], middle_mouse_button[2], middle_mouse_button[3], round_radius / 2, fill=True, color=color, - round_corner=[False, False, False, False]) + round_corner=[False, False, False, False], + line_thickness=line_thickness) # Right button. if fill: @@ -119,22 +127,25 @@ def draw_mouse(x, y, w, h, left_pressed, right_pressed, middle_pressed, color, right_mouse_button[2], right_mouse_button[3], round_radius / 2, fill=True, color=fill_color, - round_corner=[False, False, True, False]) + round_corner=[False, False, True, False], + line_thickness=line_thickness) draw_rounded_box(right_mouse_button[0], right_mouse_button[1], right_mouse_button[2], right_mouse_button[3], round_radius / 2, fill=False, color=color, - round_corner=[False, False, True, False]) + round_corner=[False, False, True, False], + line_thickness=line_thickness) if right_pressed: draw_rounded_box(right_mouse_button[0], right_mouse_button[1], right_mouse_button[2], right_mouse_button[3], round_radius / 2, fill=True, color=color, - round_corner=[False, False, True, False]) + round_corner=[False, False, True, False], + line_thickness=line_thickness) def draw_rounded_box(x, y, w, h, round_radius, fill=False, color=[1.0, 1.0, 1.0], - round_corner=[True, True, True, True]): + round_corner=[True, True, True, True], line_thickness=1): """round_corner: [Right Bottom, Left Bottom, Right Top, Left Top]""" def circle_verts_num(r): @@ -175,6 +186,8 @@ def circle_verts_num(r): ] bgl.glColor3f(*color) + bgl.glLineWidth(line_thickness) + if fill: bgl.glBegin(bgl.GL_TRIANGLE_FAN) else: @@ -183,9 +196,11 @@ def circle_verts_num(r): for _ in range(n): x = x0 + r * math.cos(angle) y = y0 + r * math.sin(angle) - bgl.glVertex2f(x, y) + bgl.glVertex3f(x, y, 0) angle += dangle bgl.glEnd() + + bgl.glLineWidth(1.0) bgl.glColor3f(1.0, 1.0, 1.0) @@ -225,29 +240,30 @@ def draw_text(text, font_id, color, shadow=False, shadow_color=None): blf.disable(font_id, blf.SHADOW) -def draw_line(p1, p2, color, shadow=False, shadow_color=None): +def draw_line(p1, p2, color, shadow=False, shadow_color=None, line_thickness=1): bgl.glEnable(bgl.GL_BLEND) - bgl.glEnable(bgl.GL_LINE_SMOOTH) # Draw shadow. if shadow: - bgl.glLineWidth(3.0) + bgl.glLineWidth(line_thickness + 3.0) bgl.glColor4f(*shadow_color, 1.0) bgl.glBegin(bgl.GL_LINES) - bgl.glVertex2f(*p1) - bgl.glVertex2f(*p2) + bgl.glVertex3f(*p1) + bgl.glVertex3f(*p2) bgl.glEnd() # Draw line. - bgl.glLineWidth(1.5 if shadow else 1.0) + bgl.glLineWidth(line_thickness + 2.0 if shadow else line_thickness) bgl.glColor3f(*color) + bgl.glBegin(bgl.GL_LINES) - bgl.glVertex2f(*p1) - bgl.glVertex2f(*p2) + bgl.glVertex3f(*p1) + bgl.glVertex3f(*p2) bgl.glEnd() bgl.glLineWidth(1.0) - bgl.glDisable(bgl.GL_LINE_SMOOTH) + bgl.glColor3f(1.0, 1.0, 1.0) + bgl.glDisable(bgl.GL_BLEND) def intersect_aabb(min1, max1, min2, max2): @@ -922,6 +938,10 @@ def draw_callback(cls, context): x = origin_x - region.x y = origin_y - region.y + # Warm up rendering. + # This is needed to render the line with more than 1.5 thickness properly. + draw_rect(0, 0, 0, 0, [0.0, 0.0, 0.0]) + # Draw draw area based background. if show_draw_area_background(prefs): draw_rect(draw_area_min_x - region.x, @@ -957,9 +977,10 @@ def draw_callback(cls, context): # Draw separator. sw = blf.dimensions(font_id, "Left Mouse")[0] offset_x, offset_y = cls.get_offset_for_alignment(sw, context) - draw_line([x + offset_x, y + offset_y], - [x + sw + offset_x, y + offset_y], - prefs.color, prefs.shadow, prefs.shadow_color) + draw_line([x + offset_x, y + offset_y, 0.0], + [x + sw + offset_x, y + offset_y, 0.0], + prefs.color, prefs.shadow, prefs.shadow_color, + prefs.line_thickness) y += sh * cls.HEIGHT_RATIO_FOR_SEPARATOR * 0.8 region_drawn = True @@ -1011,7 +1032,8 @@ def draw_callback(cls, context): prefs.color, prefs.mouse_size * 0.5, fill=prefs.background, - fill_color=prefs.background_color) + fill_color=prefs.background_color, + line_thickness=prefs.line_thickness) # Draw hold modifier keys. if cls.hold_modifier_keys or drawing: @@ -1022,7 +1044,8 @@ def draw_callback(cls, context): y + offset_y - margin + offset_y_for_hold_modifier_keys, box_width, box_height, box_height * 0.2, show_text_background(prefs), - prefs.background_color if show_text_background(prefs) else prefs.color) + prefs.background_color if show_text_background(prefs) else prefs.color, + line_thickness=prefs.line_thickness) # Draw modifier key text. blf.position(font_id, diff --git a/src/screencast_keys/preferences.py b/src/screencast_keys/preferences.py index 8468524..91c2464 100644 --- a/src/screencast_keys/preferences.py +++ b/src/screencast_keys/preferences.py @@ -150,14 +150,21 @@ class SK_Preferences(bpy.types.AddonPreferences): name="Font Size", default=compat.get_user_preferences(bpy.context).ui_styles[0].widget.points, min=6, - max=48 + max=1000 + ) + + line_thickness = bpy.props.FloatProperty( + name="Line Thickness", + default=1, + min=1, + max=100 ) mouse_size = bpy.props.IntProperty( name="Mouse Size", default=compat.get_user_preferences(bpy.context).ui_styles[0].widget.points*3, min=18, - max=144, + max=1000, ) origin = bpy.props.EnumProperty( @@ -355,6 +362,7 @@ def draw(self, context): sp = compat.layout_split(sp, factor=1.0) sp.prop(self, "background_color", text="") col.prop(self, "font_size") + col.prop(self, "line_thickness") if show_mouse_hold_status(self): col.prop(self, "mouse_size") diff --git a/src/screencast_keys/ui.py b/src/screencast_keys/ui.py index ccf7cbb..0cd351a 100644 --- a/src/screencast_keys/ui.py +++ b/src/screencast_keys/ui.py @@ -55,6 +55,7 @@ def draw(self, context): sp = compat.layout_split(sp, factor=1.0) sp.prop(prefs, "background_color", text="") column.prop(prefs, "font_size") + column.prop(prefs, "line_thickness") if show_mouse_hold_status(prefs): column.prop(prefs, "mouse_size")