17
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-11-07 14:41:18 +01:00

fix: sonar sast fixes

This commit is contained in:
jerrrrycho
2026-09-13 18:37:12 +02:00
parent 277bc46a21
commit e72870ad76
5 changed files with 136 additions and 115 deletions

View File

@@ -2494,8 +2494,8 @@ void accumulate_mesh_bounds(TSubModel const *Submodel, glm::vec3 &Minimum, glm::
{ {
while (Submodel != nullptr) while (Submodel != nullptr)
{ {
auto const &vertices{(Submodel->m_geometry.handle != null_handle ? GfxRenderer->Vertices(Submodel->m_geometry.handle) : Submodel->Vertices)}; if (auto const &vertices{(Submodel->m_geometry.handle != null_handle ? GfxRenderer->Vertices(Submodel->m_geometry.handle) : Submodel->Vertices)};
if (false == vertices.empty()) false == vertices.empty())
{ {
// the transformation chain can still hold a rotation, so the vertices go through it // the transformation chain can still hold a rotation, so the vertices go through it
// rather than get taken at their face value // rather than get taken at their face value
@@ -2551,7 +2551,7 @@ void TModel3d::assign_variant_groups()
// separate branches drawn in disjoint distance ranges, and grouping them by position is what keeps the // separate branches drawn in disjoint distance ranges, and grouping them by position is what keeps the
// object on the same variant no matter which of them is currently on screen // object on the same variant no matter which of them is currently on screen
std::vector<glm::vec3> grouppositions; // position of each group, indexed by its id std::vector<glm::vec3> grouppositions; // position of each group, indexed by its id
auto const groupid = [&grouppositions](TSubModel const *Branch) -> int { auto const groupid = [&grouppositions](TSubModel const *Branch) {
auto const position{branch_position(Branch)}; auto const position{branch_position(Branch)};
for (std::size_t index = 0; index < grouppositions.size(); ++index) for (std::size_t index = 0; index < grouppositions.size(); ++index)
{ {

View File

@@ -64,6 +64,74 @@ std::map<std::string, int> texture_bindings {
{ "normalmap", 1 } { "normalmap", 1 }
}; };
int opengl_material::texture_slot( std::string const &Key )
{
auto key { Key };
if( ( key.size() > 0 ) && ( key[ 0 ] != '_' ) )
{
// numbered binding, "textureN:" fills the slot N-1
key.erase( key.find_first_not_of( "-1234567890" ) );
size_t const num = std::stoi( key ) - 1;
if( num < gl::MAX_TEXTURES ) {
return static_cast<int>( num );
}
log_error( "invalid texture binding: " + std::to_string( num ) );
is_good = false;
return -1;
}
if( key.size() > 2 )
{
// named binding, the slot it fills is up to the shader
key.erase( 0, 1 );
key.pop_back();
if( shader && ( shader->texture_conf.find( key ) != shader->texture_conf.end() ) ) {
return static_cast<int>( shader->texture_conf[ key ].id );
}
auto const lookup { texture_bindings.find( key ) };
if( ( shader == nullptr ) && ( lookup != texture_bindings.end() ) ) {
return lookup->second;
}
// ignore unrecognized texture bindings in legacy render mode, it's most likely data for more advanced shaders
if( Global.GfxRenderer == "default" ) {
log_error( "unknown texture binding: " + key );
is_good = false;
}
return -1;
}
log_error( "unrecognized texture binding: " + key );
is_good = false;
return -1;
}
void opengl_material::build_texture_variants( std::vector<variant_binding> const &Bindings, bool const Loadnow )
{
if( true == Bindings.empty() ) { return; }
// build a texture set for each entry of the largest of the declared pools.
// pools of different size can be combined, shorter ones simply repeat from the start
std::size_t variantcount { 0 };
for( auto const &[ slot, pool ] : Bindings ) {
variantcount = std::max( variantcount, pool->size() );
}
texture_variants.resize( variantcount, textures );
for( auto const &[ slot, pool ] : Bindings ) {
for( std::size_t variantindex = 0; variantindex < variantcount; ++variantindex ) {
auto const &texturename { ( *pool )[ variantindex % pool->size() ] };
auto const texturehandle { GfxRenderer->Fetch_Texture( texturename, Loadnow ) };
if( texturehandle == null_handle ) {
// a single bad entry shouldn't take down the whole material, fall back to the basic texture
log_error( "missing texture variant: " + texturename );
continue;
}
texture_variants[ variantindex ][ slot ] = texturehandle;
}
}
}
void opengl_material::finalize(bool Loadnow) void opengl_material::finalize(bool Loadnow)
{ {
is_good = true; is_good = true;
@@ -71,81 +139,20 @@ void opengl_material::finalize(bool Loadnow)
if (parse_info) if (parse_info)
{ {
// texture bindings which come with a pool of alternatives, gathered while resolving regular bindings // texture bindings which come with a pool of alternatives, gathered while resolving regular bindings
std::vector<std::pair<size_t, std::vector<std::string> const *>> variantbindings; std::vector<variant_binding> variantbindings;
for (auto const &it : parse_info->tex_mapping) for( auto const &[ bindingkey, binding ] : parse_info->tex_mapping )
{ {
std::string key = it.first; auto const slot { texture_slot( bindingkey ) };
std::string value = it.second.name; if( slot < 0 ) { continue; }
// slot the binding resolves to, or -1 if it can't be resolved
int slot { -1 };
if (key.size() > 0 && key[0] != '_') textures[ slot ] = GfxRenderer->Fetch_Texture( binding.name, Loadnow );
{ if( binding.variants.size() > 1 ) {
key.erase( key.find_first_not_of( "-1234567890" ) ); variantbindings.emplace_back( static_cast<std::size_t>( slot ), &( binding.variants ) );
size_t num = std::stoi(key) - 1;
if (num < gl::MAX_TEXTURES) {
slot = static_cast<int>( num );
}
else {
log_error("invalid texture binding: " + std::to_string(num));
is_good = false;
}
}
else if (key.size() > 2)
{
key.erase(0, 1);
key.pop_back();
std::map<std::string, int>::iterator lookup;
if( shader && shader->texture_conf.find( key ) != shader->texture_conf.end() ) {
slot = shader->texture_conf[ key ].id;
}
else if( shader == nullptr
&& ( lookup = texture_bindings.find( key ) ) != texture_bindings.end() ) {
slot = lookup->second;
}
else {
// ignore unrecognized texture bindings in legacy render mode, it's most likely data for more advanced shaders
if( Global.GfxRenderer == "default" ) {
log_error( "unknown texture binding: " + key );
is_good = false;
}
}
}
else {
log_error("unrecognized texture binding: " + key);
is_good = false;
}
if( slot >= 0 ) {
textures[ slot ] = GfxRenderer->Fetch_Texture( value, Loadnow );
if( it.second.variants.size() > 1 ) {
variantbindings.emplace_back( static_cast<size_t>( slot ), &( it.second.variants ) );
}
} }
} }
if( false == variantbindings.empty() ) { build_texture_variants( variantbindings, Loadnow );
// build a texture set for each entry of the largest of the declared pools.
// pools of different size can be combined, shorter ones simply repeat from the start
size_t variantcount { 0 };
for( auto const &binding : variantbindings ) {
variantcount = std::max( variantcount, binding.second->size() );
}
texture_variants.resize( variantcount, textures );
for( auto const &binding : variantbindings ) {
auto const &pool { *( binding.second ) };
for( size_t variantindex = 0; variantindex < variantcount; ++variantindex ) {
auto const texturehandle { GfxRenderer->Fetch_Texture( pool[ variantindex % pool.size() ], Loadnow ) };
if( texturehandle == null_handle ) {
// a single bad entry shouldn't take down the whole material, fall back to the basic texture
log_error( "missing texture variant: " + pool[ variantindex % pool.size() ] );
continue;
}
texture_variants[ variantindex ][ binding.first ] = texturehandle;
}
}
}
if (!shader) if (!shader)
{ {
@@ -323,6 +330,44 @@ bool is_weather( std::string const &String ) {
} }
// imports member data pair from the config file // imports member data pair from the config file
void opengl_material::deserialize_texture_mapping( cParser &Input, std::string const &Key, int const Priority ) {
// a texture binding can be provided as a pool of alternatives, "textureN_variants: [ a b c ]".
// unlike a regular random set, which is resolved once when the material is loaded and thus shared
// by everything using it, such pool is preserved whole and one entry is picked per model instance
auto key { Key };
auto const variantmarker { key.find( "_variants" ) };
auto const isvariantset { variantmarker != std::string::npos };
if( true == isvariantset ) {
// reduce the key to its plain form, "N_variants:" becomes "N:"
key.erase( variantmarker, std::string( "_variants" ).size() );
}
std::vector<std::string> variants;
std::string value;
if( false == isvariantset ) {
value = deserialize_random_set( Input );
replace_slashes( value );
}
else {
variants = deserialize_set( Input );
for( auto &variant : variants ) {
replace_slashes( variant );
}
if( true == variants.empty() ) {
log_error( "empty texture variant pool: " + key );
return;
}
// first entry doubles as the regular, variant-agnostic texture of the material
value = variants.front();
}
auto const [ it, inserted ] { parse_info->tex_mapping.try_emplace( key, parse_info_s::tex_def{ value, Priority, variants } ) };
if( ( false == inserted ) && ( Priority > it->second.priority ) ) {
it->second = parse_info_s::tex_def{ value, Priority, variants };
}
}
bool bool
opengl_material::deserialize_mapping( cParser &Input, int const Priority, bool const Loadnow ) { opengl_material::deserialize_mapping( cParser &Input, int const Priority, bool const Loadnow ) {
@@ -358,44 +403,7 @@ opengl_material::deserialize_mapping( cParser &Input, int const Priority, bool c
else if (key.compare(0, 7, "texture") == 0) { else if (key.compare(0, 7, "texture") == 0) {
key.erase(0, 7); key.erase(0, 7);
deserialize_texture_mapping( Input, key, Priority );
// a texture binding can be provided as a pool of alternatives, "textureN_variants: [ a b c ]".
// unlike a regular random set, which is resolved once when the material is loaded and thus shared
// by everything using it, such pool is preserved whole and one entry is picked per model instance
auto const variantmarker { key.find( "_variants" ) };
auto const isvariantset { variantmarker != std::string::npos };
if( isvariantset ) {
// reduce the key to its plain form, "N_variants:" becomes "N:"
key.erase( variantmarker, std::string( "_variants" ).size() );
}
std::vector<std::string> variants;
std::string value;
if( false == isvariantset ) {
value = deserialize_random_set( Input );
replace_slashes( value );
}
else {
variants = deserialize_set( Input );
for( auto &variant : variants ) {
replace_slashes( variant );
}
if( true == variants.empty() ) {
log_error( "empty texture variant pool: " + key );
return true;
}
// first entry doubles as the regular, variant-agnostic texture of the material
value = variants.front();
}
auto it = parse_info->tex_mapping.find(key);
if (it == parse_info->tex_mapping.end())
parse_info->tex_mapping.emplace(std::make_pair(key, parse_info_s::tex_def({ value, Priority, variants })));
else if (Priority > it->second.priority)
{
parse_info->tex_mapping.erase(it);
parse_info->tex_mapping.emplace(std::make_pair(key, parse_info_s::tex_def({ value, Priority, variants })));
}
} }
else if (key.compare(0, 5, "param") == 0) { else if (key.compare(0, 5, "param") == 0) {
key.erase(0, 5); key.erase(0, 5);

View File

@@ -18,7 +18,7 @@ http://mozilla.org/MPL/2.0/.
// a collection of parameters for the rendering setup. // a collection of parameters for the rendering setup.
// for modern opengl this translates to set of attributes for shaders // for modern opengl this translates to set of attributes for shaders
struct opengl_material : public IMaterial { struct opengl_material : public IMaterial {
typedef std::array<texture_handle, gl::MAX_TEXTURES> texture_set; using texture_set = std::array<texture_handle, gl::MAX_TEXTURES>;
texture_set textures = { null_handle }; texture_set textures = { null_handle };
// alternative texture sets, defined with "textureN_variants:" key. // alternative texture sets, defined with "textureN_variants:" key.
@@ -85,10 +85,23 @@ struct opengl_material : public IMaterial {
bool update_on_season_change{ false }; bool update_on_season_change{ false };
private: private:
// types
// texture binding which comes with a pool of alternatives: slot the binding fills, and the pool itself
using variant_binding = std::pair<std::size_t, std::vector<std::string> const *>;
// methods // methods
// imports member data pair from the config file // imports member data pair from the config file
bool bool
deserialize_mapping( cParser &Input, int const Priority, bool const Loadnow ); deserialize_mapping( cParser &Input, int const Priority, bool const Loadnow );
// imports texture binding, potentially carrying a pool of alternatives, from the config file
void
deserialize_texture_mapping( cParser &Input, std::string const &Key, int const Priority );
// returns texture slot provided binding key resolves to, or -1 if it doesn't resolve to any
int
texture_slot( std::string const &Key );
// fills the alternative texture sets from provided pools, one set per entry of the longest pool
void
build_texture_variants( std::vector<variant_binding> const &Bindings, bool const Loadnow );
void log_error(const std::string &str); void log_error(const std::string &str);
// members // members

View File

@@ -2877,7 +2877,7 @@ opengl_renderer::Render( TSubModel *Submodel ) {
// material configuration: // material configuration:
// textures... // textures...
if( Submodel->m_material < 0 ) { // zmienialne skóry if( Submodel->m_material < 0 ) { // zmienialne skóry
Bind_Material( Submodel->ReplacableSkinId[ -Submodel->m_material ], Submodel ); Bind_Material( TSubModel::ReplacableSkinId[ -Submodel->m_material ], Submodel );
} }
else { else {
// również 0 // również 0
@@ -2895,7 +2895,7 @@ opengl_renderer::Render( TSubModel *Submodel ) {
::glColor3fv( glm::value_ptr( pick_color( m_pickcontrolsitems.size() ) ) ); ::glColor3fv( glm::value_ptr( pick_color( m_pickcontrolsitems.size() ) ) );
// textures... // textures...
if( Submodel->m_material < 0 ) { // zmienialne skóry if( Submodel->m_material < 0 ) { // zmienialne skóry
Bind_Material( Submodel->ReplacableSkinId[ -Submodel->m_material ], Submodel ); Bind_Material( TSubModel::ReplacableSkinId[ -Submodel->m_material ], Submodel );
} }
else { else {
// również 0 // również 0
@@ -3921,7 +3921,7 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) {
// material configuration: // material configuration:
// textures... // textures...
if( Submodel->m_material < 0 ) { // zmienialne skóry if( Submodel->m_material < 0 ) { // zmienialne skóry
Bind_Material( Submodel->ReplacableSkinId[ -Submodel->m_material ], Submodel ); Bind_Material( TSubModel::ReplacableSkinId[ -Submodel->m_material ], Submodel );
} }
else { else {
// również 0 // również 0

View File

@@ -512,7 +512,7 @@ std::vector<std::string> deserialize_set(cParser &Input, char const *Break)
std::vector<std::string> tokens; std::vector<std::string> tokens;
auto token{Input.getToken<std::string>(true, Break)}; auto token{Input.getToken<std::string>(true, Break)};
std::replace(token.begin(), token.end(), '\\', '/'); std::ranges::replace(token, '\\', '/');
if (token != "[") if (token != "[")
{ {
// simple case, single token // simple case, single token