diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/meshmatdesc.cpp b/Generals/Code/Libraries/Source/WWVegas/WW3D2/meshmatdesc.cpp index 27e556bae5f..548c0b5e07b 100644 --- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/meshmatdesc.cpp +++ b/Generals/Code/Libraries/Source/WWVegas/WW3D2/meshmatdesc.cpp @@ -639,6 +639,8 @@ void MeshMatDescClass::Install_UV_Array(int pass,int stage,Vector2 * uvs,int cou } +// TheSuperHackers @bugfix Cryo 10/09/2026 Skip null materials to prevent crashes and +// use each vertex's material colors to avoid incorrect ambient/emissive vertex colors. void MeshMatDescClass::Post_Load_Process(bool lighting_enabled,MeshModelClass * parent) { /* @@ -680,66 +682,38 @@ void MeshMatDescClass::Post_Load_Process(bool lighting_enabled,MeshModelClass * if (!ColorArray[0] && !ColorArray[1]) continue; // If no color arrays, we don't have a problem - Vector3 single_diffuse(0.0f,0.0f,0.0f); - Vector3 single_ambient(0.0f,0.0f,0.0f); - Vector3 single_emissive(0.0f,0.0f,0.0f); - float single_opacity=1.0f; - bool single_diffuse_used=true; - bool single_ambient_used=true; - bool single_emissive_used=true; - bool single_opacity_used=true; bool diffuse_used=false; bool ambient_used=false; bool emissive_used=false; - bool opacity_used=false; - - Vector3 mtl_diffuse; - Vector3 mtl_ambient; - Vector3 mtl_emissive; - float mtl_opacity = 1.0f; - - VertexMaterialClass * prev_mtl = nullptr; - VertexMaterialClass * mtl = Peek_Material(0, pass); - if (mtl) { - mtl->Get_Diffuse(&single_diffuse); - single_opacity = mtl->Get_Opacity(); - mtl->Get_Ambient(&single_ambient); - mtl->Get_Emissive(&single_emissive); - - if (single_diffuse.X || single_diffuse.Y || single_diffuse.Z) diffuse_used=true; - if (single_ambient.X || single_ambient.Y || single_ambient.Z) ambient_used=true; - if (single_emissive.X || single_emissive.Y || single_emissive.Z) emissive_used=true; - if (single_opacity!=1.0f) opacity_used=true; - } - for (int vidx=0; vidxGet_Diffuse(&mtl_diffuse); - mtl_opacity = mtl->Get_Opacity(); mtl->Get_Ambient(&mtl_ambient); mtl->Get_Emissive(&mtl_emissive); - } - - if (mtl_diffuse.X!=single_diffuse.X || mtl_diffuse.Y!=single_diffuse.Y || mtl_diffuse.Z!=single_diffuse.Z) { - single_diffuse_used=false; - } - if (mtl_ambient.X!=single_ambient.X || mtl_ambient.Y!=single_ambient.Y || mtl_ambient.Z!=single_ambient.Z) { - single_ambient_used=false; - } - if (mtl_emissive.X!=single_emissive.X || mtl_emissive.Y!=single_emissive.Y || mtl_emissive.Z!=single_emissive.Z) { - single_emissive_used=false; - } - if (mtl_opacity!=single_opacity) { - single_opacity_used=false; - } - if (mtl_diffuse.X || mtl_diffuse.Y || mtl_diffuse.Z) diffuse_used=true; - if (mtl_ambient.X || mtl_ambient.Y || mtl_ambient.Z) ambient_used=true; - if (mtl_emissive.X || mtl_emissive.Y || mtl_emissive.Z) emissive_used=true; - if (mtl_opacity!=1.0f) opacity_used=true; + diffuse_used = diffuse_used || mtl_diffuse.X || mtl_diffuse.Y || mtl_diffuse.Z; + ambient_used = ambient_used || mtl_ambient.X || mtl_ambient.Y || mtl_ambient.Z; + emissive_used = emissive_used || mtl_emissive.X || mtl_emissive.Y || mtl_emissive.Z; + if (diffuse_used && ambient_used && emissive_used) + { + break; + } + } } // If both DCG and DIG arrays are submitted, multiply them together to DCG channel @@ -762,7 +736,9 @@ void MeshMatDescClass::Post_Load_Process(bool lighting_enabled,MeshModelClass * if ((DCGSource[pass] != VertexMaterialClass::MATERIAL) && (ColorArray[0] != nullptr)) { unsigned * diffuse_array = ColorArray[0]->Get_Array(); Vector3 mtl_diffuse; - float mtl_opacity = 1.0f; + Vector3 mtl_ambient; + Vector3 mtl_emissive; + float mtl_opacity; VertexMaterialClass * prev_mtl = nullptr; VertexMaterialClass * mtl = Peek_Material(0,pass); @@ -770,9 +746,15 @@ void MeshMatDescClass::Post_Load_Process(bool lighting_enabled,MeshModelClass * for (int vidx=0; vidxGet_Diffuse(&mtl_diffuse); + mtl->Get_Ambient(&mtl_ambient); + mtl->Get_Emissive(&mtl_emissive); mtl_opacity = mtl->Get_Opacity(); } diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/meshmatdesc.cpp b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/meshmatdesc.cpp index 982afc7549e..c80f3d3d10d 100644 --- a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/meshmatdesc.cpp +++ b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/meshmatdesc.cpp @@ -640,6 +640,8 @@ void MeshMatDescClass::Install_UV_Array(int pass,int stage,Vector2 * uvs,int cou } +// TheSuperHackers @bugfix Cryo 10/09/2026 Skip null materials to prevent crashes and +// use each vertex's material colors to avoid incorrect ambient/emissive vertex colors. void MeshMatDescClass::Post_Load_Process(bool lighting_enabled,MeshModelClass * parent) { /* @@ -682,66 +684,38 @@ void MeshMatDescClass::Post_Load_Process(bool lighting_enabled,MeshModelClass * if (!ColorArray[0] && !ColorArray[1]) continue; // If no color arrays, we don't have a problem - Vector3 single_diffuse(0.0f,0.0f,0.0f); - Vector3 single_ambient(0.0f,0.0f,0.0f); - Vector3 single_emissive(0.0f,0.0f,0.0f); - float single_opacity=1.0f; - bool single_diffuse_used=true; - bool single_ambient_used=true; - bool single_emissive_used=true; - bool single_opacity_used=true; bool diffuse_used=false; bool ambient_used=false; bool emissive_used=false; - bool opacity_used=false; - - Vector3 mtl_diffuse; - Vector3 mtl_ambient; - Vector3 mtl_emissive; - float mtl_opacity = 1.0f; - - VertexMaterialClass * prev_mtl = nullptr; - VertexMaterialClass * mtl = Peek_Material(0, pass); - if (mtl) { - mtl->Get_Diffuse(&single_diffuse); - single_opacity = mtl->Get_Opacity(); - mtl->Get_Ambient(&single_ambient); - mtl->Get_Emissive(&single_emissive); - - if (single_diffuse.X || single_diffuse.Y || single_diffuse.Z) diffuse_used=true; - if (single_ambient.X || single_ambient.Y || single_ambient.Z) ambient_used=true; - if (single_emissive.X || single_emissive.Y || single_emissive.Z) emissive_used=true; - if (single_opacity!=1.0f) opacity_used=true; - } - for (int vidx=0; vidxGet_Diffuse(&mtl_diffuse); - mtl_opacity = mtl->Get_Opacity(); mtl->Get_Ambient(&mtl_ambient); mtl->Get_Emissive(&mtl_emissive); - } - - if (mtl_diffuse.X!=single_diffuse.X || mtl_diffuse.Y!=single_diffuse.Y || mtl_diffuse.Z!=single_diffuse.Z) { - single_diffuse_used=false; - } - if (mtl_ambient.X!=single_ambient.X || mtl_ambient.Y!=single_ambient.Y || mtl_ambient.Z!=single_ambient.Z) { - single_ambient_used=false; - } - if (mtl_emissive.X!=single_emissive.X || mtl_emissive.Y!=single_emissive.Y || mtl_emissive.Z!=single_emissive.Z) { - single_emissive_used=false; - } - if (mtl_opacity!=single_opacity) { - single_opacity_used=false; - } - if (mtl_diffuse.X || mtl_diffuse.Y || mtl_diffuse.Z) diffuse_used=true; - if (mtl_ambient.X || mtl_ambient.Y || mtl_ambient.Z) ambient_used=true; - if (mtl_emissive.X || mtl_emissive.Y || mtl_emissive.Z) emissive_used=true; - if (mtl_opacity!=1.0f) opacity_used=true; + diffuse_used = diffuse_used || mtl_diffuse.X || mtl_diffuse.Y || mtl_diffuse.Z; + ambient_used = ambient_used || mtl_ambient.X || mtl_ambient.Y || mtl_ambient.Z; + emissive_used = emissive_used || mtl_emissive.X || mtl_emissive.Y || mtl_emissive.Z; + if (diffuse_used && ambient_used && emissive_used) + { + break; + } + } } // If both DCG and DIG arrays are submitted, multiply them together to DCG channel @@ -764,7 +738,9 @@ void MeshMatDescClass::Post_Load_Process(bool lighting_enabled,MeshModelClass * if ((DCGSource[pass] != VertexMaterialClass::MATERIAL) && (ColorArray[0] != nullptr)) { unsigned * diffuse_array = ColorArray[0]->Get_Array(); Vector3 mtl_diffuse; - float mtl_opacity = 1.0f; + Vector3 mtl_ambient; + Vector3 mtl_emissive; + float mtl_opacity; VertexMaterialClass * prev_mtl = nullptr; VertexMaterialClass * mtl = Peek_Material(0,pass); @@ -772,9 +748,15 @@ void MeshMatDescClass::Post_Load_Process(bool lighting_enabled,MeshModelClass * for (int vidx=0; vidxGet_Diffuse(&mtl_diffuse); + mtl->Get_Ambient(&mtl_ambient); + mtl->Get_Emissive(&mtl_emissive); mtl_opacity = mtl->Get_Opacity(); } @@ -884,54 +866,57 @@ void MeshMatDescClass::Post_Load_Process(bool lighting_enabled,MeshModelClass * } // Set lighting to false if requested in all passes... else if (set_lighting_to_false) { - Vector3 single_diffuse(0.0f,0.0f,0.0f); - Vector3 single_ambient(0.0f,0.0f,0.0f); - Vector3 single_emissive(0.0f,0.0f,0.0f); bool diffuse_used=false; bool ambient_used=false; bool emissive_used=false; - Vector3 mtl_diffuse; - Vector3 mtl_ambient; - Vector3 mtl_emissive; - - VertexMaterialClass * prev_mtl = nullptr; - VertexMaterialClass * mtl = Peek_Material(0, pass); - if (mtl) { - mtl->Get_Diffuse(&single_diffuse); - mtl->Get_Ambient(&single_ambient); - mtl->Get_Emissive(&single_emissive); - - if (single_diffuse.X || single_diffuse.Y || single_diffuse.Z) diffuse_used=true; - if (single_ambient.X || single_ambient.Y || single_ambient.Z) ambient_used=true; - if (single_emissive.X || single_emissive.Y || single_emissive.Z) emissive_used=true; - } + VertexMaterialClass* prev_mtl = nullptr; + for (int vidx=0; vidxGet_Diffuse(&mtl_diffuse); mtl->Get_Ambient(&mtl_ambient); mtl->Get_Emissive(&mtl_emissive); - } - if (mtl_diffuse.X || mtl_diffuse.Y || mtl_diffuse.Z) diffuse_used=true; - if (mtl_ambient.X || mtl_ambient.Y || mtl_ambient.Z) ambient_used=true; - if (mtl_emissive.X || mtl_emissive.Y || mtl_emissive.Z) emissive_used=true; + diffuse_used = diffuse_used || mtl_diffuse.X || mtl_diffuse.Y || mtl_diffuse.Z; + ambient_used = ambient_used || mtl_ambient.X || mtl_ambient.Y || mtl_ambient.Z; + emissive_used = emissive_used || mtl_emissive.X || mtl_emissive.Y || mtl_emissive.Z; + + if (diffuse_used && ambient_used && emissive_used) + { + break; + } + } } - if ((DCGSource[pass] != VertexMaterialClass::MATERIAL) && (ColorArray[0] != nullptr)) { - VertexMaterialClass * prev_mtl = nullptr; - VertexMaterialClass * mtl = Peek_Material(0,pass); - for (int vidx=0; vidxSet_Lighting(false); - } + mtl->Set_Lighting(false); } } }