From f67ee1ef7e3eff3cd746fc97be98195e68c1368d Mon Sep 17 00:00:00 2001 From: salmonik Date: Wed, 4 Nov 2026 19:06:06 +0100 Subject: Chams: fix the flat viewmodel, glow outline and fullbright styles - Flat uses the solid model shader with the FLAT flag on the viewmodel; vgui/white does not draw skinned models and made the hands vanish. - Glow outline draws its wireframe contour with ZNEARER and a brightened colour, so the solid base no longer hides the contour. - Fullbright is now additive + self-illuminated with the colour lifted toward white, so it reads differently from Solid and Additive glow. --- src/studio.cpp | 38 +++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) (limited to 'src/studio.cpp') diff --git a/src/studio.cpp b/src/studio.cpp index 803b6b2..301e781 100644 --- a/src/studio.cpp +++ b/src/studio.cpp @@ -249,25 +249,28 @@ void chams_color(void *mat, float r, float g, float b) { } void chams_apply(void *mat, bool ignorez, int style, bool force_white, - const int *rgb) { + const int *rgb, bool znearer) { using FlagFn = void (*)(void *, int, bool); float r = force_white ? 1.0f : (float)rgb[0] / 255.0f; float g = force_white ? 1.0f : (float)rgb[1] / 255.0f; float b = force_white ? 1.0f : (float)rgb[2] / 255.0f; chams_color(mat, r, g, b); - // 0 Flat, 1 Wireframe, 2 Additive, 3 Solid, 4 White, 5 Fullbright, - // 6 Glow outline (solid base; the wireframe overlay is a second draw). + // 0 Flat, 1 Wireframe, 2 Additive, 3 Solid, 4 White, 5 Fullbright + // (additive white glow), 6 Glow outline (solid base; the wireframe overlay + // is a second draw with ZNEARER so its contour is not hidden by the base). vfunc(mat, 29)(mat, 1 << 15 /* IGNOREZ */, ignorez); + vfunc(mat, 29)(mat, 1 << 10 /* ZNEARER */, znearer); vfunc(mat, 29)(mat, 1 << 28 /* WIREFRAME */, style == 1); - vfunc(mat, 29)(mat, 1 << 7 /* ADDITIVE */, style == 2); - vfunc(mat, 29)(mat, 1 << 12 /* FLAT */, - style == 0 || style == 5); + vfunc(mat, 29)(mat, 1 << 7 /* ADDITIVE */, + style == 2 || style == 5); + vfunc(mat, 29)(mat, 1 << 12 /* FLAT */, style == 0); vfunc(mat, 29)(mat, 1 << 6 /* SELFILLUM */, style == 5); } void chams_reset(void *mat) { using FlagFn = void (*)(void *, int, bool); vfunc(mat, 29)(mat, 1 << 15, false); + vfunc(mat, 29)(mat, 1 << 10, false); vfunc(mat, 29)(mat, 1 << 28, false); vfunc(mat, 29)(mat, 1 << 7, false); vfunc(mat, 29)(mat, 1 << 12, false); @@ -297,17 +300,34 @@ void hkdModelExecute(void *self, const void *state, const void *info, if (style < 0) style = 0; if (style > 6) style = 6; void *mat = style_material(style); + // vgui/white (Flat) does not draw skinned models, so the viewmodel + // uses the solid model shader with the same FLAT flag. + if (is_vm && style == 0) + mat = viewmodel_material(); if (!mat) return false; bool white = style == 4; - chams_apply(mat, ignorez, style, white, rgb); + // Fullbright is an additive, self-illuminated version of the + // chosen colour: lift it toward white so it reads brighter than + // the plain additive style. + int brgb[3]; + const int *use_rgb = rgb; + if (style == 5) { + for (int i = 0; i < 3; i++) + brgb[i] = rgb[i] + (255 - rgb[i]) / 2; + use_rgb = brgb; + } + chams_apply(mat, ignorez, style, white, use_rgb, false); g_force_override(self, mat, 0 /* OVERRIDE_NORMAL */); g_orig_model_exec(self, state, info, bone); if (style == 6) { - // Solid base plus a wireframe contour pass for depth. + // Solid base plus a wireframe contour pass for depth. Brighten + // the contour and bias it forward so the base cannot bury it. void *wire = g_style_mats[1]; if (wire && wire != mat) { - chams_apply(wire, ignorez, 1, false, rgb); + int wrgb[3] = {(rgb[0] + 255) / 2, (rgb[1] + 255) / 2, + (rgb[2] + 255) / 2}; + chams_apply(wire, ignorez, 1, false, wrgb, true); g_force_override(self, wire, 0); g_orig_model_exec(self, state, info, bone); chams_reset(wire); -- cgit v1.2.3