diff options
| author | salmonik <salmonik@tuta.io> | 2026-11-04 00:43:49 +0100 |
|---|---|---|
| committer | salmonik <salmonik@tuta.io> | 2026-11-04 00:43:49 +0100 |
| commit | bbc08986d48f1c6dd88022a06f4c5ca2e651876d (patch) | |
| tree | ed0a6871b421d9b327393586caec813ca4488188 | |
| parent | Skybox image: power-of-two resize; upload at FRAME_RENDER_START (diff) | |
| download | hl2h-bbc08986d48f1c6dd88022a06f4c5ca2e651876d.tar.gz hl2h-bbc08986d48f1c6dd88022a06f4c5ca2e651876d.zip | |
Skybox image: drop Refresh/SetUndefined (crash after apply)
The last crash happened after "applied", in materialsystem while the renderer
walked a shader-parameter list that contained a null vtable entry. That points
at the Refresh()/SetUndefined experiment: undefining $hdrcompressedtexture
while the sky shader's static combo still expected it (and rebuilding state
mid-level) left a broken material.
Set the texture on $basetexture/$hdrbasetexture/$hdrcompressedtexture (and the
0/1/2 variants) and do neither SetUndefined nor Refresh: the visible-path
material binds its base texture dynamically, which is what made the earlier
black sky (empty 798x798 VTF) appear black at all. Log the first sky
material's shader name so we know whether this map uses the LDR (UnlitGeneric)
or HDR (sky) path.
Diffstat (limited to '')
| -rw-r--r-- | src/world.cpp | 33 |
1 files changed, 11 insertions, 22 deletions
diff --git a/src/world.cpp b/src/world.cpp index 1228c7a..eac31d9 100644 --- a/src/world.cpp +++ b/src/world.cpp | |||
| @@ -741,10 +741,12 @@ int apply_sky_texture() { | |||
| 741 | auto find_var = vfunc<FindVarFn>(mat, 11); // IMaterial::FindVar | 741 | auto find_var = vfunc<FindVarFn>(mat, 11); // IMaterial::FindVar |
| 742 | 742 | ||
| 743 | using GetTexFn = void *(*)(void *); | 743 | using GetTexFn = void *(*)(void *); |
| 744 | using IsDefFn = bool (*)(void *); | 744 | using ShaderFn = const char *(*)(void *); |
| 745 | using UndefFn = void (*)(void *); | ||
| 746 | static const char *tex_vars[] = {"$basetexture", "$hdrbasetexture", | 745 | static const char *tex_vars[] = {"$basetexture", "$hdrbasetexture", |
| 747 | nullptr}; | 746 | "$hdrcompressedtexture", |
| 747 | "$hdrcompressedtexture0", | ||
| 748 | "$hdrcompressedtexture1", | ||
| 749 | "$hdrcompressedtexture2", nullptr}; | ||
| 748 | for (int vi = 0; tex_vars[vi]; vi++) { | 750 | for (int vi = 0; tex_vars[vi]; vi++) { |
| 749 | bool found = false; | 751 | bool found = false; |
| 750 | void *var = find_var(mat, tex_vars[vi], &found, false); | 752 | void *var = find_var(mat, tex_vars[vi], &found, false); |
| @@ -758,26 +760,13 @@ int apply_sky_texture() { | |||
| 758 | if (vi == 0) | 760 | if (vi == 0) |
| 759 | hits++; | 761 | hits++; |
| 760 | } | 762 | } |
| 761 | // The HDR sky shader samples $hdrcompressedtexture (DXT5) when defined, | 763 | static bool logged_shader = false; |
| 762 | // which cannot hold our RGBA texture. Undefine it so the shader falls back | 764 | if (!logged_shader) { |
| 763 | // to $hdrbasetexture, which now points at our image. | 765 | logged_shader = true; |
| 764 | static const char *undef_vars[] = { | 766 | const char *shader = vfunc<ShaderFn>(mat, 49)(mat); // GetShaderName |
| 765 | "$hdrcompressedtexture", "$hdrcompressedtexture0", | 767 | logf("skybox: first sky material \"%s\" shader \"%s\"", name, |
| 766 | "$hdrcompressedtexture1", "$hdrcompressedtexture2", nullptr}; | 768 | shader ? shader : "?"); |
| 767 | for (int vi = 0; undef_vars[vi]; vi++) { | ||
| 768 | bool found = false; | ||
| 769 | void *var = find_var(mat, undef_vars[vi], &found, false); | ||
| 770 | if (!found || !var) | ||
| 771 | continue; | ||
| 772 | if (!vfunc<IsDefFn>(var, 17)(var)) | ||
| 773 | continue; | ||
| 774 | record_orig(name, undef_vars[vi], vfunc<GetStrFn>(var, 6)(var), | ||
| 775 | vfunc<GetTexFn>(var, 0)(var)); | ||
| 776 | vfunc<UndefFn>(var, 18)(var); // SetUndefined | ||
| 777 | } | 769 | } |
| 778 | // The sky shader binds its texture in SHADER_INIT, so changing the vars is | ||
| 779 | // not enough: rebuild the material's shader state. | ||
| 780 | vfunc<void (*)(void *)>(mat, 37)(mat); // IMaterial::Refresh | ||
| 781 | } | 770 | } |
| 782 | return hits; | 771 | return hits; |
| 783 | } | 772 | } |
