From d91b94d6b2e77091c215db7b8896aba1843809a5 Mon Sep 17 00:00:00 2001 From: Robert Beckebans Date: Thu, 13 Jun 2024 21:28:12 +0200 Subject: [PATCH] Extended makeMaterials command --- neo/idlib/Str.cpp | 21 +++++++++ neo/idlib/Str.h | 1 + neo/renderer/Material.cpp | 98 ++++++++++++++++++++++++++++++--------- 3 files changed, 98 insertions(+), 22 deletions(-) diff --git a/neo/idlib/Str.cpp b/neo/idlib/Str.cpp index 2cf29141..0a0f6b37 100644 --- a/neo/idlib/Str.cpp +++ b/neo/idlib/Str.cpp @@ -889,6 +889,27 @@ bool idStr::StripTrailingOnce( const char* string ) return false; } +/* +============ +idStr::IStripTrailingOnce +============ +*/ +bool idStr::IStripTrailingOnce( const char* string ) +{ + int l; + + // RB: 64 bit fixes, conversion from 'size_t' to 'int', possible loss of data + l = ( int )strlen( string ); + // RB end + if( ( l > 0 ) && ( len >= l ) && !Icmpn( string, data + len - l, l ) ) + { + len -= l; + data[len] = '\0'; + return true; + } + return false; +} + /* ============ idStr::Replace diff --git a/neo/idlib/Str.h b/neo/idlib/Str.h index 3321c275..c1fb0a43 100644 --- a/neo/idlib/Str.h +++ b/neo/idlib/Str.h @@ -262,6 +262,7 @@ public: void StripTrailing( const char c ); // strip char from end as many times as the char occurs void StripTrailing( const char* string ); // strip string from end as many times as the string occurs bool StripTrailingOnce( const char* string ); // strip string from end just once if it occurs + bool IStripTrailingOnce( const char* string ); // RB: case insensitive, strip string from end just once if it occurs void Strip( const char c ); // strip char from front and end as many times as the char occurs void Strip( const char* string ); // strip string from front and end as many times as the string occurs void StripTrailingWhitespace(); // strip trailing white space characters diff --git a/neo/renderer/Material.cpp b/neo/renderer/Material.cpp index 7c79d50d..68088b89 100644 --- a/neo/renderer/Material.cpp +++ b/neo/renderer/Material.cpp @@ -3934,6 +3934,7 @@ CONSOLE_COMMAND_SHIP( makeMaterials, "Make .mtr file from a models or textures f idStr mtrBuffer; mtrBuffer += va( "// generated by %s\n\n", ENGINE_VERSION ); + mtrBuffer += "// adjust this file as needed\n"; idStrList list = files->GetList(); for( int i = 0; i < files->GetNumFiles(); i++ ) @@ -3956,13 +3957,13 @@ CONSOLE_COMMAND_SHIP( makeMaterials, "Make .mtr file from a models or textures f imageName = imageName.StripFileExtension(); idStr baseName = imageName; - baseName.StripTrailing( "_diffuse" ); - baseName.StripTrailing( "_diff" ); - baseName.StripTrailing( "_albedo" ); - baseName.StripTrailing( "_basecolor" ); - baseName.StripTrailing( "_base" ); - baseName.StripTrailing( "_color" ); - baseName.StripTrailing( "_col" ); + baseName.IStripTrailingOnce( "_diffuse" ); + baseName.IStripTrailingOnce( "_diff" ); + baseName.IStripTrailingOnce( "_albedo" ); + baseName.IStripTrailingOnce( "_basecolor" ); + baseName.IStripTrailingOnce( "_base" ); + baseName.IStripTrailingOnce( "_color" ); + baseName.IStripTrailingOnce( "_col" ); //mtrBuffer += va( "%s/%s\n", folderName, imageName.c_str() ); mtrBuffer += baseName.c_str(); @@ -3971,30 +3972,83 @@ CONSOLE_COMMAND_SHIP( makeMaterials, "Make .mtr file from a models or textures f // TODO qer_editorImage //mtrBuffer += va( "\tqer_editorimage %s\n\n", imageName.c_str() ); + // =============================== // test opacity / transparency map - ID_TIME_T opacityStamp; - ID_TIME_T alphaStamp; + idStrList alphaNames = { "_opacity", "_alpha" }; + bool foundAlpha = false; - idStr opacityName = baseName + "_opacity"; - R_LoadImage( opacityName, NULL, NULL, NULL, &opacityStamp, true, NULL ); - - opacityName = baseName + "_alpha"; - R_LoadImage( opacityName, NULL, NULL, NULL, &alphaStamp, true, NULL ); - if( opacityStamp != FILE_NOT_FOUND_TIMESTAMP || alphaStamp != FILE_NOT_FOUND_TIMESTAMP ) + for( auto& name : alphaNames ) { - // TODO load opacity map and store values in the alpha channel of the base color image + ID_TIME_T testStamp; + idStr testName = baseName + name; - mtrBuffer += "\t{\n"; - mtrBuffer += "\t\tblend basecolormap\n"; - mtrBuffer += va( "\t\tmap %s\n", imageName.c_str() ); - mtrBuffer += "\t\talphaTest 0.5\n"; - mtrBuffer += "\t}\n"; + R_LoadImage( testName, NULL, NULL, NULL, &testStamp, true, NULL ); + + if( testStamp != FILE_NOT_FOUND_TIMESTAMP ) + { + // TODO load opacity map and store values in the alpha channel of the base color image + + mtrBuffer += "\t{\n"; + mtrBuffer += "\t\tblend basecolormap\n"; + mtrBuffer += va( "\t\tmap %s\n", imageName.c_str() ); + mtrBuffer += "\t\talphaTest 0.5\n"; + mtrBuffer += "\t}\n"; + + foundAlpha = true; + break; + } } - else + + if( !foundAlpha ) { mtrBuffer += va( "\tbasecolormap %s\n", imageName.c_str() ); } + // =============================== + // test normal map + idStrList normalNames = { "_normal", "_nor", "_nrm", "_nrml", "_norm", "_normal_directx", "_normal_opengl" }; + + for( auto& name : normalNames ) + { + ID_TIME_T testStamp; + idStr testName = baseName + name; + + R_LoadImage( testName, NULL, NULL, NULL, &testStamp, true, NULL ); + + if( testStamp != FILE_NOT_FOUND_TIMESTAMP ) + { + if( name.Cmp( "_normal_opengl" ) == 0 ) + { + mtrBuffer += va( "\tnormalmap invertGreen( %s )\n", testName.c_str() ); + } + else + { + mtrBuffer += va( "\tnormalmap %s\n", testName.c_str() ); + } + break; + } + } + + // =============================== + // test emmissive map + idStrList emmissiveName = { "_emission", "_emissive", "_emit" }; + + for( auto& name : emmissiveName ) + { + ID_TIME_T testStamp; + idStr testName = baseName + name; + + R_LoadImage( testName, NULL, NULL, NULL, &testStamp, true, NULL ); + + if( testStamp != FILE_NOT_FOUND_TIMESTAMP ) + { + mtrBuffer += "\t{\n"; + mtrBuffer += "\t\tblend add\n"; + mtrBuffer += va( "\t\tmap %s\n", testName.c_str() ); + mtrBuffer += "\t}\n"; + break; + } + } //mtrBuffer += va( "\tbumpmap addnormals ( textures/%s/%s_local.%s, heightmap ( textures/%s/%s_h.%s, 4 ) )\n", args.Argv( 1 ), args.Argv( 2 ), imagepath.c_str() ); //mtrBuffer += va( "\tspecularmap textures/%s/%s_spec.%s\n", args.Argv( 1 ), args.Argv( 2 ), imagepath.c_str() );