]> git.rm.cloudns.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
strafehud: implemented faster gradient utilizing only a few polygon vertices
authorJuhu <5894800-Juhu_@users.noreply.gitlab.com>
Tue, 17 Sep 2024 18:33:37 +0000 (20:33 +0200)
committerJuhu <5894800-Juhu_@users.noreply.gitlab.com>
Tue, 17 Sep 2024 18:45:56 +0000 (20:45 +0200)
_hud_common.cfg
qcsrc/client/hud/panel/strafehud.qc
qcsrc/client/hud/panel/strafehud.qh
qcsrc/client/hud/panel/strafehud/draw.qc
qcsrc/client/hud/panel/strafehud/draw.qh

index 383d9cd8558d8e805c3ba1f4c6044f02c62451a7..d6f5648ab9b6cdaf064b06b96d8f86d4a84ddc9c 100644 (file)
@@ -157,7 +157,7 @@ seta hud_panel_scoreboard_itemstats_showdelay_minpos 0.75 "delay displaying the
 seta _hud_panel_strafehud_demo "0" "strafehud changes angle during configure"
 seta hud_panel_strafehud_mode "0" "strafehud mode which controls whether the strafehud is centered at \"0\" = view angle, \"1\" = velocity angle"
 seta hud_panel_strafehud_range "90" "the angle range up to 360 degrees displayed on the strafehud, \"-1\" = current fov, \"0\" = dynamic (chooses the minimum range required to still see the whole area needed for accelerating)"
-seta hud_panel_strafehud_style "2" "\"0\" = no styling, \"1\" = progress bar style for the strafe bar, \"2\" = gradient for the strafe bar"
+seta hud_panel_strafehud_style "2" "\"0\" = no styling, \"1\" = progress bar style for the strafe bar, \"2\" = gradient for the strafe bar, \"3\" = fast gradient for the strafe bar (requires linear projection mode)"
 seta hud_panel_strafehud_unit_show "1" "show units"
 seta hud_panel_strafehud_bar_preaccel "1" "set to \"1\" to extend the acceleration zone by the strafe meter zone before full acceleration can be achieved"
 seta hud_panel_strafehud_bar_neutral_color "1 1 1" "color of the strafe meter neutral zone"
index ec4893bce741c7a0cb770f70931e413b76303832..2bf08dec2f0a5559955894e4b77696990f8a676e 100644 (file)
@@ -416,7 +416,7 @@ void HUD_StrafeHUD()
                                strafe_ratio = (moveangle - absolute_prebestangle) / (absolute_bestangle - absolute_prebestangle);
                        }
 
-                       if(autocvar_hud_panel_strafehud_style == STRAFEHUD_STYLE_GRADIENT)
+                       if(autocvar_hud_panel_strafehud_style == STRAFEHUD_STYLE_GRADIENT || autocvar_hud_panel_strafehud_style == STRAFEHUD_STYLE_FAST_GRADIENT)
                                currentangle_color = StrafeHUD_MixColors(
                                        autocvar_hud_panel_strafehud_angle_neutral_color,
                                        currentangle_color, fabs(strafe_ratio));
index 1c1a3d9342cd520d0673275d40efed322375d41a..0ce6cb51566513853ac8d29fac2d0223dce0c137 100644 (file)
@@ -93,6 +93,7 @@ const int STRAFEHUD_KEYS_BACKWARD = 2;
 const int STRAFEHUD_STYLE_DRAWFILL = 0;
 const int STRAFEHUD_STYLE_PROGRESSBAR = 1;
 const int STRAFEHUD_STYLE_GRADIENT = 2;
+const int STRAFEHUD_STYLE_FAST_GRADIENT = 3;
 
 const int STRAFEHUD_GRADIENT_NONE = 0;
 const int STRAFEHUD_GRADIENT_LEFT = 1;
index 9f94a1bc0fe7f9eba90be8c3d21bc1b86571d789..1e5789a8c93945bd7c6c886080cc2d24ae601bb0 100644 (file)
@@ -10,14 +10,14 @@ void StrafeHUD_DrawStrafeHUD(float startangle, float offsetangle, vector color,
        float mirror_offset;
        float mirror_width;
 
-       if(type == STRAFEHUD_STYLE_GRADIENT)
+       if(type == STRAFEHUD_STYLE_GRADIENT || type == STRAFEHUD_STYLE_FAST_GRADIENT)
        {
                projectWidth = true; // must be fully projected for gradients
                if(gradientType == STRAFEHUD_GRADIENT_NONE)
                        type = STRAFEHUD_STYLE_DRAWFILL;
        }
 
-       if(alpha <= 0 && type != STRAFEHUD_STYLE_GRADIENT || width <= 0)
+       if(alpha <= 0 && type != STRAFEHUD_STYLE_GRADIENT && type != STRAFEHUD_STYLE_FAST_GRADIENT || width <= 0)
                return;
 
        // how much is hidden by the current hud angle
@@ -101,6 +101,7 @@ void StrafeHUD_DrawStrafeHUD(float startangle, float offsetangle, vector color,
                        break;
 
                case STRAFEHUD_STYLE_GRADIENT: // gradient style (types: 1 = left, 2 = right, 3 = both)
+               case STRAFEHUD_STYLE_FAST_GRADIENT:
                        // determine whether the gradient starts in the mirrored or the non-mirrored area
                        int gradient_start;
                        float gradient_offset, gradient_mirror_offset;
@@ -129,21 +130,38 @@ void StrafeHUD_DrawStrafeHUD(float startangle, float offsetangle, vector color,
                                        gradient_mirror_offset = 0;
                        }
 
-                       StrafeHUD_DrawGradient(
-                               color, autocvar_hud_panel_strafehud_bar_neutral_color,
-                               mirror_size, original_width, mirror_offset, original_mirror_offset,
-                               alpha, gradient_mirror_offset, gradientType, range);
+                       if(type == STRAFEHUD_STYLE_FAST_GRADIENT && autocvar_hud_panel_strafehud_projection == STRAFEHUD_PROJECTION_LINEAR)
+                       {
+                               StrafeHUD_DrawGradientFast(
+                                       color, autocvar_hud_panel_strafehud_bar_neutral_color,
+                                       mirror_size, original_width, mirror_offset, alpha,
+                                       gradient_mirror_offset, gradientType);
+
+                               StrafeHUD_DrawGradientFast(
+                                       color, autocvar_hud_panel_strafehud_bar_neutral_color,
+                                       size, original_width, offset, alpha,
+                                       gradient_offset, gradientType);
+                       }
+                       else
+                       {
+                               StrafeHUD_DrawGradient(
+                                       color, autocvar_hud_panel_strafehud_bar_neutral_color,
+                                       mirror_size, original_width, mirror_offset, original_mirror_offset,
+                                       alpha, gradient_mirror_offset, gradientType, range);
 
-                       StrafeHUD_DrawGradient(
-                               color, autocvar_hud_panel_strafehud_bar_neutral_color,
-                               size, original_width, offset, original_offset,
-                               alpha, gradient_offset, gradientType, range);
+                               StrafeHUD_DrawGradient(
+                                       color, autocvar_hud_panel_strafehud_bar_neutral_color,
+                                       size, original_width, offset, original_offset,
+                                       alpha, gradient_offset, gradientType, range);
+                       }
        }
 }
 
-// FIXME: this is very bad for performance, there should be a better way to draw gradients
+// slow gradient, required for projection modes other than linear
 void StrafeHUD_DrawGradient(vector color1, vector color2, vector size, float original_width, float offset, float original_offset, float alpha, float gradientOffset, int gradientType, float range)
 {
+       if(size.x <= 0) return;
+
        float color_ratio, alpha1, alpha2;
        vector segment_size = size;
        alpha1 = bound(0, alpha, 1);
@@ -176,6 +194,61 @@ void StrafeHUD_DrawGradient(vector color1, vector color2, vector size, float ori
        }
 }
 
+// optimized gradient, does not work with projection modes other than linear, decreased visual fidelity
+void StrafeHUD_DrawGradientFast(vector color1, vector color2, vector size, float original_width, float offset, float alpha, float gradientOffset, int gradientType)
+{
+       if(size.x <= 0) return;
+
+       if(gradientType == STRAFEHUD_GRADIENT_BOTH)
+       {
+               original_width /= 2;
+
+               vector size1 = size;
+               size1.x = bound(0, original_width - gradientOffset, size.x);
+
+               vector size2 = size;
+               size2.x = size.x - size1.x;
+
+               if(size1.x > 0)
+                       StrafeHUD_DrawGradientFast(color1, color2, size1, original_width, offset, alpha, gradientOffset, STRAFEHUD_GRADIENT_LEFT);
+
+               if(size2.x > 0)
+                       StrafeHUD_DrawGradientFast(color1, color2, size2, original_width, offset + size1.x, alpha, max(0, gradientOffset - original_width), STRAFEHUD_GRADIENT_RIGHT);
+
+               return;
+       }
+
+       float alpha1 = bound(0, alpha, 1);
+       float alpha2 = bound(0, autocvar_hud_panel_strafehud_bar_neutral_alpha * panel_fg_alpha, 1);
+       if((alpha1 + alpha2) == 0) return;
+
+       float ratio1 = gradientOffset / original_width;
+       if(gradientType == STRAFEHUD_GRADIENT_LEFT)
+               ratio1 = 1 - ratio1;
+
+       float ratio2 = (gradientOffset + size.x) / original_width;
+       if(gradientType == STRAFEHUD_GRADIENT_LEFT)
+               ratio2 = 1 - ratio2;
+
+       vector origin = HUD_Shift(panel_pos);
+       offset = HUD_ScaleX(offset);
+       size = HUD_Scale(size);
+
+       R_BeginPolygon("", DRAWFLAG_NORMAL, true);
+       R_PolygonVertex(origin + eX *  offset,                         '0 0 0', color1, alpha1 * (1 - ratio1));
+       R_PolygonVertex(origin + eX *  offset           + eY * size.y, '0 0 0', color1, alpha1 * (1 - ratio1));
+       R_PolygonVertex(origin + eX * (offset + size.x) + eY * size.y, '0 0 0', color1, alpha1 * (1 - ratio2));
+       R_PolygonVertex(origin + eX * (offset + size.x),               '0 0 0', color1, alpha1 * (1 - ratio2));
+       R_EndPolygon();
+
+       R_BeginPolygon("", DRAWFLAG_NORMAL, true);
+       R_PolygonVertex(origin + eX *  offset,                         '0 0 0', color2, alpha2 * ratio1);
+       R_PolygonVertex(origin + eX *  offset           + eY * size.y, '0 0 0', color2, alpha2 * ratio1);
+       R_PolygonVertex(origin + eX * (offset + size.x) + eY * size.y, '0 0 0', color2, alpha2 * ratio2);
+       R_PolygonVertex(origin + eX * (offset + size.x),               '0 0 0', color2, alpha2 * ratio2);
+       R_EndPolygon();
+}
+
 // draw the strafe arrows (inspired by drawspritearrow() in common/mutators/mutator/waypoints/waypointsprites.qc)
 void StrafeHUD_DrawStrafeArrow(vector origin, float size, vector color, float alpha, bool flipped, float connection_width)
 {
index 1f366a20f16795377525d96e7226e585bd6625da..b3ec1a26e5958139aa26cae8e7e577cfc802392e 100644 (file)
@@ -3,5 +3,6 @@
 
 void StrafeHUD_DrawStrafeHUD(float, float, vector, float, int, int, bool, float);
 void StrafeHUD_DrawGradient(vector, vector, vector, float, float, float, float, float, int, float);
+void StrafeHUD_DrawGradientFast(vector, vector, vector, float, float, float, float, int);
 void StrafeHUD_DrawStrafeArrow(vector, float, vector, float, bool, float);
 bool StrafeHUD_DrawTextIndicator(string, float, vector, float, float, float, int);