From 39ed87570bdb2f86969d4be821c94b722dc71179 Mon Sep 17 00:00:00 2001 From: Joe Ludwig Date: Wed, 26 Jun 2013 15:22:04 -0700 Subject: First version of the SOurce SDK 2013 --- .../utils/height2normal/height2normal-2010.vcxproj | 241 +++++++++++++++ .../height2normal-2010.vcxproj.filters | 56 ++++ mp/src/utils/height2normal/height2normal.cpp | 343 +++++++++++++++++++++ 3 files changed, 640 insertions(+) create mode 100644 mp/src/utils/height2normal/height2normal-2010.vcxproj create mode 100644 mp/src/utils/height2normal/height2normal-2010.vcxproj.filters create mode 100644 mp/src/utils/height2normal/height2normal.cpp (limited to 'mp/src/utils/height2normal') diff --git a/mp/src/utils/height2normal/height2normal-2010.vcxproj b/mp/src/utils/height2normal/height2normal-2010.vcxproj new file mode 100644 index 00000000..40f3288c --- /dev/null +++ b/mp/src/utils/height2normal/height2normal-2010.vcxproj @@ -0,0 +1,241 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + Height2normal + {129A563E-9F48-79D9-E0C5-EE2DAF7FEAB7} + + + + Application + MultiByte + height2normal + + + Application + MultiByte + height2normal + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + .\Debug\win32\ + .\Debug\win32\ + ..\..\devtools\vstools;$(ExecutablePath);$(Path) + true + true + true + true + true + .\Release\win32\ + .\Release\win32\ + ..\..\devtools\vstools;$(ExecutablePath);$(Path) + true + true + false + true + true + + + + if EXIST ..\..\..\game\bin\$(TargetFileName) for /f "delims=" %%A in ('attrib "..\..\..\game\bin\$(TargetFileName)"') do set valveTmpIsReadOnly="%%A" set valveTmpIsReadOnlyLetter=%valveTmpIsReadOnly:~6,1% if "%valveTmpIsReadOnlyLetter%"=="R" del /q "$(TargetDir)"$(TargetFileName) if exist ..\..\devtools\bin\vpc.exe ..\..\devtools\bin\vpc.exe -crc2 height2normal.vcxproj if ERRORLEVEL 1 exit 1 + + + /MP + Disabled + ..\..\common;..\..\public;..\..\public\tier0;..\..\public\tier1;..\common + _HAS_ITERATOR_DEBUGGING=0;_DEBUG;_WIN32;_CONSOLE;VPCGAMECAPS=VALVE;PROJECTDIR=D:\dev\games\rel\hl2\src\utils\height2normal;_DLL_EXT=.dll;VPCGAME=valve + true + false + Default + MultiThreadedDebug + true + StreamingSIMDExtensions + Fast + true + true + true + false + NotUsing + false + NoListing + $(IntDir)/ + $(IntDir)/ + $(IntDir)/ + false + Level4 + true + EditAndContinue + CompileAsCpp + $(IntDir)/ + Prompt + + + _DEBUG;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE + 1033 + + + + + /NXCOMPAT /ignore:4221 + %(AdditionalDependencies) + NotSet + $(OutDir)\height2normal.exe + true + libc;libcd;libcmt + true + $(IntDir)/$(TargetName).pdb + false + $(IntDir)/$(TargetName).map + Console + + MachineX86 + PromptImmediately + false + + + true + + + true + + + true + $(OutDir)/height2normal.bsc + + + Publishing to ..\..\..\game\bin + if not exist "..\..\..\game\bin" mkdir "..\..\..\game\bin" copy "$(TargetDir)"$(TargetFileName) ..\..\..\game\bin\$(TargetFileName) if ERRORLEVEL 1 goto BuildEventFailed if exist "$(TargetDir)"$(TargetName).map copy "$(TargetDir)"$(TargetName).map ..\..\..\game\bin\$(TargetName).map copy "$(TargetDir)"$(TargetName).pdb ..\..\..\game\bin\$(TargetName).pdb if ERRORLEVEL 1 goto BuildEventFailed goto BuildEventOK :BuildEventFailed echo *** ERROR! PostBuildStep FAILED for $(ProjectName)! EXE or DLL is probably running. *** del /q "$(TargetDir)"$(TargetFileName) exit 1 :BuildEventOK + + + + + + + if EXIST ..\..\..\game\bin\$(TargetFileName) for /f "delims=" %%A in ('attrib "..\..\..\game\bin\$(TargetFileName)"') do set valveTmpIsReadOnly="%%A" set valveTmpIsReadOnlyLetter=%valveTmpIsReadOnly:~6,1% if "%valveTmpIsReadOnlyLetter%"=="R" del /q "$(TargetDir)"$(TargetFileName) if exist ..\..\devtools\bin\vpc.exe ..\..\devtools\bin\vpc.exe -crc2 height2normal.vcxproj if ERRORLEVEL 1 exit 1 + + + /MP /d2Zi+ + MaxSpeed + AnySuitable + true + Speed + ..\..\common;..\..\public;..\..\public\tier0;..\..\public\tier1;..\common + _HAS_ITERATOR_DEBUGGING=0;_DEBUG;_WIN32;_CONSOLE;VPCGAMECAPS=VALVE;PROJECTDIR=D:\dev\games\rel\hl2\src\utils\height2normal;_DLL_EXT=.dll;VPCGAME=valve + true + false + MultiThreaded + false + true + StreamingSIMDExtensions + Fast + true + true + true + false + NotUsing + false + NoListing + $(IntDir)/ + $(IntDir)/ + $(IntDir)/ + false + Level4 + true + ProgramDatabase + CompileAsCpp + $(IntDir)/ + Prompt + + + NDEBUG;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE + 1033 + + + + + /DYNAMICBASE /NXCOMPAT /ignore:4221 + %(AdditionalDependencies) + NotSet + $(OutDir)\height2normal.exe + true + libc;libcd;libcmtd + true + $(IntDir)/$(TargetName).pdb + false + $(IntDir)/$(TargetName).map + Console + true + true + + MachineX86 + PromptImmediately + + + true + + + true + + + true + $(OutDir)/height2normal.bsc + + + Publishing to ..\..\..\game\bin + if not exist "..\..\..\game\bin" mkdir "..\..\..\game\bin" copy "$(TargetDir)"$(TargetFileName) ..\..\..\game\bin\$(TargetFileName) if ERRORLEVEL 1 goto BuildEventFailed if exist "$(TargetDir)"$(TargetName).map copy "$(TargetDir)"$(TargetName).map ..\..\..\game\bin\$(TargetName).map copy "$(TargetDir)"$(TargetName).pdb ..\..\..\game\bin\$(TargetName).pdb if ERRORLEVEL 1 goto BuildEventFailed goto BuildEventOK :BuildEventFailed echo *** ERROR! PostBuildStep FAILED for $(ProjectName)! EXE or DLL is probably running. *** del /q "$(TargetDir)"$(TargetFileName) exit 1 :BuildEventOK + + + + + + + + + + + + + + + + + + + + + + + + Compiling pointeroverride.asm + "$(VCInstallDir)bin\ml.exe" /c /Cp /Zi /Fo"$(IntDir)\%(Filename).obj" "%(FullPath)" + $(IntDir)\%(Filename).obj + Compiling pointeroverride.asm + "$(VCInstallDir)bin\ml.exe" /c /Cp /Zi /Fo"$(IntDir)\%(Filename).obj" "%(FullPath)" + $(IntDir)\%(Filename).obj + + + + + + + + diff --git a/mp/src/utils/height2normal/height2normal-2010.vcxproj.filters b/mp/src/utils/height2normal/height2normal-2010.vcxproj.filters new file mode 100644 index 00000000..192274bd --- /dev/null +++ b/mp/src/utils/height2normal/height2normal-2010.vcxproj.filters @@ -0,0 +1,56 @@ + + + + + {1680C80B-FF1E-EA4D-9817-CC12254F2E40} + + + {C5D73B3A-C648-896C-B7CE-F174808E5BA5} + + + {BA03E055-4FA2-FCE3-8A1C-D348547D379C} + + + + + Link Libraries + + + Link Libraries + + + Link Libraries + + + Link Libraries + + + Link Libraries + + + Link Libraries + + + + + Header Files + + + Header Files + + + + + Source Files + + + + + + + Source Files + + + + + diff --git a/mp/src/utils/height2normal/height2normal.cpp b/mp/src/utils/height2normal/height2normal.cpp new file mode 100644 index 00000000..f0dff189 --- /dev/null +++ b/mp/src/utils/height2normal/height2normal.cpp @@ -0,0 +1,343 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//===========================================================================// +#include +#include +#include +#include "bitmap/imageformat.h" +#include "tier1/strtools.h" +#include "mathlib/mathlib.h" +#include "bitmap/TGAWriter.h" +#include "bitmap/TGALoader.h" +#include +#include +#include "tier1/utlbuffer.h" +#include "tier2/tier2.h" +#include "filesystem.h" + +static bool g_NoPause = false; +static bool g_Quiet = false; + +static void Pause( void ) +{ + if( !g_NoPause ) + { + printf( "Hit a key to continue\n" ); + getch(); + } +} + +static bool ImageRGBA8888HasAlpha( unsigned char *pImage, int numTexels ) +{ + int i; + for( i = 0; i < numTexels; i++ ) + { + if( pImage[i*4+3] != 255 ) + { + return true; + } + } + return false; +} + +static bool GetKeyValueFromBuffer( CUtlBuffer &buf, char **key, char **val ) +{ + char stringBuf[2048]; + while( buf.IsValid() ) + { + buf.GetLine( stringBuf, sizeof(stringBuf) ); + char *scan = stringBuf; + // search for the first quote for the key. + while( 1 ) + { + if( *scan == '\"' ) + { + *key = ++scan; + break; + } + if( *scan == '#' ) + { + goto next_line; // comment + } + if( *scan == '\0' ) + { + goto next_line; // end of line. + } + scan++; + } + // read the key until another quote. + while( 1 ) + { + if( *scan == '\"' ) + { + *scan = '\0'; + scan++; + break; + } + if( *scan == '\0' ) + { + goto next_line; + } + scan++; + } + // search for the first quote for the value. + while( 1 ) + { + if( *scan == '\"' ) + { + *val = ++scan; + break; + } + if( *scan == '#' ) + { + goto next_line; // comment + } + if( *scan == '\0' ) + { + goto next_line; // end of line. + } + scan++; + } + // read the value until another quote. + while( 1 ) + { + if( *scan == '\"' ) + { + *scan = '\0'; + scan++; + // got a key and a value, so get the hell out of here. + return true; + } + if( *scan == '\0' ) + { + goto next_line; + } + scan++; + } +next_line: + ; + } + return false; +} + +static void LoadConfigFile( const char *pFileName, float *bumpScale, int *startFrame, int *endFrame ) +{ + CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER ); + if ( !g_pFullFileSystem->ReadFile( pFileName, NULL, buf ) ) + { + fprintf( stderr, "Can't open: %s\n", pFileName ); + Pause(); + exit( -1 ); + } + + char *key = NULL; + char *val = NULL; + while( GetKeyValueFromBuffer( buf, &key, &val ) ) + { + if( stricmp( key, "bumpscale" ) == 0 ) + { + *bumpScale = atof( val ); + } + if( stricmp( key, "startframe" ) == 0 ) + { + *startFrame = atoi( val ); + } + else if( stricmp( key, "endframe" ) == 0 ) + { + *endFrame = atoi( val ); + } + } +} + +static void Usage() +{ + fprintf( stderr, "Usage: height2normal [-nopause] [-quiet] tex1_normal.txt tex2_normal.txt . . .\n" ); + fprintf( stderr, "-quiet : don't print anything out, don't pause for input\n" ); + fprintf( stderr, "-nopause : don't pause for input\n" ); + Pause(); + exit( -1 ); +} + +void ProcessFiles( const char *pNormalFileNameWithoutExtension, + int startFrame, int endFrame, + float bumpScale ) +{ + static char heightTGAFileName[1024]; + static char normalTGAFileName[1024]; + static char buf[1024]; + bool animated = !( startFrame == -1 || endFrame == -1 ); + int numFrames = endFrame - startFrame + 1; + int frameID; + + for( frameID = 0; frameID < numFrames; frameID++ ) + { + if( animated ) + { + sprintf( normalTGAFileName, "%s%03d.tga", pNormalFileNameWithoutExtension, frameID + startFrame ); + } + else + { + sprintf( normalTGAFileName, "%s.tga", pNormalFileNameWithoutExtension ); + } + if( !Q_stristr( pNormalFileNameWithoutExtension, "_normal" ) ) + { + fprintf( stderr, "ERROR: config file name must end in _normal.txt\n" ); + return; + } + + strcpy( buf, pNormalFileNameWithoutExtension ); + + // Strip '_normal' off the end because we're looking for '_height' + char *pcUnderscore = Q_stristr( buf, "_normal" ); + *pcUnderscore = NULL; + + if( animated ) + { + sprintf( heightTGAFileName, "%s_height%03d.tga", buf, frameID + startFrame ); + } + else + { + sprintf( heightTGAFileName, "%s_height.tga", buf ); + } + + enum ImageFormat imageFormat; + int width, height; + float sourceGamma; + CUtlBuffer buf; + if ( !g_pFullFileSystem->ReadFile( heightTGAFileName, NULL, buf ) ) + { + fprintf( stderr, "%s not found\n", heightTGAFileName ); + return; + } + + if ( !TGALoader::GetInfo( buf, &width, &height, &imageFormat, &sourceGamma ) ) + { + fprintf( stderr, "error in %s\n", heightTGAFileName ); + return; + } + + int memRequired = ImageLoader::GetMemRequired( width, height, 1, IMAGE_FORMAT_IA88, false ); + unsigned char *pImageIA88 = new unsigned char[memRequired]; + + buf.SeekGet( CUtlBuffer::SEEK_HEAD, 0 ); + TGALoader::Load( pImageIA88, buf, width, height, IMAGE_FORMAT_IA88, sourceGamma, false ); + + memRequired = ImageLoader::GetMemRequired( width, height, 1, IMAGE_FORMAT_RGBA8888, false ); + unsigned char *pImageRGBA8888 = new unsigned char[memRequired]; + ImageLoader::ConvertIA88ImageToNormalMapRGBA8888( pImageIA88, width, height, pImageRGBA8888, bumpScale ); + + CUtlBuffer normalBuf; + ImageLoader::NormalizeNormalMapRGBA8888( pImageRGBA8888, width * height ); + if( ImageRGBA8888HasAlpha( pImageRGBA8888, width * height ) ) + { + TGAWriter::WriteToBuffer( pImageRGBA8888, normalBuf, width, height, IMAGE_FORMAT_RGBA8888, IMAGE_FORMAT_RGBA8888 ); + } + else + { + memRequired = ImageLoader::GetMemRequired( width, height, 1, IMAGE_FORMAT_RGB888, false ); + unsigned char *pImageRGB888 = new unsigned char[memRequired]; + ImageLoader::ConvertImageFormat( pImageRGBA8888, IMAGE_FORMAT_RGBA8888, + pImageRGB888, IMAGE_FORMAT_RGB888, width, height, 0, 0 ); + TGAWriter::WriteToBuffer( pImageRGB888, normalBuf, width, height, IMAGE_FORMAT_RGB888, IMAGE_FORMAT_RGB888 ); + delete [] pImageRGB888; + } + if ( !g_pFullFileSystem->WriteFile( normalTGAFileName, NULL, normalBuf ) ) + { + fprintf( stderr, "unable to write %s\n", normalTGAFileName ); + return; + } + delete [] pImageIA88; + delete [] pImageRGBA8888; + } +} + +int main( int argc, char **argv ) +{ + if( argc < 2 ) + { + Usage(); + } + MathLib_Init( 2.2f, 2.2f, 0.0f, 2.0f ); + InitDefaultFileSystem(); + + int i = 1; + while( i < argc ) + { + if( stricmp( argv[i], "-quiet" ) == 0 ) + { + i++; + g_Quiet = true; + g_NoPause = true; // no point in pausing if we aren't going to print anything out. + } + if( stricmp( argv[i], "-nopause" ) == 0 ) + { + i++; + g_NoPause = true; + } + else + { + break; + } + } + + char pCurrentDirectory[MAX_PATH]; + if ( _getcwd( pCurrentDirectory, sizeof(pCurrentDirectory) ) == NULL ) + { + fprintf( stderr, "Unable to get the current directory\n" ); + return -1; + } + + Q_FixSlashes( pCurrentDirectory ); + Q_StripTrailingSlash( pCurrentDirectory ); + + for( ; i < argc; i++ ) + { + static char normalFileNameWithoutExtension[1024]; + char *pFileName; + if ( !Q_IsAbsolutePath( argv[i] ) ) + { + Q_snprintf( normalFileNameWithoutExtension, sizeof(normalFileNameWithoutExtension), "%s\\%s", pCurrentDirectory, argv[i] ); + pFileName = normalFileNameWithoutExtension; + } + else + { + pFileName = argv[i]; + } + + if( !g_Quiet ) + { + printf( "file: %s\n", pFileName ); + } + float bumpScale = -1.0f; + int startFrame = -1; + int endFrame = -1; + LoadConfigFile( pFileName, &bumpScale, &startFrame, &endFrame ); + if( bumpScale == -1.0f ) + { + fprintf( stderr, "Must specify \"bumpscale\" in config file\n" ); + Pause(); + continue; + } + if( ( startFrame == -1 && endFrame != -1 ) || + ( startFrame != -1 && endFrame == -1 ) ) + { + fprintf( stderr, "ERROR: If you use startframe, you must use endframe, and vice versa.\n" ); + Pause(); + continue; + } + if( !g_Quiet ) + { + printf( "\tbumpscale: %f\n", bumpScale ); + } + + Q_StripExtension( pFileName, normalFileNameWithoutExtension, sizeof( normalFileNameWithoutExtension ) ); + ProcessFiles( normalFileNameWithoutExtension, + startFrame, endFrame, + bumpScale ); + } + return 0; +} -- cgit v1.2.3