From d7201a987ba6cc56fda3d3ea69275307385f7c3e Mon Sep 17 00:00:00 2001 From: salmonik Date: Wed, 4 Nov 2026 18:43:28 +0100 Subject: Chams: preload style materials outside the model draw FindMaterial inside DrawModelExecute did not load the style VMTs, so every style fell back to the solid material. Preload the six style materials from outer_draw (throttled) and have the render hook use the cached pointers only. world_find_material now returns only the exact requested material; the caller falls back to the solid style. Add a vgui/white probe and per-style preload logs. --- src/hl2h.h | 1 + src/menu.cpp | 1 + src/studio.cpp | 65 ++++++++++++++++++++++++++++++++++++++++++++-------------- src/world.cpp | 15 +------------- 4 files changed, 53 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/hl2h.h b/src/hl2h.h index 1be1bb1..0f7e1f2 100644 --- a/src/hl2h.h +++ b/src/hl2h.h @@ -339,6 +339,7 @@ bool esp_is_npc_index(int idx); bool esp_is_viewmodel_index(int idx); void *world_find_material(const char *name); void chams_init(); +void chams_preload(); int engine_get_local_player(); void draw_text_col(int x, int y, const char *s, int r, int g, int b); void draw_text_small_col(int x, int y, const char *s, int r, int g, int b); diff --git a/src/menu.cpp b/src/menu.cpp index 376a779..6a3c607 100644 --- a/src/menu.cpp +++ b/src/menu.cpp @@ -999,6 +999,7 @@ void outer_draw() { world_tint_update(); prop_tint_update(); fog_update(); + chams_preload(); gui_handle_input(); // HL2H_DRAW_TEST=1 draws a probe rect without needing the GUI open static bool draw_test = getenv("HL2H_DRAW_TEST") != nullptr; diff --git a/src/studio.cpp b/src/studio.cpp index 1ca8ad7..44d1bb4 100644 --- a/src/studio.cpp +++ b/src/studio.cpp @@ -19,6 +19,7 @@ #include #include #include +#include namespace { @@ -196,34 +197,37 @@ using ForceOverrideFn = void (*)(void *, void *, int); void *g_modelrender = nullptr; ModelExecFn g_orig_model_exec = nullptr; ForceOverrideFn g_force_override = nullptr; -void *g_chams_mat = nullptr; -int g_chams_mat_idx = -1; +void *g_style_mats[6] = {}; + +void *viewmodel_material(); const char *chams_material_name(int idx) { - (void)idx; - // Only this debug material is reliably resident in the base game; the other - // debug VMTs are not loaded and FindMaterial does not make them available. - // Visual styles are applied as material flags instead. - return "debug/debugtranslucentsinglecolor"; + switch (idx) { + case 1: return "debug/debugwireframe"; + case 2: return "debug/additivevertexcolorvertexalpha"; + case 3: return "debug/debugtranslucentsinglecolor"; + case 4: return "debug/debugtranslucentvertexcolor"; + case 5: return "debug/debugmrmfullbright2"; + default: return "models/debug/debugwhite"; + } } void *chams_material() { int idx = g_chams_mat_index; if (idx < 0) idx = 0; if (idx > 5) idx = 5; - if (g_chams_mat && g_chams_mat_idx == idx) - return g_chams_mat; - g_chams_mat = world_find_material(chams_material_name(idx)); - if (!g_chams_mat) - g_chams_mat = world_find_material("debug/debugtranslucentsinglecolor"); - g_chams_mat_idx = idx; - logf("chams: style %d -> %p", idx, g_chams_mat); - return g_chams_mat; + if (g_style_mats[idx]) + return g_style_mats[idx]; + if (g_style_mats[3]) + return g_style_mats[3]; + return viewmodel_material(); } // Viewmodels need a model shader; the VGUI white materials used by some // styles do not draw skinned models and make the hands/weapon disappear. void *viewmodel_material() { + if (g_style_mats[3]) + return g_style_mats[3]; static void *mat = nullptr; if (!mat) mat = world_find_material("debug/debugtranslucentsinglecolor"); @@ -307,6 +311,37 @@ void hkdModelExecute(void *self, const void *state, const void *info, } // namespace +static double chams_now() { + timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + return (double)ts.tv_sec + (double)ts.tv_nsec * 1e-9; +} + +// Called from outer_draw (outside the model draw) so FindMaterial can load +// the style VMTs. The render hook only reads the cached pointers. +void chams_preload() { + static double last = 0.0; + static bool probed = false; + double now = chams_now(); + if (now - last < 1.5) + return; + last = now; + if (!probed) { + probed = true; + void *probe = world_find_material("vgui/white"); + logf("chams: probe vgui/white = %p", probe); + } + for (int i = 0; i < 6; i++) { + if (g_style_mats[i]) + continue; + void *m = world_find_material(chams_material_name(i)); + if (m) { + g_style_mats[i] = m; + logf("chams: preloaded style %d %s = %p", i, chams_material_name(i), m); + } + } +} + void chams_init() { if (g_modelrender || !g_iface.modelrender) { if (!g_iface.modelrender) diff --git a/src/world.cpp b/src/world.cpp index d071281..ea186b4 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -1065,19 +1065,6 @@ void *world_find_material(const char *name) { logf("chams: material %s = %p", name, mat); return mat; } - static const char *fallbacks[] = {"debug/debugtranslucentsinglecolor", - "models/debug/debugwhite", "vgui/white", - nullptr}; - for (int i = 0; fallbacks[i]; i++) { - mat = walk(fallbacks[i]); - if (!mat) - mat = find(fallbacks[i]); - if (mat) { - logf("chams: material %s (fallback for %s) = %p", fallbacks[i], name, - mat); - return mat; - } - } - logf("chams: material %s not found", name); + logd("chams: material %s not found", name); return nullptr; } -- cgit v1.2.3