diff --git a/Engine/source/T3D/assets/ShapeAsset.h b/Engine/source/T3D/assets/ShapeAsset.h index 81b716d08..7c87cf8de 100644 --- a/Engine/source/T3D/assets/ShapeAsset.h +++ b/Engine/source/T3D/assets/ShapeAsset.h @@ -39,7 +39,7 @@ #endif #ifndef _TSSHAPE_H_ -#include "ts/TSShape.h" +#include "ts/tsShape.h" #endif #ifndef __RESOURCE_H__ #include "core/resource.h" diff --git a/Engine/source/T3D/player.cpp b/Engine/source/T3D/player.cpp index 3c258c374..6e33284a6 100644 --- a/Engine/source/T3D/player.cpp +++ b/Engine/source/T3D/player.cpp @@ -4659,9 +4659,9 @@ Point3F Player::_move( const F32 travelTime, Collision *outCol ) } Point3F distance = end - start; - if (mFabs(distance.x) < mObjBox.len_x() && - mFabs(distance.y) < mObjBox.len_y() && - mFabs(distance.z) < mObjBox.len_z()) + if (mFabs(distance.x) < mScaledBox.len_x() && + mFabs(distance.y) < mScaledBox.len_y() && + mFabs(distance.z) < mScaledBox.len_z()) { // We can potentially early out of this. If there are no polys in the clipped polylist at our // end position, then we can bail, and just set start = end; diff --git a/Engine/source/T3D/tsStatic.cpp b/Engine/source/T3D/tsStatic.cpp index 0ca66b32f..78240ce16 100644 --- a/Engine/source/T3D/tsStatic.cpp +++ b/Engine/source/T3D/tsStatic.cpp @@ -91,6 +91,9 @@ ConsoleDocClass( TSStatic, ); TSStatic::TSStatic() +: + cubeDescId( 0 ), + reflectorDesc( NULL ) { mNetFlags.set(Ghostable | ScopeAlways); @@ -186,6 +189,11 @@ void TSStatic::initPersistFields() endGroup("Rendering"); + addGroup( "Reflection" ); + addField( "cubeReflectorDesc", TypeRealString, Offset( cubeDescName, TSStatic ), + "References a ReflectorDesc datablock that defines performance and quality properties for dynamic reflections.\n"); + endGroup( "Reflection" ); + addGroup("Collision"); addField( "collisionType", TypeTSMeshType, Offset( mCollisionType, TSStatic ), @@ -292,6 +300,14 @@ bool TSStatic::onAdd() addToScene(); + if ( isClientObject() ) + { + mCubeReflector.unregisterReflector(); + + if ( reflectorDesc ) + mCubeReflector.registerReflector( this, reflectorDesc ); + } + _updateShouldTick(); // Accumulation @@ -357,6 +373,16 @@ bool TSStatic::_createShape() if ( mAmbientThread ) mShapeInstance->setSequence( mAmbientThread, ambientSeq, 0); + // Resolve CubeReflectorDesc. + if ( cubeDescName.isNotEmpty() ) + { + Sim::findObject( cubeDescName, reflectorDesc ); + } + else if( cubeDescId > 0 ) + { + Sim::findObject( cubeDescId, reflectorDesc ); + } + return true; } @@ -429,6 +455,8 @@ void TSStatic::onRemove() mShapeInstance = NULL; mAmbientThread = NULL; + if ( isClientObject() ) + mCubeReflector.unregisterReflector(); Parent::onRemove(); } @@ -561,6 +589,12 @@ void TSStatic::prepRenderImage( SceneRenderState* state ) F32 invScale = (1.0f/getMax(getMax(mObjScale.x,mObjScale.y),mObjScale.z)); + // If we're currently rendering our own reflection we + // don't want to render ourselves into it. + if ( mCubeReflector.isRendering() ) + return; + + if ( mForceDetail == -1 ) mShapeInstance->setDetailFromDistance( state, dist * invScale ); else @@ -577,6 +611,9 @@ void TSStatic::prepRenderImage( SceneRenderState* state ) rdata.setFadeOverride( 1.0f ); rdata.setOriginSort( mUseOriginSort ); + if ( mCubeReflector.isEnabled() ) + rdata.setCubemap( mCubeReflector.getCubemap() ); + // Acculumation rdata.setAccuTex(mAccuTex); @@ -604,6 +641,20 @@ void TSStatic::prepRenderImage( SceneRenderState* state ) mat.scale( mObjScale ); GFX->setWorldMatrix( mat ); + if ( state->isDiffusePass() && mCubeReflector.isEnabled() && mCubeReflector.getOcclusionQuery() ) + { + RenderPassManager *pass = state->getRenderPass(); + OccluderRenderInst *ri = pass->allocInst(); + + ri->type = RenderPassManager::RIT_Occluder; + ri->query = mCubeReflector.getOcclusionQuery(); + mObjToWorld.mulP( mObjBox.getCenter(), &ri->position ); + ri->scale.set( mObjBox.getExtents() ); + ri->orientation = pass->allocUniqueXform( mObjToWorld ); + ri->isSphere = false; + state->getRenderPass()->addInst( ri ); + } + mShapeInstance->animate(); if(mShapeInstance) { @@ -715,6 +766,10 @@ U32 TSStatic::packUpdate(NetConnection *con, U32 mask, BitStream *stream) if ( mLightPlugin ) retMask |= mLightPlugin->packUpdate(this, AdvancedStaticOptionsMask, con, mask, stream); + if( stream->writeFlag( reflectorDesc != NULL ) ) + { + stream->writeRangedU32( reflectorDesc->getId(), DataBlockObjectIdFirst, DataBlockObjectIdLast ); + } return retMask; } @@ -782,6 +837,11 @@ void TSStatic::unpackUpdate(NetConnection *con, BitStream *stream) mLightPlugin->unpackUpdate(this, con, stream); } + if( stream->readFlag() ) + { + cubeDescId = stream->readRangedU32( DataBlockObjectIdFirst, DataBlockObjectIdLast ); + } + if ( isProperlyAdded() ) _updateShouldTick(); } diff --git a/Engine/source/T3D/tsStatic.h b/Engine/source/T3D/tsStatic.h index 704cac783..5bf4b5353 100644 --- a/Engine/source/T3D/tsStatic.h +++ b/Engine/source/T3D/tsStatic.h @@ -39,6 +39,10 @@ #include "ts/tsShape.h" #endif +#ifndef _REFLECTOR_H_ + #include "scene/reflector.h" +#endif + class TSShapeInstance; class TSThread; class TSStatic; @@ -147,6 +151,11 @@ protected: /// Start or stop processing ticks depending on our state. void _updateShouldTick(); + String cubeDescName; + U32 cubeDescId; + ReflectorDesc *reflectorDesc; + CubeReflector mCubeReflector; + protected: Convex *mConvexList; diff --git a/Engine/source/console/consoleFunctions.cpp b/Engine/source/console/consoleFunctions.cpp index eea6422e1..be265add8 100644 --- a/Engine/source/console/consoleFunctions.cpp +++ b/Engine/source/console/consoleFunctions.cpp @@ -25,6 +25,11 @@ #include "console/consoleInternal.h" #include "console/engineAPI.h" #include "console/ast.h" + +#ifndef _CONSOLFUNCTIONS_H_ +#include "console/consoleFunctions.h" +#endif + #include "core/strings/findMatch.h" #include "core/strings/stringUnit.h" #include "core/strings/unicode.h" @@ -32,6 +37,7 @@ #include "console/compiler.h" #include "platform/platformInput.h" #include "core/util/journal/journal.h" +#include "gfx/gfxEnums.h" #include "core/util/uuid.h" #include "core/color.h" #include "math/mPoint3.h" @@ -44,6 +50,132 @@ bool LinkConsoleFunctions = false; // Buffer for expanding script filenames. static char scriptFilenameBuffer[1024]; +bool isInt(const char* str) +{ + int len = dStrlen(str); + if(len <= 0) + return false; + + // Ignore whitespace + int start = 0; + for(int i = start; i < len; i++) + if(str[i] != ' ') + { + start = i; + break; + } + + for(int i = start; i < len; i++) + switch(str[i]) + { + case '+': case '-': + if(i != 0) + return false; + break; + case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '0': + break; + case ' ': // ignore whitespace + for(int j = i+1; j < len; j++) + if(str[j] != ' ') + return false; + return true; + break; + default: + return false; + } + return true; +} + +bool isFloat(const char* str, bool sciOk = false) +{ + int len = dStrlen(str); + if(len <= 0) + return false; + + // Ingore whitespace + int start = 0; + for(int i = start; i < len; i++) + if(str[i] != ' ') + { + start = i; + break; + } + + bool seenDot = false; + int eLoc = -1; + for(int i = 0; i < len; i++) + switch(str[i]) + { + case '+': case '-': + if(sciOk) + { + //Haven't found e or scientific notation symbol + if(eLoc == -1) + { + //only allowed in beginning + if(i != 0) + return false; + } + else + { + //if not right after the e + if(i != (eLoc + 1)) + return false; + } + } + else + { + //only allowed in beginning + if(i != 0) + return false; + } + break; + case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '0': + break; + case 'e': case 'E': + if(!sciOk) + return false; + else + { + //already saw it so can't have 2 + if(eLoc != -1) + return false; + + eLoc = i; + } + break; + case '.': + if(seenDot | (sciOk && eLoc != -1)) + return false; + seenDot = true; + break; + case ' ': // ignore whitespace + for(int j = i+1; j < len; j++) + if(str[j] != ' ') + return false; + return true; + break; + default: + return false; + } + return true; +} + +bool isValidIP(const char* ip) +{ + unsigned b1, b2, b3, b4; + unsigned char c; + int rc = dSscanf(ip, "%3u.%3u.%3u.%3u%c", &b1, &b2, &b3, &b4, &c); + if (rc != 4 && rc != 5) return false; + if ((b1 | b2 | b3 | b4) > 255) return false; + if (dStrspn(ip, "0123456789.") < dStrlen(ip)) return false; + return true; +} + +bool isValidPort(U16 port) +{ + return (port >= 0 && port <=65535); +} //============================================================================= // String Functions. @@ -238,6 +370,40 @@ DefineConsoleFunction( strlen, S32, ( const char* str ),, return dStrlen( str ); } +//----------------------------------------------------------------------------- +DefineConsoleFunction( strlenskip, S32, ( const char* str, const char* first, const char* last ),, + "Calculate the length of a string in characters, skipping everything between and including first and last.\n" + "@param str A string.\n" + "@param first First character to look for to skip block of text.\n" + "@param last Second character to look for to skip block of text.\n" + "@return The length of the given string skipping blocks of text between characters.\n" + "@ingroup Strings" ) +{ + const UTF8* pos = str; + U32 size = 0; + U32 length = dStrlen(str); + bool count = true; + + //loop through each character counting each character, skipping tags (anything with < followed by >) + for(U32 i = 0; i < length; i++, pos++) + { + if(count) + { + if(*pos == first[0]) + count = false; + else + size++; + } + else + { + if(*pos == last[0]) + count = true; + } + } + + return S32(size); +} + //----------------------------------------------------------------------------- DefineConsoleFunction( strstr, S32, ( const char* string, const char* substring ),, @@ -284,6 +450,33 @@ DefineConsoleFunction( strpos, S32, ( const char* haystack, const char* needle, //----------------------------------------------------------------------------- +DefineConsoleFunction( strposr, S32, ( const char* haystack, const char* needle, S32 offset ), ( 0 ), + "Find the start of @a needle in @a haystack searching from right to left beginning at the given offset.\n" + "@param haystack The string to search.\n" + "@param needle The string to search for.\n" + "@return The index at which the first occurrence of @a needle was found in @a heystack or -1 if no match was found.\n\n" + "@tsexample\n" + "strposr( \"b ab\", \"b\", 1 ) // Returns 2.\n" + "@endtsexample\n" + "@ingroup Strings" ) +{ + U32 sublen = dStrlen( needle ); + U32 strlen = dStrlen( haystack ); + S32 start = strlen - offset; + + if(start < 0 || start > strlen) + return -1; + + if (start + sublen > strlen) + start = strlen - sublen; + for(; start >= 0; start--) + if(!dStrncmp(haystack + start, needle, sublen)) + return start; + return -1; +} + +//----------------------------------------------------------------------------- + DefineConsoleFunction( ltrim, const char*, ( const char* str ),, "Remove leading whitespace from the string.\n" "@param str A string.\n" @@ -630,6 +823,18 @@ DefineConsoleFunction( stripTrailingNumber, String, ( const char* str ),, return String::GetTrailingNumber( str, suffix ); } +//----------------------------------------------------------------------------- + +DefineConsoleFunction( getFirstNumber, String, ( const char* str ),, + "Get the first occuring number from @a str.\n" + "@param str The string from which to read out the first number.\n" + "@return String representation of the number or "" if no number.\n\n") +{ + U32 start; + U32 end; + return String::GetFirstNumber(str, start, end); +} + //---------------------------------------------------------------- DefineConsoleFunction( isspace, bool, ( const char* str, S32 index ),, @@ -829,69 +1034,175 @@ DefineConsoleFunction(ColorFloatToInt, ColorI, (ColorF color), , } DefineConsoleFunction(ColorIntToFloat, ColorF, (ColorI color), , - "Convert from a integer color to an float color (0 to 255 to 0.0 - 1.0).\n" - "@param color Integer color value to be converted in the form \"R G B A\", where R is red, G is green, B is blue, and A is alpha.\n" - "@return Converted color value (0.0 - 1.0)\n\n" - "@tsexample\n" - "ColorIntToFloat( \"0 0 255 128\" ) // Returns \"0 0 1 0.5\".\n" - "@endtsexample\n" - "@ingroup Strings") + "Convert from a integer color to an float color (0 to 255 to 0.0 - 1.0).\n" + "@param color Integer color value to be converted in the form \"R G B A\", where R is red, G is green, B is blue, and A is alpha.\n" + "@return Converted color value (0.0 - 1.0)\n\n" + "@tsexample\n" + "ColorIntToFloat( \"0 0 255 128\" ) // Returns \"0 0 1 0.5\".\n" + "@endtsexample\n" + "@ingroup Strings") { - return (ColorF)color; + return (ColorF)color; } DefineConsoleFunction(ColorRGBToHEX, const char*, (ColorI color), , - "Convert from a integer RGB (red, green, blue) color to hex color value (0 to 255 to 00 - FF).\n" - "@param color Integer color value to be converted in the form \"R G B A\", where R is red, G is green, B is blue, and A is alpha. It excepts an alpha, but keep in mind this will not be converted.\n" - "@return Hex color value (#000000 - #FFFFFF), alpha isn't handled/converted so it is only the RGB value\n\n" - "@tsexample\n" - "ColorRBGToHEX( \"0 0 255 128\" ) // Returns \"#0000FF\".\n" - "@endtsexample\n" - "@ingroup Strings") + "Convert from a integer RGB (red, green, blue) color to hex color value (0 to 255 to 00 - FF).\n" + "@param color Integer color value to be converted in the form \"R G B A\", where R is red, G is green, B is blue, and A is alpha. It excepts an alpha, but keep in mind this will not be converted.\n" + "@return Hex color value (#000000 - #FFFFFF), alpha isn't handled/converted so it is only the RGB value\n\n" + "@tsexample\n" + "ColorRBGToHEX( \"0 0 255 128\" ) // Returns \"#0000FF\".\n" + "@endtsexample\n" + "@ingroup Strings") { - return Con::getReturnBuffer(color.getHex()); + return Con::getReturnBuffer(color.getHex()); } DefineConsoleFunction(ColorRGBToHSB, const char*, (ColorI color), , - "Convert from a integer RGB (red, green, blue) color to HSB (hue, saturation, brightness). HSB is also know as HSL or HSV as well, with the last letter standing for lightness or value.\n" - "@param color Integer color value to be converted in the form \"R G B A\", where R is red, G is green, B is blue, and A is alpha. It excepts an alpha, but keep in mind this will not be converted.\n" - "@return HSB color value, alpha isn't handled/converted so it is only the RGB value\n\n" - "@tsexample\n" - "ColorRBGToHSB( \"0 0 255 128\" ) // Returns \"240 100 100\".\n" - "@endtsexample\n" - "@ingroup Strings") + "Convert from a integer RGB (red, green, blue) color to HSB (hue, saturation, brightness). HSB is also know as HSL or HSV as well, with the last letter standing for lightness or value.\n" + "@param color Integer color value to be converted in the form \"R G B A\", where R is red, G is green, B is blue, and A is alpha. It excepts an alpha, but keep in mind this will not be converted.\n" + "@return HSB color value, alpha isn't handled/converted so it is only the RGB value\n\n" + "@tsexample\n" + "ColorRBGToHSB( \"0 0 255 128\" ) // Returns \"240 100 100\".\n" + "@endtsexample\n" + "@ingroup Strings") { - ColorI::Hsb hsb(color.getHSB()); - String s(String::ToString(hsb.hue) + " " + String::ToString(hsb.sat) + " " + String::ToString(hsb.brightness)); - return Con::getReturnBuffer(s); + ColorI::Hsb hsb(color.getHSB()); + String s(String::ToString(hsb.hue) + " " + String::ToString(hsb.sat) + " " + String::ToString(hsb.brightness)); + return Con::getReturnBuffer(s); } DefineConsoleFunction(ColorHEXToRGB, ColorI, (const char* hex), , - "Convert from a hex color value to an integer RGB (red, green, blue) color (00 - FF to 0 to 255).\n" - "@param hex Hex color value (#000000 - #FFFFFF) to be converted to an RGB (red, green, blue) value.\n" - "@return Integer color value to be converted in the form \"R G B A\", where R is red, G is green, B is blue, and A is alpha. Alpha isn't handled/converted so only pay attention to the RGB value\n\n" - "@tsexample\n" - "ColorHEXToRGB( \"#0000FF\" ) // Returns \"0 0 255 0\".\n" - "@endtsexample\n" - "@ingroup Strings") + "Convert from a hex color value to an integer RGB (red, green, blue) color (00 - FF to 0 to 255).\n" + "@param hex Hex color value (#000000 - #FFFFFF) to be converted to an RGB (red, green, blue) value.\n" + "@return Integer color value to be converted in the form \"R G B A\", where R is red, G is green, B is blue, and A is alpha. Alpha isn't handled/converted so only pay attention to the RGB value\n\n" + "@tsexample\n" + "ColorHEXToRGB( \"#0000FF\" ) // Returns \"0 0 255 0\".\n" + "@endtsexample\n" + "@ingroup Strings") { - ColorI color; - color.set(hex); - return color; + S32 rgb = dAtoui(hex, 16); + + ColorI color; + color.set(rgb & 0x000000FF, (rgb & 0x0000FF00) >> 8, (rgb & 0x00FF0000) >> 16); + return color; } DefineConsoleFunction(ColorHSBToRGB, ColorI, (Point3I hsb), , - "Convert from a HSB (hue, saturation, brightness) to an integer RGB (red, green, blue) color. HSB is also know as HSL or HSV as well, with the last letter standing for lightness or value.\n" - "@param hsb HSB (hue, saturation, brightness) value to be converted.\n" - "@return Integer color value to be converted in the form \"R G B A\", where R is red, G is green, B is blue, and A is alpha. Alpha isn't handled/converted so only pay attention to the RGB value\n\n" - "@tsexample\n" - "ColorHSBToRGB( \"240 100 100\" ) // Returns \"0 0 255 0\".\n" - "@endtsexample\n" - "@ingroup Strings") + "Convert from a HSB (hue, saturation, brightness) to an integer RGB (red, green, blue) color. HSB is also know as HSL or HSV as well, with the last letter standing for lightness or value.\n" + "@param hsb HSB (hue, saturation, brightness) value to be converted.\n" + "@return Integer color value to be converted in the form \"R G B A\", where R is red, G is green, B is blue, and A is alpha. Alpha isn't handled/converted so only pay attention to the RGB value\n\n" + "@tsexample\n" + "ColorHSBToRGB( \"240 100 100\" ) // Returns \"0 0 255 0\".\n" + "@endtsexample\n" + "@ingroup Strings") { - ColorI color; - color.set(ColorI::Hsb(hsb.x, hsb.y, hsb.z)); - return color; + ColorI color; + color.set(ColorI::Hsb(hsb.x, hsb.y, hsb.z)); + return color; +} + +//---------------------------------------------------------------- + +DefineConsoleFunction( strToggleCaseToWords, const char*, ( const char* str ),, + "Parse a Toggle Case word into separate words.\n" + "@param str The string to parse.\n" + "@return new string space separated.\n\n" + "@tsexample\n" + "strToggleCaseToWords( \"HelloWorld\" ) // Returns \"Hello World\".\n" + "@endtsexample\n" + "@ingroup Strings" ) +{ + String newStr; + for(S32 i = 0; str[i]; i++) + { + //If capitol add a space + if(i != 0 && str[i] >= 65 && str[i] <= 90) + newStr += " "; + + newStr += str[i]; + } + + return Con::getReturnBuffer(newStr); +} + +//---------------------------------------------------------------- + +// Warning: isInt and isFloat are very 'strict' and might need to be adjusted to allow other values. //seanmc +DefineConsoleFunction( isInt, bool, ( const char* str),, + "Returns true if the string is an integer.\n" + "@param str The string to test.\n" + "@return true if @a str is an integer and false if not\n\n" + "@tsexample\n" + "isInt( \"13\" ) // Returns true.\n" + "@endtsexample\n" + "@ingroup Strings" ) +{ + return isInt(str); +} + +//---------------------------------------------------------------- + +DefineConsoleFunction( isFloat, bool, ( const char* str, bool sciOk), (false), + "Returns true if the string is a float.\n" + "@param str The string to test.\n" + "@param sciOk Test for correct scientific notation and accept it (ex. 1.2e+14)" + "@return true if @a str is a float and false if not\n\n" + "@tsexample\n" + "isFloat( \"13.5\" ) // Returns true.\n" + "@endtsexample\n" + "@ingroup Strings" ) +{ + return isFloat(str, sciOk); +} + +//---------------------------------------------------------------- + +DefineConsoleFunction( isValidPort, bool, ( const char* str),, + "Returns true if the string is a valid port number.\n" + "@param str The string to test.\n" + "@return true if @a str is a port and false if not\n\n" + "@tsexample\n" + "isValidPort( \"8080\" ) // Returns true.\n" + "@endtsexample\n" + "@ingroup Strings" ) +{ + if(isInt(str)) + { + U16 port = dAtous(str); + return isValidPort(port); + } + else + return false; +} + +//---------------------------------------------------------------- + +DefineConsoleFunction( isValidIP, bool, ( const char* str),, + "Returns true if the string is a valid ip address, excepts localhost.\n" + "@param str The string to test.\n" + "@return true if @a str is a valid ip address and false if not\n\n" + "@tsexample\n" + "isValidIP( \"localhost\" ) // Returns true.\n" + "@endtsexample\n" + "@ingroup Strings" ) +{ + if(dStrcmp(str, "localhost") == 0) + { + return true; + } + else + return isValidIP(str); +} + +//---------------------------------------------------------------- + +// Torque won't normally add another string if it already exists with another casing, +// so this forces the addition. It should be called once near the start, such as in main.cs. +ConsoleFunction(addCaseSensitiveStrings,void,2,0,"[string1, string2, ...]" + "Adds case sensitive strings to the StringTable.") +{ + for(int i = 1; i < argc; i++) + StringTable->insert(argv[i], true); } //============================================================================= @@ -912,6 +1223,7 @@ DefineConsoleFunction( getWord, const char*, ( const char* text, S32 index ),, "@endtsexample\n\n" "@see getWords\n" "@see getWordCount\n" + "@see getToken\n" "@see getField\n" "@see getRecord\n" "@ingroup FieldManip" ) @@ -935,6 +1247,7 @@ DefineConsoleFunction( getWords, const char*, ( const char* text, S32 startIndex "@endtsexample\n\n" "@see getWord\n" "@see getWordCount\n" + "@see getTokens\n" "@see getFields\n" "@see getRecords\n" "@ingroup FieldManip" ) @@ -959,6 +1272,7 @@ DefineConsoleFunction( setWord, const char*, ( const char* text, S32 index, cons "setWord( \"a b c d\", 2, \"f\" ) // Returns \"a b f d\"\n" "@endtsexample\n\n" "@see getWord\n" + "@see setToken\n" "@see setField\n" "@see setRecord\n" "@ingroup FieldManip" ) @@ -978,6 +1292,7 @@ DefineConsoleFunction( removeWord, const char*, ( const char* text, S32 index ), "@tsexample\n" "removeWord( \"a b c d\", 2 ) // Returns \"a b d\"\n" "@endtsexample\n\n" + "@see removeToken\n" "@see removeField\n" "@see removeRecord\n" "@ingroup FieldManip" ) @@ -995,6 +1310,7 @@ DefineConsoleFunction( getWordCount, S32, ( const char* text ),, "@tsexample\n" "getWordCount( \"a b c d e\" ) // Returns 5\n" "@endtsexample\n\n" + "@see getTokenCount\n" "@see getFieldCount\n" "@see getRecordCount\n" "@ingroup FieldManip" ) @@ -1004,6 +1320,49 @@ DefineConsoleFunction( getWordCount, S32, ( const char* text ),, //----------------------------------------------------------------------------- +DefineEngineFunction( monthNumToStr, String, ( S32 num, bool abbreviate ), (false), + "@brief returns month as a word given a number or \"\" if number is bad" + "@return month as a word given a number or \"\" if number is bad" + "@ingroup FileSystem") +{ + switch(num) + { + case 1: return abbreviate ? "Jan" : "January"; break; + case 2: return abbreviate ? "Feb" : "February"; break; + case 3: return abbreviate ? "Mar" : "March"; break; + case 4: return abbreviate ? "Apr" : "April"; break; + case 5: return "May"; break; + case 6: return abbreviate ? "Jun" : "June"; break; + case 7: return abbreviate ? "Jul" : "July"; break; + case 8: return abbreviate ? "Aug" : "August"; break; + case 9: return abbreviate ? "Sep" : "September"; break; + case 10: return abbreviate ? "Oct" : "October"; break; + case 11: return abbreviate ? "Nov" : "November"; break; + case 12: return abbreviate ? "Dec" : "December"; break; + default: return ""; + } +} + +DefineEngineFunction( weekdayNumToStr, String, ( S32 num, bool abbreviate ), (false), + "@brief returns weekday as a word given a number or \"\" if number is bad" + "@return weekday as a word given a number or \"\" if number is bad" + "@ingroup FileSystem") +{ + switch(num) + { + case 0: return abbreviate ? "Sun" : "Sunday"; break; + case 1: return abbreviate ? "Mon" : "Monday"; break; + case 2: return abbreviate ? "Tue" : "Tuesday"; break; + case 3: return abbreviate ? "Wed" : "Wednesday"; break; + case 4: return abbreviate ? "Thu" : "Thursday"; break; + case 5: return abbreviate ? "Fri" : "Friday"; break; + case 6: return abbreviate ? "Sat" : "Saturday"; break; + default: return ""; + } +} + +//----------------------------------------------------------------------------- + DefineConsoleFunction( getField, const char*, ( const char* text, S32 index ),, "Extract the field at the given @a index in the newline and/or tab separated list in @a text.\n" "Fields in @a text must be separated by newlines and/or tabs.\n" @@ -1325,6 +1684,114 @@ DefineConsoleFunction( nextToken, const char*, ( const char* str1, const char* t return ret; } +//----------------------------------------------------------------------------- + +DefineConsoleFunction( getToken, const char*, ( const char* text, const char* delimiters, S32 index ),, + "Extract the substring at the given @a index in the @a delimiters separated list in @a text.\n" + "@param text A @a delimiters list of substrings.\n" + "@param delimiters Character or characters that separate the list of substrings in @a text.\n" + "@param index The zero-based index of the substring to extract.\n" + "@return The substring at the given index or \"\" if the index is out of range.\n\n" + "@tsexample\n" + "getToken( \"a b c d\", \" \", 2 ) // Returns \"c\"\n" + "@endtsexample\n\n" + "@see getTokens\n" + "@see getTokenCount\n" + "@see getWord\n" + "@see getField\n" + "@see getRecord\n" + "@ingroup FieldManip" ) +{ + return Con::getReturnBuffer( StringUnit::getUnit(text, index, delimiters)); +} + +//----------------------------------------------------------------------------- + +DefineConsoleFunction( getTokens, const char*, ( const char* text, const char* delimiters, S32 startIndex, S32 endIndex ), ( -1 ), + "Extract a range of substrings separated by @a delimiters at the given @a startIndex onwards thru @a endIndex.\n" + "@param text A @a delimiters list of substrings.\n" + "@param delimiters Character or characters that separate the list of substrings in @a text.\n" + "@param startIndex The zero-based index of the first substring to extract from @a text.\n" + "@param endIndex The zero-based index of the last substring to extract from @a text. If this is -1, all words beginning " + "with @a startIndex are extracted from @a text.\n" + "@return A string containing the specified range of substrings from @a text or \"\" if @a startIndex " + "is out of range or greater than @a endIndex.\n\n" + "@tsexample\n" + "getTokens( \"a b c d\", \" \", 1, 2, ) // Returns \"b c\"\n" + "@endtsexample\n\n" + "@see getToken\n" + "@see getTokenCount\n" + "@see getWords\n" + "@see getFields\n" + "@see getRecords\n" + "@ingroup FieldManip" ) +{ + if( endIndex < 0 ) + endIndex = 1000000; + + return Con::getReturnBuffer( StringUnit::getUnits( text, startIndex, endIndex, delimiters ) ); +} + +//----------------------------------------------------------------------------- + +DefineConsoleFunction( setToken, const char*, ( const char* text, const char* delimiters, S32 index, const char* replacement ),, + "Replace the substring in @a text separated by @a delimiters at the given @a index with @a replacement.\n" + "@param text A @a delimiters list of substrings.\n" + "@param delimiters Character or characters that separate the list of substrings in @a text.\n" + "@param index The zero-based index of the substring to replace.\n" + "@param replacement The string with which to replace the substring.\n" + "@return A new string with the substring at the given @a index replaced by @a replacement or the original " + "string if @a index is out of range.\n\n" + "@tsexample\n" + "setToken( \"a b c d\", \" \", 2, \"f\" ) // Returns \"a b f d\"\n" + "@endtsexample\n\n" + "@see getToken\n" + "@see setWord\n" + "@see setField\n" + "@see setRecord\n" + "@ingroup FieldManip" ) +{ + return Con::getReturnBuffer( StringUnit::setUnit( text, index, replacement, delimiters) ); +} + +//----------------------------------------------------------------------------- + +DefineConsoleFunction( removeToken, const char*, ( const char* text, const char* delimiters, S32 index ),, + "Remove the substring in @a text separated by @a delimiters at the given @a index.\n" + "@param text A @a delimiters list of substrings.\n" + "@param delimiters Character or characters that separate the list of substrings in @a text.\n" + "@param index The zero-based index of the word in @a text.\n" + "@return A new string with the substring at the given index removed or the original string if @a index is " + "out of range.\n\n" + "@tsexample\n" + "removeToken( \"a b c d\", \" \", 2 ) // Returns \"a b d\"\n" + "@endtsexample\n\n" + "@see removeWord\n" + "@see removeField\n" + "@see removeRecord\n" + "@ingroup FieldManip" ) +{ + return Con::getReturnBuffer( StringUnit::removeUnit( text, index, delimiters ) ); +} + +//----------------------------------------------------------------------------- + +DefineConsoleFunction( getTokenCount, S32, ( const char* text, const char* delimiters),, + "Return the number of @a delimiters substrings in @a text.\n" + "@param text A @a delimiters list of substrings.\n" + "@param delimiters Character or characters that separate the list of substrings in @a text.\n" + "@return The number of @a delimiters substrings in @a text.\n\n" + "@tsexample\n" + "getTokenCount( \"a b c d e\", \" \" ) // Returns 5\n" + "@endtsexample\n\n" + "@see getWordCount\n" + "@see getFieldCount\n" + "@see getRecordCount\n" + "@ingroup FieldManip" ) +{ + return StringUnit::getUnitCount( text, delimiters ); +} + //============================================================================= // Tagged Strings. //============================================================================= @@ -2680,3 +3147,10 @@ DefineEngineFunction( isToolBuild, bool, (),, return false; #endif } + +DefineEngineFunction( getMaxDynamicVerts, S32, (),, + "Get max number of allowable dynamic vertices in a single vertex buffer.\n\n" + "@return the max number of allowable dynamic vertices in a single vertex buffer" ) +{ + return MAX_DYNAMIC_VERTS / 2; +} diff --git a/Engine/source/core/color.h b/Engine/source/core/color.h index 40fc79f49..1fa5d7676 100644 --- a/Engine/source/core/color.h +++ b/Engine/source/core/color.h @@ -127,12 +127,12 @@ class ColorI struct Hsb { - Hsb() :hue(0), sat(0), brightness(0){}; - Hsb(U32 h, U32 s, U32 b) :hue(h), sat(s), brightness(b){}; + Hsb() :hue(0), sat(0), brightness(0){}; + Hsb(U32 h, U32 s, U32 b) :hue(h), sat(s), brightness(b){}; - U32 hue; ///Hue - U32 sat; ///Saturation - U32 brightness; //Brightness/Value/Lightness + U32 hue; ///Hue + U32 sat; ///Saturation + U32 brightness; //Brightness/Value/Lightness }; public: diff --git a/Engine/source/core/stream/stream.cpp b/Engine/source/core/stream/stream.cpp index da1b1dc82..8a7fb2b40 100644 --- a/Engine/source/core/stream/stream.cpp +++ b/Engine/source/core/stream/stream.cpp @@ -128,7 +128,7 @@ bool Stream::writeFormattedBuffer(const char *format, ...) char buffer[4096]; va_list args; va_start(args, format); - const S32 length = vsprintf(buffer, format, args); + const S32 length = dVsprintf(buffer, sizeof(buffer), format, args); // Sanity! AssertFatal(length <= sizeof(buffer), "writeFormattedBuffer - String format exceeded buffer size. This will cause corruption."); diff --git a/Engine/source/gfx/bitmap/gBitmap.cpp b/Engine/source/gfx/bitmap/gBitmap.cpp index 151a792ed..78454d5e3 100644 --- a/Engine/source/gfx/bitmap/gBitmap.cpp +++ b/Engine/source/gfx/bitmap/gBitmap.cpp @@ -326,7 +326,7 @@ void GBitmap::allocateBitmap(const U32 in_width, const U32 in_height, const bool mNumMipLevels++; allocPixels += currWidth * currHeight * mBytesPerPixel; - } while (currWidth != 1 || currHeight != 1); + } while (currWidth != 1 && currHeight != 1); } AssertFatal(mNumMipLevels <= c_maxMipLevels, "GBitmap::allocateBitmap: too many miplevels"); diff --git a/Engine/source/gfx/gfxDevice.cpp b/Engine/source/gfx/gfxDevice.cpp index c72c109d0..3f63fb884 100644 --- a/Engine/source/gfx/gfxDevice.cpp +++ b/Engine/source/gfx/gfxDevice.cpp @@ -148,7 +148,7 @@ GFXDevice::GFXDevice() mGlobalAmbientColor = ColorF(0.0f, 0.0f, 0.0f, 1.0f); mLightMaterialDirty = false; - dMemset(&mCurrentLightMaterial, NULL, sizeof(GFXLightMaterial)); + dMemset(&mCurrentLightMaterial, 0, sizeof(GFXLightMaterial)); // State block mStateBlockDirty = false; diff --git a/Engine/source/gfx/gfxTextureManager.cpp b/Engine/source/gfx/gfxTextureManager.cpp index e367ed883..b656fcffd 100644 --- a/Engine/source/gfx/gfxTextureManager.cpp +++ b/Engine/source/gfx/gfxTextureManager.cpp @@ -1099,7 +1099,7 @@ void GFXTextureManager::_validateTexParams( const U32 width, const U32 height, currHeight = 1; inOutNumMips++; - } while ( currWidth != 1 || currHeight != 1 ); + } while ( currWidth != 1 && currHeight != 1 ); } } } diff --git a/Engine/source/gfx/gl/gfxGLCircularVolatileBuffer.h b/Engine/source/gfx/gl/gfxGLCircularVolatileBuffer.h index c291cb229..6d7d0e4b1 100644 --- a/Engine/source/gfx/gl/gfxGLCircularVolatileBuffer.h +++ b/Engine/source/gfx/gl/gfxGLCircularVolatileBuffer.h @@ -143,6 +143,11 @@ public: init(); } + ~GLCircularVolatileBuffer() + { + glDeleteBuffers(1, &mBufferName); + } + void init() { glGenBuffers(1, &mBufferName); @@ -290,4 +295,4 @@ protected: }; -#endif \ No newline at end of file +#endif diff --git a/Engine/source/gfx/gl/gfxGLTextureTarget.cpp b/Engine/source/gfx/gl/gfxGLTextureTarget.cpp index 1569b9a85..ddb308adc 100644 --- a/Engine/source/gfx/gl/gfxGLTextureTarget.cpp +++ b/Engine/source/gfx/gl/gfxGLTextureTarget.cpp @@ -260,7 +260,10 @@ GFXGLTextureTarget::GFXGLTextureTarget() : mCopyFboSrc(0), mCopyFboDst(0) GFXGLTextureTarget::~GFXGLTextureTarget() { - GFXTextureManager::removeEventDelegate( this, &GFXGLTextureTarget::_onTextureEvent ); + GFXTextureManager::removeEventDelegate(this, &GFXGLTextureTarget::_onTextureEvent); + + glDeleteFramebuffers(1, &mCopyFboSrc); + glDeleteFramebuffers(1, &mCopyFboDst); } const Point2I GFXGLTextureTarget::getSize() diff --git a/Engine/source/gfx/gl/gfxGLWindowTarget.cpp b/Engine/source/gfx/gl/gfxGLWindowTarget.cpp index c02ff1bc3..c00506835 100644 --- a/Engine/source/gfx/gl/gfxGLWindowTarget.cpp +++ b/Engine/source/gfx/gl/gfxGLWindowTarget.cpp @@ -42,6 +42,14 @@ GFXGLWindowTarget::GFXGLWindowTarget(PlatformWindow *win, GFXDevice *d) win->appEvent.notify(this, &GFXGLWindowTarget::_onAppSignal); } +GFXGLWindowTarget::~GFXGLWindowTarget() +{ + if(glIsFramebuffer(mCopyFBO)) + { + glDeleteFramebuffers(1, &mCopyFBO); + } +} + void GFXGLWindowTarget::resetMode() { if(mWindow->getVideoMode().fullScreen != mWindow->isFullscreen()) diff --git a/Engine/source/gfx/gl/gfxGLWindowTarget.h b/Engine/source/gfx/gl/gfxGLWindowTarget.h index 4baa6a53f..af368e192 100644 --- a/Engine/source/gfx/gl/gfxGLWindowTarget.h +++ b/Engine/source/gfx/gl/gfxGLWindowTarget.h @@ -30,6 +30,8 @@ class GFXGLWindowTarget : public GFXWindowTarget public: GFXGLWindowTarget(PlatformWindow *win, GFXDevice *d); + ~GFXGLWindowTarget(); + const Point2I getSize() { return mWindow->getClientExtent(); @@ -64,4 +66,4 @@ private: void _WindowPresent(); }; -#endif \ No newline at end of file +#endif diff --git a/Engine/source/gfx/gl/sdl/gfxGLDevice.sdl.cpp b/Engine/source/gfx/gl/sdl/gfxGLDevice.sdl.cpp index 10e18deb4..74e1773fc 100644 --- a/Engine/source/gfx/gl/sdl/gfxGLDevice.sdl.cpp +++ b/Engine/source/gfx/gl/sdl/gfxGLDevice.sdl.cpp @@ -83,6 +83,10 @@ void GFXGLDevice::enumerateAdapters( Vector &adapterList ) ); SDL_ClearError(); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); + SDL_GLContext tempContext = SDL_GL_CreateContext( tempWindow ); if( !tempContext ) { diff --git a/Engine/source/gfx/gl/tGL/tGL.cpp b/Engine/source/gfx/gl/tGL/tGL.cpp index 94953b487..8d62a7fd1 100644 --- a/Engine/source/gfx/gl/tGL/tGL.cpp +++ b/Engine/source/gfx/gl/tGL/tGL.cpp @@ -29,6 +29,7 @@ namespace GL { void gglPerformBinds() { + glewExperimental = GL_TRUE; GLenum err = glewInit(); AssertFatal(GLEW_OK == err, avar("Error: %s\n", glewGetErrorString(err)) ); } diff --git a/Engine/source/gfx/gl/tGL/tGL.h b/Engine/source/gfx/gl/tGL/tGL.h index aa1275ee5..bb21422b7 100644 --- a/Engine/source/gfx/gl/tGL/tGL.h +++ b/Engine/source/gfx/gl/tGL/tGL.h @@ -24,7 +24,13 @@ #define T_GL_H #include "GL/glew.h" +#if defined (TORQUE_OS_WIN) +// This doesn't work on Mesa drivers. #define gglHasExtension(EXTENSION) GLEW_##EXTENSION +#else +// Slower but reliably detects extensions on Mesa. +#define gglHasExtension(EXTENSION) glewGetExtension("GL_" # EXTENSION) +#endif #endif diff --git a/Engine/source/gfx/sim/debugDraw.cpp b/Engine/source/gfx/sim/debugDraw.cpp index 68b8c835d..b31a6925e 100644 --- a/Engine/source/gfx/sim/debugDraw.cpp +++ b/Engine/source/gfx/sim/debugDraw.cpp @@ -132,6 +132,11 @@ void DebugDrawer::setupStateBlocks() d.setZReadWrite(false); mRenderZOffSB = GFX->createStateBlock(d); + + d.setCullMode(GFXCullCCW); + d.setZReadWrite(true, false); + d.setBlend(true); + mRenderAlpha = GFX->createStateBlock(d); } void DebugDrawer::render() @@ -158,10 +163,13 @@ void DebugDrawer::render() // Set up the state block... GFXStateBlockRef currSB; - if(p->useZ) + if(p->type==DebugPrim::Capsule){ + currSB = mRenderAlpha; + }else if(p->useZ){ currSB = mRenderZOnSB; - else + }else{ currSB = mRenderZOffSB; + } GFX->setStateBlock( currSB ); Point3F d; @@ -180,6 +188,47 @@ void DebugDrawer::render() PrimBuild::end(); break; + case DebugPrim::DirectionLine: + { + const static F32 ARROW_LENGTH = 0.2f, ARROW_RADIUS = 0.035f, CYLINDER_RADIUS = 0.008f; + Point3F &start = p->a, &end = p->b; + Point3F direction = end - start; + F32 length = direction.len(); + if( length>ARROW_LENGTH ){ + //cylinder with arrow on end + direction *= (1.0f/length); + Point3F baseArrow = end - (direction*ARROW_LENGTH); + GFX->getDrawUtil()->drawCone(currSB->getDesc(), baseArrow, end, ARROW_RADIUS, p->color); + GFX->getDrawUtil()->drawCylinder(currSB->getDesc(), start, baseArrow, CYLINDER_RADIUS, p->color); + }else if( length>0 ){ + //short, so just draw arrow + GFX->getDrawUtil()->drawCone(currSB->getDesc(), start, end, ARROW_RADIUS, p->color); + } + } + break; + case DebugPrim::Capsule: + GFX->getDrawUtil()->drawCapsule(currSB->getDesc(), p->a, p->b.x, p->b.y, p->color); + break; + case DebugPrim::OutlinedText: + { + GFXTransformSaver saver; + Point3F result; + if (MathUtils::mProjectWorldToScreen(p->a, &result, GFX->getViewport(), GFX->getWorldMatrix(), GFX->getProjectionMatrix())) + { + GFX->setClipRect(GFX->getViewport()); + Point2I where = Point2I(result.x, result.y); + + GFX->getDrawUtil()->setBitmapModulation(p->color2); + GFX->getDrawUtil()->drawText(mFont, Point2I(where.x-1, where.y), p->mText); + GFX->getDrawUtil()->drawText(mFont, Point2I(where.x+1, where.y), p->mText); + GFX->getDrawUtil()->drawText(mFont, Point2I(where.x, where.y-1), p->mText); + GFX->getDrawUtil()->drawText(mFont, Point2I(where.x, where.y+1), p->mText); + + GFX->getDrawUtil()->setBitmapModulation(p->color); + GFX->getDrawUtil()->drawText(mFont, where, p->mText); + } + } + break; case DebugPrim::Box: d = p->a - p->b; GFX->getDrawUtil()->drawCube(currSB->getDesc(), d * 0.5, (p->a + p->b) * 0.5, p->color); @@ -262,6 +311,63 @@ void DebugDrawer::drawLine(const Point3F &a, const Point3F &b, const ColorF &col mHead = n; } +void DebugDrawer::drawCapsule(const Point3F &a, const F32 &radius, const F32 &height, const ColorF &color) +{ + if(isFrozen || !isDrawing) + return; + + DebugPrim *n = mPrimChunker.alloc(); + + n->useZ = true; + n->dieTime = 0; + n->a = a; + n->b.x = radius; + n->b.y = height; + n->color = color; + n->type = DebugPrim::Capsule; + + n->next = mHead; + mHead = n; + +} + +void DebugDrawer::drawDirectionLine(const Point3F &a, const Point3F &b, const ColorF &color) +{ + if(isFrozen || !isDrawing) + return; + + DebugPrim *n = mPrimChunker.alloc(); + + n->useZ = true; + n->dieTime = 0; + n->a = a; + n->b = b; + n->color = color; + n->type = DebugPrim::DirectionLine; + + n->next = mHead; + mHead = n; +} + +void DebugDrawer::drawOutlinedText(const Point3F& pos, const String& text, const ColorF &color, const ColorF &colorOutline) +{ + if(isFrozen || !isDrawing) + return; + + DebugPrim *n = mPrimChunker.alloc(); + + n->useZ = false; + n->dieTime = 0; + n->a = pos; + n->color = color; + n->color2 = colorOutline; + dStrncpy(n->mText, text.c_str(), 256); + n->type = DebugPrim::OutlinedText; + + n->next = mHead; + mHead = n; +} + void DebugDrawer::drawTri(const Point3F &a, const Point3F &b, const Point3F &c, const ColorF &color) { if(isFrozen || !isDrawing) diff --git a/Engine/source/gfx/sim/debugDraw.h b/Engine/source/gfx/sim/debugDraw.h index b1ab55970..a07f52ca4 100644 --- a/Engine/source/gfx/sim/debugDraw.h +++ b/Engine/source/gfx/sim/debugDraw.h @@ -124,7 +124,10 @@ public: void drawLine(const Point3F &a, const Point3F &b, const ColorF &color = ColorF(1.0f,1.0f,1.0f)); void drawTri(const Point3F &a, const Point3F &b, const Point3F &c, const ColorF &color = ColorF(1.0f,1.0f,1.0f)); void drawText(const Point3F& pos, const String& text, const ColorF &color = ColorF(1.0f,1.0f,1.0f)); - + void drawCapsule(const Point3F &a, const F32 &radius, const F32 &height, const ColorF &color = ColorF(1.0f, 1.0f, 1.0f)); + void drawDirectionLine(const Point3F &a, const Point3F &b, const ColorF &color = ColorF(1.0f, 1.0f, 1.0f)); + void drawOutlinedText(const Point3F& pos, const String& text, const ColorF &color = ColorF(1.0f, 1.0f, 1.0f), const ColorF &colorOutline = ColorF(0.0f, 0.0f, 0.0f)); + /// Render a wireframe view of the given polyhedron. void drawPolyhedron( const AnyPolyhedron& polyhedron, const ColorF& color = ColorF( 1.f, 1.f, 1.f ) ); @@ -161,6 +164,7 @@ private: { /// Color used for this primitive. ColorF color; + ColorF color2; /// Points used to store positional data. Exact semantics determined by type. Point3F a, b, c; @@ -168,7 +172,10 @@ private: Tri, Box, Line, - Text + Text, + DirectionLine, + OutlinedText, + Capsule, } type; ///< Type of the primitive. The meanings of a,b,c are determined by this. SimTime dieTime; ///< Time at which we should remove this from the list. @@ -188,6 +195,7 @@ private: GFXStateBlockRef mRenderZOffSB; GFXStateBlockRef mRenderZOnSB; + GFXStateBlockRef mRenderAlpha; Resource mFont; diff --git a/Engine/source/gui/controls/guiColorPicker.cpp b/Engine/source/gui/controls/guiColorPicker.cpp index 39c140434..97a8470d8 100644 --- a/Engine/source/gui/controls/guiColorPicker.cpp +++ b/Engine/source/gui/controls/guiColorPicker.cpp @@ -39,13 +39,13 @@ ColorF colorAlpha(0.0f, 0.0f, 0.0f, 0.0f); ColorF colorAlphaW(1.0f, 1.0f, 1.0f, 0.0f); ColorI GuiColorPickerCtrl::mColorRange[7] = { - ColorI(255,0,0), // Red - ColorI(255,0,255), // Pink - ColorI(0,0,255), // Blue - ColorI(0,255,255), // Light blue - ColorI(0,255,0), // Green - ColorI(255,255,0), // Yellow - ColorI(255,0,0), // Red + ColorI(255,0,0), // Red + ColorI(255,0,255), // Pink + ColorI(0,0,255), // Blue + ColorI(0,255,255), // Light blue + ColorI(0,255,0), // Green + ColorI(255,255,0), // Yellow + ColorI(255,0,0), // Red }; /// @} @@ -57,7 +57,6 @@ ConsoleDocClass( GuiColorPickerCtrl, "@internal" ); -//-------------------------------------------------------------------------- GuiColorPickerCtrl::GuiColorPickerCtrl() { setExtent(140, 30); @@ -70,56 +69,50 @@ GuiColorPickerCtrl::GuiColorPickerCtrl() mPositionChanged = false; mSelectorGap = 1; mActionOnMove = false; - mShowReticle = true; - mSelectColor = false; - mSetColor = mSetColor.BLACK; - mBitmap = NULL; + mShowReticle = true; + mSelectColor = false; + mSetColor = mSetColor.BLACK; + mBitmap = NULL; } GuiColorPickerCtrl::~GuiColorPickerCtrl() { - if (mBitmap) - { - delete mBitmap; - mBitmap = NULL; - } + if (mBitmap) + { + delete mBitmap; + mBitmap = NULL; + } } -//-------------------------------------------------------------------------- - ImplementEnumType( GuiColorPickMode, "\n\n" "@ingroup GuiUtil" "@internal" ) - { GuiColorPickerCtrl::pPallet, "Pallete" }, - { GuiColorPickerCtrl::pHorizColorRange, "HorizColor"}, - { GuiColorPickerCtrl::pVertColorRange, "VertColor" }, - { GuiColorPickerCtrl::pHorizColorBrightnessRange, "HorizBrightnessColor"}, - { GuiColorPickerCtrl::pVertColorBrightnessRange, "VertBrightnessColor" }, - { GuiColorPickerCtrl::pBlendColorRange, "BlendColor"}, - { GuiColorPickerCtrl::pHorizAlphaRange, "HorizAlpha"}, - { GuiColorPickerCtrl::pVertAlphaRange, "VertAlpha" }, - { GuiColorPickerCtrl::pDropperBackground, "Dropper" }, + { GuiColorPickerCtrl::pPallet, "Pallete" }, + { GuiColorPickerCtrl::pHorizColorRange, "HorizColor"}, + { GuiColorPickerCtrl::pVertColorRange, "VertColor" }, + { GuiColorPickerCtrl::pHorizColorBrightnessRange, "HorizBrightnessColor" }, + { GuiColorPickerCtrl::pVertColorBrightnessRange, "VertBrightnessColor" }, + { GuiColorPickerCtrl::pBlendColorRange, "BlendColor" }, + { GuiColorPickerCtrl::pHorizAlphaRange, "HorizAlpha" }, + { GuiColorPickerCtrl::pVertAlphaRange, "VertAlpha" }, + { GuiColorPickerCtrl::pDropperBackground, "Dropper" }, EndImplementEnumType; -//-------------------------------------------------------------------------- void GuiColorPickerCtrl::initPersistFields() { addGroup("ColorPicker"); - addField("baseColor", TypeColorF, Offset(mBaseColor, GuiColorPickerCtrl)); addField("pickColor", TypeColorF, Offset(mPickColor, GuiColorPickerCtrl)); addField("selectorGap", TypeS32, Offset(mSelectorGap, GuiColorPickerCtrl)); addField("displayMode", TYPEID< PickMode >(), Offset(mDisplayMode, GuiColorPickerCtrl) ); addField("actionOnMove", TypeBool,Offset(mActionOnMove, GuiColorPickerCtrl)); addField("showReticle", TypeBool, Offset(mShowReticle, GuiColorPickerCtrl)); - endGroup("ColorPicker"); Parent::initPersistFields(); } -//-------------------------------------------------------------------------- // Function to draw a box which can have 4 different colors in each corner blended together void GuiColorPickerCtrl::drawBlendBox(RectI &bounds, ColorF &c1, ColorF &c2, ColorF &c3, ColorF &c4) { @@ -131,54 +124,54 @@ void GuiColorPickerCtrl::drawBlendBox(RectI &bounds, ColorF &c1, ColorF &c2, Col //A couple of checks to determine if color blend if(c1 == colorWhite && c3 == colorAlpha && c4 == colorBlack) { - //Color - PrimBuild::begin( GFXTriangleFan, 4 ); - PrimBuild::color( c2 ); - PrimBuild::vertex2i( r, t ); + //Color + PrimBuild::begin(GFXTriangleFan, 4); + PrimBuild::color( c2 ); + PrimBuild::vertex2i( r, t ); - PrimBuild::color( c2 ); - PrimBuild::vertex2i( r, b ); + PrimBuild::color( c2 ); + PrimBuild::vertex2i( r, b ); - PrimBuild::color( c2 ); - PrimBuild::vertex2i( l, b ); + PrimBuild::color( c2 ); + PrimBuild::vertex2i( l, b ); - PrimBuild::color( c2 ); - PrimBuild::vertex2i( l, t ); - PrimBuild::end(); + PrimBuild::color( c2 ); + PrimBuild::vertex2i( l, t ); + PrimBuild::end(); - //White - PrimBuild::begin( GFXTriangleFan, 4 ); - PrimBuild::color( colorAlphaW ); - PrimBuild::vertex2i( r, t ); + //White + PrimBuild::begin( GFXTriangleFan, 4 ); + PrimBuild::color( colorAlphaW ); + PrimBuild::vertex2i( r, t ); - PrimBuild::color( colorAlphaW ); - PrimBuild::vertex2i( r, b ); + PrimBuild::color( colorAlphaW ); + PrimBuild::vertex2i( r, b ); - PrimBuild::color( c1 ); - PrimBuild::vertex2i( l, b ); + PrimBuild::color( c1 ); + PrimBuild::vertex2i( l, b ); - PrimBuild::color( c1 ); - PrimBuild::vertex2i( l, t ); - PrimBuild::end(); + PrimBuild::color( c1 ); + PrimBuild::vertex2i( l, t ); + PrimBuild::end(); - //Black - PrimBuild::begin( GFXTriangleFan, 4 ); - PrimBuild::color( c3 ); - PrimBuild::vertex2i( r, t ); + //Black + PrimBuild::begin( GFXTriangleFan, 4 ); + PrimBuild::color( c3 ); + PrimBuild::vertex2i( r, t ); - PrimBuild::color( c4 ); - PrimBuild::vertex2i( r, b ); + PrimBuild::color( c4 ); + PrimBuild::vertex2i( r, b ); - PrimBuild::color( c4 ); - PrimBuild::vertex2i( l, b ); + PrimBuild::color( c4 ); + PrimBuild::vertex2i( l, b ); - PrimBuild::color( c3 ); - PrimBuild::vertex2i( l, t ); - PrimBuild::end(); + PrimBuild::color( c3 ); + PrimBuild::vertex2i( l, t ); + PrimBuild::end(); } else { - PrimBuild::begin( GFXTriangleFan, 4 ); + PrimBuild::begin( GFXTriangleFan, 4 ); PrimBuild::color( c1 ); PrimBuild::vertex2i( l, t ); @@ -245,31 +238,29 @@ void GuiColorPickerCtrl::drawBlendRangeBox(RectI &bounds, bool vertical, U8 numC void GuiColorPickerCtrl::drawSelector(RectI &bounds, Point2I &selectorPos, SelectorMode mode) { - if( !mShowReticle ) - return; + if( !mShowReticle ) + return; - U16 sMax = mSelectorGap*2; - switch (mode) - { - case sVertical: - // Now draw the vertical selector - // Up -> Pos - if (selectorPos.y != bounds.point.y+1) - GFX->getDrawUtil()->drawLine(selectorPos.x, bounds.point.y, selectorPos.x, selectorPos.y-sMax-1, colorWhiteBlend); - // Down -> Pos - if (selectorPos.y != bounds.point.y+bounds.extent.y) - GFX->getDrawUtil()->drawLine(selectorPos.x, selectorPos.y + sMax, selectorPos.x, bounds.point.y + bounds.extent.y, colorWhiteBlend); - break; - case sHorizontal: - // Now draw the horizontal selector - // Left -> Pos - if (selectorPos.x != bounds.point.x) + U16 sMax = mSelectorGap*2; + switch (mode) + { + case sVertical: + // Now draw the vertical selector Up -> Pos + if (selectorPos.y != bounds.point.y+1) + GFX->getDrawUtil()->drawLine(selectorPos.x, bounds.point.y, selectorPos.x, selectorPos.y-sMax-1, colorWhiteBlend); + // Down -> Pos + if (selectorPos.y != bounds.point.y+bounds.extent.y) + GFX->getDrawUtil()->drawLine(selectorPos.x, selectorPos.y + sMax, selectorPos.x, bounds.point.y + bounds.extent.y, colorWhiteBlend); + break; + case sHorizontal: + // Now draw the horizontal selector Left -> Pos + if (selectorPos.x != bounds.point.x) GFX->getDrawUtil()->drawLine(bounds.point.x, selectorPos.y-1, selectorPos.x-sMax, selectorPos.y-1, colorWhiteBlend); - // Right -> Pos - if (selectorPos.x != bounds.point.x) + // Right -> Pos + if (selectorPos.x != bounds.point.x) GFX->getDrawUtil()->drawLine(bounds.point.x+mSelectorPos.x+sMax, selectorPos.y-1, bounds.point.x + bounds.extent.x, selectorPos.y-1, colorWhiteBlend); - break; - } + break; + } } //-------------------------------------------------------------------------- @@ -281,10 +272,10 @@ void GuiColorPickerCtrl::renderColorBox(RectI &bounds) pickerBounds.point.y = bounds.point.y+1; pickerBounds.extent.x = bounds.extent.x-1; pickerBounds.extent.y = bounds.extent.y-1; - + if (mProfile->mBorder) GFX->getDrawUtil()->drawRect(bounds, mProfile->mBorderColor); - + Point2I selectorPos = Point2I(bounds.point.x+mSelectorPos.x+1, bounds.point.y+mSelectorPos.y+1); // Draw color box differently depending on mode @@ -343,183 +334,176 @@ void GuiColorPickerCtrl::renderColorBox(RectI &bounds) void GuiColorPickerCtrl::onRender(Point2I offset, const RectI& updateRect) { - if (mStateBlock.isNull()) - { - GFXStateBlockDesc desc; - desc.setBlend(true, GFXBlendSrcAlpha, GFXBlendInvSrcAlpha); - desc.setZReadWrite(false); - desc.zWriteEnable = false; - desc.setCullMode(GFXCullNone); - mStateBlock = GFX->createStateBlock(desc); - } + if (mStateBlock.isNull()) + { + GFXStateBlockDesc desc; + desc.setBlend(true, GFXBlendSrcAlpha, GFXBlendInvSrcAlpha); + desc.setZReadWrite(false); + desc.zWriteEnable = false; + desc.setCullMode(GFXCullNone); + mStateBlock = GFX->createStateBlock(desc); + } - RectI boundsRect(offset, getExtent()); - renderColorBox(boundsRect); + RectI boundsRect(offset, getExtent()); + renderColorBox(boundsRect); - if (mPositionChanged || mBitmap == NULL) - { - bool nullBitmap = false; + if (mPositionChanged || mBitmap == NULL) + { + bool nullBitmap = false; - if (mPositionChanged == false && mBitmap == NULL) - nullBitmap = true; + if (mPositionChanged == false && mBitmap == NULL) + nullBitmap = true; - mPositionChanged = false; - Point2I extent = getRoot()->getExtent(); - // If we are anything but a pallete, change the pick color - if (mDisplayMode != pPallet) - { - Point2I resolution = getRoot()->getExtent(); + mPositionChanged = false; + Point2I extent = getRoot()->getExtent(); - U32 buf_x = offset.x + mSelectorPos.x + 1; - U32 buf_y = resolution.y - (extent.y - (offset.y + mSelectorPos.y + 1)); + // If we are anything but a pallete, change the pick color + if (mDisplayMode != pPallet) + { + Point2I resolution = getRoot()->getExtent(); - GFXTexHandle bb(resolution.x, - resolution.y, - GFXFormatR8G8B8A8, &GFXDefaultRenderTargetProfile, avar("%s() - bb (line %d)", __FUNCTION__, __LINE__)); + U32 buf_x = offset.x + mSelectorPos.x + 1; + U32 buf_y = resolution.y - (extent.y - (offset.y + mSelectorPos.y + 1)); - Point2I tmpPt(buf_x, buf_y); + GFXTexHandle bb( resolution.x, resolution.y, GFXFormatR8G8B8A8, &GFXDefaultRenderTargetProfile, avar("%s() - bb (line %d)", __FUNCTION__, __LINE__) ); - GFXTarget *targ = GFX->getActiveRenderTarget(); - targ->resolveTo(bb); + Point2I tmpPt(buf_x, buf_y); - if (mBitmap) - { - delete mBitmap; - mBitmap = NULL; - } + GFXTarget *targ = GFX->getActiveRenderTarget(); + targ->resolveTo(bb); - mBitmap = new GBitmap(bb.getWidth(), bb.getHeight()); + if (mBitmap) + { + delete mBitmap; + mBitmap = NULL; + } - bb.copyToBmp(mBitmap); + mBitmap = new GBitmap(bb.getWidth(), bb.getHeight()); - //bmp.writePNGDebug( "foo.png" ); + bb.copyToBmp(mBitmap); - if (!nullBitmap) - { - if (mSelectColor) - { - Point2I pos = findColor(mSetColor, offset, resolution, *mBitmap); - mSetColor = mSetColor.BLACK; - mSelectColor = false; + if (!nullBitmap) + { + if (mSelectColor) + { + Point2I pos = findColor(mSetColor, offset, resolution, *mBitmap); + mSetColor = mSetColor.BLACK; + mSelectColor = false; + setSelectorPos(pos); + } + else + { + ColorI tmp; + mBitmap->getColor(buf_x, buf_y, tmp); - setSelectorPos(pos); - } - else - { - ColorI tmp; - mBitmap->getColor(buf_x, buf_y, tmp); + mPickColor = (ColorF)tmp; - mPickColor = (ColorF)tmp; + // Now do onAction() if we are allowed + if (mActionOnMove) + onAction(); + } + } + } + } - // Now do onAction() if we are allowed - if (mActionOnMove) - onAction(); - } - } - } - - } - - //render the children - renderChildControls(offset, updateRect); + //render the children + renderChildControls(offset, updateRect); } void GuiColorPickerCtrl::setSelectorPos(const ColorF & color) { - if (mBitmap && !mPositionChanged) - { - Point2I resolution = getRoot() ? getRoot()->getExtent() : Point2I(1024, 768); - RectI rect(getGlobalBounds()); - Point2I pos = findColor(color, rect.point, resolution, *mBitmap); - mSetColor = mSetColor.BLACK; - mSelectColor = false; + if (mBitmap && !mPositionChanged) + { + Point2I resolution = getRoot() ? getRoot()->getExtent() : Point2I(1024, 768); + RectI rect(getGlobalBounds()); + Point2I pos = findColor(color, rect.point, resolution, *mBitmap); + mSetColor = mSetColor.BLACK; + mSelectColor = false; - setSelectorPos(pos); - } - else - { - mSetColor = color; - mSelectColor = true; - mPositionChanged = true; - } + setSelectorPos(pos); + } + else + { + mSetColor = color; + mSelectColor = true; + mPositionChanged = true; + } } Point2I GuiColorPickerCtrl::findColor(const ColorF & color, const Point2I& offset, const Point2I& resolution, GBitmap& bmp) { - RectI rect; - Point2I ext = getExtent(); - if (mDisplayMode != pDropperBackground) - { - ext.x -= 3; - ext.y -= 2; - rect = RectI(Point2I(1, 1), ext); - } - else - { - rect = RectI(Point2I(0, 0), ext); - } + RectI rect; + Point2I ext = getExtent(); + if (mDisplayMode != pDropperBackground) + { + ext.x -= 3; + ext.y -= 2; + rect = RectI(Point2I(1, 1), ext); + } + else + { + rect = RectI(Point2I(0, 0), ext); + } - Point2I closestPos(-1, -1); + Point2I closestPos(-1, -1); - /* Debugging - char filename[256]; - dSprintf( filename, 256, "%s.%s", "colorPickerTest", "png" ); + /* Debugging + char filename[256]; + dSprintf( filename, 256, "%s.%s", "colorPickerTest", "png" ); - // Open up the file on disk. - FileStream fs; - if ( !fs.open( filename, Torque::FS::File::Write ) ) - Con::errorf( "GuiObjectView::saveAsImage() - Failed to open output file '%s'!", filename ); - else - { - // Write it and close. - bmp.writeBitmap( "png", fs ); + // Open up the file on disk. + FileStream fs; + if ( !fs.open( filename, Torque::FS::File::Write ) ) + Con::errorf( "GuiObjectView::saveAsImage() - Failed to open output file '%s'!", filename ); + else + { + // Write it and close. + bmp.writeBitmap( "png", fs ); - fs.close(); - } - */ + fs.close(); + } + */ - ColorI tmp; - U32 buf_x; - U32 buf_y; - ColorF curColor; - F32 val(10000.0f); - F32 closestVal(10000.0f); - bool closestSet = false; + ColorI tmp; + U32 buf_x; + U32 buf_y; + ColorF curColor; + F32 val(10000.0f); + F32 closestVal(10000.0f); + bool closestSet = false; - for (S32 x = rect.point.x; x <= rect.extent.x; x++) - { - for (S32 y = rect.point.y; y <= rect.extent.y; y++) - { - buf_x = offset.x + x + 1; - buf_y = (resolution.y - (offset.y + y + 1)); - if (GFX->getAdapterType() != OpenGL) - buf_y = resolution.y - buf_y; + for (S32 x = rect.point.x; x <= rect.extent.x; x++) + { + for (S32 y = rect.point.y; y <= rect.extent.y; y++) + { + buf_x = offset.x + x + 1; + buf_y = (resolution.y - (offset.y + y + 1)); + buf_y = resolution.y - buf_y; - //Get the color at that position - bmp.getColor(buf_x, buf_y, tmp); - curColor = (ColorF)tmp; + //Get the color at that position + bmp.getColor(buf_x, buf_y, tmp); + curColor = (ColorF)tmp; - //Evaluate how close the color is to our desired color - val = mFabs(color.red - curColor.red) + mFabs(color.green - curColor.green) + mFabs(color.blue - curColor.blue); + //Evaluate how close the color is to our desired color + val = mFabs(color.red - curColor.red) + mFabs(color.green - curColor.green) + mFabs(color.blue - curColor.blue); - if (!closestSet) - { - closestVal = val; - closestPos.set(x, y); - closestSet = true; - } - else if (val < closestVal) - { - closestVal = val; - closestPos.set(x, y); - } - } - } + if (!closestSet) + { + closestVal = val; + closestPos.set(x, y); + closestSet = true; + } + else if (val < closestVal) + { + closestVal = val; + closestPos.set(x, y); + } + } + } - return closestPos; + return closestPos; } -//-------------------------------------------------------------------------- void GuiColorPickerCtrl::setSelectorPos(const Point2I &pos) { Point2I extent = getExtent(); @@ -564,7 +548,6 @@ void GuiColorPickerCtrl::setSelectorPos(const Point2I &pos) } } -//-------------------------------------------------------------------------- void GuiColorPickerCtrl::onMouseDown(const GuiEvent &event) { if (!mActive) @@ -577,14 +560,14 @@ void GuiColorPickerCtrl::onMouseDown(const GuiEvent &event) if (mProfile->mCanKeyFocus) setFirstResponder(); - - if (mActive && (mDisplayMode != pDropperBackground)) + + if (mActive && (mDisplayMode != pDropperBackground)) onAction(); // Update the picker cross position if (mDisplayMode != pPallet) - setSelectorPos(globalToLocalCoord(event.mousePoint)); - + setSelectorPos(globalToLocalCoord(event.mousePoint)); + mMouseDown = true; } @@ -600,10 +583,8 @@ void GuiColorPickerCtrl::onMouseDragged(const GuiEvent &event) if( !mActionOnMove ) execAltConsoleCallback(); - } -//-------------------------------------------------------------------------- void GuiColorPickerCtrl::onMouseMove(const GuiEvent &event) { // Only for dropper mode @@ -611,45 +592,40 @@ void GuiColorPickerCtrl::onMouseMove(const GuiEvent &event) setSelectorPos(globalToLocalCoord(event.mousePoint)); } -//-------------------------------------------------------------------------- void GuiColorPickerCtrl::onMouseEnter(const GuiEvent &event) { mMouseOver = true; } -//-------------------------------------------------------------------------- void GuiColorPickerCtrl::onMouseLeave(const GuiEvent &) { // Reset state mMouseOver = false; } -//-------------------------------------------------------------------------- void GuiColorPickerCtrl::onMouseUp(const GuiEvent &) { //if we released the mouse within this control, perform the action - if (mActive && mMouseDown && (mDisplayMode != pDropperBackground)) + if (mActive && mMouseDown && (mDisplayMode != pDropperBackground)) mMouseDown = false; - if (mActive && (mDisplayMode == pDropperBackground)) + if (mActive && (mDisplayMode == pDropperBackground)) { // In a dropper, the alt command executes the mouse up action (to signal stopping) execAltConsoleCallback(); } - + mouseUnlock(); } -//-------------------------------------------------------------------------- const char *GuiColorPickerCtrl::getScriptValue() { static char temp[256]; ColorF color = getValue(); - dSprintf(temp,256,"%f %f %f %f",color.red, color.green, color.blue, color.alpha); - return temp; + dSprintf( temp, 256, "%f %f %f %f", color.red, color.green, color.blue, color.alpha ); + return temp; } -//-------------------------------------------------------------------------- void GuiColorPickerCtrl::setScriptValue(const char *value) { ColorF newValue; @@ -669,12 +645,12 @@ DefineConsoleMethod(GuiColorPickerCtrl, setSelectorPos, void, (Point2I newPos), DefineConsoleMethod(GuiColorPickerCtrl, updateColor, void, (), , "Forces update of pick color") { - object->updateColor(); + object->updateColor(); } DefineEngineMethod(GuiColorPickerCtrl, setSelectorColor, void, (ColorF color), , - "Sets the current position of the selector based on a color.n" - "@param color Color to look for.n") + "Sets the current position of the selector based on a color.n" + "@param color Color to look for.n") { - object->setSelectorPos(color); -} \ No newline at end of file + object->setSelectorPos(color); +} diff --git a/Engine/source/gui/controls/guiColorPicker.h b/Engine/source/gui/controls/guiColorPicker.h index 202a2b5ca..42531c3bb 100644 --- a/Engine/source/gui/controls/guiColorPicker.h +++ b/Engine/source/gui/controls/guiColorPicker.h @@ -59,29 +59,28 @@ class GuiColorPickerCtrl : public GuiControl public: enum PickMode { - pPallet = 0, ///< We just have a solid color; We just act like a pallet - pHorizColorRange, ///< We have a range of base colors going horizontally - pVertColorRange, ///< We have a range of base colors going vertically + pPallet = 0, ///< We just have a solid color; We just act like a pallet + pHorizColorRange, ///< We have a range of base colors going horizontally + pVertColorRange, ///< We have a range of base colors going vertically pHorizColorBrightnessRange, ///< HorizColorRange with brightness - pVertColorBrightnessRange, ///< VertColorRange with brightness - pBlendColorRange, ///< We have a box which shows a range in brightness of the color - pHorizAlphaRange, ///< We have a box which shows a range in alpha going horizontally - pVertAlphaRange, ///< We have a box which shows a range in alpha going vertically - pDropperBackground ///< The control does not draw anything; Only does something when you click, or move the mouse (when active) + pVertColorBrightnessRange, ///< VertColorRange with brightness + pBlendColorRange, ///< We have a box which shows a range in brightness of the color + pHorizAlphaRange, ///< We have a box which shows a range in alpha going horizontally + pVertAlphaRange, ///< We have a box which shows a range in alpha going vertically + pDropperBackground ///< The control does not draw anything; Only does something when you click, or move the mouse (when active) }; enum SelectorMode { - sHorizontal = 0, ///< Horizontal selector with small gap - sVertical, ///< Vertical selector with small gap + sHorizontal = 0, ///< Horizontal selector with small gap + sVertical, ///< Vertical selector with small gap }; - + protected: - /// @name Core Rendering functions /// @{ - void renderColorBox(RectI &bounds); ///< Function that draws the actual color box - void drawSelector(RectI &bounds, Point2I &selectorPos, SelectorMode mode); ///< Function that draws the selection indicator + void renderColorBox(RectI &bounds); ///< Function that draws the actual color box + void drawSelector(RectI &bounds, Point2I &selectorPos, SelectorMode mode); /// < Function that draws the selection indicator void drawBlendBox(RectI &bounds, ColorF &c1, ColorF &c2, ColorF &c3, ColorF &c4); void drawBlendRangeBox(RectI &bounds, bool vertical, U8 numColors, ColorI *colors); /// @} @@ -111,8 +110,8 @@ class GuiColorPickerCtrl : public GuiControl static ColorI mColorRange[7]; ///< Color range for pHorizColorRange and pVertColorRange /// @} - public: - + public: + DECLARE_CONOBJECT(GuiColorPickerCtrl); DECLARE_CATEGORY( "Gui Editor" ); @@ -127,19 +126,19 @@ class GuiColorPickerCtrl : public GuiControl /// NOTE: setValue only sets baseColor, since setting pickColor wouldn't be useful void setValue(ColorF &value) {mBaseColor = value;} /// NOTE: getValue() returns baseColor if pallet (since pallet controls can't "pick" colours themselves) - ColorF getValue() {return mDisplayMode == pPallet ? mBaseColor : mPickColor;} + ColorF getValue() { return mDisplayMode == pPallet ? mBaseColor : mPickColor; } const char *getScriptValue(); void setScriptValue(const char *value); void updateColor() {mPositionChanged = true;} /// @} - + /// @name Selector Functions /// @{ void setSelectorPos(const Point2I &pos); ///< Set new pos (in local coords) void setSelectorPos(const ColorF & color); Point2I getSelectorPos() {return mSelectorPos;} /// @} - + /// @name Input Events /// @{ void onMouseDown(const GuiEvent &); diff --git a/Engine/source/gui/controls/guiTextEditCtrl.cpp b/Engine/source/gui/controls/guiTextEditCtrl.cpp index e3f3855f6..99a1342c0 100644 --- a/Engine/source/gui/controls/guiTextEditCtrl.cpp +++ b/Engine/source/gui/controls/guiTextEditCtrl.cpp @@ -1254,27 +1254,27 @@ void GuiTextEditCtrl::onLoseFirstResponder() Parent::onLoseFirstResponder(); } -void GuiTextEditCtrl::onRender(Point2I offset, const RectI &updateRect) +void GuiTextEditCtrl::onRender( Point2I offset, const RectI &updateRect ) { RectI ctrlRect( offset, getExtent() ); //if opaque, fill the update rect with the fill color if ( mProfile->mOpaque ) { - if (!mTextValid) - GFX->getDrawUtil()->drawRectFill(ctrlRect, mProfile->mFillColorNA); - else if (isFirstResponder()) - GFX->getDrawUtil()->drawRectFill(ctrlRect, mProfile->mFillColorHL); - else - GFX->getDrawUtil()->drawRectFill(ctrlRect, mProfile->mFillColor); + if ( !mTextValid ) + GFX->getDrawUtil()->drawRectFill( ctrlRect, mProfile->mFillColorERR ); + else if ( isFirstResponder() ) + GFX->getDrawUtil()->drawRectFill( ctrlRect, mProfile->mFillColorHL ); + else + GFX->getDrawUtil()->drawRectFill( ctrlRect, mProfile->mFillColor ); } //if there's a border, draw the border - if (mProfile->mBorder) + if ( mProfile->mBorder ) { - renderBorder(ctrlRect, mProfile); - if (!mTextValid) - GFX->getDrawUtil()->drawRectFill(ctrlRect, mProfile->mFillColorNA); + renderBorder( ctrlRect, mProfile ); + if ( !mTextValid ) + GFX->getDrawUtil()->drawRectFill( ctrlRect, mProfile->mFillColorERR ); } drawText( ctrlRect, isFirstResponder() ); @@ -1498,25 +1498,25 @@ void GuiTextEditCtrl::drawText( const RectI &drawRect, bool isFocused ) bool GuiTextEditCtrl::hasText() { - return (mTextBuffer.length()); + return ( mTextBuffer.length() ); } void GuiTextEditCtrl::invalidText(bool playSound) { - mTextValid = false; + mTextValid = false; - if (playSound) - playDeniedSound(); + if ( playSound ) + playDeniedSound(); } void GuiTextEditCtrl::validText() { - mTextValid = true; + mTextValid = true; } bool GuiTextEditCtrl::isValidText() { - return mTextValid; + return mTextValid; } void GuiTextEditCtrl::playDeniedSound() diff --git a/Engine/source/gui/core/guiControl.cpp b/Engine/source/gui/core/guiControl.cpp index c0c822a11..f3cacc27a 100644 --- a/Engine/source/gui/core/guiControl.cpp +++ b/Engine/source/gui/core/guiControl.cpp @@ -175,6 +175,9 @@ ImplementEnumType( GuiHorizontalSizing, { GuiControl::horizResizeLeft, "left" }, { GuiControl::horizResizeCenter, "center" }, { GuiControl::horizResizeRelative, "relative" }, + { GuiControl::horizResizeAspectLeft, "aspectLeft" }, + { GuiControl::horizResizeAspectRight, "aspectRight" }, + { GuiControl::horizResizeAspectCenter, "aspectCenter" }, { GuiControl::horizResizeWindowRelative, "windowRelative" } EndImplementEnumType; @@ -186,6 +189,9 @@ ImplementEnumType( GuiVerticalSizing, { GuiControl::vertResizeTop, "top" }, { GuiControl::vertResizeCenter, "center" }, { GuiControl::vertResizeRelative, "relative" }, + { GuiControl::vertResizeAspectTop, "aspectTop" }, + { GuiControl::vertResizeAspectBottom, "aspectBottom" }, + { GuiControl::vertResizeAspectCenter, "aspectCenter" }, { GuiControl::vertResizeWindowRelative, "windowRelative" } EndImplementEnumType; @@ -1370,6 +1376,36 @@ void GuiControl::parentResized(const RectI &oldParentRect, const RectI &newParen newPosition.x = newLeft; newExtent.x = newWidth; } + else if (mHorizSizing == horizResizeAspectLeft && oldParentRect.extent.x != 0) + { + S32 newLeft = mRoundToNearest((F32(newPosition.x) / F32(oldParentRect.extent.x)) * F32(newParentRect.extent.x)); + S32 newWidth = mRoundToNearest((F32(newExtent.x) / F32(oldParentRect.extent.y)) * F32(newParentRect.extent.y)); + + newPosition.x = newLeft; + newExtent.x = newWidth; + } + else if (mHorizSizing == horizResizeAspectRight && oldParentRect.extent.x != 0) + { + S32 newLeft = mRoundToNearest((F32(newPosition.x) / F32(oldParentRect.extent.x)) * F32(newParentRect.extent.x)); + S32 newWidth = mRoundToNearest((F32(newExtent.x) / F32(oldParentRect.extent.y)) * F32(newParentRect.extent.y)); //origional aspect ratio corrected width + S32 rWidth = mRoundToNearest((F32(newExtent.x) / F32(oldParentRect.extent.x)) * F32(newParentRect.extent.x)); //parent aspect ratio relative width + + S32 offset = rWidth - newWidth; // account for change in relative width + newLeft += offset; + newPosition.x = newLeft; + newExtent.x = newWidth; + } + else if (mHorizSizing == horizResizeAspectCenter && oldParentRect.extent.x != 0) + { + S32 newLeft = mRoundToNearest((F32(newPosition.x) / F32(oldParentRect.extent.x)) * F32(newParentRect.extent.x)); + S32 newWidth = mRoundToNearest((F32(newExtent.x) / F32(oldParentRect.extent.y)) * F32(newParentRect.extent.y)); //origional aspect ratio corrected width + S32 rWidth = mRoundToNearest((F32(newExtent.x) / F32(oldParentRect.extent.x)) * F32(newParentRect.extent.x)); //parent aspect ratio relative width + + S32 offset = rWidth - newWidth; // account for change in relative width + newLeft += offset/2; + newPosition.x = newLeft; + newExtent.x = newWidth; + } if (mVertSizing == vertResizeCenter) newPosition.y = (newParentRect.extent.y - getHeight()) >> 1; @@ -1385,6 +1421,36 @@ void GuiControl::parentResized(const RectI &oldParentRect, const RectI &newParen newPosition.y = newTop; newExtent.y = newHeight; } + else if (mVertSizing == vertResizeAspectTop && oldParentRect.extent.y != 0) + { + S32 newTop = mRoundToNearest((F32(newPosition.y) / F32(oldParentRect.extent.y)) * F32(newParentRect.extent.y)); + S32 newHeight = mRoundToNearest((F32(newExtent.y) / F32(oldParentRect.extent.x)) * F32(newParentRect.extent.x)); + + newPosition.y = newTop; + newExtent.y = newHeight; + } + else if (mVertSizing == vertResizeAspectBottom && oldParentRect.extent.y != 0) + { + S32 newTop = mRoundToNearest((F32(newPosition.y) / F32(oldParentRect.extent.y)) * F32(newParentRect.extent.y)); + S32 newHeight = mRoundToNearest((F32(newExtent.y) / F32(oldParentRect.extent.x)) * F32(newParentRect.extent.x)); //origional aspect ratio corrected hieght + S32 rHeight = mRoundToNearest((F32(newExtent.y) / F32(oldParentRect.extent.y)) * F32(newParentRect.extent.y)); //parent aspect ratio relative hieght + + S32 offset = rHeight - newHeight; // account for change in relative hieght + newTop += offset; + newPosition.y = newTop; + newExtent.y = newHeight; + } + else if (mVertSizing == vertResizeAspectCenter && oldParentRect.extent.y != 0) + { + S32 newTop = mRoundToNearest((F32(newPosition.y) / F32(oldParentRect.extent.y)) * F32(newParentRect.extent.y)); + S32 newHeight = mRoundToNearest((F32(newExtent.y) / F32(oldParentRect.extent.x)) * F32(newParentRect.extent.x)); //origional aspect ratio corrected hieght + S32 rHeight = mRoundToNearest((F32(newExtent.y) / F32(oldParentRect.extent.y)) * F32(newParentRect.extent.y)); //parent aspect ratio relative hieght + + S32 offset = rHeight - newHeight; // account for change in relative hieght + newTop += offset / 2; + newPosition.y = newTop; + newExtent.y = newHeight; + } // Resizing Re factor [9/18/2006] // Only resize if our minExtent is satisfied with it. diff --git a/Engine/source/gui/core/guiControl.h b/Engine/source/gui/core/guiControl.h index 4240fbad6..ca873878d 100644 --- a/Engine/source/gui/core/guiControl.h +++ b/Engine/source/gui/core/guiControl.h @@ -121,6 +121,9 @@ class GuiControl : public SimGroup horizResizeLeft, ///< fixed on the right and width horizResizeCenter, horizResizeRelative, ///< resize relative + horizResizeAspectLeft, ///< resize relative to height delta (offset Left) + horizResizeAspectRight, ///< resize relative to height delta (offset Right) + horizResizeAspectCenter, ///< resize relative to height delta (Centered) horizResizeWindowRelative ///< resize window relative }; enum vertSizingOptions @@ -130,6 +133,9 @@ class GuiControl : public SimGroup vertResizeTop, ///< fixed in height and on the bottom vertResizeCenter, vertResizeRelative, ///< resize relative + vertResizeAspectTop, ///< resize relative to width delta (offset Left) + vertResizeAspectBottom, ///< resize relative to width delta (offset Right) + vertResizeAspectCenter, ///< resize relative to width delta Centered) vertResizeWindowRelative ///< resize window relative }; diff --git a/Engine/source/gui/core/guiTypes.cpp b/Engine/source/gui/core/guiTypes.cpp index 4f96884bf..870ef1355 100644 --- a/Engine/source/gui/core/guiTypes.cpp +++ b/Engine/source/gui/core/guiTypes.cpp @@ -269,6 +269,7 @@ GuiControlProfile::GuiControlProfile(void) : mFillColor(255,0,255,255), mFillColorHL(255,0,255,255), mFillColorNA(255,0,255,255), + mFillColorERR(255,0,0,255), mFillColorSEL(255,0,255,255), mBorderColor(255,0,255,255), mBorderColorHL(255,0,255,255), @@ -334,6 +335,7 @@ GuiControlProfile::GuiControlProfile(void) : mFillColor = def->mFillColor; mFillColorHL = def->mFillColorHL; mFillColorNA = def->mFillColorNA; + mFillColorERR = def->mFillColorERR; mFillColorSEL = def->mFillColorSEL; mBorder = def->mBorder; @@ -398,6 +400,7 @@ void GuiControlProfile::initPersistFields() addField("fillColor", TypeColorI, Offset(mFillColor, GuiControlProfile)); addField("fillColorHL", TypeColorI, Offset(mFillColorHL, GuiControlProfile)); addField("fillColorNA", TypeColorI, Offset(mFillColorNA, GuiControlProfile)); + addField("fillColorERR", TypeColorI, Offset(mFillColorERR, GuiControlProfile)); addField("fillColorSEL", TypeColorI, Offset(mFillColorSEL, GuiControlProfile)); addField("border", TypeS32, Offset(mBorder, GuiControlProfile), "Border type (0=no border)." ); diff --git a/Engine/source/gui/core/guiTypes.h b/Engine/source/gui/core/guiTypes.h index c9dc36bad..51f33d21b 100644 --- a/Engine/source/gui/core/guiTypes.h +++ b/Engine/source/gui/core/guiTypes.h @@ -385,6 +385,7 @@ public: ColorI mFillColor; ///< Fill color, this is used to fill the bounds of the control if it is opaque ColorI mFillColorHL; ///< This is used instead of mFillColor if the object is highlighted ColorI mFillColorNA; ///< This is used instead of mFillColor if the object is not active or disabled + ColorI mFillColorERR; ///< This is used instead of mFillColor if the object has an error or is invalid ColorI mFillColorSEL; ///< This is used instead of mFillColor if the object is selected S32 mBorder; ///< For most controls, if mBorder is > 0 a border will be drawn, some controls use this to draw different types of borders however @see guiDefaultControlRender.cc diff --git a/Engine/source/lighting/advanced/advancedLightBinManager.cpp b/Engine/source/lighting/advanced/advancedLightBinManager.cpp index dd71afeb0..98330a5de 100644 --- a/Engine/source/lighting/advanced/advancedLightBinManager.cpp +++ b/Engine/source/lighting/advanced/advancedLightBinManager.cpp @@ -318,6 +318,8 @@ void AdvancedLightBinManager::render( SceneRenderState *state ) const U32 numPrims = curEntry.numPrims; const U32 numVerts = curEntry.vertBuffer->mNumVerts; + ShadowMapParams *lsp = curLightInfo->getExtended(); + // Skip lights which won't affect the scene. if ( !curLightMat || curLightInfo->getBrightness() <= 0.001f ) continue; @@ -329,15 +331,12 @@ void AdvancedLightBinManager::render( SceneRenderState *state ) mShadowManager->setLightShadowMap( curEntry.shadowMap ); mShadowManager->setLightDynamicShadowMap( curEntry.dynamicShadowMap ); - // Let the shadow know we're about to render from it. - if ( curEntry.shadowMap ) - curEntry.shadowMap->preLightRender(); - if ( curEntry.dynamicShadowMap ) curEntry.dynamicShadowMap->preLightRender(); - // Set geometry GFX->setVertexBuffer( curEntry.vertBuffer ); GFX->setPrimitiveBuffer( curEntry.primBuffer ); + lsp->getOcclusionQuery()->begin(); + // Render the material passes while( curLightMat->matInstance->setupPass( state, sgData ) ) { @@ -352,10 +351,7 @@ void AdvancedLightBinManager::render( SceneRenderState *state ) GFX->drawPrimitive(GFXTriangleList, 0, numPrims); } - // Tell it we're done rendering. - if ( curEntry.shadowMap ) - curEntry.shadowMap->postLightRender(); - if ( curEntry.dynamicShadowMap ) curEntry.dynamicShadowMap->postLightRender(); + lsp->getOcclusionQuery()->end(); } // Set NULL for active shadow map (so nothing gets confused) diff --git a/Engine/source/lighting/advanced/advancedLightManager.cpp b/Engine/source/lighting/advanced/advancedLightManager.cpp index d82f4f69c..baefa15b5 100644 --- a/Engine/source/lighting/advanced/advancedLightManager.cpp +++ b/Engine/source/lighting/advanced/advancedLightManager.cpp @@ -105,7 +105,7 @@ void AdvancedLightManager::activate( SceneManager *sceneManager ) // we prefer the floating point format if it works. Vector formats; formats.push_back( GFXFormatR16G16B16A16F ); - formats.push_back( GFXFormatR16G16B16A16 ); + //formats.push_back( GFXFormatR16G16B16A16 ); GFXFormat blendTargetFormat = GFX->selectSupportedFormat( &GFXDefaultRenderTargetProfile, formats, true, diff --git a/Engine/source/lighting/shadowMap/lightShadowMap.cpp b/Engine/source/lighting/shadowMap/lightShadowMap.cpp index 53a6f4e8d..984f6cbc6 100644 --- a/Engine/source/lighting/shadowMap/lightShadowMap.cpp +++ b/Engine/source/lighting/shadowMap/lightShadowMap.cpp @@ -89,8 +89,6 @@ LightShadowMap::LightShadowMap( LightInfo *light ) mLastUpdate( 0 ), mLastCull( 0 ), mIsViewDependent( false ), - mVizQuery( NULL ), - mWasOccluded( false ), mLastScreenSize( 0.0f ), mLastPriority( 0.0f ), mIsDynamic( false ) @@ -98,9 +96,7 @@ LightShadowMap::LightShadowMap( LightInfo *light ) GFXTextureManager::addEventDelegate( this, &LightShadowMap::_onTextureEvent ); mTarget = GFX->allocRenderToTextureTarget(); - mVizQuery = GFX->createOcclusionQuery(); - - smShadowMaps.push_back(this); + smShadowMaps.push_back( this ); mStaticRefreshTimer = PlatformTimer::create(); mDynamicRefreshTimer = PlatformTimer::create(); } @@ -108,8 +104,9 @@ LightShadowMap::LightShadowMap( LightInfo *light ) LightShadowMap::~LightShadowMap() { mTarget = NULL; - SAFE_DELETE( mVizQuery ); - + SAFE_DELETE(mStaticRefreshTimer); + SAFE_DELETE(mDynamicRefreshTimer); + releaseTextures(); smShadowMaps.remove( this ); @@ -334,23 +331,6 @@ void LightShadowMap::render( RenderPassManager* renderPass, mLastUpdate = Sim::getCurrentTime(); } -void LightShadowMap::preLightRender() -{ - PROFILE_SCOPE( LightShadowMap_prepLightRender ); - - if ( mVizQuery ) - { - mWasOccluded = mVizQuery->getStatus( true ) == GFXOcclusionQuery::Occluded; - mVizQuery->begin(); - } -} - -void LightShadowMap::postLightRender() -{ - if ( mVizQuery ) - mVizQuery->end(); -} - BaseMatInstance* LightShadowMap::getShadowMaterial( BaseMatInstance *inMat ) const { // See if we have an existing material hook. @@ -610,11 +590,14 @@ ShadowMapParams::ShadowMapParams( LightInfo *light ) shadowSoftness = 0.15f; fadeStartDist = 0.0f; lastSplitTerrainOnly = false; + mQuery = GFX->createOcclusionQuery(); + _validate(); } ShadowMapParams::~ShadowMapParams() { + SAFE_DELETE( mQuery ); SAFE_DELETE( mShadowMap ); SAFE_DELETE( mDynamicShadowMap ); } diff --git a/Engine/source/lighting/shadowMap/lightShadowMap.h b/Engine/source/lighting/shadowMap/lightShadowMap.h index 2cbb2ca5e..d96481192 100644 --- a/Engine/source/lighting/shadowMap/lightShadowMap.h +++ b/Engine/source/lighting/shadowMap/lightShadowMap.h @@ -47,6 +47,9 @@ #ifndef _GFXSHADER_H_ #include "gfx/gfxShader.h" #endif +#ifndef _GFXOCCLUSIONQUERY_H_ +#include "gfx/gfxOcclusionQuery.h" +#endif #ifndef _PLATFORM_PLATFORMTIMER_H_ #include "platform/platformTimer.h" #endif @@ -61,7 +64,6 @@ struct SceneData; class GFXShaderConstBuffer; class GFXShaderConstHandle; class GFXShader; -class GFXOcclusionQuery; class LightManager; class RenderPassManager; @@ -169,12 +171,6 @@ public: bool isViewDependent() const { return mIsViewDependent; } - bool wasOccluded() const { return mWasOccluded; } - - void preLightRender(); - - void postLightRender(); - void updatePriority( const SceneRenderState *state, U32 currTimeMs ); F32 getLastScreenSize() const { return mLastScreenSize; } @@ -257,15 +253,6 @@ protected: /// The time this shadow was last culled and prioritized. U32 mLastCull; - /// The shadow occlusion query used when the light is - /// rendered to determine if any pixel of it is visible. - GFXOcclusionQuery *mVizQuery; - - /// If true the light was occluded by geometry the - /// last frame it was updated. - //the last frame. - bool mWasOccluded; - F32 mLastScreenSize; F32 mLastPriority; @@ -325,6 +312,8 @@ public: bool hasCookieTex() const { return cookie.isNotEmpty(); } + GFXOcclusionQuery* getOcclusionQuery() const { return mQuery; } + GFXTextureObject* getCookieTex(); GFXCubemap* getCookieCubeTex(); @@ -339,6 +328,7 @@ protected: /// LightShadowMap *mShadowMap; LightShadowMap *mDynamicShadowMap; + GFXOcclusionQuery* mQuery; LightInfo *mLight; diff --git a/Engine/source/lighting/shadowMap/shadowMapPass.cpp b/Engine/source/lighting/shadowMap/shadowMapPass.cpp index 7c17046e1..dea7305b5 100644 --- a/Engine/source/lighting/shadowMap/shadowMapPass.cpp +++ b/Engine/source/lighting/shadowMap/shadowMapPass.cpp @@ -174,12 +174,12 @@ void ShadowMapPass::render( SceneManager *sceneManager, continue; // --- Static Shadow Map --- - LightShadowMap *lsm = params->getOrCreateShadowMap(); - LightShadowMap *dlsm = params->getOrCreateShadowMap(true); + LightShadowMap *lsm = params->getOrCreateShadowMap(); + LightShadowMap *dlsm = params->getOrCreateShadowMap(true); // First check the visiblity query... if it wasn't // visible skip it. - if (lsm->wasOccluded() || dlsm->wasOccluded()) + if(params->getOcclusionQuery()->getStatus(true) == GFXOcclusionQuery::Occluded) continue; // Any shadow that is visible is counted as being @@ -187,9 +187,9 @@ void ShadowMapPass::render( SceneManager *sceneManager, ++smActiveShadowMaps; // Do a priority update for this shadow. - lsm->updatePriority(diffuseState, currTime); + lsm->updatePriority(diffuseState, currTime); - shadowMaps.push_back(lsm); + shadowMaps.push_back(lsm); // --- Dynamic Shadow Map --- @@ -198,7 +198,7 @@ void ShadowMapPass::render( SceneManager *sceneManager, ++smActiveShadowMaps; // Do a priority update for this shadow. - dlsm->updatePriority(diffuseState, currTime); + dlsm->updatePriority(diffuseState, currTime); shadowMaps.push_back( dlsm ); } @@ -306,4 +306,4 @@ void DynamicShadowRenderPassManager::addInst( RenderInst *inst ) } Parent::addInst(inst); -} \ No newline at end of file +} diff --git a/Engine/source/materials/materialFeatureTypes.cpp b/Engine/source/materials/materialFeatureTypes.cpp index f7a63815b..9cdc57415 100644 --- a/Engine/source/materials/materialFeatureTypes.cpp +++ b/Engine/source/materials/materialFeatureTypes.cpp @@ -46,6 +46,7 @@ ImplementFeatureType( MFT_AlphaTest, MFG_Texture, 7.0f, true ); ImplementFeatureType( MFT_SpecularMap, MFG_Texture, 8.0f, true ); ImplementFeatureType( MFT_NormalMap, MFG_Texture, 9.0f, true ); ImplementFeatureType( MFT_DetailNormalMap, MFG_Texture, 10.0f, true ); +ImplementFeatureType( MFT_Imposter, U32(-1), -1, true ); ImplementFeatureType( MFT_AccuMap, MFG_PreLighting, 2.0f, true ); diff --git a/Engine/source/materials/materialFeatureTypes.h b/Engine/source/materials/materialFeatureTypes.h index 55b52506c..c302045c2 100644 --- a/Engine/source/materials/materialFeatureTypes.h +++ b/Engine/source/materials/materialFeatureTypes.h @@ -94,6 +94,7 @@ DeclareFeatureType( MFT_OverlayMap ); DeclareFeatureType( MFT_DetailMap ); DeclareFeatureType( MFT_DiffuseColor ); DeclareFeatureType( MFT_DetailNormalMap ); +DeclareFeatureType( MFT_Imposter ); DeclareFeatureType( MFT_AccuMap ); DeclareFeatureType( MFT_AccuScale ); diff --git a/Engine/source/math/mConsoleFunctions.cpp b/Engine/source/math/mConsoleFunctions.cpp index df380da1b..1d57743e6 100644 --- a/Engine/source/math/mConsoleFunctions.cpp +++ b/Engine/source/math/mConsoleFunctions.cpp @@ -104,16 +104,16 @@ DefineConsoleFunction( mRound, S32, ( F32 v ),, } DefineConsoleFunction( mRoundColour, F32, ( F32 v, S32 n ), (0), - "Round v to the nth decimal place or the nearest whole number by default." - "@param v Value to roundn" - "@param n Number of decimal places to round to, 0 by defaultn" - "@return The rounded value as a S32." - "@ingroup Math") + "Round v to the nth decimal place or the nearest whole number by default." + "@param v Value to roundn" + "@param n Number of decimal places to round to, 0 by defaultn" + "@return The rounded value as a S32." + "@ingroup Math") { - if (n <= 0) - return mRound(v); - else - return mRound(v, n); + if (n <= 0) + return mRound(v); + else + return mRound(v, n); } DefineConsoleFunction( mCeil, S32, ( F32 v ),, diff --git a/Engine/source/math/mQuat.h b/Engine/source/math/mQuat.h index 2ea1b94c1..ca6ed5d82 100644 --- a/Engine/source/math/mQuat.h +++ b/Engine/source/math/mQuat.h @@ -227,8 +227,8 @@ inline F32 QuatF::dot( const QuatF &q ) const inline F32 QuatF::angleBetween( const QuatF & q ) { - // angle between to quaternions - return mAcos(x * q.x + y * q.y + z * q.z + w * q.w); + // angle between two normalized quaternions. + return mAcos(q.dot(*this)) * 2.0f; } #endif // _MQUAT_H_ diff --git a/Engine/source/math/mathUtils.cpp b/Engine/source/math/mathUtils.cpp index f6086c5e4..5ffd9a870 100644 --- a/Engine/source/math/mathUtils.cpp +++ b/Engine/source/math/mathUtils.cpp @@ -1847,7 +1847,7 @@ U32 extrudePolygonEdgesFromPoint( const Point3F* vertices, U32 numVertices, cons //----------------------------------------------------------------------------- -void MathUtils::mBuildHull2D(const Vector _inPoints, Vector &hullPoints) +void mBuildHull2D(const Vector _inPoints, Vector &hullPoints) { /// Andrew's monotone chain convex hull algorithm implementation diff --git a/Engine/source/navigation/navMesh.cpp b/Engine/source/navigation/navMesh.cpp index 02de1b071..f029c5deb 100644 --- a/Engine/source/navigation/navMesh.cpp +++ b/Engine/source/navigation/navMesh.cpp @@ -112,13 +112,39 @@ DefineConsoleFunction(NavMeshUpdateAll, void, (S32 objid, bool remove), (0, fals SimSet *set = NavMesh::getServerSet(); for(U32 i = 0; i < set->size(); i++) { - NavMesh *m = static_cast(set->at(i)); - m->buildTiles(obj->getWorldBox()); + NavMesh *m = dynamic_cast(set->at(i)); + if (m) + { + m->cancelBuild(); + m->buildTiles(obj->getWorldBox()); + } } if(remove) obj->enableCollision(); } +DefineConsoleFunction(NavMeshUpdateAroundObject, void, (S32 objid, bool remove), (0, false), + "@brief Update all NavMesh tiles that intersect the given object's world box.") +{ + SceneObject *obj; + if (!Sim::findObject(objid, obj)) + return; + if (remove) + obj->disableCollision(); + SimSet *set = NavMesh::getServerSet(); + for (U32 i = 0; i < set->size(); i++) + { + NavMesh *m = dynamic_cast(set->at(i)); + if (m) + { + m->cancelBuild(); + m->buildTiles(obj->getWorldBox()); + } + } + if (remove) + obj->enableCollision(); +} + DefineConsoleFunction(NavMeshUpdateOne, void, (S32 meshid, S32 objid, bool remove), (0, 0, false), "@brief Update all tiles in a given NavMesh that intersect the given object's world box.") { @@ -147,7 +173,7 @@ NavMesh::NavMesh() mFileName = StringTable->insert(""); mNetFlags.clear(Ghostable); - mSaveIntermediates = true; + mSaveIntermediates = false; nm = NULL; ctx = NULL; @@ -765,13 +791,15 @@ void NavMesh::buildNextTile() // Intermediate data for tile build. TileData tempdata; TileData &tdata = mSaveIntermediates ? mTileData[i] : tempdata; + + // Remove any previous data. + nm->removeTile(nm->getTileRefAt(tile.x, tile.y, 0), 0, 0); + // Generate navmesh for this tile. U32 dataSize = 0; unsigned char* data = buildTileData(tile, tdata, dataSize); if(data) { - // Remove any previous data. - nm->removeTile(nm->getTileRefAt(tile.x, tile.y, 0), 0, 0); // Add new data (navmesh owns and deletes the data). dtStatus status = nm->addTile(data, dataSize, DT_TILE_FREE_DATA, 0, 0); int success = 1; @@ -830,6 +858,7 @@ unsigned char *NavMesh::buildTileData(const Tile &tile, TileData &data, U32 &dat SceneContainer::CallbackInfo info; info.context = PLC_Navigation; info.boundingBox = box; + data.geom.clear(); info.polyList = &data.geom; info.key = this; getContainer()->findObjects(box, StaticShapeObjectType | TerrainObjectType, buildCallback, &info); @@ -843,8 +872,11 @@ unsigned char *NavMesh::buildTileData(const Tile &tile, TileData &data, U32 &dat } // Check for no geometry. - if(!data.geom.getVertCount()) + if (!data.geom.getVertCount()) + { + data.geom.clear(); return NULL; + } // Figure out voxel dimensions of this tile. U32 width = 0, height = 0; diff --git a/Engine/source/persistence/taml/fsTinyXml.cpp b/Engine/source/persistence/taml/fsTinyXml.cpp index 1fb97398b..441169742 100644 --- a/Engine/source/persistence/taml/fsTinyXml.cpp +++ b/Engine/source/persistence/taml/fsTinyXml.cpp @@ -38,7 +38,7 @@ bool fsTiXmlDocument::LoadFile( const char * pFilename, TiXmlEncoding encoding ) #endif // File open for read? - if ( !stream.open( filenameBuffer, Torque::FS::File::AccessMode::Read ) ) + if ( !stream.open( filenameBuffer, Torque::FS::File::Read ) ) { // No, so warn. Con::warnf("TamlXmlParser::parse() - Could not open filename '%s' for parse.", filenameBuffer ); @@ -67,7 +67,7 @@ bool fsTiXmlDocument::SaveFile( const char * pFilename ) const FileStream stream; // File opened? - if ( !stream.open( filenameBuffer, Torque::FS::File::AccessMode::Write ) ) + if ( !stream.open( filenameBuffer, Torque::FS::File::Write ) ) { // No, so warn. Con::warnf("Taml::writeFile() - Could not open filename '%s' for write.", filenameBuffer ); @@ -744,4 +744,4 @@ return 0; // All is well. return p; } -*/ \ No newline at end of file +*/ diff --git a/Engine/source/persistence/taml/fsTinyXml.h b/Engine/source/persistence/taml/fsTinyXml.h index f2fb14129..864abec09 100644 --- a/Engine/source/persistence/taml/fsTinyXml.h +++ b/Engine/source/persistence/taml/fsTinyXml.h @@ -25,7 +25,7 @@ #ifndef TINYXML_INCLUDED -#include "tinyXML/tinyxml.h" +#include "tinyxml/tinyxml.h" #endif #include "platform/platform.h" @@ -245,4 +245,4 @@ static bool AttemptPrintTiNode(class fsTiXmlDocument* node, FileStream& stream, } return false; } -#endif //_FSTINYXML_H_ \ No newline at end of file +#endif //_FSTINYXML_H_ diff --git a/Engine/source/persistence/taml/xml/tamlXmlParser.h b/Engine/source/persistence/taml/xml/tamlXmlParser.h index 85b34079d..28b51a472 100644 --- a/Engine/source/persistence/taml/xml/tamlXmlParser.h +++ b/Engine/source/persistence/taml/xml/tamlXmlParser.h @@ -28,7 +28,7 @@ #endif #ifndef TINYXML_INCLUDED -#include "tinyXML/tinyxml.h" +#include "tinyxml/tinyxml.h" #endif //----------------------------------------------------------------------------- @@ -54,4 +54,4 @@ private: bool mDocumentDirty; }; -#endif // _TAML_XMLPARSER_H_ \ No newline at end of file +#endif // _TAML_XMLPARSER_H_ diff --git a/Engine/source/persistence/taml/xml/tamlXmlReader.cpp b/Engine/source/persistence/taml/xml/tamlXmlReader.cpp index 04b43a5d2..aa8be618f 100644 --- a/Engine/source/persistence/taml/xml/tamlXmlReader.cpp +++ b/Engine/source/persistence/taml/xml/tamlXmlReader.cpp @@ -24,7 +24,7 @@ // Debug Profiling. #include "platform/profiler.h" -#include "persistence/taml/fsTinyxml.h" +#include "persistence/taml/fsTinyXml.h" //----------------------------------------------------------------------------- diff --git a/Engine/source/persistence/taml/xml/tamlXmlWriter.cpp b/Engine/source/persistence/taml/xml/tamlXmlWriter.cpp index 4ffad7223..e8481cb87 100644 --- a/Engine/source/persistence/taml/xml/tamlXmlWriter.cpp +++ b/Engine/source/persistence/taml/xml/tamlXmlWriter.cpp @@ -24,7 +24,7 @@ // Debug Profiling. #include "platform/profiler.h" -#include "persistence/taml/fsTinyxml.h" +#include "persistence/taml/fsTinyXml.h" //----------------------------------------------------------------------------- diff --git a/Engine/source/platformMac/macCarbFileio.mm b/Engine/source/platformMac/macCarbFileio.mm index 7a913986e..a1961d710 100644 --- a/Engine/source/platformMac/macCarbFileio.mm +++ b/Engine/source/platformMac/macCarbFileio.mm @@ -724,6 +724,11 @@ bool Platform::hasSubDirectory(const char *path) return false; // either this dir had no subdirectories, or they were all on the exclude list. } + bool Platform::fileDelete(const char * name) + { + return dFileDelete(name); + } + //----------------------------------------------------------------------------- bool recurseDumpDirectories(const char *basePath, const char *path, Vector &directoryVector, S32 depth, bool noBasePath) { diff --git a/Engine/source/platformSDL/sdlPlatformGL.cpp b/Engine/source/platformSDL/sdlPlatformGL.cpp index 6562f2c80..b71846d8b 100644 --- a/Engine/source/platformSDL/sdlPlatformGL.cpp +++ b/Engine/source/platformSDL/sdlPlatformGL.cpp @@ -13,18 +13,16 @@ namespace PlatformGL return; inited = true; - const U32 majorOGL = 4; + const U32 majorOGL = 3; const U32 minorOGL = 2; U32 debugFlag = 0; #ifdef TORQUE_DEBUG debugFlag |= SDL_GL_CONTEXT_DEBUG_FLAG; #endif -#if 0 // cause problem with glew, no extension load SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, majorOGL); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, minorOGL); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); -#endif SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, debugFlag); SDL_ClearError(); diff --git a/Engine/source/platformX86UNIX/x86UNIXFileio.cpp b/Engine/source/platformX86UNIX/x86UNIXFileio.cpp index 22c40a187..6c2dd6955 100644 --- a/Engine/source/platformX86UNIX/x86UNIXFileio.cpp +++ b/Engine/source/platformX86UNIX/x86UNIXFileio.cpp @@ -325,7 +325,7 @@ bool dPathCopy(const char *fromName, const char *toName, bool nooverwrite) if (modType == TOUCH) return(utime(prefPathName, 0) != -1); else if (modType == DELETE) - return (remove(prefPathName) != -1); + return (remove(prefPathName) == 0); else AssertFatal(false, "Unknown File Mod type"); return false; @@ -1140,6 +1140,11 @@ bool dPathCopy(const char *fromName, const char *toName, bool nooverwrite) return false; } + bool Platform::fileDelete(const char * name) + { + return ModifyFile(name, DELETE); + } + static bool recurseDumpDirectories(const char *basePath, const char *subPath, Vector &directoryVector, S32 currentDepth, S32 recurseDepth, bool noBasePath) { char Path[1024]; diff --git a/Engine/source/sfx/fmod/sfxFMODDevice.h b/Engine/source/sfx/fmod/sfxFMODDevice.h index f710faa20..fc15041e9 100644 --- a/Engine/source/sfx/fmod/sfxFMODDevice.h +++ b/Engine/source/sfx/fmod/sfxFMODDevice.h @@ -105,8 +105,8 @@ struct FModFNTable } ~FModFNTable() { - eventDllRef = NULL; dllRef = NULL; + eventDllRef = NULL; delete mutex; } diff --git a/Engine/source/shaderGen/GLSL/accuFeatureGLSL.cpp b/Engine/source/shaderGen/GLSL/accuFeatureGLSL.cpp index c663b93ea..04a280e09 100644 --- a/Engine/source/shaderGen/GLSL/accuFeatureGLSL.cpp +++ b/Engine/source/shaderGen/GLSL/accuFeatureGLSL.cpp @@ -144,6 +144,8 @@ void AccuTexFeatGLSL::processPix(Vector &componentList, // get the accu pixel color meta->addStatement( new GenOp( " @ = tex2D(@, @ * @);\r\n", colorAccuDecl, accuMap, inTex, accuScale ) ); + if (!fd.features[MFT_Imposter]) + meta->addStatement(new GenOp(" @ = toLinear(@);\r\n", accuColor, accuColor)); // scale up normals meta->addStatement( new GenOp( " @.xyz = @.xyz * 2.0 - 0.5;\r\n", bumpNorm, bumpNorm ) ); diff --git a/Engine/source/shaderGen/GLSL/shaderFeatureGLSL.cpp b/Engine/source/shaderGen/GLSL/shaderFeatureGLSL.cpp index 7567b5516..eed42dd68 100644 --- a/Engine/source/shaderGen/GLSL/shaderFeatureGLSL.cpp +++ b/Engine/source/shaderGen/GLSL/shaderFeatureGLSL.cpp @@ -828,6 +828,12 @@ Var* ShaderFeatureGLSL::addOutDetailTexCoord( Vector &compon // Base Texture //**************************************************************************** +DiffuseMapFeatGLSL::DiffuseMapFeatGLSL() +: mTorqueDep("shaders/common/gl/torque.glsl") +{ + addDependency(&mTorqueDep); +} + void DiffuseMapFeatGLSL::processVert( Vector &componentList, const MaterialFeatureData &fd ) { @@ -855,20 +861,23 @@ void DiffuseMapFeatGLSL::processPix( Vector &componentList, diffuseMap->sampler = true; diffuseMap->constNum = Var::getTexUnitNum(); // used as texture unit num here + // create sample color var + Var *diffColor = new Var; + diffColor->setType("vec4"); + diffColor->setName("diffuseColor"); + LangElement *colorDecl = new DecOp( diffColor ); + + MultiLine * meta = new MultiLine; + output = meta; + if ( fd.features[MFT_CubeMap] ) { - MultiLine * meta = new MultiLine; - - // create sample color - Var *diffColor = new Var; - diffColor->setType( "vec4" ); - diffColor->setName( "diffuseColor" ); - LangElement *colorDecl = new DecOp( diffColor ); - meta->addStatement( new GenOp( " @ = tex2D(@, @);\r\n", colorDecl, diffuseMap, inTex ) ); + if (!fd.features[MFT_Imposter]) + meta->addStatement( new GenOp(" @ = toLinear(@);\r\n", diffColor, diffColor) ); meta->addStatement( new GenOp( " @;\r\n", assignColor( diffColor, Material::Mul ) ) ); output = meta; @@ -877,8 +886,6 @@ void DiffuseMapFeatGLSL::processPix( Vector &componentList, { // Handle atlased textures // http://www.infinity-universe.com/Infinity/index.php?option=com_content&task=view&id=65&Itemid=47 - MultiLine * meta = new MultiLine; - output = meta; Var *atlasedTex = new Var; atlasedTex->setName("atlasedTexCoord"); @@ -934,11 +941,6 @@ void DiffuseMapFeatGLSL::processPix( Vector &componentList, // For the rest of the feature... inTex = atlasedTex; - // create sample color var - Var *diffColor = new Var; - diffColor->setType("vec4"); - diffColor->setName("diffuseColor"); - // To dump out UV coords... //#define DEBUG_ATLASED_UV_COORDS #ifdef DEBUG_ATLASED_UV_COORDS @@ -954,21 +956,26 @@ void DiffuseMapFeatGLSL::processPix( Vector &componentList, { meta->addStatement(new GenOp( " @ = tex2Dlod(@, float4(@, 0.0, mipLod));\r\n", new DecOp(diffColor), diffuseMap, inTex)); + if (!fd.features[MFT_Imposter]) + meta->addStatement(new GenOp(" @ = toLinear(@);\r\n", diffColor, diffColor)); } else { meta->addStatement(new GenOp( " @ = tex2D(@, @);\r\n", new DecOp(diffColor), diffuseMap, inTex)); + if (!fd.features[MFT_Imposter]) + meta->addStatement(new GenOp(" @ = toLinear(@);\r\n", diffColor, diffColor)); } meta->addStatement(new GenOp( " @;\r\n", assignColor(diffColor, Material::Mul))); } else { - LangElement *statement = new GenOp( "tex2D(@, @)", diffuseMap, inTex ); - output = new GenOp( " @;\r\n", assignColor( statement, Material::Mul ) ); + meta->addStatement(new GenOp("@ = tex2D(@, @);\r\n", colorDecl, diffuseMap, inTex)); + if (!fd.features[MFT_Imposter]) + meta->addStatement(new GenOp(" @ = toLinear(@);\r\n", diffColor, diffColor)); + meta->addStatement(new GenOp(" @;\r\n", assignColor(diffColor, Material::Mul))); } - } ShaderFeature::Resources DiffuseMapFeatGLSL::getResources( const MaterialFeatureData &fd ) diff --git a/Engine/source/shaderGen/GLSL/shaderFeatureGLSL.h b/Engine/source/shaderGen/GLSL/shaderFeatureGLSL.h index a0e831e93..276183d99 100644 --- a/Engine/source/shaderGen/GLSL/shaderFeatureGLSL.h +++ b/Engine/source/shaderGen/GLSL/shaderFeatureGLSL.h @@ -236,7 +236,12 @@ public: /// Base texture class DiffuseMapFeatGLSL : public ShaderFeatureGLSL { + +protected: + + ShaderIncludeDependency mTorqueDep; public: + DiffuseMapFeatGLSL(); virtual void processVert( Vector &componentList, const MaterialFeatureData &fd ); diff --git a/Engine/source/shaderGen/GLSL/shaderGenGLSLInit.cpp b/Engine/source/shaderGen/GLSL/shaderGenGLSLInit.cpp index 3c4065d44..ef15793a5 100644 --- a/Engine/source/shaderGen/GLSL/shaderGenGLSLInit.cpp +++ b/Engine/source/shaderGen/GLSL/shaderGenGLSLInit.cpp @@ -68,6 +68,7 @@ void _initShaderGenGLSL( ShaderGen *shaderGen ) FEATUREMGR->registerFeature( MFT_IsTranslucent, new NamedFeatureGLSL( "Translucent" ) ); FEATUREMGR->registerFeature( MFT_Visibility, new VisibilityFeatGLSL ); FEATUREMGR->registerFeature( MFT_Fog, new FogFeatGLSL ); + FEATUREMGR->registerFeature( MFT_Imposter, new NamedFeatureGLSL( "Imposter" ) ); FEATUREMGR->registerFeature( MFT_NormalsOut, new NormalsOutFeatGLSL ); diff --git a/Engine/source/shaderGen/HLSL/accuFeatureHLSL.cpp b/Engine/source/shaderGen/HLSL/accuFeatureHLSL.cpp index 63161c258..1e90faa12 100644 --- a/Engine/source/shaderGen/HLSL/accuFeatureHLSL.cpp +++ b/Engine/source/shaderGen/HLSL/accuFeatureHLSL.cpp @@ -141,6 +141,8 @@ void AccuTexFeatHLSL::processPix( Vector &componentList, // get the accu pixel color meta->addStatement( new GenOp( " @ = tex2D(@, @ * @);\r\n", colorAccuDecl, accuMap, inTex, accuScale ) ); + if (!fd.features[MFT_Imposter]) + meta->addStatement(new GenOp(" @ = toLinear(@);\r\n", accuColor, accuColor)); // scale up normals meta->addStatement( new GenOp( " @.xyz = @.xyz * 2.0 - 0.5;\r\n", bumpNorm, bumpNorm ) ); diff --git a/Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp b/Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp index 8f8b5918a..17cf6333c 100644 --- a/Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp +++ b/Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp @@ -826,6 +826,12 @@ Var* ShaderFeatureHLSL::addOutDetailTexCoord( Vector &compon // Base Texture //**************************************************************************** +DiffuseMapFeatHLSL::DiffuseMapFeatHLSL() +: mTorqueDep("shaders/common/torque.hlsl") +{ + addDependency(&mTorqueDep); +} + void DiffuseMapFeatHLSL::processVert( Vector &componentList, const MaterialFeatureData &fd ) { @@ -853,30 +859,30 @@ void DiffuseMapFeatHLSL::processPix( Vector &componentList, diffuseMap->sampler = true; diffuseMap->constNum = Var::getTexUnitNum(); // used as texture unit num here + // create sample color + Var *diffColor = new Var; + diffColor->setType("float4"); + diffColor->setName("diffuseColor"); + LangElement *colorDecl = new DecOp(diffColor); + + MultiLine * meta = new MultiLine; + output = meta; + if ( fd.features[MFT_CubeMap] ) { - MultiLine * meta = new MultiLine; - - // create sample color - Var *diffColor = new Var; - diffColor->setType( "float4" ); - diffColor->setName( "diffuseColor" ); - LangElement *colorDecl = new DecOp( diffColor ); - meta->addStatement( new GenOp( " @ = tex2D(@, @);\r\n", colorDecl, diffuseMap, inTex ) ); + if (!fd.features[MFT_Imposter]) + meta->addStatement(new GenOp(" @ = toLinear(@);\r\n", diffColor, diffColor)); meta->addStatement( new GenOp( " @;\r\n", assignColor( diffColor, Material::Mul ) ) ); - output = meta; } else if(fd.features[MFT_DiffuseMapAtlas]) { // Handle atlased textures // http://www.infinity-universe.com/Infinity/index.php?option=com_content&task=view&id=65&Itemid=47 - MultiLine * meta = new MultiLine; - output = meta; Var *atlasedTex = new Var; atlasedTex->setName("atlasedTexCoord"); @@ -932,11 +938,6 @@ void DiffuseMapFeatHLSL::processPix( Vector &componentList, // For the rest of the feature... inTex = atlasedTex; - // create sample color var - Var *diffColor = new Var; - diffColor->setType("float4"); - diffColor->setName("diffuseColor"); - // To dump out UV coords... //#define DEBUG_ATLASED_UV_COORDS #ifdef DEBUG_ATLASED_UV_COORDS @@ -958,15 +959,18 @@ void DiffuseMapFeatHLSL::processPix( Vector &componentList, meta->addStatement(new GenOp( " @ = tex2D(@, @);\r\n", new DecOp(diffColor), diffuseMap, inTex)); } + if (!fd.features[MFT_Imposter]) + meta->addStatement(new GenOp(" @ = toLinear(@);\r\n", diffColor, diffColor)); meta->addStatement(new GenOp( " @;\r\n", assignColor(diffColor, Material::Mul))); } else { - LangElement *statement = new GenOp( "tex2D(@, @)", diffuseMap, inTex ); - output = new GenOp( " @;\r\n", assignColor( statement, Material::Mul ) ); + meta->addStatement(new GenOp("@ = tex2D(@, @);\r\n", colorDecl, diffuseMap, inTex)); + if (!fd.features[MFT_Imposter]) + meta->addStatement(new GenOp(" @ = toLinear(@);\r\n", diffColor, diffColor)); + meta->addStatement(new GenOp(" @;\r\n", assignColor(diffColor, Material::Mul))); } - } ShaderFeature::Resources DiffuseMapFeatHLSL::getResources( const MaterialFeatureData &fd ) diff --git a/Engine/source/shaderGen/HLSL/shaderFeatureHLSL.h b/Engine/source/shaderGen/HLSL/shaderFeatureHLSL.h index 3c2fc821e..4f77c175a 100644 --- a/Engine/source/shaderGen/HLSL/shaderFeatureHLSL.h +++ b/Engine/source/shaderGen/HLSL/shaderFeatureHLSL.h @@ -236,7 +236,12 @@ public: /// Base texture class DiffuseMapFeatHLSL : public ShaderFeatureHLSL { +protected: + + ShaderIncludeDependency mTorqueDep; + public: + DiffuseMapFeatHLSL(); virtual void processVert( Vector &componentList, const MaterialFeatureData &fd ); diff --git a/Engine/source/shaderGen/HLSL/shaderGenHLSLInit.cpp b/Engine/source/shaderGen/HLSL/shaderGenHLSLInit.cpp index c754e1b25..a5c6165e0 100644 --- a/Engine/source/shaderGen/HLSL/shaderGenHLSLInit.cpp +++ b/Engine/source/shaderGen/HLSL/shaderGenHLSLInit.cpp @@ -70,6 +70,7 @@ void _initShaderGenHLSL( ShaderGen *shaderGen ) FEATUREMGR->registerFeature( MFT_GlossMap, new NamedFeatureHLSL( "Gloss Map" ) ); FEATUREMGR->registerFeature( MFT_LightbufferMRT, new NamedFeatureHLSL( "Lightbuffer MRT" ) ); FEATUREMGR->registerFeature( MFT_RenderTarget1_Zero, new RenderTargetZeroHLSL( ShaderFeature::RenderTarget1 ) ); + FEATUREMGR->registerFeature( MFT_Imposter, new NamedFeatureHLSL( "Imposter" ) ); FEATUREMGR->registerFeature( MFT_DiffuseMapAtlas, new NamedFeatureHLSL( "Diffuse Map Atlas" ) ); FEATUREMGR->registerFeature( MFT_NormalMapAtlas, new NamedFeatureHLSL( "Normal Map Atlas" ) ); diff --git a/Engine/source/shaderGen/featureSet.cpp b/Engine/source/shaderGen/featureSet.cpp index 7189beacc..2eff50e1c 100644 --- a/Engine/source/shaderGen/featureSet.cpp +++ b/Engine/source/shaderGen/featureSet.cpp @@ -170,7 +170,7 @@ void FeatureSet::removeFeature( const FeatureType &type ) } } -U32 FeatureSet::getNextFeatureIndex( const FeatureType &type, S32 index ) const +S32 FeatureSet::getNextFeatureIndex( const FeatureType &type, S32 index ) const { for ( U32 i=0; i < mFeatures.size(); i++ ) { diff --git a/Engine/source/shaderGen/featureSet.h b/Engine/source/shaderGen/featureSet.h index e8920dc67..03b46f62a 100644 --- a/Engine/source/shaderGen/featureSet.h +++ b/Engine/source/shaderGen/featureSet.h @@ -106,7 +106,7 @@ public: void removeFeature( const FeatureType &type ); /// - U32 getNextFeatureIndex( const FeatureType &type, S32 index ) const; + S32 getNextFeatureIndex( const FeatureType &type, S32 index ) const; /// Removes features that are not in the input set. void filter( const FeatureSet &features ); diff --git a/Engine/source/shaderGen/shaderFeature.h b/Engine/source/shaderGen/shaderFeature.h index f18fae7f9..c6ac4955d 100644 --- a/Engine/source/shaderGen/shaderFeature.h +++ b/Engine/source/shaderGen/shaderFeature.h @@ -153,7 +153,7 @@ public: void setProcessIndex( S32 index ) { mProcessIndex = index; } /// - U32 getProcessIndex() const { return mProcessIndex; } + S32 getProcessIndex() const { return mProcessIndex; } //----------------------------------------------------------------------- // Virtual Functions diff --git a/Engine/source/terrain/glsl/terrFeatureGLSL.cpp b/Engine/source/terrain/glsl/terrFeatureGLSL.cpp index ebe052e00..dd67124c6 100644 --- a/Engine/source/terrain/glsl/terrFeatureGLSL.cpp +++ b/Engine/source/terrain/glsl/terrFeatureGLSL.cpp @@ -64,6 +64,12 @@ MODULE_BEGIN( TerrainFeatGLSL ) MODULE_END; +TerrainFeatGLSL::TerrainFeatGLSL() + : mTorqueDep( "shaders/common/gl/torque.glsl" ) + { + addDependency( &mTorqueDep ); + } + Var* TerrainFeatGLSL::_getUniformVar( const char *name, const char *type, ConstantSortPosition csp ) { Var *theVar = (Var*)LangElement::find( name ); @@ -262,6 +268,7 @@ void TerrainBaseMapFeatGLSL::processPix( Vector &componentLis baseColor->setType( "vec4" ); baseColor->setName( "baseColor" ); meta->addStatement( new GenOp( " @ = tex2D( @, @.xy );\r\n", new DecOp( baseColor ), diffuseMap, texCoord ) ); + meta->addStatement(new GenOp(" @ = toLinear(@);\r\n", baseColor, baseColor)); meta->addStatement( new GenOp( " @;\r\n", assignColor( baseColor, Material::Mul ) ) ); output = meta; @@ -291,7 +298,7 @@ TerrainDetailMapFeatGLSL::TerrainDetailMapFeatGLSL() void TerrainDetailMapFeatGLSL::processVert( Vector &componentList, const MaterialFeatureData &fd ) { - const U32 detailIndex = getProcessIndex(); + const S32 detailIndex = getProcessIndex(); // Grab incoming texture coords... the base map feature // made sure this was created. @@ -376,7 +383,7 @@ void TerrainDetailMapFeatGLSL::processVert( Vector &component void TerrainDetailMapFeatGLSL::processPix( Vector &componentList, const MaterialFeatureData &fd ) { - const U32 detailIndex = getProcessIndex(); + const S32 detailIndex = getProcessIndex(); Var *inTex = getVertTexCoord( "texCoord" ); MultiLine *meta = new MultiLine; @@ -609,7 +616,7 @@ TerrainMacroMapFeatGLSL::TerrainMacroMapFeatGLSL() void TerrainMacroMapFeatGLSL::processVert( Vector &componentList, const MaterialFeatureData &fd ) { - const U32 detailIndex = getProcessIndex(); + const S32 detailIndex = getProcessIndex(); // Grab incoming texture coords... the base map feature // made sure this was created. @@ -667,7 +674,7 @@ void TerrainMacroMapFeatGLSL::processVert( Vector &componentL void TerrainMacroMapFeatGLSL::processPix( Vector &componentList, const MaterialFeatureData &fd ) { - const U32 detailIndex = getProcessIndex(); + const S32 detailIndex = getProcessIndex(); Var *inTex = getVertTexCoord( "texCoord" ); MultiLine *meta = new MultiLine; @@ -893,7 +900,7 @@ void TerrainNormalMapFeatGLSL::processPix( Vector &component meta->addStatement( new GenOp( " @ = tGetMatrix3Row(@, 2);\r\n", new DecOp( gbNormal ), viewToTangent ) ); } - const U32 normalIndex = getProcessIndex(); + const S32 normalIndex = getProcessIndex(); Var *detailBlend = (Var*)LangElement::find( String::ToString( "detailBlend%d", normalIndex ) ); AssertFatal( detailBlend, "The detail blend is missing!" ); diff --git a/Engine/source/terrain/glsl/terrFeatureGLSL.h b/Engine/source/terrain/glsl/terrFeatureGLSL.h index 790a8a342..6cb3a3c0c 100644 --- a/Engine/source/terrain/glsl/terrFeatureGLSL.h +++ b/Engine/source/terrain/glsl/terrFeatureGLSL.h @@ -36,7 +36,10 @@ class TerrainFeatGLSL : public ShaderFeatureGLSL { protected: + ShaderIncludeDependency mTorqueDep; +public: + TerrainFeatGLSL(); Var* _getInDetailCoord(Vector &componentList ); Var* _getInMacroCoord(Vector &componentList ); diff --git a/Engine/source/terrain/hlsl/terrFeatureHLSL.cpp b/Engine/source/terrain/hlsl/terrFeatureHLSL.cpp index 7190d7f82..d993f4bd8 100644 --- a/Engine/source/terrain/hlsl/terrFeatureHLSL.cpp +++ b/Engine/source/terrain/hlsl/terrFeatureHLSL.cpp @@ -64,6 +64,12 @@ MODULE_BEGIN( TerrainFeatHLSL ) MODULE_END; +TerrainFeatHLSL::TerrainFeatHLSL() + : mTorqueDep( "shaders/common/torque.hlsl" ) + { + addDependency( &mTorqueDep ); + } + Var* TerrainFeatHLSL::_getUniformVar( const char *name, const char *type, ConstantSortPosition csp ) { Var *theVar = (Var*)LangElement::find( name ); @@ -262,6 +268,7 @@ void TerrainBaseMapFeatHLSL::processPix( Vector &componentLis baseColor->setType( "float4" ); baseColor->setName( "baseColor" ); meta->addStatement( new GenOp( " @ = tex2D( @, @.xy );\r\n", new DecOp( baseColor ), diffuseMap, texCoord ) ); + meta->addStatement(new GenOp(" @ = toLinear(@);\r\n", baseColor, baseColor)); meta->addStatement( new GenOp( " @;\r\n", assignColor( baseColor, Material::Mul ) ) ); output = meta; @@ -291,7 +298,7 @@ TerrainDetailMapFeatHLSL::TerrainDetailMapFeatHLSL() void TerrainDetailMapFeatHLSL::processVert( Vector &componentList, const MaterialFeatureData &fd ) { - const U32 detailIndex = getProcessIndex(); + const S32 detailIndex = getProcessIndex(); // Grab incoming texture coords... the base map feature // made sure this was created. @@ -376,7 +383,7 @@ void TerrainDetailMapFeatHLSL::processVert( Vector &component void TerrainDetailMapFeatHLSL::processPix( Vector &componentList, const MaterialFeatureData &fd ) { - const U32 detailIndex = getProcessIndex(); + const S32 detailIndex = getProcessIndex(); Var *inTex = getVertTexCoord( "texCoord" ); MultiLine *meta = new MultiLine; @@ -608,7 +615,7 @@ TerrainMacroMapFeatHLSL::TerrainMacroMapFeatHLSL() void TerrainMacroMapFeatHLSL::processVert( Vector &componentList, const MaterialFeatureData &fd ) { - const U32 detailIndex = getProcessIndex(); + const S32 detailIndex = getProcessIndex(); // Grab incoming texture coords... the base map feature // made sure this was created. @@ -666,7 +673,7 @@ void TerrainMacroMapFeatHLSL::processVert( Vector &componentL void TerrainMacroMapFeatHLSL::processPix( Vector &componentList, const MaterialFeatureData &fd ) { - const U32 detailIndex = getProcessIndex(); + const S32 detailIndex = getProcessIndex(); Var *inTex = getVertTexCoord( "texCoord" ); MultiLine *meta = new MultiLine; @@ -893,7 +900,7 @@ void TerrainNormalMapFeatHLSL::processPix( Vector &component meta->addStatement( new GenOp( " @ = @[2];\r\n", new DecOp( gbNormal ), viewToTangent ) ); } - const U32 normalIndex = getProcessIndex(); + const S32 normalIndex = getProcessIndex(); Var *detailBlend = (Var*)LangElement::find( String::ToString( "detailBlend%d", normalIndex ) ); AssertFatal( detailBlend, "The detail blend is missing!" ); diff --git a/Engine/source/terrain/hlsl/terrFeatureHLSL.h b/Engine/source/terrain/hlsl/terrFeatureHLSL.h index 85f75a29e..e6297f3b4 100644 --- a/Engine/source/terrain/hlsl/terrFeatureHLSL.h +++ b/Engine/source/terrain/hlsl/terrFeatureHLSL.h @@ -37,6 +37,10 @@ class TerrainFeatHLSL : public ShaderFeatureHLSL { protected: + ShaderIncludeDependency mTorqueDep; + +public: + TerrainFeatHLSL(); Var* _getInDetailCoord(Vector &componentList ); Var* _getInMacroCoord(Vector &componentList ); diff --git a/Engine/source/util/imposterCapture.cpp b/Engine/source/util/imposterCapture.cpp index fb0786390..f6bcba23f 100644 --- a/Engine/source/util/imposterCapture.cpp +++ b/Engine/source/util/imposterCapture.cpp @@ -136,6 +136,7 @@ void ImposterCaptureMaterialHook::_overrideFeatures( ProcessedMaterial *mat, fd.features.addFeature( MFT_NormalsOut ); fd.features.addFeature( MFT_ForwardShading ); + fd.features.addFeature( MFT_Imposter ); } ImposterCaptureMaterialHook* ImposterCaptureMaterialHook::_getOrCreateHook( BaseMatInstance *inMat ) diff --git a/Engine/source/windowManager/win32/win32Window.cpp b/Engine/source/windowManager/win32/win32Window.cpp index 5c9b8ed11..c714586b9 100644 --- a/Engine/source/windowManager/win32/win32Window.cpp +++ b/Engine/source/windowManager/win32/win32Window.cpp @@ -26,8 +26,10 @@ #include #include #include "math/mMath.h" +#include "gfx/gfxDevice.h" #include "gfx/gfxStructs.h" +#include "windowManager/platformWindowMgr.h" #include "windowManager/win32/win32Window.h" #include "windowManager/win32/win32WindowMgr.h" #include "windowManager/win32/win32CursorController.h" @@ -39,11 +41,6 @@ // for winState structure #include "platformWin32/platformWin32.h" -#include -#include "gfx/gfxDevice.h" - -#include - const UTF16* _MainWindowClassName = L"TorqueJuggernaughtWindow"; const UTF16* _CurtainWindowClassName = L"TorqueJuggernaughtCurtainWindow"; @@ -148,96 +145,93 @@ const GFXVideoMode & Win32Window::getVideoMode() void Win32Window::setVideoMode( const GFXVideoMode &mode ) { - bool needCurtain = (mVideoMode.fullScreen != mode.fullScreen); + bool needCurtain = ( mVideoMode.fullScreen != mode.fullScreen ); - if(needCurtain) + if( needCurtain ) { - Con::errorf("Win32Window::setVideoMode - invoking curtain"); + Con::printf( "Win32Window::setVideoMode - invoking curtain" ); mOwningManager->lowerCurtain(); } - mVideoMode = mode; - mSuppressReset = true; + mVideoMode = mode; + mSuppressReset = true; // Can't switch to fullscreen while a child of another window - if(mode.fullScreen && !Platform::getWebDeployment() && mOwningManager->getParentWindow()) + if( mode.fullScreen && !Platform::getWebDeployment() && mOwningManager->getParentWindow() ) { - mOldParent = (HWND)mOwningManager->getParentWindow(); - mOwningManager->setParentWindow(NULL); + mOldParent = reinterpret_cast( mOwningManager->getParentWindow() ); + mOwningManager->setParentWindow( NULL ); } - else if(!mode.fullScreen && mOldParent) + else if( !mode.fullScreen && mOldParent ) { - mOwningManager->setParentWindow(mOldParent); + mOwningManager->setParentWindow( mOldParent ); mOldParent = NULL; } - // Set our window to have the right style based on the mode - if(mode.fullScreen && !Platform::getWebDeployment() && !mOffscreenRender) + // Set our window to have the right style based on the mode + if( mode.fullScreen && !Platform::getWebDeployment() && !mOffscreenRender ) { - WINDOWPLACEMENT wplacement = { sizeof(wplacement) }; - DWORD dwStyle = GetWindowLong(getHWND(), GWL_STYLE); - MONITORINFO mi = { sizeof(mi) }; + WINDOWPLACEMENT wplacement = { sizeof( wplacement ) }; + DWORD dwStyle = GetWindowLong( getHWND(), GWL_STYLE ); + MONITORINFO mi = { sizeof(mi) }; - if (GetWindowPlacement(getHWND(), &wplacement) && GetMonitorInfo(MonitorFromWindow(getHWND(), MONITOR_DEFAULTTOPRIMARY), &mi)) - { - DISPLAY_DEVICE dd = GetPrimaryDevice(); - DEVMODE dv; - ZeroMemory(&dv, sizeof(dv)); - dv.dmSize = sizeof(DEVMODE); - EnumDisplaySettings(dd.DeviceName, ENUM_CURRENT_SETTINGS, &dv); - dv.dmPelsWidth = mode.resolution.x; - dv.dmPelsHeight = mode.resolution.y; - dv.dmBitsPerPel = mode.bitDepth; - dv.dmDisplayFrequency = mode.refreshRate; - dv.dmFields = (DM_PELSWIDTH | DM_PELSHEIGHT); - ChangeDisplaySettings(&dv, CDS_FULLSCREEN); - SetWindowLong(getHWND(), GWL_STYLE, dwStyle & ~WS_OVERLAPPEDWINDOW); - SetWindowPos(getHWND(), HWND_TOP, - mi.rcMonitor.left, - mi.rcMonitor.top, - mi.rcMonitor.right - mi.rcMonitor.left, - mi.rcMonitor.bottom - mi.rcMonitor.top, - SWP_NOOWNERZORDER | SWP_FRAMECHANGED); - } - - if(mDisplayWindow) - ShowWindow(getHWND(), SW_SHOWNORMAL); - - // Clear the menu bar from the window for full screen - HMENU menu = GetMenu(getHWND()); - if(menu) + if ( GetWindowPlacement( getHWND(), &wplacement ) && GetMonitorInfo( MonitorFromWindow( getHWND(), MONITOR_DEFAULTTOPRIMARY ), &mi ) ) { - SetMenu(getHWND(), NULL); + DISPLAY_DEVICE dd = GetPrimaryDevice(); + DEVMODE dv; + ZeroMemory( &dv, sizeof( dv ) ); + dv.dmSize = sizeof( DEVMODE ); + EnumDisplaySettings( dd.DeviceName, ENUM_CURRENT_SETTINGS, &dv ); + dv.dmPelsWidth = mode.resolution.x; + dv.dmPelsHeight = mode.resolution.y; + dv.dmBitsPerPel = mode.bitDepth; + dv.dmDisplayFrequency = mode.refreshRate; + dv.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT; + ChangeDisplaySettings( &dv, CDS_FULLSCREEN ); + SetWindowLong( getHWND(), GWL_STYLE, dwStyle & ~WS_OVERLAPPEDWINDOW ); + SetWindowPos( getHWND(), HWND_TOP, mi.rcMonitor.left, + mi.rcMonitor.top, + mi.rcMonitor.right - mi.rcMonitor.left, + mi.rcMonitor.bottom - mi.rcMonitor.top, + SWP_NOOWNERZORDER | SWP_FRAMECHANGED ); } + if( mDisplayWindow ) + ShowWindow( getHWND(), SW_SHOWNORMAL ); + + // Clear the menu bar from the window for full screen + if( GetMenu( getHWND() ) ) + SetMenu( getHWND(), NULL ); + // When switching to Fullscreen, reset device after setting style - if(mTarget.isValid()) - mTarget->resetMode(); + if( mTarget.isValid() ) + mTarget->resetMode(); mFullscreen = true; - } - else - { - DISPLAY_DEVICE dd = GetPrimaryDevice(); - DEVMODE dv; - ZeroMemory(&dv, sizeof(dv)); - dv.dmSize = sizeof(DEVMODE); - EnumDisplaySettings(dd.DeviceName, ENUM_CURRENT_SETTINGS, &dv); + } + else + { + DISPLAY_DEVICE dd = GetPrimaryDevice(); + DEVMODE dv; + ZeroMemory( &dv, sizeof( dv ) ); + dv.dmSize = sizeof( DEVMODE ); + EnumDisplaySettings( dd.DeviceName, ENUM_CURRENT_SETTINGS, &dv ); - if ((mode.resolution.x != dv.dmPelsWidth) || (mode.resolution.y != dv.dmPelsHeight)) - ChangeDisplaySettings(NULL, 0); + if ( ( WindowManager->getDesktopResolution() != mode.resolution || + ( mode.resolution.x != dv.dmPelsWidth ) || ( mode.resolution.y != dv.dmPelsHeight ) ) ) + ChangeDisplaySettings( NULL, 0 ); - // Reset device *first*, so that when we call setSize() and let it - // access the monitor settings, it won't end up with our fullscreen - // geometry that is just about to change. + // Reset device *first*, so that when we call setSize() and let it + // access the monitor settings, it won't end up with our fullscreen + // geometry that is just about to change. - if(mTarget.isValid()) - mTarget->resetMode(); + if( mTarget.isValid() ) + mTarget->resetMode(); - if (!mOffscreenRender) + if ( !mOffscreenRender ) { - SetWindowLong( getHWND(), GWL_STYLE, mWindowedWindowStyle); - SetWindowPos( getHWND(), HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED); + SetWindowLong( getHWND(), GWL_STYLE, mWindowedWindowStyle); + SetWindowPos( getHWND(), HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED); // Put back the menu bar, if any if(mMenuHandle) @@ -253,42 +247,37 @@ void Win32Window::setVideoMode( const GFXVideoMode &mode ) } else { - HWND parentWin = (HWND)mOwningManager->getParentWindow(); + HWND parentWin = reinterpret_cast( mOwningManager->getParentWindow() ); RECT windowRect; - GetClientRect(parentWin, &windowRect); - Point2I res(windowRect.right-windowRect.left, windowRect.bottom-windowRect.top); - if (res.x == 0 || res.y == 0) - { - // Must be too early in the window set up to obtain the parent's size. - setSize(mode.resolution); - } + GetClientRect( parentWin, &windowRect ); + Point2I res( windowRect.right - windowRect.left, windowRect.bottom - windowRect.top ); + + if ( res.x == 0 || res.y == 0 ) + setSize( mode.resolution ); // Must be too early in the window set up to obtain the parent's size. else - { - setSize(res); - } + setSize( res ); } - if (!mOffscreenRender) + if ( !mOffscreenRender ) { - // We have to force Win32 to update the window frame and make the window - // visible and no longer topmost - this code might be possible to simplify. - SetWindowPos( getHWND(), HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED); + // We have to force Win32 to update the window frame and make the window + // visible and no longer topmost - this code might be possible to simplify. + SetWindowPos( getHWND(), HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED ); if(mDisplayWindow) - ShowWindow( getHWND(), SW_SHOWNORMAL); + ShowWindow( getHWND(), SW_SHOWNORMAL ); } mFullscreen = false; - } + } - mSuppressReset = false; + mSuppressReset = false; - if(needCurtain) - mOwningManager->raiseCurtain(); + if( needCurtain ) + mOwningManager->raiseCurtain(); - SetForegroundWindow(getHWND()); - - getScreenResChangeSignal().trigger(this, true); + SetForegroundWindow( getHWND() ); + getScreenResChangeSignal().trigger( this, true ); } bool Win32Window::clearFullscreen() diff --git a/Templates/Empty/game/core/main.cs b/Templates/Empty/game/core/main.cs index 0baeb9364..f666c948c 100644 --- a/Templates/Empty/game/core/main.cs +++ b/Templates/Empty/game/core/main.cs @@ -141,11 +141,11 @@ function parseArgs() switch$ (%arg) { case "-fullscreen": - setFullScreen(true); + $cliFullscreen = true; $argUsed[%i]++; case "-windowed": - setFullScreen(false); + $cliFullscreen = false; $argUsed[%i]++; case "-openGL": diff --git a/Templates/Empty/game/core/scripts/client/canvas.cs b/Templates/Empty/game/core/scripts/client/canvas.cs index 69dd6da71..5c1d377c5 100644 --- a/Templates/Empty/game/core/scripts/client/canvas.cs +++ b/Templates/Empty/game/core/scripts/client/canvas.cs @@ -39,9 +39,14 @@ function configureCanvas() %rate = getWord($pref::Video::mode, $WORD::REFRESH); %fsaa = getWord($pref::Video::mode, $WORD::AA); - echo("--------------"); - echo("Attempting to set resolution to \"" @ $pref::Video::mode @ "\""); + if($cliFullscreen !$= "") { + %fs = $cliFullscreen; + $cliFullscreen = ""; + } + echo("--------------"); + echo("Attempting to set resolution to \"" @ %resX SPC %resY SPC %fs SPC %bpp SPC %rate SPC %fsaa @ "\""); + %deskRes = getDesktopResolution(); %deskResX = getWord(%deskRes, $WORD::RES_X); %deskResY = getWord(%deskRes, $WORD::RES_Y); diff --git a/Templates/Full/game/art/datablocks/environment.cs b/Templates/Full/game/art/datablocks/environment.cs index 386703f67..c9d2b0a51 100644 --- a/Templates/Full/game/art/datablocks/environment.cs +++ b/Templates/Full/game/art/datablocks/environment.cs @@ -84,3 +84,15 @@ datablock LightningData(DefaultStorm) thunderSounds[2] = ThunderCrash3Sound; thunderSounds[3] = ThunderCrash4Sound; }; + +datablock ReflectorDesc( DefaultCubeDesc ) +{ + texSize = 256; + nearDist = 0.1; + farDist = 1000.0; + objectTypeMask = 0xFFFFFFFF; + detailAdjust = 1.0; + priority = 1.0; + maxRateMs = 15; + useOcclusionQuery = true; +}; diff --git a/Templates/Full/game/art/gui/optionsDlg.gui b/Templates/Full/game/art/gui/optionsDlg.gui index fcff1cb95..9f12a272a 100644 --- a/Templates/Full/game/art/gui/optionsDlg.gui +++ b/Templates/Full/game/art/gui/optionsDlg.gui @@ -33,7 +33,7 @@ anchorLeft = "1"; anchorRight = "0"; position = "323 232"; - extent = "377 303"; + extent = "377 355"; minExtent = "8 8"; horizSizing = "center"; vertSizing = "center"; @@ -51,7 +51,7 @@ groupNum = "-1"; buttonType = "PushButton"; useMouseEvents = "0"; - position = "306 271"; + position = "304 319"; extent = "60 23"; minExtent = "8 8"; horizSizing = "right"; @@ -179,47 +179,49 @@ canSave = "1"; canSaveDynamicFields = "0"; }; - - new GuiSliderCtrl(OptMouseSensitivity) { - range = "0.02 2"; - ticks = "10"; - value = "0.75"; - isContainer = "0"; - Profile = "GuiSliderProfile"; - HorizSizing = "right"; - VertSizing = "bottom"; - position = "105 182"; - Extent = "244 18"; - MinExtent = "8 2"; - canSave = "1"; - Visible = "1"; - Command = "OptMouseSetSensitivity(OptMouseSensitivity.value);"; - tooltipprofile = "GuiToolTipProfile"; - hovertime = "1000"; - canSaveDynamicFields = "0"; - }; - new GuiTextCtrl() { - text = "Mouse Sensitivity:"; - maxLength = "255"; - Margin = "0 0 0 0"; - Padding = "0 0 0 0"; - AnchorTop = "1"; - AnchorBottom = "0"; - AnchorLeft = "1"; - AnchorRight = "0"; - isContainer = "0"; - Profile = "GuiTextProfile"; - HorizSizing = "right"; - VertSizing = "bottom"; - position = "15 182"; - Extent = "85 18"; - MinExtent = "8 8"; - canSave = "1"; - Visible = "1"; - tooltipprofile = "GuiToolTipProfile"; - hovertime = "1000"; - canSaveDynamicFields = "0"; - }; + new GuiSliderCtrl(OptMouseSensitivity) { + range = "0.02 2"; + ticks = "10"; + snap = "0"; + value = "1"; + position = "105 182"; + extent = "244 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderProfile"; + visible = "1"; + active = "1"; + command = "OptMouseSetSensitivity(OptMouseSensitivity.value);"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Mouse Sensitivity:"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "15 182"; + extent = "85 18"; + minExtent = "8 8"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; }; new GuiBitmapBorderCtrl() { position = "9 55"; @@ -601,7 +603,7 @@ }; new GuiBitmapBorderCtrl() { position = "9 55"; - extent = "358 210"; + extent = "358 252"; minExtent = "8 8"; horizSizing = "right"; vertSizing = "bottom"; @@ -1252,6 +1254,66 @@ canSave = "1"; canSaveDynamicFields = "0"; }; + new GuiControl() { + position = "0 227"; + extent = "352 15"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "GammaSliderContainer"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiSliderCtrl() { + range = "0.5 1.5"; + ticks = "0"; + snap = "0"; + value = "1"; + position = "76 -1"; + extent = "268 15"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderProfile"; + visible = "1"; + active = "1"; + variable = "$pref::Video::Contrast"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Contrast:"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "18 -4"; + extent = "105 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; new GuiControl() { position = "0 190"; extent = "352 15"; @@ -1269,10 +1331,10 @@ canSaveDynamicFields = "0"; new GuiSliderCtrl() { - range = "0.001 2.2"; + range = "2.0 2.5"; ticks = "0"; snap = "0"; - value = "1"; + value = "2.2"; position = "76 -1"; extent = "268 15"; minExtent = "8 2"; @@ -1312,6 +1374,66 @@ canSaveDynamicFields = "0"; }; }; + new GuiControl() { + position = "0 208"; + extent = "352 15"; + minExtent = "8 2"; + horizSizing = "width"; + vertSizing = "bottom"; + profile = "GuiDefaultProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "1"; + internalName = "GammaSliderContainer"; + canSave = "1"; + canSaveDynamicFields = "0"; + + new GuiSliderCtrl() { + range = "-0.5 0.5"; + ticks = "0"; + snap = "0"; + value = "0"; + position = "76 -1"; + extent = "268 15"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiSliderProfile"; + visible = "1"; + active = "1"; + variable = "$pref::Video::Brightness"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + new GuiTextCtrl() { + text = "Brightness:"; + maxLength = "255"; + margin = "0 0 0 0"; + padding = "0 0 0 0"; + anchorTop = "1"; + anchorBottom = "0"; + anchorLeft = "1"; + anchorRight = "0"; + position = "6 -3"; + extent = "105 18"; + minExtent = "8 2"; + horizSizing = "right"; + vertSizing = "bottom"; + profile = "GuiTextProfile"; + visible = "1"; + active = "1"; + tooltipProfile = "GuiToolTipProfile"; + hovertime = "1000"; + isContainer = "0"; + canSave = "1"; + canSaveDynamicFields = "0"; + }; + }; }; new GuiControl() { position = "9 55"; @@ -1396,7 +1518,7 @@ groupNum = "-1"; buttonType = "PushButton"; useMouseEvents = "0"; - position = "241 271"; + position = "239 319"; extent = "60 23"; minExtent = "8 8"; horizSizing = "right"; diff --git a/Templates/Full/game/core/main.cs b/Templates/Full/game/core/main.cs index 0baeb9364..f666c948c 100644 --- a/Templates/Full/game/core/main.cs +++ b/Templates/Full/game/core/main.cs @@ -141,11 +141,11 @@ function parseArgs() switch$ (%arg) { case "-fullscreen": - setFullScreen(true); + $cliFullscreen = true; $argUsed[%i]++; case "-windowed": - setFullScreen(false); + $cliFullscreen = false; $argUsed[%i]++; case "-openGL": diff --git a/Templates/Full/game/core/scripts/client/canvas.cs b/Templates/Full/game/core/scripts/client/canvas.cs index 69dd6da71..5c1d377c5 100644 --- a/Templates/Full/game/core/scripts/client/canvas.cs +++ b/Templates/Full/game/core/scripts/client/canvas.cs @@ -39,9 +39,14 @@ function configureCanvas() %rate = getWord($pref::Video::mode, $WORD::REFRESH); %fsaa = getWord($pref::Video::mode, $WORD::AA); - echo("--------------"); - echo("Attempting to set resolution to \"" @ $pref::Video::mode @ "\""); + if($cliFullscreen !$= "") { + %fs = $cliFullscreen; + $cliFullscreen = ""; + } + echo("--------------"); + echo("Attempting to set resolution to \"" @ %resX SPC %resY SPC %fs SPC %bpp SPC %rate SPC %fsaa @ "\""); + %deskRes = getDesktopResolution(); %deskResX = getWord(%deskRes, $WORD::RES_X); %deskResY = getWord(%deskRes, $WORD::RES_Y); diff --git a/Templates/Full/game/core/scripts/client/defaults.cs b/Templates/Full/game/core/scripts/client/defaults.cs index 0142a9410..d1805d337 100644 --- a/Templates/Full/game/core/scripts/client/defaults.cs +++ b/Templates/Full/game/core/scripts/client/defaults.cs @@ -73,7 +73,9 @@ $pref::Video::disableCubemapping = false; /// $pref::Video::disableParallaxMapping = false; -$pref::Video::Gamma = 1.0; +$pref::Video::Gamma = 2.2; +$pref::Video::Contrast = 1.0; +$pref::Video::Brightness = 0; // Console-friendly defaults if($platform $= "xenon") diff --git a/Templates/Full/game/core/scripts/client/postFx/GammaPostFX.cs b/Templates/Full/game/core/scripts/client/postFx/GammaPostFX.cs index 383a0c8cd..b88f31305 100644 --- a/Templates/Full/game/core/scripts/client/postFx/GammaPostFX.cs +++ b/Templates/Full/game/core/scripts/client/postFx/GammaPostFX.cs @@ -44,7 +44,7 @@ singleton GFXStateBlockData( GammaStateBlock : PFX_DefaultStateBlock ) singleton PostEffect( GammaPostFX ) { isEnabled = true; - allowReflectPass = false; + allowReflectPass = true; renderTime = "PFXBeforeBin"; renderBin = "EditorBin"; @@ -65,6 +65,8 @@ function GammaPostFX::preProcess( %this ) function GammaPostFX::setShaderConsts( %this ) { - %clampedGamma = mClamp( $pref::Video::Gamma, 0.001, 2.2); + %clampedGamma = mClamp( $pref::Video::Gamma, 2.0, 2.5); %this.setShaderConst( "$OneOverGamma", 1 / %clampedGamma ); + %this.setShaderConst( "$Brightness", $pref::Video::Brightness ); + %this.setShaderConst( "$Contrast", $pref::Video::Contrast ); } \ No newline at end of file diff --git a/Templates/Full/game/core/scripts/client/postFx/hdr.cs b/Templates/Full/game/core/scripts/client/postFx/hdr.cs index a5c450799..136a5ca95 100644 --- a/Templates/Full/game/core/scripts/client/postFx/hdr.cs +++ b/Templates/Full/game/core/scripts/client/postFx/hdr.cs @@ -253,8 +253,10 @@ function HDRPostFX::setShaderConsts( %this ) %combinePass.setShaderConst( "$g_fEnableBlueShift", $HDRPostFX::enableBlueShift ); %combinePass.setShaderConst( "$g_fBlueShiftColor", $HDRPostFX::blueShiftColor ); - %clampedGamma = mClamp( $pref::Video::Gamma, 0.001, 2.2); + %clampedGamma = mClamp( $pref::Video::Gamma, 2.0, 2.5); %combinePass.setShaderConst( "$g_fOneOverGamma", 1 / %clampedGamma ); + %combinePass.setShaderConst( "$Brightness", $pref::Video::Brightness ); + %combinePass.setShaderConst( "$Contrast", $pref::Video::Contrast ); %whiteCutoff = ( $HDRPostFX::whiteCutoff * $HDRPostFX::whiteCutoff ) * ( $HDRPostFX::whiteCutoff * $HDRPostFX::whiteCutoff ); @@ -329,7 +331,7 @@ function HDRPostFX::onDisabled( %this ) singleton PostEffect( HDRPostFX ) { isEnabled = false; - allowReflectPass = false; + allowReflectPass = true; // Resolve the HDR before we render any editor stuff // and before we resolve the scene to the backbuffer. @@ -355,6 +357,7 @@ singleton PostEffect( HDRPostFX ) new PostEffect() { + allowReflectPass = true; shader = HDR_DownScale4x4Shader; stateBlock = HDR_DownSampleStateBlock; texture[0] = "$inTex"; @@ -365,6 +368,7 @@ singleton PostEffect( HDRPostFX ) new PostEffect() { + allowReflectPass = true; internalName = "bloomH"; shader = HDR_BloomGaussBlurHShader; @@ -376,6 +380,7 @@ singleton PostEffect( HDRPostFX ) new PostEffect() { + allowReflectPass = true; internalName = "bloomV"; shader = HDR_BloomGaussBlurVShader; @@ -390,6 +395,7 @@ singleton PostEffect( HDRPostFX ) // Now calculate the adapted luminance. new PostEffect() { + allowReflectPass = true; internalName = "adaptLum"; shader = HDR_SampleLumShader; @@ -401,6 +407,7 @@ singleton PostEffect( HDRPostFX ) new PostEffect() { + allowReflectPass = true; shader = HDR_DownSampleLumShader; stateBlock = HDR_DownSampleStateBlock; texture[0] = "$inTex"; @@ -411,6 +418,7 @@ singleton PostEffect( HDRPostFX ) new PostEffect() { + allowReflectPass = true; shader = HDR_DownSampleLumShader; stateBlock = HDR_DownSampleStateBlock; texture[0] = "$inTex"; @@ -421,6 +429,7 @@ singleton PostEffect( HDRPostFX ) new PostEffect() { + allowReflectPass = true; shader = HDR_DownSampleLumShader; stateBlock = HDR_DownSampleStateBlock; texture[0] = "$inTex"; @@ -434,6 +443,7 @@ singleton PostEffect( HDRPostFX ) // one... PostEffect takes care to manage that. new PostEffect() { + allowReflectPass = true; internalName = "finalLum"; shader = HDR_CalcAdaptedLumShader; stateBlock = HDR_DownSampleStateBlock; @@ -450,6 +460,7 @@ singleton PostEffect( HDRPostFX ) // version of the scene. new PostEffect() { + allowReflectPass = true; internalName = "combinePass"; shader = HDR_CombineShader; diff --git a/Templates/Full/game/core/scripts/client/renderManager.cs b/Templates/Full/game/core/scripts/client/renderManager.cs index 5734bbce6..71200ad49 100644 --- a/Templates/Full/game/core/scripts/client/renderManager.cs +++ b/Templates/Full/game/core/scripts/client/renderManager.cs @@ -33,7 +33,7 @@ function initRenderManager() { enabled = "false"; - format = "GFXFormatR8G8B8A8"; + format = "GFXFormatR16G16B16A16F"; depthFormat = "GFXFormatD24S8"; aaLevel = 0; // -1 = match backbuffer @@ -49,20 +49,21 @@ function initRenderManager() // We really need to fix the sky to render after all the // meshes... but that causes issues in reflections. - DiffuseRenderPassManager.addManager( new RenderObjectMgr() { bintype = "Sky"; renderOrder = 0.1; processAddOrder = 0.1; } ); + DiffuseRenderPassManager.addManager( new RenderObjectMgr(SkyBin) { bintype = "Sky"; renderOrder = 0.1; processAddOrder = 0.1; } ); //DiffuseRenderPassManager.addManager( new RenderVistaMgr() { bintype = "Vista"; renderOrder = 0.15; processAddOrder = 0.15; } ); - DiffuseRenderPassManager.addManager( new RenderObjectMgr() { bintype = "Begin"; renderOrder = 0.2; processAddOrder = 0.2; } ); + DiffuseRenderPassManager.addManager( new RenderObjectMgr(BeginBin) { bintype = "Begin"; renderOrder = 0.2; processAddOrder = 0.2; } ); // Normal mesh rendering. - DiffuseRenderPassManager.addManager( new RenderTerrainMgr() { renderOrder = 0.4; processAddOrder = 0.4; } ); - DiffuseRenderPassManager.addManager( new RenderMeshMgr() { bintype = "Mesh"; renderOrder = 0.5; processAddOrder = 0.5; } ); - DiffuseRenderPassManager.addManager( new RenderImposterMgr() { renderOrder = 0.56; processAddOrder = 0.56; } ); - DiffuseRenderPassManager.addManager( new RenderObjectMgr() { bintype = "Object"; renderOrder = 0.6; processAddOrder = 0.6; } ); - - DiffuseRenderPassManager.addManager( new RenderObjectMgr() { bintype = "Shadow"; renderOrder = 0.7; processAddOrder = 0.7; } ); - DiffuseRenderPassManager.addManager( new RenderMeshMgr() { bintype = "Decal"; renderOrder = 0.8; processAddOrder = 0.8; } ); - DiffuseRenderPassManager.addManager( new RenderOcclusionMgr() { bintype = "Occluder"; renderOrder = 0.9; processAddOrder = 0.9; } ); + DiffuseRenderPassManager.addManager( new RenderTerrainMgr(TerrainBin) { renderOrder = 0.4; processAddOrder = 0.4; } ); + DiffuseRenderPassManager.addManager( new RenderMeshMgr(MeshBin) { bintype = "Mesh"; renderOrder = 0.5; processAddOrder = 0.5; } ); + DiffuseRenderPassManager.addManager( new RenderImposterMgr(ImposterBin) { renderOrder = 0.56; processAddOrder = 0.56; } ); + DiffuseRenderPassManager.addManager( new RenderObjectMgr(ObjectBin) { bintype = "Object"; renderOrder = 0.6; processAddOrder = 0.6; } ); + + DiffuseRenderPassManager.addManager( new RenderObjectMgr(ShadowBin) { bintype = "Shadow"; renderOrder = 0.7; processAddOrder = 0.7; } ); + DiffuseRenderPassManager.addManager( new RenderMeshMgr(DecalRoadBin) { bintype = "DecalRoad"; renderOrder = 0.8; processAddOrder = 0.8; } ); + DiffuseRenderPassManager.addManager( new RenderMeshMgr(DecalBin) { bintype = "Decal"; renderOrder = 0.81; processAddOrder = 0.81; } ); + DiffuseRenderPassManager.addManager( new RenderOcclusionMgr(OccluderBin){ bintype = "Occluder"; renderOrder = 0.9; processAddOrder = 0.9; } ); // We now render translucent objects that should handle // their own fogging and lighting. @@ -70,10 +71,10 @@ function initRenderManager() // Note that the fog effect is triggered before this bin. DiffuseRenderPassManager.addManager( new RenderObjectMgr(ObjTranslucentBin) { bintype = "ObjectTranslucent"; renderOrder = 1.0; processAddOrder = 1.0; } ); - DiffuseRenderPassManager.addManager( new RenderObjectMgr() { bintype = "Water"; renderOrder = 1.2; processAddOrder = 1.2; } ); - DiffuseRenderPassManager.addManager( new RenderObjectMgr() { bintype = "Foliage"; renderOrder = 1.3; processAddOrder = 1.3; } ); - DiffuseRenderPassManager.addManager( new RenderParticleMgr() { renderOrder = 1.35; processAddOrder = 1.35; } ); - DiffuseRenderPassManager.addManager( new RenderTranslucentMgr() { renderOrder = 1.4; processAddOrder = 1.4; } ); + DiffuseRenderPassManager.addManager( new RenderObjectMgr(WaterBin) { bintype = "Water"; renderOrder = 1.2; processAddOrder = 1.2; } ); + DiffuseRenderPassManager.addManager( new RenderObjectMgr(FoliageBin) { bintype = "Foliage"; renderOrder = 1.3; processAddOrder = 1.3; } ); + DiffuseRenderPassManager.addManager( new RenderParticleMgr(ParticleBin) { renderOrder = 1.35; processAddOrder = 1.35; } ); + DiffuseRenderPassManager.addManager( new RenderTranslucentMgr(TranslucentBin){ renderOrder = 1.4; processAddOrder = 1.4; } ); DiffuseRenderPassManager.addManager(new RenderObjectMgr(FogBin){ bintype = "ObjectVolumetricFog"; renderOrder = 1.45; processAddOrder = 1.45; } ); @@ -85,7 +86,7 @@ function initRenderManager() DiffuseRenderPassManager.addManager( new RenderObjectMgr(EditorBin) { bintype = "Editor"; renderOrder = 1.6; processAddOrder = 1.6; } ); // Resolve format change token last. - DiffuseRenderPassManager.addManager( new RenderPassStateBin() { renderOrder = 1.7; stateToken = AL_FormatToken; } ); + DiffuseRenderPassManager.addManager( new RenderPassStateBin(FinalBin) { renderOrder = 1.7; stateToken = AL_FormatToken; } ); } /// This post effect is used to copy data from the non-MSAA back-buffer to the diff --git a/Templates/Full/game/shaders/common/gl/torque.glsl b/Templates/Full/game/shaders/common/gl/torque.glsl index 9032a57f7..65580cb7b 100644 --- a/Templates/Full/game/shaders/common/gl/torque.glsl +++ b/Templates/Full/game/shaders/common/gl/torque.glsl @@ -284,4 +284,37 @@ void fizzle(vec2 vpos, float visibility) /// @note This macro will only work in the void main() method of a pixel shader. #define assert(condition, color) { if(!any(condition)) { OUT_col = color; return; } } +// Deferred Shading: Material Info Flag Check +bool getFlag(float flags, int num) +{ + float process = round(flags * 255); + float squareNum = pow(2, num); + return (mod(process, pow(2, squareNum)) >= squareNum); +} + +// #define TORQUE_STOCK_GAMMA +#ifdef TORQUE_STOCK_GAMMA +// Sample in linear space. Decodes gamma. +vec4 toLinear(vec4 tex) +{ + return tex; +} +// Encodes gamma. +vec4 toGamma(vec4 tex) +{ + return tex; +} +#else +// Sample in linear space. Decodes gamma. +vec4 toLinear(vec4 tex) +{ + return vec4(pow(abs(tex.rgb), vec3(2.2)), tex.a); +} +// Encodes gamma. +vec4 toGamma(vec4 tex) +{ + return vec4(pow(abs(tex.rgb), vec3(1.0/2.2)), tex.a); +} +#endif // + #endif // _TORQUE_GLSL_ diff --git a/Templates/Full/game/shaders/common/postFx/gammaP.hlsl b/Templates/Full/game/shaders/common/postFx/gammaP.hlsl index dedfe8eb5..20196548b 100644 --- a/Templates/Full/game/shaders/common/postFx/gammaP.hlsl +++ b/Templates/Full/game/shaders/common/postFx/gammaP.hlsl @@ -28,7 +28,8 @@ uniform sampler2D backBuffer : register(S0); uniform sampler1D colorCorrectionTex : register( s1 ); uniform float OneOverGamma; - +uniform float Brightness; +uniform float Contrast; float4 main( PFXVertToPix IN ) : COLOR0 { @@ -42,5 +43,11 @@ float4 main( PFXVertToPix IN ) : COLOR0 // Apply gamma correction color.rgb = pow( abs(color.rgb), OneOverGamma ); + // Apply contrast + color.rgb = ((color.rgb - 0.5f) * Contrast) + 0.5f; + + // Apply brightness + color.rgb += Brightness; + return color; } \ No newline at end of file diff --git a/Templates/Full/game/shaders/common/postFx/gl/gammaP.glsl b/Templates/Full/game/shaders/common/postFx/gl/gammaP.glsl index 414a277d3..1bf5d1b8f 100644 --- a/Templates/Full/game/shaders/common/postFx/gl/gammaP.glsl +++ b/Templates/Full/game/shaders/common/postFx/gl/gammaP.glsl @@ -28,6 +28,8 @@ uniform sampler2D backBuffer; uniform sampler1D colorCorrectionTex; uniform float OneOverGamma; +uniform float Brightness; +uniform float Contrast; in vec2 uv0; @@ -45,5 +47,11 @@ void main() // Apply gamma correction color.rgb = pow( abs(color.rgb), vec3(OneOverGamma) ); + // Apply contrast + color.rgb = ((color.rgb - 0.5f) * Contrast) + 0.5f; + + // Apply brightness + color.rgb += Brightness; + OUT_col = color; } \ No newline at end of file diff --git a/Templates/Full/game/shaders/common/postFx/hdr/finalPassCombineP.hlsl b/Templates/Full/game/shaders/common/postFx/hdr/finalPassCombineP.hlsl index 7ac71bebd..9541f39cb 100644 --- a/Templates/Full/game/shaders/common/postFx/hdr/finalPassCombineP.hlsl +++ b/Templates/Full/game/shaders/common/postFx/hdr/finalPassCombineP.hlsl @@ -41,6 +41,8 @@ uniform float3 g_fBlueShiftColor; uniform float g_fBloomScale; uniform float g_fOneOverGamma; +uniform float Brightness; +uniform float Contrast; float4 main( PFXVertToPix IN ) : COLOR0 @@ -90,6 +92,12 @@ float4 main( PFXVertToPix IN ) : COLOR0 // Apply gamma correction sample.rgb = pow( abs(sample.rgb), g_fOneOverGamma ); + + // Apply contrast + sample.rgb = ((sample.rgb - 0.5f) * Contrast) + 0.5f; + + // Apply brightness + sample.rgb += Brightness; return sample; } diff --git a/Templates/Full/game/shaders/common/postFx/hdr/gl/finalPassCombineP.glsl b/Templates/Full/game/shaders/common/postFx/hdr/gl/finalPassCombineP.glsl index 38762baa5..123c831f3 100644 --- a/Templates/Full/game/shaders/common/postFx/hdr/gl/finalPassCombineP.glsl +++ b/Templates/Full/game/shaders/common/postFx/hdr/gl/finalPassCombineP.glsl @@ -42,6 +42,8 @@ uniform vec3 g_fBlueShiftColor; uniform float g_fBloomScale; uniform float g_fOneOverGamma; +uniform float Brightness; +uniform float Contrast; out vec4 OUT_col; @@ -93,6 +95,12 @@ void main() // Apply gamma correction _sample.rgb = pow( abs(_sample.rgb), vec3(g_fOneOverGamma) ); + + // Apply contrast + _sample.rgb = ((_sample.rgb - 0.5f) * Contrast) + 0.5f; + + // Apply brightness + _sample.rgb += Brightness; OUT_col = _sample; } diff --git a/Templates/Full/game/shaders/common/torque.hlsl b/Templates/Full/game/shaders/common/torque.hlsl index 1d253936b..f50832cb8 100644 --- a/Templates/Full/game/shaders/common/torque.hlsl +++ b/Templates/Full/game/shaders/common/torque.hlsl @@ -277,5 +277,37 @@ void fizzle(float2 vpos, float visibility) clip( visibility - frac( determinant( m ) ) ); } +// Deferred Shading: Material Info Flag Check +bool getFlag(float flags, int num) +{ + int process = round(flags * 255); + int squareNum = pow(2, num); + return (fmod(process, pow(2, squareNum)) >= squareNum); +} + +// #define TORQUE_STOCK_GAMMA +#ifdef TORQUE_STOCK_GAMMA +// Sample in linear space. Decodes gamma. +float4 toLinear(float4 tex) +{ + return tex; +} +// Encodes gamma. +float4 toLinear(float4 tex) +{ + return tex; +} +#else +// Sample in linear space. Decodes gamma. +float4 toLinear(float4 tex) +{ + return float4(pow(abs(tex.rgb), 2.2), tex.a); +} +// Encodes gamma. +float4 toGamma(float4 tex) +{ + return float4(pow(abs(tex.rgb), 1.0/2.2), tex.a); +} +#endif // #endif // _TORQUE_HLSL_ diff --git a/Templates/Full/game/shaders/common/water/gl/waterBasicP.glsl b/Templates/Full/game/shaders/common/water/gl/waterBasicP.glsl index 82c421031..1d5a07c3f 100644 --- a/Templates/Full/game/shaders/common/water/gl/waterBasicP.glsl +++ b/Templates/Full/game/shaders/common/water/gl/waterBasicP.glsl @@ -120,6 +120,7 @@ void main() { // Modulate baseColor by the ambientColor. vec4 waterBaseColor = baseColor * vec4( ambientColor.rgb, 1 ); + waterBaseColor = toLinear(waterBaseColor); // Get the bumpNorm... vec3 bumpNorm = ( texture( bumpMap, IN_rippleTexCoord01.xy ).rgb * 2.0 - 1.0 ) * rippleMagnitude.x; diff --git a/Templates/Full/game/shaders/common/water/gl/waterP.glsl b/Templates/Full/game/shaders/common/water/gl/waterP.glsl index af151020a..15002849f 100644 --- a/Templates/Full/game/shaders/common/water/gl/waterP.glsl +++ b/Templates/Full/game/shaders/common/water/gl/waterP.glsl @@ -324,6 +324,7 @@ void main() // Calculate the water "base" color based on depth. vec4 waterBaseColor = baseColor * texture( depthGradMap, saturate( delta / depthGradMax ) ); + waterBaseColor = toLinear(waterBaseColor); // Modulate baseColor by the ambientColor. waterBaseColor *= vec4( ambientColor.rgb, 1 ); diff --git a/Templates/Full/game/shaders/common/water/waterBasicP.hlsl b/Templates/Full/game/shaders/common/water/waterBasicP.hlsl index d27b28c67..7ae933f6f 100644 --- a/Templates/Full/game/shaders/common/water/waterBasicP.hlsl +++ b/Templates/Full/game/shaders/common/water/waterBasicP.hlsl @@ -117,6 +117,7 @@ float4 main( ConnectData IN ) : COLOR { // Modulate baseColor by the ambientColor. float4 waterBaseColor = baseColor * float4( ambientColor.rgb, 1 ); + waterBaseColor = toLinear(waterBaseColor); // Get the bumpNorm... float3 bumpNorm = ( tex2D( bumpMap, IN.rippleTexCoord01.xy ).rgb * 2.0 - 1.0 ) * rippleMagnitude.x; diff --git a/Templates/Full/game/shaders/common/water/waterP.hlsl b/Templates/Full/game/shaders/common/water/waterP.hlsl index 851fb471f..2b4035755 100644 --- a/Templates/Full/game/shaders/common/water/waterP.hlsl +++ b/Templates/Full/game/shaders/common/water/waterP.hlsl @@ -311,6 +311,7 @@ float4 main( ConnectData IN ) : COLOR // Calculate the water "base" color based on depth. float4 waterBaseColor = baseColor * tex1D( depthGradMap, saturate( delta / depthGradMax ) ); + waterBaseColor = toLinear(waterBaseColor); // Modulate baseColor by the ambientColor. waterBaseColor *= float4( ambientColor.rgb, 1 );