diff options
| author | salmonik <salmonik@tuta.io> | 2026-11-04 18:37:04 +0100 |
|---|---|---|
| committer | salmonik <salmonik@tuta.io> | 2026-11-04 18:37:04 +0100 |
| commit | 8e6efa22610be51391459238a2c5e16d1ff1a060 (patch) | |
| tree | ba5c80fe079967fd93bcb270aeeb304e7e1da698 | |
| parent | Chams: model-safe styles and a dedicated viewmodel material (diff) | |
| download | hl2h-8e6efa22610be51391459238a2c5e16d1ff1a060.tar.gz hl2h-8e6efa22610be51391459238a2c5e16d1ff1a060.zip | |
Chams: style flags on the resident debug material
The base game only has debug/debugtranslucentsinglecolor resident, so the
other debug VMTs silently fell back to it and every style looked flat. Use that
material for every style and apply material flags instead: FLAT, WIREFRAME,
ADDITIVE, and FLAT|SELFILLUM for fullbright; white forces the colour. Flags are
cleared after the draw.
| -rw-r--r-- | CONTEXT.md | 21 | ||||
| -rw-r--r-- | src/studio.cpp | 53 |
2 files changed, 43 insertions, 31 deletions
| @@ -296,20 +296,17 @@ vocabulary / decisions. | |||
| 296 | vars (IMaterialVar slot 11, SetVecValue 3-float slot 11), because some forced | 296 | vars (IMaterialVar slot 11, SetVecValue 3-float slot 11), because some forced |
| 297 | materials ignore ColorModulate. The shared material's flag and colour are | 297 | materials ignore ColorModulate. The shared material's flag and colour are |
| 298 | restored to (false, white) after the draw. | 298 | restored to (false, white) after the draw. |
| 299 | - Material lookup walks the `IMaterialSystem` list (`world_find_material`), with | 299 | - The base game does not have the other debug VMTs resident and `FindMaterial` |
| 300 | `FindMaterial` (slot 71) as the fallback. The **exact requested style** is | 300 | does not make them available reliably, so all styles use the resident |
| 301 | tried first (resident, then loaded on demand), and only if that fails does it | 301 | `debug/debugtranslucentsinglecolor` and differ by material flags: |
| 302 | fall back to `debug/debugtranslucentsinglecolor`/debugwhite/vgui white. | 302 | 0 Flat (`FLAT`), 1 Wireframe (`WIREFRAME`), 2 Additive (`ADDITIVE`), |
| 303 | Styles: 0 Flat (`models/debug/debugwhite`), 1 Wireframe | 303 | 3 Solid (none), 4 White (colour forced to white), 5 Fullbright |
| 304 | (`debug/debugwireframe`), 2 Additive (`debug/additivevertexcolorvertexalpha`), | 304 | (`FLAT|SELFILLUM`). Flags are reset after the draw. |
| 305 | 3 Solid (`debug/debugtranslucentsinglecolor`), 4 White | ||
| 306 | (`debug/debugtranslucentvertexcolor`), 5 Fullbright | ||
| 307 | (`debug/debugmrmfullbright2`). The chosen material name is logged. | ||
| 308 | - `Viewmodel (hands/weapon)` applies the override to entities whose class | 305 | - `Viewmodel (hands/weapon)` applies the override to entities whose class |
| 309 | contains `viewmodel` or whose model path is `.../v_...`. Viewmodels always | 306 | contains `viewmodel` or whose model path is `.../v_...`. Viewmodels always |
| 310 | use the model-safe solid material (`debug/debugtranslucentsinglecolor`); | 307 | use the solid style (no style flags) with the selected colour; VGUI/white |
| 311 | VGUI/white materials do not draw skinned models and made the hands/weapon | 308 | materials do not draw skinned models and made the hands/weapon disappear. |
| 312 | disappear. Only the normal-depth pass is used. | 309 | Only the normal-depth pass is used. |
| 313 | - Feature is off by default; `[chams] active/bind/walls/viewmodel/material/r/g/b`, | 310 | - Feature is off by default; `[chams] active/bind/walls/viewmodel/material/r/g/b`, |
| 314 | with Through walls, Viewmodel, a Material dropdown and colour in the Visuals | 311 | with Through walls, Viewmodel, a Material dropdown and colour in the Visuals |
| 315 | card. | 312 | card. |
diff --git a/src/studio.cpp b/src/studio.cpp index f67936c..1ca8ad7 100644 --- a/src/studio.cpp +++ b/src/studio.cpp | |||
| @@ -200,14 +200,11 @@ void *g_chams_mat = nullptr; | |||
| 200 | int g_chams_mat_idx = -1; | 200 | int g_chams_mat_idx = -1; |
| 201 | 201 | ||
| 202 | const char *chams_material_name(int idx) { | 202 | const char *chams_material_name(int idx) { |
| 203 | switch (idx) { | 203 | (void)idx; |
| 204 | case 1: return "debug/debugwireframe"; | 204 | // Only this debug material is reliably resident in the base game; the other |
| 205 | case 2: return "debug/additivevertexcolorvertexalpha"; | 205 | // debug VMTs are not loaded and FindMaterial does not make them available. |
| 206 | case 3: return "debug/debugtranslucentsinglecolor"; | 206 | // Visual styles are applied as material flags instead. |
| 207 | case 4: return "debug/debugtranslucentvertexcolor"; | 207 | return "debug/debugtranslucentsinglecolor"; |
| 208 | case 5: return "debug/debugmrmfullbright2"; | ||
| 209 | default: return "models/debug/debugwhite"; | ||
| 210 | } | ||
| 211 | } | 208 | } |
| 212 | 209 | ||
| 213 | void *chams_material() { | 210 | void *chams_material() { |
| @@ -248,12 +245,29 @@ void chams_color(void *mat, float r, float g, float b) { | |||
| 248 | vfunc<ColorFn>(mat, 28)(mat, r, g, b); | 245 | vfunc<ColorFn>(mat, 28)(mat, r, g, b); |
| 249 | } | 246 | } |
| 250 | 247 | ||
| 251 | void chams_apply(void *mat, bool ignorez) { | 248 | void chams_apply(void *mat, bool ignorez, int style, bool force_white) { |
| 249 | using FlagFn = void (*)(void *, int, bool); | ||
| 250 | float r = force_white ? 1.0f : (float)g_chams_rgb[0] / 255.0f; | ||
| 251 | float g = force_white ? 1.0f : (float)g_chams_rgb[1] / 255.0f; | ||
| 252 | float b = force_white ? 1.0f : (float)g_chams_rgb[2] / 255.0f; | ||
| 253 | chams_color(mat, r, g, b); | ||
| 254 | // 0 Flat, 1 Wireframe, 2 Additive, 3 Solid, 4 White, 5 Fullbright. | ||
| 255 | vfunc<FlagFn>(mat, 29)(mat, 1 << 15 /* IGNOREZ */, ignorez); | ||
| 256 | vfunc<FlagFn>(mat, 29)(mat, 1 << 28 /* WIREFRAME */, style == 1); | ||
| 257 | vfunc<FlagFn>(mat, 29)(mat, 1 << 7 /* ADDITIVE */, style == 2); | ||
| 258 | vfunc<FlagFn>(mat, 29)(mat, 1 << 12 /* FLAT */, | ||
| 259 | style == 0 || style == 5); | ||
| 260 | vfunc<FlagFn>(mat, 29)(mat, 1 << 6 /* SELFILLUM */, style == 5); | ||
| 261 | } | ||
| 262 | |||
| 263 | void chams_reset(void *mat) { | ||
| 252 | using FlagFn = void (*)(void *, int, bool); | 264 | using FlagFn = void (*)(void *, int, bool); |
| 253 | chams_color(mat, (float)g_chams_rgb[0] / 255.0f, | 265 | vfunc<FlagFn>(mat, 29)(mat, 1 << 15, false); |
| 254 | (float)g_chams_rgb[1] / 255.0f, | 266 | vfunc<FlagFn>(mat, 29)(mat, 1 << 28, false); |
| 255 | (float)g_chams_rgb[2] / 255.0f); | 267 | vfunc<FlagFn>(mat, 29)(mat, 1 << 7, false); |
| 256 | vfunc<FlagFn>(mat, 29)(mat, 1 << 15 /* MATERIAL_VAR_IGNOREZ */, ignorez); | 268 | vfunc<FlagFn>(mat, 29)(mat, 1 << 12, false); |
| 269 | vfunc<FlagFn>(mat, 29)(mat, 1 << 6, false); | ||
| 270 | chams_color(mat, 1.0f, 1.0f, 1.0f); | ||
| 257 | } | 271 | } |
| 258 | 272 | ||
| 259 | void hkdModelExecute(void *self, const void *state, const void *info, | 273 | void hkdModelExecute(void *self, const void *state, const void *info, |
| @@ -269,19 +283,20 @@ void hkdModelExecute(void *self, const void *state, const void *info, | |||
| 269 | if (is_npc || is_vm) { | 283 | if (is_npc || is_vm) { |
| 270 | void *mat = is_vm ? viewmodel_material() : chams_material(); | 284 | void *mat = is_vm ? viewmodel_material() : chams_material(); |
| 271 | if (mat) { | 285 | if (mat) { |
| 286 | int style = is_vm ? 3 : g_chams_mat_index; | ||
| 287 | if (style < 0) style = 0; | ||
| 288 | if (style > 5) style = 5; | ||
| 289 | bool white = !is_vm && style == 4; | ||
| 272 | if (g_chams_walls && !is_vm) { | 290 | if (g_chams_walls && !is_vm) { |
| 273 | chams_apply(mat, true); | 291 | chams_apply(mat, true, style, white); |
| 274 | g_force_override(self, mat, 0 /* OVERRIDE_NORMAL */); | 292 | g_force_override(self, mat, 0 /* OVERRIDE_NORMAL */); |
| 275 | g_orig_model_exec(self, state, info, bone); | 293 | g_orig_model_exec(self, state, info, bone); |
| 276 | } | 294 | } |
| 277 | chams_apply(mat, false); | 295 | chams_apply(mat, false, style, white); |
| 278 | g_force_override(self, mat, 0); | 296 | g_force_override(self, mat, 0); |
| 279 | g_orig_model_exec(self, state, info, bone); | 297 | g_orig_model_exec(self, state, info, bone); |
| 280 | g_force_override(self, nullptr, 0); | 298 | g_force_override(self, nullptr, 0); |
| 281 | // debugwhite is shared: restore colour and depth behaviour. | 299 | chams_reset(mat); |
| 282 | using FlagFn = void (*)(void *, int, bool); | ||
| 283 | vfunc<FlagFn>(mat, 29)(mat, 1 << 15, false); | ||
| 284 | chams_color(mat, 1.0f, 1.0f, 1.0f); | ||
| 285 | return; | 300 | return; |
| 286 | } | 301 | } |
| 287 | } | 302 | } |
