Kaynağa Gözat

Merge branch 'ColorPickerAdvanced' of https://github.com/Azaezel/Torque3D into ColorPickerAdvanced

Anis A. Hireche 9 yıl önce
ebeveyn
işleme
e7bee6585d
83 değiştirilmiş dosya ile 1736 ekleme ve 690 silme
  1. 1 1
      Engine/source/T3D/assets/ShapeAsset.h
  2. 3 3
      Engine/source/T3D/player.cpp
  3. 60 0
      Engine/source/T3D/tsStatic.cpp
  4. 9 0
      Engine/source/T3D/tsStatic.h
  5. 520 46
      Engine/source/console/consoleFunctions.cpp
  6. 5 5
      Engine/source/core/color.h
  7. 1 1
      Engine/source/core/stream/stream.cpp
  8. 1 1
      Engine/source/gfx/bitmap/gBitmap.cpp
  9. 1 1
      Engine/source/gfx/gfxDevice.cpp
  10. 1 1
      Engine/source/gfx/gfxTextureManager.cpp
  11. 6 1
      Engine/source/gfx/gl/gfxGLCircularVolatileBuffer.h
  12. 4 1
      Engine/source/gfx/gl/gfxGLTextureTarget.cpp
  13. 8 0
      Engine/source/gfx/gl/gfxGLWindowTarget.cpp
  14. 3 1
      Engine/source/gfx/gl/gfxGLWindowTarget.h
  15. 4 0
      Engine/source/gfx/gl/sdl/gfxGLDevice.sdl.cpp
  16. 1 0
      Engine/source/gfx/gl/tGL/tGL.cpp
  17. 6 0
      Engine/source/gfx/gl/tGL/tGL.h
  18. 108 2
      Engine/source/gfx/sim/debugDraw.cpp
  19. 10 2
      Engine/source/gfx/sim/debugDraw.h
  20. 256 280
      Engine/source/gui/controls/guiColorPicker.cpp
  21. 18 19
      Engine/source/gui/controls/guiColorPicker.h
  22. 17 17
      Engine/source/gui/controls/guiTextEditCtrl.cpp
  23. 66 0
      Engine/source/gui/core/guiControl.cpp
  24. 6 0
      Engine/source/gui/core/guiControl.h
  25. 3 0
      Engine/source/gui/core/guiTypes.cpp
  26. 1 0
      Engine/source/gui/core/guiTypes.h
  27. 5 9
      Engine/source/lighting/advanced/advancedLightBinManager.cpp
  28. 1 1
      Engine/source/lighting/advanced/advancedLightManager.cpp
  29. 7 24
      Engine/source/lighting/shadowMap/lightShadowMap.cpp
  30. 6 16
      Engine/source/lighting/shadowMap/lightShadowMap.h
  31. 7 7
      Engine/source/lighting/shadowMap/shadowMapPass.cpp
  32. 1 0
      Engine/source/materials/materialFeatureTypes.cpp
  33. 1 0
      Engine/source/materials/materialFeatureTypes.h
  34. 9 9
      Engine/source/math/mConsoleFunctions.cpp
  35. 2 2
      Engine/source/math/mQuat.h
  36. 1 1
      Engine/source/math/mathUtils.cpp
  37. 38 6
      Engine/source/navigation/navMesh.cpp
  38. 3 3
      Engine/source/persistence/taml/fsTinyXml.cpp
  39. 2 2
      Engine/source/persistence/taml/fsTinyXml.h
  40. 2 2
      Engine/source/persistence/taml/xml/tamlXmlParser.h
  41. 1 1
      Engine/source/persistence/taml/xml/tamlXmlReader.cpp
  42. 1 1
      Engine/source/persistence/taml/xml/tamlXmlWriter.cpp
  43. 5 0
      Engine/source/platformMac/macCarbFileio.mm
  44. 1 3
      Engine/source/platformSDL/sdlPlatformGL.cpp
  45. 6 1
      Engine/source/platformX86UNIX/x86UNIXFileio.cpp
  46. 1 1
      Engine/source/sfx/fmod/sfxFMODDevice.h
  47. 2 0
      Engine/source/shaderGen/GLSL/accuFeatureGLSL.cpp
  48. 25 18
      Engine/source/shaderGen/GLSL/shaderFeatureGLSL.cpp
  49. 5 0
      Engine/source/shaderGen/GLSL/shaderFeatureGLSL.h
  50. 1 0
      Engine/source/shaderGen/GLSL/shaderGenGLSLInit.cpp
  51. 2 0
      Engine/source/shaderGen/HLSL/accuFeatureHLSL.cpp
  52. 23 19
      Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp
  53. 5 0
      Engine/source/shaderGen/HLSL/shaderFeatureHLSL.h
  54. 1 0
      Engine/source/shaderGen/HLSL/shaderGenHLSLInit.cpp
  55. 1 1
      Engine/source/shaderGen/featureSet.cpp
  56. 1 1
      Engine/source/shaderGen/featureSet.h
  57. 1 1
      Engine/source/shaderGen/shaderFeature.h
  58. 12 5
      Engine/source/terrain/glsl/terrFeatureGLSL.cpp
  59. 3 0
      Engine/source/terrain/glsl/terrFeatureGLSL.h
  60. 12 5
      Engine/source/terrain/hlsl/terrFeatureHLSL.cpp
  61. 4 0
      Engine/source/terrain/hlsl/terrFeatureHLSL.h
  62. 1 0
      Engine/source/util/imposterCapture.cpp
  63. 81 92
      Engine/source/windowManager/win32/win32Window.cpp
  64. 2 2
      Templates/Empty/game/core/main.cs
  65. 7 2
      Templates/Empty/game/core/scripts/client/canvas.cs
  66. 12 0
      Templates/Full/game/art/datablocks/environment.cs
  67. 169 47
      Templates/Full/game/art/gui/optionsDlg.gui
  68. 2 2
      Templates/Full/game/core/main.cs
  69. 7 2
      Templates/Full/game/core/scripts/client/canvas.cs
  70. 3 1
      Templates/Full/game/core/scripts/client/defaults.cs
  71. 4 2
      Templates/Full/game/core/scripts/client/postFx/GammaPostFX.cs
  72. 13 2
      Templates/Full/game/core/scripts/client/postFx/hdr.cs
  73. 17 16
      Templates/Full/game/core/scripts/client/renderManager.cs
  74. 33 0
      Templates/Full/game/shaders/common/gl/torque.glsl
  75. 8 1
      Templates/Full/game/shaders/common/postFx/gammaP.hlsl
  76. 8 0
      Templates/Full/game/shaders/common/postFx/gl/gammaP.glsl
  77. 8 0
      Templates/Full/game/shaders/common/postFx/hdr/finalPassCombineP.hlsl
  78. 8 0
      Templates/Full/game/shaders/common/postFx/hdr/gl/finalPassCombineP.glsl
  79. 32 0
      Templates/Full/game/shaders/common/torque.hlsl
  80. 1 0
      Templates/Full/game/shaders/common/water/gl/waterBasicP.glsl
  81. 1 0
      Templates/Full/game/shaders/common/water/gl/waterP.glsl
  82. 1 0
      Templates/Full/game/shaders/common/water/waterBasicP.hlsl
  83. 1 0
      Templates/Full/game/shaders/common/water/waterP.hlsl

+ 1 - 1
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"

+ 3 - 3
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;

+ 60 - 0
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<OccluderRenderInst>();  
+       
+       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();
 }

+ 9 - 0
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;

+ 520 - 46
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;
+}
+
+//----------------------------------------------------------------
+
+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" )
 {
-	ColorI color;
-	color.set(ColorI::Hsb(hsb.x, hsb.y, hsb.z));
-	return color;
+   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;
+}

+ 5 - 5
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:

+ 1 - 1
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.");

+ 1 - 1
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");
 

+ 1 - 1
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;

+ 1 - 1
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 );
       }
    }
 }

+ 6 - 1
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
+#endif

+ 4 - 1
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()

+ 8 - 0
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())

+ 3 - 1
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
+#endif

+ 4 - 0
Engine/source/gfx/gl/sdl/gfxGLDevice.sdl.cpp

@@ -83,6 +83,10 @@ void GFXGLDevice::enumerateAdapters( Vector<GFXAdapter*> &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 )
    {

+ 1 - 0
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)) );
    }

+ 6 - 0
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
 

+ 108 - 2
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)

+ 10 - 2
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<GFont> mFont;
 

+ 256 - 280
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; 
-
-	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) 
+   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) 
             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);
-	}
-
-	RectI boundsRect(offset, getExtent());
-	renderColorBox(boundsRect);
-
-	if (mPositionChanged || mBitmap == NULL)
-	{
-		bool nullBitmap = false;
-
-		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();
-
-			U32 buf_x = offset.x + mSelectorPos.x + 1;
-			U32 buf_y = resolution.y - (extent.y - (offset.y + mSelectorPos.y + 1));
-
-			GFXTexHandle bb(resolution.x,
-				resolution.y,
-				GFXFormatR8G8B8A8, &GFXDefaultRenderTargetProfile, avar("%s() - bb (line %d)", __FUNCTION__, __LINE__));
-
-			Point2I tmpPt(buf_x, buf_y);
-
-			GFXTarget *targ = GFX->getActiveRenderTarget();
-			targ->resolveTo(bb);
-
-			if (mBitmap)
-			{
-				delete mBitmap;
-				mBitmap = NULL;
-			}
-
-			mBitmap = new GBitmap(bb.getWidth(), bb.getHeight());
-
-			bb.copyToBmp(mBitmap);
-
-			//bmp.writePNGDebug( "foo.png" );
-
-			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);
-
-					mPickColor = (ColorF)tmp;
-
-					// Now do onAction() if we are allowed
-					if (mActionOnMove)
-						onAction();
-				}
-			}
-		}
-
-	}
-
-	//render the children
-	renderChildControls(offset, updateRect);
+   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);
+
+   if (mPositionChanged || mBitmap == NULL)
+   {
+      bool nullBitmap = false;
+
+      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();
+
+         U32 buf_x = offset.x + mSelectorPos.x + 1;
+         U32 buf_y = resolution.y - (extent.y - (offset.y + mSelectorPos.y + 1));
+
+         GFXTexHandle bb( resolution.x, resolution.y, GFXFormatR8G8B8A8, &GFXDefaultRenderTargetProfile, avar("%s() - bb (line %d)", __FUNCTION__, __LINE__) );
+
+         Point2I tmpPt(buf_x, buf_y);
+
+         GFXTarget *targ = GFX->getActiveRenderTarget();
+         targ->resolveTo(bb);
+
+         if (mBitmap)
+         {
+            delete mBitmap;
+            mBitmap = NULL;
+         }
+
+         mBitmap = new GBitmap(bb.getWidth(), bb.getHeight());
+
+         bb.copyToBmp(mBitmap);
+
+         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);
+
+               mPickColor = (ColorF)tmp;
+
+               // Now do onAction() if we are allowed
+               if (mActionOnMove)
+                  onAction();
+            }
+         }
+      }
+   }
+
+   //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;
-
-		setSelectorPos(pos);
-	}
-	else
-	{
-		mSetColor = color;
-		mSelectColor = true;
-		mPositionChanged = true;
-	}
+   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;
+   }
 }
 
 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);
-	}
-
-	Point2I closestPos(-1, -1);
-
-	/* 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 );
-
-	fs.close();
-	}
-	*/
-
-	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;
-
-			//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);
-
-			if (!closestSet)
-			{
-				closestVal = val;
-				closestPos.set(x, y);
-				closestSet = true;
-			}
-			else if (val < closestVal)
-			{
-				closestVal = val;
-				closestPos.set(x, y);
-			}
-		}
-	}
-
-	return closestPos;
+   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);
+
+   /* 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 );
+
+   fs.close();
+   }
+   */
+
+   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));
+         buf_y = resolution.y - buf_y;
+
+         //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);
+
+         if (!closestSet)
+         {
+            closestVal = val;
+            closestPos.set(x, y);
+            closestSet = true;
+         }
+         else if (val < closestVal)
+         {
+            closestVal = val;
+            closestPos.set(x, y);
+         }
+      }
+   }
+
+   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);
-}
+   object->setSelectorPos(color);
+}

+ 18 - 19
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 &);

+ 17 - 17
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()

+ 66 - 0
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.

+ 6 - 0
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
       };
       

+ 3 - 0
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)." );

+ 1 - 0
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

+ 5 - 9
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<ShadowMapParams>();
+
       // 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)

+ 1 - 1
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<GFXFormat> formats;
    formats.push_back( GFXFormatR16G16B16A16F );
-   formats.push_back( GFXFormatR16G16B16A16 );
+   //formats.push_back( GFXFormatR16G16B16A16 );
    GFXFormat blendTargetFormat = GFX->selectSupportedFormat( &GFXDefaultRenderTargetProfile,
                                                          formats,
                                                          true,

+ 7 - 24
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 );
 }

+ 6 - 16
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;
 

+ 7 - 7
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);
-}
+}

+ 1 - 0
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 );
 

+ 1 - 0
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 );

+ 9 - 9
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 ),,

+ 2 - 2
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_

+ 1 - 1
Engine/source/math/mathUtils.cpp

@@ -1847,7 +1847,7 @@ U32 extrudePolygonEdgesFromPoint( const Point3F* vertices, U32 numVertices, cons
 
 //-----------------------------------------------------------------------------
 
-void MathUtils::mBuildHull2D(const Vector<Point2F> _inPoints, Vector<Point2F> &hullPoints)
+void mBuildHull2D(const Vector<Point2F> _inPoints, Vector<Point2F> &hullPoints)
 {
    /// Andrew's monotone chain convex hull algorithm implementation
 

+ 38 - 6
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<NavMesh*>(set->at(i));
-      m->buildTiles(obj->getWorldBox());
+      NavMesh *m = dynamic_cast<NavMesh*>(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<NavMesh*>(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;

+ 3 - 3
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;
 }
-*/
+*/

+ 2 - 2
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_
+#endif //_FSTINYXML_H_

+ 2 - 2
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_
+#endif // _TAML_XMLPARSER_H_

+ 1 - 1
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"
 
 //-----------------------------------------------------------------------------
 

+ 1 - 1
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"
 
 //-----------------------------------------------------------------------------
 

+ 5 - 0
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<StringTableEntry> &directoryVector, S32 depth, bool noBasePath)
 {

+ 1 - 3
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();

+ 6 - 1
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<StringTableEntry> &directoryVector, S32 currentDepth, S32 recurseDepth, bool noBasePath)
  {
    char Path[1024];

+ 1 - 1
Engine/source/sfx/fmod/sfxFMODDevice.h

@@ -105,8 +105,8 @@ struct FModFNTable
    }
    ~FModFNTable()
    {
-      eventDllRef = NULL;
       dllRef = NULL;
+      eventDllRef = NULL;      
       delete mutex;
    }
 

+ 2 - 0
Engine/source/shaderGen/GLSL/accuFeatureGLSL.cpp

@@ -144,6 +144,8 @@ void AccuTexFeatGLSL::processPix(Vector<ShaderComponent*> &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 ) );

+ 25 - 18
Engine/source/shaderGen/GLSL/shaderFeatureGLSL.cpp

@@ -828,6 +828,12 @@ Var* ShaderFeatureGLSL::addOutDetailTexCoord(   Vector<ShaderComponent*> &compon
 // Base Texture
 //****************************************************************************
 
+DiffuseMapFeatGLSL::DiffuseMapFeatGLSL()
+: mTorqueDep("shaders/common/gl/torque.glsl")
+{
+	addDependency(&mTorqueDep);
+}
+
 void DiffuseMapFeatGLSL::processVert( Vector<ShaderComponent*> &componentList, 
                                        const MaterialFeatureData &fd )
 {
@@ -855,20 +861,23 @@ void DiffuseMapFeatGLSL::processPix(   Vector<ShaderComponent*> &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<ShaderComponent*> &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<ShaderComponent*> &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<ShaderComponent*> &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 )

+ 5 - 0
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<ShaderComponent*> &componentList,
                              const MaterialFeatureData &fd );
 

+ 1 - 0
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 );
 	

+ 2 - 0
Engine/source/shaderGen/HLSL/accuFeatureHLSL.cpp

@@ -141,6 +141,8 @@ void AccuTexFeatHLSL::processPix(   Vector<ShaderComponent*> &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 ) );

+ 23 - 19
Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp

@@ -826,6 +826,12 @@ Var* ShaderFeatureHLSL::addOutDetailTexCoord(   Vector<ShaderComponent*> &compon
 // Base Texture
 //****************************************************************************
 
+DiffuseMapFeatHLSL::DiffuseMapFeatHLSL()
+: mTorqueDep("shaders/common/torque.hlsl")
+{
+	addDependency(&mTorqueDep);
+}
+
 void DiffuseMapFeatHLSL::processVert( Vector<ShaderComponent*> &componentList, 
                                        const MaterialFeatureData &fd )
 {
@@ -853,30 +859,30 @@ void DiffuseMapFeatHLSL::processPix(   Vector<ShaderComponent*> &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<ShaderComponent*> &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<ShaderComponent*> &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 )

+ 5 - 0
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<ShaderComponent*> &componentList,
                              const MaterialFeatureData &fd );
 

+ 1 - 0
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" ) );

+ 1 - 1
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++ )
    {

+ 1 - 1
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 );

+ 1 - 1
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

+ 12 - 5
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<ShaderComponent*> &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<ShaderComponent*> &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<ShaderComponent*> &component
 void TerrainDetailMapFeatGLSL::processPix(   Vector<ShaderComponent*> &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<ShaderComponent*> &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<ShaderComponent*> &componentL
 void TerrainMacroMapFeatGLSL::processPix(   Vector<ShaderComponent*> &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<ShaderComponent*> &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!" );

+ 3 - 0
Engine/source/terrain/glsl/terrFeatureGLSL.h

@@ -36,7 +36,10 @@
 class TerrainFeatGLSL : public ShaderFeatureGLSL
 {
 protected:
+   ShaderIncludeDependency mTorqueDep;
    
+public:
+   TerrainFeatGLSL();
    Var* _getInDetailCoord(Vector<ShaderComponent*> &componentList );
    
    Var* _getInMacroCoord(Vector<ShaderComponent*> &componentList );

+ 12 - 5
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<ShaderComponent*> &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<ShaderComponent*> &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<ShaderComponent*> &component
 void TerrainDetailMapFeatHLSL::processPix(   Vector<ShaderComponent*> &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<ShaderComponent*> &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<ShaderComponent*> &componentL
 void TerrainMacroMapFeatHLSL::processPix(   Vector<ShaderComponent*> &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<ShaderComponent*> &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!" );

+ 4 - 0
Engine/source/terrain/hlsl/terrFeatureHLSL.h

@@ -37,6 +37,10 @@ class TerrainFeatHLSL : public ShaderFeatureHLSL
 {
 protected:
 
+   ShaderIncludeDependency mTorqueDep;
+
+public:
+   TerrainFeatHLSL();
    Var* _getInDetailCoord(Vector<ShaderComponent*> &componentList );
 
    Var* _getInMacroCoord(Vector<ShaderComponent*> &componentList );

+ 1 - 0
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 )

+ 81 - 92
Engine/source/windowManager/win32/win32Window.cpp

@@ -26,8 +26,10 @@
 #include <tchar.h>
 #include <winuser.h>
 #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 <d3d9types.h>
-#include "gfx/gfxDevice.h"
-
-#include <zmouse.h>
-
 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<HWND>( 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) };
-
-	  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);
+      WINDOWPLACEMENT wplacement = { sizeof( wplacement ) };
+      DWORD dwStyle = GetWindowLong( getHWND(), GWL_STYLE );
+      MONITORINFO mi = { sizeof(mi) };
 
-      // 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<HWND>( 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;
+   }
 
-	if(needCurtain)
-		mOwningManager->raiseCurtain();
+   mSuppressReset = false;
 
-	SetForegroundWindow(getHWND());
+   if( needCurtain )
+      mOwningManager->raiseCurtain();
 
-   getScreenResChangeSignal().trigger(this, true);
+   SetForegroundWindow( getHWND() );
+   getScreenResChangeSignal().trigger( this, true );
 }
 
 bool Win32Window::clearFullscreen()

+ 2 - 2
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":

+ 7 - 2
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);

+ 12 - 0
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;
+};

+ 169 - 47
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";
@@ -1253,7 +1255,7 @@
             canSaveDynamicFields = "0";
          };
          new GuiControl() {
-            position = "0 190";
+            position = "0 227";
             extent = "352 15";
             minExtent = "8 2";
             horizSizing = "width";
@@ -1269,7 +1271,7 @@
             canSaveDynamicFields = "0";
 
             new GuiSliderCtrl() {
-               range = "0.001 2.2";
+               range = "0.5 1.5";
                ticks = "0";
                snap = "0";
                value = "1";
@@ -1281,6 +1283,66 @@
                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";
+            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 = "2.0 2.5";
+               ticks = "0";
+               snap = "0";
+               value = "2.2";
+               position = "76 -1";
+               extent = "268 15";
+               minExtent = "8 2";
+               horizSizing = "right";
+               vertSizing = "bottom";
+               profile = "GuiSliderProfile";
+               visible = "1";
+               active = "1";
                variable = "$pref::Video::Gamma";
                tooltipProfile = "GuiToolTipProfile";
                hovertime = "1000";
@@ -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";

+ 2 - 2
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":

+ 7 - 2
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);

+ 3 - 1
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")

+ 4 - 2
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 );
 }

+ 13 - 2
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;

+ 17 - 16
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

+ 33 - 0
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_

+ 8 - 1
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;    
 }

+ 8 - 0
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;
 }

+ 8 - 0
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;
 }

+ 8 - 0
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;
 }

+ 32 - 0
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_

+ 1 - 0
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;

+ 1 - 0
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 );     

+ 1 - 0
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;

+ 1 - 0
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 );