From 06fc3915f48393f5f7b77186dc9aac551cc4ee82 Mon Sep 17 00:00:00 2001 From: jerrrrycho Date: Fri, 2 Oct 2026 21:19:16 +0200 Subject: [PATCH] fix(renderer): guard replacable skin lookup and light colour access (#200) --- rendering/openglrenderer.cpp | 66 +++++++++++++++++++++--------------- 1 file changed, 38 insertions(+), 28 deletions(-) diff --git a/rendering/openglrenderer.cpp b/rendering/openglrenderer.cpp index dcbd1df2..bc6c9d14 100644 --- a/rendering/openglrenderer.cpp +++ b/rendering/openglrenderer.cpp @@ -31,6 +31,23 @@ int constexpr EU07_PICKBUFFERSIZE { 1024 }; // size of (square) textures bound w int constexpr EU07_ENVIRONMENTBUFFERSIZE { 256 }; // size of (square) environmental cube map texture int constexpr EU07_REFLECTIONFIDELITYOFFSET { 250 }; // artificial increase of range for reflection pass detail reduction +namespace { + +// returns material assigned to the submodel, resolving replacable skins. null_handle if no skin set is bound +material_handle +submodel_material( TSubModel const *Submodel ) { + + if( Submodel->m_material >= 0 ) { + return Submodel->m_material; + } + return ( + TSubModel::ReplacableSkinId != nullptr ? + TSubModel::ReplacableSkinId[ -Submodel->m_material ] : + null_handle ); +} + +} // namespace + float const EU07_OPACITYDEFAULT { 0.5f }; bool @@ -1790,8 +1807,7 @@ opengl_renderer::Material( material_handle const Material ) const { opengl_material const & opengl_renderer::Material( TSubModel const * Submodel ) const { - auto const material { Submodel->m_material >= 0 ? Submodel->m_material : Submodel->ReplacableSkinId[ -Submodel->m_material ] }; - return m_materials.material( material ); + return m_materials.material( submodel_material( Submodel ) ); } // shader methods @@ -2768,10 +2784,7 @@ opengl_renderer::Render( TSubModel *Submodel ) { } #endif // material configuration: - auto const material{ ( - Submodel->m_material < 0 ? - Submodel->ReplacableSkinId[ -Submodel->m_material ] : // zmienialne skóry - Submodel->m_material ) }; // również 0 + auto const material{ submodel_material( Submodel ) }; // zmienialne skóry, również 0 // textures... Bind_Material( material ); // ...colors and opacity... @@ -2879,7 +2892,7 @@ opengl_renderer::Render( TSubModel *Submodel ) { // material configuration: // textures... if( Submodel->m_material < 0 ) { // zmienialne skóry - Bind_Material( TSubModel::ReplacableSkinId[ -Submodel->m_material ], Submodel ); + Bind_Material( submodel_material( Submodel ), Submodel ); } else { // również 0 @@ -2897,7 +2910,7 @@ opengl_renderer::Render( TSubModel *Submodel ) { ::glColor3fv( glm::value_ptr( pick_color( m_pickcontrolsitems.size() ) ) ); // textures... if( Submodel->m_material < 0 ) { // zmienialne skóry - Bind_Material( TSubModel::ReplacableSkinId[ -Submodel->m_material ], Submodel ); + Bind_Material( submodel_material( Submodel ), Submodel ); } else { // również 0 @@ -2971,10 +2984,10 @@ opengl_renderer::Render( TSubModel *Submodel ) { auto const unitstate = m_unitstate; switch_units( m_unitstate.diffuse, false, false ); - auto const *lightcolor { + glm::vec3 const lightcolor { Submodel->DiffuseOverride.r < 0.f ? // -1 indicates no override - glm::value_ptr( Submodel->f4Diffuse ) : - glm::value_ptr( Submodel->DiffuseOverride ) }; + glm::vec3( Submodel->f4Diffuse ) : + Submodel->DiffuseOverride }; // main draw call if( Global.Overcast > 1.f ) { @@ -2987,9 +3000,9 @@ opengl_renderer::Render( TSubModel *Submodel ) { ::glPointSize( pointsize * fogfactor ); ::glColor4f( - lightcolor[ 0 ], - lightcolor[ 1 ], - lightcolor[ 2 ], + lightcolor.r, + lightcolor.g, + lightcolor.b, Submodel->fVisible * std::min( 1.f, lightlevel ) * 0.5f ); ::glDepthMask( GL_FALSE ); m_geometry.draw( Submodel->m_geometry.handle ); @@ -2997,9 +3010,9 @@ opengl_renderer::Render( TSubModel *Submodel ) { } ::glPointSize( pointsize ); ::glColor4f( - lightcolor[ 0 ], - lightcolor[ 1 ], - lightcolor[ 2 ], + lightcolor.r, + lightcolor.g, + lightcolor.b, Submodel->fVisible * std::min( 1.f, lightlevel ) ); m_geometry.draw( Submodel->m_geometry.handle ); @@ -3845,10 +3858,7 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) { #endif // material configuration: // textures... - auto const material { ( - Submodel->m_material < 0 ? - Submodel->ReplacableSkinId[ -Submodel->m_material ] : // zmienialne skóry - Submodel->m_material ) }; // również 0 + auto const material { submodel_material( Submodel ) }; // zmienialne skóry, również 0 // textures... Bind_Material( material ); // ...colors and opacity... @@ -3923,7 +3933,7 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) { // material configuration: // textures... if( Submodel->m_material < 0 ) { // zmienialne skóry - Bind_Material( TSubModel::ReplacableSkinId[ -Submodel->m_material ], Submodel ); + Bind_Material( submodel_material( Submodel ), Submodel ); } else { // również 0 @@ -3986,14 +3996,14 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) { auto const unitstate = m_unitstate; switch_units( unitstate.diffuse, false, false ); - auto const *lightcolor { + glm::vec3 const lightcolor { Submodel->DiffuseOverride.r < 0.f ? // -1 indicates no override - glm::value_ptr( Submodel->f4Diffuse ) : - glm::value_ptr( Submodel->DiffuseOverride ) }; + glm::vec3( Submodel->f4Diffuse ) : + Submodel->DiffuseOverride }; ::glColor4f( - lightcolor[ 0 ], - lightcolor[ 1 ], - lightcolor[ 2 ], + lightcolor.r, + lightcolor.g, + lightcolor.b, Submodel->fVisible * glarelevel ); // main draw call