diff options
Diffstat (limited to '')
| -rw-r--r-- | src/studio.cpp | 46 |
1 files changed, 13 insertions, 33 deletions
diff --git a/src/studio.cpp b/src/studio.cpp index 086d213..cf145d1 100644 --- a/src/studio.cpp +++ b/src/studio.cpp | |||
| @@ -199,20 +199,21 @@ ModelExecFn g_orig_model_exec = nullptr; | |||
| 199 | ForceOverrideFn g_force_override = nullptr; | 199 | ForceOverrideFn g_force_override = nullptr; |
| 200 | void *g_style_mats[7] = {}; | 200 | void *g_style_mats[7] = {}; |
| 201 | 201 | ||
| 202 | void *viewmodel_material(); | ||
| 203 | |||
| 204 | const char *chams_material_name(int idx) { | 202 | const char *chams_material_name(int idx) { |
| 205 | switch (idx) { | 203 | switch (idx) { |
| 206 | case 1: return "debug/debugwireframe"; | 204 | case 1: return "debug/debugwireframe"; |
| 207 | case 2: | 205 | case 2: |
| 206 | case 5: return "debug/debugtranslucentmodelhulls"; | ||
| 208 | case 3: | 207 | case 3: |
| 209 | case 4: | 208 | case 4: |
| 210 | case 5: | ||
| 211 | case 6: | 209 | case 6: |
| 212 | default: return "debug/debugtranslucentsinglecolor"; | 210 | default: return "debug/debugtranslucentsinglecolor"; |
| 213 | } | 211 | } |
| 214 | } | 212 | } |
| 215 | 213 | ||
| 214 | // Never call FindMaterial here: this runs inside DrawModelExecute, where | ||
| 215 | // loading a material can crash the material system. chams_preload fills the | ||
| 216 | // cache from outer_draw instead. | ||
| 216 | void *style_material(int idx) { | 217 | void *style_material(int idx) { |
| 217 | if (idx < 0) idx = 0; | 218 | if (idx < 0) idx = 0; |
| 218 | if (idx > 6) idx = 6; | 219 | if (idx > 6) idx = 6; |
| @@ -220,17 +221,7 @@ void *style_material(int idx) { | |||
| 220 | return g_style_mats[idx]; | 221 | return g_style_mats[idx]; |
| 221 | if (g_style_mats[3]) | 222 | if (g_style_mats[3]) |
| 222 | return g_style_mats[3]; | 223 | return g_style_mats[3]; |
| 223 | return viewmodel_material(); | 224 | return nullptr; |
| 224 | } | ||
| 225 | |||
| 226 | // Viewmodels need a model shader; vgui materials do not draw skinned models. | ||
| 227 | void *viewmodel_material() { | ||
| 228 | if (g_style_mats[3]) | ||
| 229 | return g_style_mats[3]; | ||
| 230 | static void *mat = nullptr; | ||
| 231 | if (!mat) | ||
| 232 | mat = world_find_material("debug/debugtranslucentsinglecolor"); | ||
| 233 | return mat; | ||
| 234 | } | 225 | } |
| 235 | 226 | ||
| 236 | void chams_color(void *mat, float r, float g, float b) { | 227 | void chams_color(void *mat, float r, float g, float b) { |
| @@ -260,6 +251,7 @@ void chams_alpha(void *mat, float a) { | |||
| 260 | void chams_apply(void *mat, bool ignorez, int style, bool force_white, | 251 | void chams_apply(void *mat, bool ignorez, int style, bool force_white, |
| 261 | const int *rgb, bool znearer) { | 252 | const int *rgb, bool znearer) { |
| 262 | using FlagFn = void (*)(void *, int, bool); | 253 | using FlagFn = void (*)(void *, int, bool); |
| 254 | bool additive = style == 2 || style == 5; | ||
| 263 | float r = force_white ? 1.0f : (float)rgb[0] / 255.0f; | 255 | float r = force_white ? 1.0f : (float)rgb[0] / 255.0f; |
| 264 | float g = force_white ? 1.0f : (float)rgb[1] / 255.0f; | 256 | float g = force_white ? 1.0f : (float)rgb[1] / 255.0f; |
| 265 | float b = force_white ? 1.0f : (float)rgb[2] / 255.0f; | 257 | float b = force_white ? 1.0f : (float)rgb[2] / 255.0f; |
| @@ -268,12 +260,12 @@ void chams_apply(void *mat, bool ignorez, int style, bool force_white, | |||
| 268 | // 0 Flat, 1 Wireframe, 2 Additive, 3 Solid, 4 White, 5 Fullbright | 260 | // 0 Flat, 1 Wireframe, 2 Additive, 3 Solid, 4 White, 5 Fullbright |
| 269 | // (additive white glow), 6 Glow outline (solid base; the wireframe overlay | 261 | // (additive white glow), 6 Glow outline (solid base; the wireframe overlay |
| 270 | // is a second draw with ZNEARER so its contour is not hidden by the base). | 262 | // is a second draw with ZNEARER so its contour is not hidden by the base). |
| 263 | // Styles 2/5 use debug/debugtranslucentmodelhulls, whose VMT already has | ||
| 264 | // $additive; ADDITIVE on debugtranslucentsinglecolor did nothing. | ||
| 271 | vfunc<FlagFn>(mat, 29)(mat, 1 << 15 /* IGNOREZ */, ignorez); | 265 | vfunc<FlagFn>(mat, 29)(mat, 1 << 15 /* IGNOREZ */, ignorez); |
| 272 | vfunc<FlagFn>(mat, 29)(mat, 1 << 21 /* TRANSLUCENT */, rgb[3] < 255); | ||
| 273 | vfunc<FlagFn>(mat, 29)(mat, 1 << 10 /* ZNEARER */, znearer); | 266 | vfunc<FlagFn>(mat, 29)(mat, 1 << 10 /* ZNEARER */, znearer); |
| 274 | vfunc<FlagFn>(mat, 29)(mat, 1 << 28 /* WIREFRAME */, style == 1); | 267 | vfunc<FlagFn>(mat, 29)(mat, 1 << 28 /* WIREFRAME */, style == 1); |
| 275 | vfunc<FlagFn>(mat, 29)(mat, 1 << 7 /* ADDITIVE */, | 268 | vfunc<FlagFn>(mat, 29)(mat, 1 << 7 /* ADDITIVE */, additive); |
| 276 | style == 2 || style == 5); | ||
| 277 | vfunc<FlagFn>(mat, 29)(mat, 1 << 12 /* FLAT */, style == 0); | 269 | vfunc<FlagFn>(mat, 29)(mat, 1 << 12 /* FLAT */, style == 0); |
| 278 | vfunc<FlagFn>(mat, 29)(mat, 1 << 6 /* SELFILLUM */, style == 5); | 270 | vfunc<FlagFn>(mat, 29)(mat, 1 << 6 /* SELFILLUM */, style == 5); |
| 279 | } | 271 | } |
| @@ -281,7 +273,6 @@ void chams_apply(void *mat, bool ignorez, int style, bool force_white, | |||
| 281 | void chams_reset(void *mat) { | 273 | void chams_reset(void *mat) { |
| 282 | using FlagFn = void (*)(void *, int, bool); | 274 | using FlagFn = void (*)(void *, int, bool); |
| 283 | vfunc<FlagFn>(mat, 29)(mat, 1 << 15, false); | 275 | vfunc<FlagFn>(mat, 29)(mat, 1 << 15, false); |
| 284 | vfunc<FlagFn>(mat, 29)(mat, 1 << 21, false); | ||
| 285 | vfunc<FlagFn>(mat, 29)(mat, 1 << 10, false); | 276 | vfunc<FlagFn>(mat, 29)(mat, 1 << 10, false); |
| 286 | vfunc<FlagFn>(mat, 29)(mat, 1 << 28, false); | 277 | vfunc<FlagFn>(mat, 29)(mat, 1 << 28, false); |
| 287 | vfunc<FlagFn>(mat, 29)(mat, 1 << 7, false); | 278 | vfunc<FlagFn>(mat, 29)(mat, 1 << 7, false); |
| @@ -317,21 +308,6 @@ void hkdModelExecute(void *self, const void *state, const void *info, | |||
| 317 | return false; | 308 | return false; |
| 318 | bool white = style == 4 || style == 5; | 309 | bool white = style == 4 || style == 5; |
| 319 | const int *use_rgb = rgb; | 310 | const int *use_rgb = rgb; |
| 320 | // Additive blending vanishes against bright backgrounds (sky, | ||
| 321 | // white walls, strong fog), which made the viewmodel disappear in | ||
| 322 | // some places. Lay down a faint translucent base so the first-person | ||
| 323 | // model keeps a silhouette on bright backgrounds without turning | ||
| 324 | // into an opaque blob; the additive pass still provides the glow. | ||
| 325 | if (is_vm && (style == 2 || style == 5) && rgb[3] > 0) { | ||
| 326 | int ba = rgb[3] / 8; | ||
| 327 | if (ba < 16) | ||
| 328 | ba = 16; | ||
| 329 | int drgb[4] = {rgb[0], rgb[1], rgb[2], ba}; | ||
| 330 | chams_apply(mat, ignorez, 3, false, drgb, false); | ||
| 331 | g_force_override(self, mat, 0 /* OVERRIDE_NORMAL */); | ||
| 332 | g_orig_model_exec(self, state, info, bone); | ||
| 333 | chams_reset(mat); | ||
| 334 | } | ||
| 335 | chams_apply(mat, ignorez, style, white, use_rgb, false); | 311 | chams_apply(mat, ignorez, style, white, use_rgb, false); |
| 336 | g_force_override(self, mat, 0 /* OVERRIDE_NORMAL */); | 312 | g_force_override(self, mat, 0 /* OVERRIDE_NORMAL */); |
| 337 | g_orig_model_exec(self, state, info, bone); | 313 | g_orig_model_exec(self, state, info, bone); |
| @@ -391,6 +367,10 @@ void chams_preload() { | |||
| 391 | continue; | 367 | continue; |
| 392 | void *m = world_find_material(chams_material_name(i)); | 368 | void *m = world_find_material(chams_material_name(i)); |
| 393 | if (m) { | 369 | if (m) { |
| 370 | // FindMaterial can hand back an unreferenced material; the engine warns | ||
| 371 | // ("bad reference count 0") and may reset its vars when it is bound. | ||
| 372 | using RefFn = void (*)(void *); | ||
| 373 | vfunc<RefFn>(m, 12)(m); // IMaterial::IncrementReferenceCount | ||
| 394 | g_style_mats[i] = m; | 374 | g_style_mats[i] = m; |
| 395 | logf("chams: preloaded style %d %s = %p", i, chams_material_name(i), m); | 375 | logf("chams: preloaded style %d %s = %p", i, chams_material_name(i), m); |
| 396 | } | 376 | } |
