diff options
| author | salmonik <salmonik@tuta.io> | 2026-11-04 11:49:32 +0100 |
|---|---|---|
| committer | salmonik <salmonik@tuta.io> | 2026-11-04 11:49:45 +0100 |
| commit | cc06dab406a0086ddcb9e4ced3759614f65e069e (patch) | |
| tree | 3506bc169caa80cddfc7a206bf54c74a9c796048 | |
| parent | Props: force colour inside prop DrawModel; no prop material tint (diff) | |
| download | hl2h-cc06dab406a0086ddcb9e4ced3759614f65e069e.tar.gz hl2h-cc06dab406a0086ddcb9e4ced3759614f65e069e.zip | |
Props: remove studio diagnostics; document the prop tint path
Drop the temporary DrawModel/SetColor logs now that the prop tint works, and
document the IStudioRender hook layout, the short model-name format used for
prop detection, the SetColor-before-DrawModel ordering, and why prop
materials cannot be tinted directly.
Diffstat (limited to '')
| -rw-r--r-- | CONTEXT.md | 26 | ||||
| -rw-r--r-- | src/studio.cpp | 20 |
2 files changed, 21 insertions, 25 deletions
| @@ -329,11 +329,27 @@ vocabulary / decisions. | |||
| 329 | already-loaded `materialsystem.so` and walk every material with | 329 | already-loaded `materialsystem.so` and walk every material with |
| 330 | `FirstMaterial` / `NextMaterial` / `GetMaterial`. | 330 | `FirstMaterial` / `NextMaterial` / `GetMaterial`. |
| 331 | - `IMaterial::ColorModulate(r,g,b)` is applied to materials whose | 331 | - `IMaterial::ColorModulate(r,g,b)` is applied to materials whose |
| 332 | `GetTextureGroupName()` is `World textures` (sky names excluded), to | 332 | `GetTextureGroupName()` is `World textures` (sky names excluded) and to |
| 333 | `SkyBox textures` (or names containing `sky`), and to prop materials whose | 333 | `SkyBox textures` (or names containing `sky`). Lightmaps are not touched. |
| 334 | name starts with `models/props` (static props and prop_physics share those | 334 | - Props are NOT tinted through their materials: VertexLitGeneric materials get |
| 335 | model materials; NPC/player/weapon materials are excluded). Lightmaps are | 335 | their colour modulation from `IStudioRender`, which the engine sets per |
| 336 | not touched. | 336 | model draw (white), so the material var is overridden. `src/studio.cpp` |
| 337 | hooks the `VStudioRender025` interface object instead: | ||
| 338 | `SetColorModulation`/`SetAlphaModulation` (slots 27/28), `DrawModel` (29), | ||
| 339 | `DrawModelStaticProp` (30) and `DrawModelArray` (46), all checked against | ||
| 340 | `CStudioRenderContext`'s vtable in `studiorender.so`. | ||
| 341 | `DrawModel` checks `DrawModelInfo_t::m_pStudioHdr->name`; note the name is | ||
| 342 | the short form with Windows separators (`props_junk\wood_crate002a.mdl`, | ||
| 343 | no `models/` prefix), so prop detection matches `props/`, `props\` and | ||
| 344 | `props_` after stripping `models/` (excluding `props_skybox`). For a prop it | ||
| 345 | sets the prop colour right before calling the original draw; setting the | ||
| 346 | colour from a flag inside the draw does not work because the engine calls | ||
| 347 | `SetColorModulation(1,1,1)` *before* `DrawModel`. | ||
| 348 | Do not force `SetAlphaModulation` there: the earlier attempt produced | ||
| 349 | error-material props and a material-system crash. | ||
| 350 | - `prop_tint_update()` also writes `m_clrRender` on prop entities (dynamic | ||
| 351 | props) as a secondary path; the netvar resolver rejects offset 0 (an | ||
| 352 | embedded-table false positive) and only accepts 0x20..0x2000. | ||
| 337 | - Slot map (2013 SDK layout, registered under `VMaterialSystem080`): | 353 | - Slot map (2013 SDK layout, registered under `VMaterialSystem080`): |
| 338 | `IMaterialSystem` 73/74/75/76/77 = First/Next/Invalid/Get/GetNumMaterials; | 354 | `IMaterialSystem` 73/74/75/76/77 = First/Next/Invalid/Get/GetNumMaterials; |
| 339 | `IMaterial` 0/1/28 = GetName/GetTextureGroupName/ColorModulate. | 355 | `IMaterial` 0/1/28 = GetName/GetTextureGroupName/ColorModulate. |
diff --git a/src/studio.cpp b/src/studio.cpp index c4c3cfb..485b4fb 100644 --- a/src/studio.cpp +++ b/src/studio.cpp | |||
| @@ -40,8 +40,6 @@ bool g_installed = false; | |||
| 40 | int g_prop_depth = 0; | 40 | int g_prop_depth = 0; |
| 41 | int g_static_calls = 0; | 41 | int g_static_calls = 0; |
| 42 | int g_static_props = 0; | 42 | int g_static_props = 0; |
| 43 | int g_model_logs = 0; | ||
| 44 | int g_array_logs = 0; | ||
| 45 | 43 | ||
| 46 | bool prop_tint_on() { | 44 | bool prop_tint_on() { |
| 47 | return feature_active(FEAT_WORLD_TINT) && g_tint_prop_on; | 45 | return feature_active(FEAT_WORLD_TINT) && g_tint_prop_on; |
| @@ -89,15 +87,7 @@ bool is_prop_model(const char *name) { | |||
| 89 | strncmp(name, "props_", 6) == 0; | 87 | strncmp(name, "props_", 6) == 0; |
| 90 | } | 88 | } |
| 91 | 89 | ||
| 92 | int g_color_logs = 0; | ||
| 93 | |||
| 94 | void hook_set_color(void *self, const float *color) { | 90 | void hook_set_color(void *self, const float *color) { |
| 95 | if (g_color_logs < 10) { | ||
| 96 | g_color_logs++; | ||
| 97 | logf("studio: SetColorModulation depth=%d color=%.2f,%.2f,%.2f", | ||
| 98 | g_prop_depth, color ? color[0] : 0.0f, color ? color[1] : 0.0f, | ||
| 99 | color ? color[2] : 0.0f); | ||
| 100 | } | ||
| 101 | if (g_prop_depth > 0 && prop_tint_on()) { | 91 | if (g_prop_depth > 0 && prop_tint_on()) { |
| 102 | float c[4]; | 92 | float c[4]; |
| 103 | prop_color(c); | 93 | prop_color(c); |
| @@ -120,11 +110,6 @@ void hook_draw_model(void *self, void *results, void *info, void *bone, | |||
| 120 | void *flex, void *flex_delayed, int flags) { | 110 | void *flex, void *flex_delayed, int flags) { |
| 121 | const char *model = info_model_name(info); | 111 | const char *model = info_model_name(info); |
| 122 | bool prop = prop_tint_on() && is_prop_model(model); | 112 | bool prop = prop_tint_on() && is_prop_model(model); |
| 123 | if (g_model_logs < 10) { | ||
| 124 | g_model_logs++; | ||
| 125 | logf("studio: DrawModel model=\"%s\" prop=%d", model ? model : "?", | ||
| 126 | (int)prop); | ||
| 127 | } | ||
| 128 | if (prop) { | 113 | if (prop) { |
| 129 | float c[4]; | 114 | float c[4]; |
| 130 | prop_color(c); | 115 | prop_color(c); |
| @@ -140,11 +125,6 @@ void hook_draw_array(void *self, void *info, int count, void *instances, | |||
| 140 | int stride, int flags) { | 125 | int stride, int flags) { |
| 141 | const char *model = info_model_name(info); | 126 | const char *model = info_model_name(info); |
| 142 | bool prop = prop_tint_on() && is_prop_model(model); | 127 | bool prop = prop_tint_on() && is_prop_model(model); |
| 143 | if (g_array_logs < 10) { | ||
| 144 | g_array_logs++; | ||
| 145 | logf("studio: DrawModelArray count=%d model=\"%s\" prop=%d", count, | ||
| 146 | model ? model : "?", (int)prop); | ||
| 147 | } | ||
| 148 | if (prop) | 128 | if (prop) |
| 149 | g_prop_depth++; | 129 | g_prop_depth++; |
| 150 | g_orig_draw_array(self, info, count, instances, stride, flags); | 130 | g_orig_draw_array(self, info, count, instances, stride, flags); |
