@@ -61,62 +61,71 @@ void GuiRotationDial::onDraw(sp::RenderTarget& renderer)
6161 // Apply the theme texture with 9-segment UV scaling to the curved arc
6262 // triangle mesh. Fix corners, stretch middle segments along arc (U), and
6363 // stretch edge segments along radius (V).
64+ if (!front.texture .empty ())
65+ {
66+ // Approximate arc length at mid-radius for arc-axis corner sizing.
67+ const float arc_length = 2 .0f * handle_half_arc * ((inner_r + outer_r) * 0 .5f );
68+ // Use front.size as the corner size in pixels, as in drawStretchedHV.
69+ // Clamp corner sizes so they never exceed half of each dimension.
70+ const float u_corner = std::min (front.size , arc_length * 0 .5f );
71+ const float v_corner = std::min (front.size , effective_thickness * 0 .5f );
72+
73+ // Build four radial (V-axis) rings from outer to inner edges.
74+ const float radii[4 ] = {outer_r, outer_r - v_corner, inner_r + v_corner, inner_r};
75+ constexpr float v_uvs[4 ] = {0 .0f , 0 .5f , 0 .5f , 1 .0f };
76+
77+ std::vector<glm::vec2> positions;
78+ std::vector<glm::vec2> uvs;
79+
80+ // Reserve vertex positions and their UVs for handle segments across
81+ // three radial rows.
82+ positions.reserve ((handle_segments + 1 ) * 2 * 3 );
83+ uvs.reserve ((handle_segments + 1 ) * 2 * 3 );
6484
65- // Approximate arc length at mid-radius for arc-axis corner sizing.
66- const float arc_length = 2 .0f * handle_half_arc * ((inner_r + outer_r) * 0 .5f );
67- // Use front.size as the corner size in pixels, as in drawStretchedHV.
68- // Clamp corner sizes so they never exceed half of each dimension.
69- const float u_corner = std::min (front.size , arc_length * 0 .5f );
70- const float v_corner = std::min (front.size , effective_thickness * 0 .5f );
71-
72- // Build four radial (V-axis) rings from outer to inner edges.
73- const float radii[4 ] = {outer_r, outer_r - v_corner, inner_r + v_corner, inner_r};
74- constexpr float v_uvs[4 ] = {0 .0f , 0 .5f , 0 .5f , 1 .0f };
75-
76- std::vector<glm::vec2> positions;
77- std::vector<glm::vec2> uvs;
78- const bool is_handle_textured = !front.texture .empty ();
79-
80- // Reserve handle segment vertex positions. 1 if untextured, 3 if textured.
81- positions.reserve ((handle_segments + 1 ) * 2 * (is_handle_textured ? 1 : 3 ));
85+ // Process each segment in each band.
86+ for (int band = 0 ; band < 3 ; band++)
87+ {
88+ for (int i = 0 ; i <= handle_segments; i++)
89+ {
90+ // Cache angle calculations and U-axis coords for each segment.
91+ const float angle = angle_rad - handle_half_arc + handle_half_arc * 2 .0f * static_cast <float >(i) / static_cast <float >(handle_segments);
92+ const float angle_sin = sinf (angle);
93+ const float angle_cos = cosf (angle);
94+ const float u = getUForSegment (i, arc_length, u_corner, handle_segments);
95+
96+ // Push positions and UVs for each band from the outer to inner
97+ // edge.
98+ positions.push_back (center + glm::vec2{angle_sin * radii[band], angle_cos * radii[band]});
99+ uvs.push_back ({u, v_uvs[band]});
100+ positions.push_back (center + glm::vec2{angle_sin * radii[band + 1 ], angle_cos * radii[band + 1 ]});
101+ uvs.push_back ({u, v_uvs[band + 1 ]});
102+ }
103+ }
82104
83- // Reserve UVs if textured.
84- if (is_handle_textured)
85- uvs.reserve ((handle_segments + 1 ) * 2 * 3 );
105+ // Render the segments.
106+ renderer.drawTexturedTriangleStrip (front.texture , positions, uvs, front.color );
107+ }
108+ // If not textured, draw the handle as a flat-colored triangle strip
109+ // without segmenting on radial rings.
110+ else
111+ {
112+ // Build the handle segments.
113+ std::vector<glm::vec2> positions;
114+ positions.reserve ((handle_segments + 1 ) * 2 );
86115
87- // Shared ring-building logic.
88- auto buildRing = [&](int band) {
89116 for (int i = 0 ; i <= handle_segments; i++)
90117 {
91- // Cache angle calculations.
118+ // Cache angle calculations for each segment .
92119 const float angle = angle_rad - handle_half_arc + handle_half_arc * 2 .0f * static_cast <float >(i) / static_cast <float >(handle_segments);
93120 const float angle_sin = sinf (angle);
94121 const float angle_cos = cosf (angle);
95122
96- // Build upper and lower bands.
97- positions.push_back (center + glm::vec2{angle_sin * radii[band], angle_cos * radii[band]});
98-
99- // Push UVs if textured.
100- if (is_handle_textured)
101- uvs.push_back ({getUForSegment (i, arc_length, u_corner, handle_segments), v_uvs[band]});
102-
103- positions.push_back (center + glm::vec2{angle_sin * radii[band + 1 ], angle_cos * radii[band + 1 ]});
104-
105- // Push UVs if textured.
106- if (is_handle_textured)
107- uvs.push_back ({getUForSegment (i, arc_length, u_corner, handle_segments), v_uvs[band + 1 ]});
123+ // Push positions from the outer to inner edge.
124+ positions.push_back (center + glm::vec2{angle_sin * outer_r, angle_cos * outer_r});
125+ positions.push_back (center + glm::vec2{angle_sin * inner_r, angle_cos * inner_r});
108126 }
109- };
110127
111- // Use handle texture if present, draw with color only if not.
112- if (is_handle_textured)
113- {
114- for (int band = 0 ; band < 3 ; band++) buildRing (band);
115- renderer.drawTexturedTriangleStrip (front.texture , positions, uvs, front.color );
116- }
117- else
118- {
119- buildRing (0 );
128+ // Render the segments.
120129 renderer.drawTriangleStrip (positions, front.color );
121130 }
122131}
0 commit comments