Browse Source

Merge branch 'development' into navMess2

Conflicts:
	Engine/source/navigation/navMesh.cpp
Azaezel 9 years ago
parent
commit
554a871df9
100 changed files with 3406 additions and 319 deletions
  1. 1 1
      Engine/source/T3D/assets/ShapeAsset.h
  2. 1 0
      Engine/source/T3D/decal/decalData.cpp
  3. 3 3
      Engine/source/T3D/player.cpp
  4. 60 0
      Engine/source/T3D/tsStatic.cpp
  5. 9 0
      Engine/source/T3D/tsStatic.h
  6. 53 57
      Engine/source/console/consoleObject.h
  7. 1 0
      Engine/source/core/color.h
  8. 1 1
      Engine/source/core/stream/stream.cpp
  9. 1319 0
      Engine/source/environment/VolumetricFog.cpp
  10. 243 0
      Engine/source/environment/VolumetricFog.h
  11. 299 0
      Engine/source/environment/VolumetricFogRTManager.cpp
  12. 92 0
      Engine/source/environment/VolumetricFogRTManager.h
  13. 1 1
      Engine/source/gfx/bitmap/gBitmap.cpp
  14. 1 1
      Engine/source/gfx/gfxDevice.cpp
  15. 4 4
      Engine/source/gfx/gfxDrawUtil.cpp
  16. 1 1
      Engine/source/gfx/gfxTextureManager.cpp
  17. 6 1
      Engine/source/gfx/gl/gfxGLCircularVolatileBuffer.h
  18. 4 1
      Engine/source/gfx/gl/gfxGLTextureTarget.cpp
  19. 8 0
      Engine/source/gfx/gl/gfxGLWindowTarget.cpp
  20. 3 1
      Engine/source/gfx/gl/gfxGLWindowTarget.h
  21. 4 0
      Engine/source/gfx/gl/sdl/gfxGLDevice.sdl.cpp
  22. 1 0
      Engine/source/gfx/gl/tGL/tGL.cpp
  23. 6 0
      Engine/source/gfx/gl/tGL/tGL.h
  24. 108 2
      Engine/source/gfx/sim/debugDraw.cpp
  25. 10 2
      Engine/source/gfx/sim/debugDraw.h
  26. 3 0
      Engine/source/gui/core/guiCanvas.cpp
  27. 10 0
      Engine/source/gui/core/guiCanvas.h
  28. 66 0
      Engine/source/gui/core/guiControl.cpp
  29. 6 0
      Engine/source/gui/core/guiControl.h
  30. 2 2
      Engine/source/gui/worldEditor/worldEditor.cpp
  31. 5 9
      Engine/source/lighting/advanced/advancedLightBinManager.cpp
  32. 1 1
      Engine/source/lighting/advanced/advancedLightManager.cpp
  33. 7 24
      Engine/source/lighting/shadowMap/lightShadowMap.cpp
  34. 6 16
      Engine/source/lighting/shadowMap/lightShadowMap.h
  35. 7 7
      Engine/source/lighting/shadowMap/shadowMapPass.cpp
  36. 1 0
      Engine/source/materials/materialFeatureTypes.cpp
  37. 1 0
      Engine/source/materials/materialFeatureTypes.h
  38. 2 0
      Engine/source/math/mPoint2.h
  39. 2 2
      Engine/source/math/mQuat.h
  40. 1 1
      Engine/source/math/mathUtils.cpp
  41. 7 7
      Engine/source/navigation/navMesh.cpp
  42. 1 1
      Engine/source/navigation/navMesh.h
  43. 3 3
      Engine/source/persistence/taml/fsTinyXml.cpp
  44. 2 2
      Engine/source/persistence/taml/fsTinyXml.h
  45. 2 2
      Engine/source/persistence/taml/xml/tamlXmlParser.h
  46. 1 1
      Engine/source/persistence/taml/xml/tamlXmlReader.cpp
  47. 1 1
      Engine/source/persistence/taml/xml/tamlXmlWriter.cpp
  48. 5 0
      Engine/source/platformMac/macCarbFileio.mm
  49. 1 3
      Engine/source/platformSDL/sdlPlatformGL.cpp
  50. 17 6
      Engine/source/platformWin32/winFileio.cpp
  51. 6 1
      Engine/source/platformX86UNIX/x86UNIXFileio.cpp
  52. 1 0
      Engine/source/renderInstance/renderPassManager.cpp
  53. 1 0
      Engine/source/renderInstance/renderPassManager.h
  54. 1 2
      Engine/source/renderInstance/renderTexTargetBinManager.cpp
  55. 10 0
      Engine/source/renderInstance/renderTranslucentMgr.cpp
  56. 1 1
      Engine/source/sfx/fmod/sfxFMODDevice.h
  57. 2 0
      Engine/source/shaderGen/GLSL/accuFeatureGLSL.cpp
  58. 25 18
      Engine/source/shaderGen/GLSL/shaderFeatureGLSL.cpp
  59. 5 0
      Engine/source/shaderGen/GLSL/shaderFeatureGLSL.h
  60. 1 0
      Engine/source/shaderGen/GLSL/shaderGenGLSLInit.cpp
  61. 2 0
      Engine/source/shaderGen/HLSL/accuFeatureHLSL.cpp
  62. 23 19
      Engine/source/shaderGen/HLSL/shaderFeatureHLSL.cpp
  63. 5 0
      Engine/source/shaderGen/HLSL/shaderFeatureHLSL.h
  64. 1 0
      Engine/source/shaderGen/HLSL/shaderGenHLSLInit.cpp
  65. 1 1
      Engine/source/shaderGen/featureSet.cpp
  66. 1 1
      Engine/source/shaderGen/featureSet.h
  67. 1 1
      Engine/source/shaderGen/shaderFeature.h
  68. 12 5
      Engine/source/terrain/glsl/terrFeatureGLSL.cpp
  69. 3 0
      Engine/source/terrain/glsl/terrFeatureGLSL.h
  70. 12 5
      Engine/source/terrain/hlsl/terrFeatureHLSL.cpp
  71. 4 0
      Engine/source/terrain/hlsl/terrFeatureHLSL.h
  72. 1 1
      Engine/source/ts/collada/colladaAppMesh.h
  73. 1 1
      Engine/source/ts/collada/colladaAppNode.h
  74. 1 1
      Engine/source/ts/tsShapeInstance.cpp
  75. 1 0
      Engine/source/util/imposterCapture.cpp
  76. 6 1
      Engine/source/windowManager/platformWindow.cpp
  77. 8 3
      Engine/source/windowManager/platformWindow.h
  78. 81 90
      Engine/source/windowManager/win32/win32Window.cpp
  79. BIN
      Templates/Empty/game/art/environment/FogMod_heavy.dds
  80. BIN
      Templates/Empty/game/art/environment/FogMod_light.dds
  81. BIN
      Templates/Empty/game/art/environment/FogMod_med.dds
  82. 97 0
      Templates/Empty/game/art/environment/Fog_Cube.DAE
  83. 8 0
      Templates/Empty/game/art/environment/Fog_Cube.cs
  84. 2 2
      Templates/Empty/game/core/main.cs
  85. 7 2
      Templates/Empty/game/core/scripts/client/canvas.cs
  86. 76 0
      Templates/Empty/game/core/scripts/client/postFx/glow.cs
  87. 1 0
      Templates/Empty/game/core/scripts/client/postFx/postFxManager.gui.settings.cs
  88. 2 0
      Templates/Empty/game/core/scripts/client/renderManager.cs
  89. 106 0
      Templates/Empty/game/scripts/server/VolumetricFog.cs
  90. 1 0
      Templates/Empty/game/scripts/server/scriptExec.cs
  91. 87 0
      Templates/Empty/game/shaders/common/VolumetricFog/VFogP.hlsl
  92. 39 0
      Templates/Empty/game/shaders/common/VolumetricFog/VFogPreP.hlsl
  93. 46 0
      Templates/Empty/game/shaders/common/VolumetricFog/VFogPreV.hlsl
  94. 36 0
      Templates/Empty/game/shaders/common/VolumetricFog/VFogRefl.hlsl
  95. 45 0
      Templates/Empty/game/shaders/common/VolumetricFog/VFogV.hlsl
  96. 87 0
      Templates/Empty/game/shaders/common/VolumetricFog/gl/VFogP.glsl
  97. 37 0
      Templates/Empty/game/shaders/common/VolumetricFog/gl/VFogPreP.glsl
  98. 42 0
      Templates/Empty/game/shaders/common/VolumetricFog/gl/VFogPreV.glsl
  99. 33 0
      Templates/Empty/game/shaders/common/VolumetricFog/gl/VFogRefl.glsl
  100. 38 0
      Templates/Empty/game/shaders/common/VolumetricFog/gl/VFogV.glsl

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

+ 1 - 0
Engine/source/T3D/decal/decalData.cpp

@@ -284,6 +284,7 @@ void DecalData::unpackData( BitStream *stream )
    Parent::unpackData( stream );
 
    stream->read( &lookupName );
+   assignName(lookupName);
    stream->read( &size );  
    stream->read( &materialName );
    _updateMaterial();

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

+ 53 - 57
Engine/source/console/consoleObject.h

@@ -48,7 +48,7 @@
    #include "console/simObjectRef.h"
 #endif
 #ifndef TINYXML_INCLUDED
-   #include "tinyXML/tinyxml.h"
+   #include "tinyxml.h"
 #endif
 
 /// @file
@@ -212,7 +212,7 @@ public:
    ///
    /// @param conIdPtr Pointer to the static S32 console ID.
    /// @param conTypeName Console type name.
-   AbstractClassRep( S32* conIdPtr, const char* typeName ) 
+   AbstractClassRep( S32* conIdPtr, const char* typeName )
       : Parent( sizeof( void* ), conIdPtr, typeName )
    {
       VECTOR_SET_ASSOCIATION( mFieldList );
@@ -323,13 +323,13 @@ public:
 
    /// Return the namespace that contains the methods of this class.
    Namespace* getNameSpace() const { return mNamespace; }
-   
+
    /// Return the AbstractClassRep of the class that this class is derived from.
    AbstractClassRep* getParentClass() const { return parentClass; }
 
    virtual AbstractClassRep*    getContainerChildClass(const bool recurse) = 0;
    virtual WriteCustomTamlSchema getCustomTamlSchema(void) = 0;
-   
+
    /// Return the size of instances of this class in bytes.
    S32 getSizeof() const { return mClassSizeof; }
 
@@ -396,7 +396,7 @@ protected:
    Namespace *        mNamespace;
 
    /// @}
-   
+
 public:
 
    bool mIsRenderEnabled;
@@ -404,23 +404,23 @@ public:
 
    bool isRenderEnabled() const { return mIsRenderEnabled; }
    bool isSelectionEnabled() const { return mIsSelectionEnabled; }
-      
+
    /// @name Categories
    /// @{
-   
+
 protected:
 
    const char* mCategory;
    const char* mDescription;
-      
+
 public:
 
    /// Return the space separated category path for the class.
    const char* getCategory() const { return mCategory; }
-   
+
    /// Return a short description string suitable for displaying in tooltips.
    const char* getDescription() const { return mDescription; }
-   
+
    /// @}
 
    /// @name Fields
@@ -434,16 +434,12 @@ public:
    /// This is a function pointer typedef to support optional writing for fields.
    typedef bool(*WriteDataNotify)(void* obj, StringTableEntry pFieldName);
 
-   /// Allows the writing of a custom TAML schema.
-   typedef void(*WriteCustomTamlSchema)(const AbstractClassRep* pClassRep, TiXmlElement* pParentElement);
-
-
    /// These are special field type values used to mark
    /// groups and arrays in the field list.
    /// @see Field::type
    /// @see addArray, endArray
-   /// @see addGroup, endGroup   
-   /// @see addGroup, endGroup   
+   /// @see addGroup, endGroup
+   /// @see addGroup, endGroup
    /// @see addDeprecatedField
    enum ACRFieldTypes
    {
@@ -451,35 +447,35 @@ public:
       /// types greater or equal to this one are not
       /// console data types.
       ARCFirstCustomField = 0xFFFFFFFB,
-      
+
       /// Marks the start of a fixed size array of fields.
       /// @see addArray
       StartArrayFieldType = 0xFFFFFFFB,
-      
+
       /// Marks the end of a fixed size array of fields.
       /// @see endArray
       EndArrayFieldType   = 0xFFFFFFFC,
-      
+
       /// Marks the beginning of a group of fields.
       /// @see addGroup
       StartGroupFieldType = 0xFFFFFFFD,
-      
+
       /// Marks the beginning of a group of fields.
       /// @see endGroup
       EndGroupFieldType   = 0xFFFFFFFE,
-      
-      /// Marks a field that is depreciated and no 
+
+      /// Marks a field that is depreciated and no
       /// longer stores a value.
       /// @see addDeprecatedField
       DeprecatedFieldType = 0xFFFFFFFF
    };
-   
+
    enum FieldFlags
    {
       FIELD_HideInInspectors     = BIT( 0 ),    ///< Do not show the field in inspectors.
    };
 
-   struct Field 
+   struct Field
    {
       Field()
          :  pFieldname( NULL ),
@@ -525,10 +521,10 @@ public:
 
    /// @name Console Type Interface
    /// @{
-   
+
    virtual void* getNativeVariable() { return new ( AbstractClassRep* ); } // Any pointer-sized allocation will do.
    virtual void deleteNativeVariable( void* var ) { delete reinterpret_cast< AbstractClassRep** >( var ); }
-   
+
    /// @}
 
    /// @name Abstract Class Database
@@ -574,10 +570,10 @@ template< class T >
 class ConcreteClassRep : public AbstractClassRep
 {
    public:
-   
+
       static EnginePropertyTable _smPropertyTable;
       static EnginePropertyTable& smPropertyTable;
-      
+
       ConcreteClassRep(    const char* name,
                            const char* conTypeName,
                            S32* conTypeIdPtr,
@@ -591,10 +587,10 @@ class ConcreteClassRep : public AbstractClassRep
          mClassName = StringTable->insert( name );
          mCategory = T::__category();
          mTypeInfo = _MAPTYPE< T >();
-         
+
          if( mTypeInfo )
             const_cast< EngineTypeInfo* >( mTypeInfo )->mPropertyTable = &smPropertyTable;
-         
+
          if( &T::__description != parentDesc )
             mDescription = T::__description();
 
@@ -642,7 +638,7 @@ class ConcreteClassRep : public AbstractClassRep
          // Get handle to our parent class, if any, and ourselves (we are our parent's child).
          AbstractClassRep *parent = T::getParentStaticClassRep();
          AbstractClassRep *child  = T::getStaticClassRep();
-                  
+
          // If we got reps, then link those namespaces! (To get proper inheritance.)
          if(parent && child)
             Con::classLinkNamespaces(parent->getNameSpace(), child->getNameSpace());
@@ -657,7 +653,7 @@ class ConcreteClassRep : public AbstractClassRep
 
       /// Wrap constructor.
       ConsoleObject* create() const { return new T; }
-      
+
       /// @name Console Type Interface
       /// @{
 
@@ -671,16 +667,16 @@ class ConcreteClassRep : public AbstractClassRep
          else
             Con::errorf( "Cannot set multiple args to a single ConsoleObject*.");
       }
-      
+
       virtual const char* getData( void* dptr, const EnumTable* tbl, BitSet32 flag )
       {
          T** obj = ( T** ) dptr;
          return Con::getReturnBuffer( T::__getObjectId( *obj ) );
       }
-      
+
       virtual const char* getTypeClassName() { return mClassName; }
       virtual const bool isDatablock() { return T::__smIsDatablock; };
-      
+
       /// @}
 };
 
@@ -751,7 +747,7 @@ bool defaultProtectedWriteFn(void* obj, StringTableEntry pFieldName);
 class ConsoleObject : public EngineObject
 {
    DECLARE_ABSTRACT_CLASS( ConsoleObject, EngineObject );
-   
+
 protected:
 
    /// @deprecated This is disallowed.
@@ -760,7 +756,7 @@ protected:
 public:
 
    ConsoleObject() {}
-   
+
    /// Get a reference to a field by name.
    const AbstractClassRep::Field *findField(StringTableEntry fieldName) const;
 
@@ -769,7 +765,7 @@ public:
 
    /// Set the value of a field.
    bool setField(const char *fieldName, const char *value);
-   
+
 public:
 
    /// @name Object Creation
@@ -799,11 +795,11 @@ public:
    static void endGroup(const char*  in_pGroupname);
 
    /// Marks the start of a fixed size array of fields.
-   /// @see console_autodoc   
+   /// @see console_autodoc
    static void addArray( const char *arrayName, S32 count );
 
    /// Marks the end of an array of fields.
-   /// @see console_autodoc      
+   /// @see console_autodoc
    static void endArray( const char *arrayName );
 
    /// Register a complex field.
@@ -928,16 +924,16 @@ public:
    static bool removeField(const char* in_pFieldname);
 
    /// @}
-   
+
    /// @name Logging
    /// @{
-   
+
    /// Overload this in subclasses to change the message formatting.
    /// @param fmt A printf style format string.
    /// @param args A va_list containing the args passed ot a log function.
    /// @note It is suggested that you use String::VToString.
    virtual String _getLogMessage(const char* fmt, va_list args) const;
-   
+
    /// @}
 
 public:
@@ -946,16 +942,16 @@ public:
    /// These functions will try to print out a message along the lines
    /// of "ObjectClass - ObjectName(ObjectId) - formatted message"
    /// @{
-   
+
    /// Logs with Con::printf.
    void logMessage(const char* fmt, ...) const;
-   
+
    /// Logs with Con::warnf.
    void logWarning(const char* fmt, ...) const;
-   
+
    /// Logs with Con::errorf.
    void logError(const char* fmt, ...) const;
-   
+
    /// @}
 
    /// Register dynamic fields in a subclass of ConsoleObject.
@@ -1016,16 +1012,16 @@ public:
 
    static const char* __category() { return ""; }
    static const char* __description() { return ""; }
-   
+
    /// Subclasses of ConsoleObjects that are datablocks should redefine this static member variable
    /// and set it to true.
    static const bool __smIsDatablock = false;
-   
+
    /// @name Object IDs and lookup.
    /// For a subclass hierarchy based on ConsoleObject to become functional for use as a console object type,
    /// the hierarchy must implement a naming scheme and indexing function for looking up objects by name.
    /// @{
-   
+
    static ConsoleObject* __findObject( const char* ) { return NULL; }
    static const char* __getObjectId( ConsoleObject* ) { return ""; }
 };
@@ -1120,11 +1116,11 @@ inline bool& ConsoleObject::getDynamicGroupExpand()
    static SimObjectRefConsoleBaseType< className > ptrRefType;         \
    static AbstractClassRep::WriteCustomTamlSchema getStaticWriteCustomTamlSchema();         \
    static AbstractClassRep* getContainerChildStaticClassRep();         \
-   virtual AbstractClassRep* getClassRep() const      
-      
+   virtual AbstractClassRep* getClassRep() const
+
 #define DECLARE_CATEGORY( string )                      \
    static const char* __category() { return string; }
-   
+
 #define DECLARE_DESCRIPTION( string )                   \
    static const char* __description() { return string; }
 
@@ -1199,7 +1195,7 @@ inline bool& ConsoleObject::getDynamicGroupExpand()
    AbstractClassRep* className::getContainerChildStaticClassRep() { return NULL; }                 \
    AbstractClassRep::WriteCustomTamlSchema className::getStaticWriteCustomTamlSchema() { return NULL; }            \
    ConcreteClassRep<className> className::dynClassRep(#className, "Type" #className, &_smTypeId, NetClassGroupGameMask, NetClassTypeDataBlock, 0, className::getParentStaticClassRep(), &Parent::__description )
-   
+
 // Support for adding properties to classes CONOBJECT style.
 #define PROPERTY_TABLE( className )                                                                      \
    namespace { namespace _ ## className {                                                                \
@@ -1209,13 +1205,13 @@ inline bool& ConsoleObject::getDynamicGroupExpand()
    ConcreteClassRep< className >::smPropertyTable = _ ## className::_propTable;                          \
    namespace { namespace _ ## className {                                                                \
       EnginePropertyTable::Property _props[] = {
-      
+
 #define END_PROPERTY_TABLE                                                                               \
          { NULL }                                                                                        \
       };                                                                                                 \
       EnginePropertyTable _propTable( sizeof( _props ) / sizeof( _props[ 0 ] ) - 1, _props );            \
    } }
-   
+
 /// Add an auto-doc for a class.
 #define ConsoleDocClass( className, docString ) \
    CLASSDOC( className, docString )
@@ -1225,7 +1221,7 @@ inline bool& ConsoleObject::getDynamicGroupExpand()
 //------------------------------------------------------------------------------
 // Protected field default get/set functions
 //
-// The reason for these functions is that it will save one branch per console 
+// The reason for these functions is that it will save one branch per console
 // data request and script functions will still execute at the same speed as
 // before the modifications to allow protected static fields. These will just
 // inline and the code should be roughly the same size, and just as fast as

+ 1 - 0
Engine/source/core/color.h

@@ -503,6 +503,7 @@ inline ColorI& ColorI::operator*=(const S32 in_mul)
 
 inline ColorI& ColorI::operator/=(const S32 in_mul)
 {
+   AssertFatal(in_mul != 0.0f, "Error, div by zero...");
    red   = red    / in_mul;
    green = green  / in_mul;
    blue  = blue   / in_mul;

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

+ 1319 - 0
Engine/source/environment/VolumetricFog.cpp

@@ -0,0 +1,1319 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+#include "environment/VolumetricFog.h"
+#include "windowManager/platformWindowMgr.h"
+#include "gfx/gfxTransformSaver.h"
+#include "renderInstance/renderPassManager.h"
+#include "math/mathIO.h"
+#include "materials/shaderData.h"
+#include "math/util/matrixSet.h"
+#include "core/resourceManager.h"
+#include "core/stream/bitStream.h"
+#include "T3D/gameBase/gameConnection.h"
+#include "T3D/shapeBase.h"
+#include "ts/tsShapeInstance.h"
+#include "console/engineAPI.h"
+#include "gui/core/guiCanvas.h"
+#include "VolumetricFogRTManager.h"
+#include "lighting/lightInfo.h"
+#include "lighting/lightManager.h"
+
+#define COLBOX_SCALE Point3F(1.02f, 1.02f, 1.02f)
+
+IMPLEMENT_CO_NETOBJECT_V1(VolumetricFog);
+
+ConsoleDocClass(VolumetricFog,
+"@brief Volumetric Fog Object class. Main class defining the Volumetric\n"
+"Fog objects in the scene. Used in conjunction with the VolumetricFogRTManager\n"
+"class which is responsible for the required rendertargets.\n\n"
+"Methods (exposed to script):\n"
+" setFogColorF(color) Changes the overall fog color (color.rgba range 0.0 - 1.0).\n;"
+" setFogColor(color) Changes the overall fog color color.rgba range 0 - 255).\n;"
+" setFogDensity(density) Changes the overall fog density.\n"
+" setFogModulation(strength, speed1, speed2) changes the strength\n"
+" and the speeds of the 2 animation layers.\n\n"
+"Callbacks:\n"
+"onEnterFog triggered whenever the controlobject (Player or Camera) enters the Fog.\n"
+" (current Fog object and the controlobject are exposed to script.\n"
+"onLeaveFog triggered whenever the controlobject (Player or Camera) left the Fog.\n"
+" (current Fog object and the controlobject are exposed to script.\n\n"
+"@tsexample\n"
+" new VolumetricFog()\n"
+" {\n"
+" shapeName = \"art/environment/FogRCube.dts\";\n"
+" fogColor = \"200 200 200 128\";\n"
+" fogDensity = \"0.2\";\n"
+" ignoreWater = \"0\";\n"
+" MinSize = \"250\";\n"
+" FadeSize = \"750\";\n"
+" texture = \"art/environment/FogMod_heavy.dds\";\n"
+" tiles = \"1.5\";\n"
+" modStrength = \"0.2\";\n"
+" PrimSpeed = \"-0.01 0.04\";\n"
+" SecSpeed = \"0.02 -0.02\";\n"
+" position = \"748.644 656.371 65.3506\"; \n"
+" rotation = \"0 0 1 20.354\";\n"
+" scale = \"40 30 6\";\n"
+" };\n"
+"@endtsexample\n"
+);
+
+IMPLEMENT_CALLBACK(VolumetricFog, onEnterFog, void, (SimObjectId obj), (obj),
+"@brief Called when an object enters the volume of the Fog instance.\n\n"
+
+"@param obj the controlobject entering the fog.");
+
+IMPLEMENT_CALLBACK(VolumetricFog, onLeaveFog, void, (SimObjectId obj), (obj),
+"@brief Called when an object left the volume of the Fog instance.\n\n"
+
+"@param obj the controlobject leaving the fog.");
+
+
+VolumetricFog::VolumetricFog()
+{
+   AssertFatal(VFRTM != NULL, "VolumetricFog Fatal Error: No Manager found");
+
+   if (!VFRTM->IsInitialized())
+   VFRTM->Init();
+
+   mNetFlags.set(Ghostable | ScopeAlways);
+
+   mTypeMask |= EnvironmentObjectType | StaticObjectType;
+
+   mPrepassTarget = NULL;
+   mDepthBufferTarget = NULL;
+   mFrontBufferTarget = NULL;
+
+   z_buf = NULL;
+   mTexture = NULL;
+
+   mIsVBDirty = false;
+   mIsPBDirty = false;
+
+   mFogColor.set(200, 200, 200, 255);
+   mFogDensity = 0.3f;
+   mIgnoreWater = false;
+   mReflect = false;
+   mCamInFog = false;
+   mResizing = false;
+   mFogReflStrength = 20.0;
+   mUseGlow = false;
+   mGlowStrength = 0.3f;
+   mGlowing = 0;
+   mModifLightRays = false;
+   mLightRayMod = 1.0f;
+   mOldLightRayStrength = 0.1f;
+
+   mShapeName = "";
+   mShapeLoaded = false;
+   mMinDisplaySize = 10.0f;
+   mFadeSize = 0.0f;
+   mCurDetailLevel = 0;
+   mNumDetailLevels = 0;
+   det_size.clear();
+
+   mTextureName = "";
+   mIsTextured = false;
+   mStrength = 0.5f;
+   mTexTiles = 1.0f;
+   mSpeed1.set(0.5f, 0.0f);
+   mSpeed2.set(0.1f, 0.1f);
+}
+
+VolumetricFog::~VolumetricFog()
+{
+   if (isClientObject())
+      return;
+
+   for (S32 i = 0; i < det_size.size(); i++)
+   {
+      if (det_size[i].indices != NULL)
+         delete(det_size[i].indices);
+      if (det_size[i].piArray != NULL)
+         delete(det_size[i].piArray);
+      if (det_size[i].verts != NULL)
+         delete(det_size[i].verts);
+   }
+   det_size.clear();
+
+   if (z_buf.isValid())
+      SAFE_DELETE(z_buf);
+
+   if (!mTexture.isNull())
+      mTexture.free();
+}
+
+void VolumetricFog::initPersistFields()
+{
+   addGroup("VolumetricFogData");
+   addField("shapeName", TypeShapeFilename, Offset(mShapeName, VolumetricFog),
+      "Path and filename of the model file (.DTS, .DAE) to use for this Volume.");
+   addField("FogColor", TypeColorI, Offset(mFogColor, VolumetricFog),
+      "Fog color RGBA (Alpha is ignored)");
+   addField("FogDensity", TypeF32, Offset(mFogDensity, VolumetricFog), 
+      "Overal fog density value (0 disables the fog).");
+   addField("IgnoreWater", TypeBool, Offset(mIgnoreWater, VolumetricFog), 
+      "Set to true if volumetric fog should continue while submerged.");
+   addField("MinSize", TypeF32, Offset(mMinDisplaySize, VolumetricFog), 
+      "Min size (in pixels) for fog to be rendered.");
+   addField("FadeSize", TypeF32, Offset(mFadeSize, VolumetricFog), 
+      "Object size in pixels at which the FX-fading kicks in (0 disables fading).");
+   endGroup("VolumetricFogData");
+
+   addGroup("VolumetricFogModulation");
+   addField("texture", TypeImageFilename, Offset(mTextureName, VolumetricFog),
+      "A texture which contains Fogdensity modulator in the red channel and color with 1-green channel. No texture disables modulation.");
+   addField("tiles", TypeF32, Offset(mTexTiles, VolumetricFog), 
+      "How many times the texture is mapped to the object.");
+   addField("modStrength", TypeF32, Offset(mStrength, VolumetricFog),
+      "Overall strength of the density modulation (0 disables modulation).");
+   addField("PrimSpeed", TypePoint2F, Offset(mSpeed1, VolumetricFog),
+      "Overall primary speed of the density modulation (x-speed(u) y-speed(v))");
+   addField("SecSpeed", TypePoint2F, Offset(mSpeed2, VolumetricFog),
+      "Overall secundary speed of the density modulation (x-speed(u) y-speed(v))");
+   endGroup("VolumetricFogModulation");
+
+   addGroup("Reflections");
+   addField("Reflectable", TypeBool, Offset(mReflect, VolumetricFog), 
+      "Set to true if volumetric fog should be reflected.");
+   addField("ReflectStrength", TypeF32, Offset(mFogReflStrength, VolumetricFog), 
+      "Strength of the reflections (0 disables the fog).");
+   endGroup("Reflections");
+
+   addGroup("PostFX");
+   addField("useGlow", TypeBool, Offset(mUseGlow, VolumetricFog), 
+      "Set to true if volumetric fog should use glow PostFX.");
+   addField("glowStrength", TypeF32, Offset(mGlowStrength, VolumetricFog),
+      "Overall strength of the glow PostFX.");
+   addField("modLightRay", TypeBool, Offset(mModifLightRays, VolumetricFog), 
+      "Set to true if volumetric fog should modify the brightness of the Lightrays.");
+   addField("lightRayMod", TypeF32, Offset(mLightRayMod, VolumetricFog),
+      "Modifier for LightRay PostFX when inside Fog.");
+   endGroup("PostFX");
+   Parent::initPersistFields();
+}
+
+void VolumetricFog::inspectPostApply()
+{
+   Parent::inspectPostApply();
+   mSpeed.set(mSpeed1.x, mSpeed1.y, mSpeed2.x, mSpeed2.y);
+   setMaskBits(VolumetricFogMask | FogColorMask | FogDensityMask | FogModulationMask | FogPostFXMask | FogShapeMask);
+}
+
+bool VolumetricFog::onAdd()
+{
+   if (!Parent::onAdd())
+      return false;
+
+   if (!VFRTM->IsInitialized())
+   {
+      Con::errorf("No VolumetricFogRTManager present!!");
+      return false;
+   }
+
+   resetWorldBox();
+
+   mShapeLoaded = LoadShape();
+
+   setRenderTransform(mObjToWorld);
+
+   addToScene();
+   ColBox.set(getTransform(), (mObjBox.getExtents() * getScale() * COLBOX_SCALE));
+   mObjSize = mWorldBox.getGreatestDiagonalLength();
+   mObjScale = getScale();
+   mTexTiles = mAbs(mTexTiles);
+   mSpeed.set(mSpeed1.x, mSpeed1.y, mSpeed2.x, mSpeed2.y);
+   mInvScale = (1.0f / getMax(getMax(mObjScale.x, mObjScale.y), mObjScale.z));
+
+   if (isClientObject())
+   {
+      conn = GameConnection::getConnectionToServer();
+      if (!conn)
+      {  
+         Con::errorf("VolumetricFog::onAdd - No Serverconnection");
+         return false;
+      }
+
+      glowFX = static_cast<PostEffect*>(Sim::findObject("VolFogGlowPostFx"));
+
+      mOldLightRayStrength = Con::getFloatVariable("$LightRayPostFX::brightScalar",1.0f);
+
+      GuiCanvas* cv = dynamic_cast<GuiCanvas*>(Sim::findObject("Canvas"));
+      if (cv == NULL)
+      {
+         Con::errorf("VolumetricFog::onAdd - Canvas not found!!");
+         return false;
+      }
+      mPlatformWindow = cv->getPlatformWindow();
+      VolumetricFogRTManager::getVolumetricFogRTMResizeSignal().notify(this, &VolumetricFog::handleResize);
+      GuiCanvas::getCanvasSizeChangeSignal().notify(this, &VolumetricFog::handleCanvasResize);
+
+      InitTexture();
+      return setupRenderer();
+   }
+
+   VFRTM->IncFogObjects();
+   
+   return true;
+}
+
+void VolumetricFog::onRemove()
+{
+   if (isClientObject())
+   {
+      if (isTicking())
+      {
+         setProcessTick(false);
+         if (mGlowing != 0)
+         {
+            mGlowing = 0;
+            glowFX->disable();
+         }
+         _leaveFog(static_cast<ShapeBase*>(conn->getControlObject()));
+      }
+      VolumetricFogRTManager::getVolumetricFogRTMResizeSignal().remove(this, &VolumetricFog::handleResize);
+      GuiCanvas::getCanvasSizeChangeSignal().remove(this, &VolumetricFog::handleCanvasResize);
+   }
+   removeFromScene();
+   VFRTM->DecFogObjects();
+   Parent::onRemove();
+}
+void VolumetricFog::handleCanvasResize(GuiCanvas* canvas)
+{
+   UpdateBuffers(0,true);
+}
+
+void VolumetricFog::handleResize(VolumetricFogRTManager *RTM, bool resize)
+{
+   if (resize)
+   {
+      mResizing = true;
+      RTM->FogAnswered();
+   }
+   else
+      mResizing = false;
+
+   if (mIsTextured)
+   {
+      F32 width = (F32)mPlatformWindow->getClientExtent().x;
+      F32 height = (F32)mPlatformWindow->getClientExtent().y;
+      if (!mPlatformWindow->isFullscreen())
+         height -= 20;//subtract caption bar from rendertarget size.
+      mTexScale.x = 2.0f - ((F32)mTexture.getWidth() / width);
+      mTexScale.y = 2.0f - ((F32)mTexture.getHeight() / height);
+   }
+
+   UpdateBuffers(0,true);
+}
+
+//-----------------------------------------------------------------------------
+// Loadshape extracted from TSMesh and TSShapeInstance
+//-----------------------------------------------------------------------------
+
+bool VolumetricFog::LoadShape()
+{
+   GFXPrimitiveType GFXdrawTypes[] = { GFXTriangleList, GFXTriangleStrip };
+   if (!mShapeName || mShapeName[0] == '\0')
+   {
+      Con::errorf("VolumetricFog::LoadShape() - No shape name! Volumetric Fog will not be rendered!");
+      return false;
+   }
+
+   // Load shape, server side only reads bounds and radius
+
+   Resource<TSShape> mShape;
+   mShape = ResourceManager::get().load(mShapeName);
+   if (bool(mShape) == false)
+   {
+      Con::errorf("VolumetricFog::LoadShape() - Unable to load shape: %s", mShapeName);
+      return false;
+   }
+
+   mObjBox = mShape->bounds;
+   mRadius = mShape->radius;
+   resetWorldBox();
+
+   if (!isClientObject())
+      return false;
+
+   TSShapeInstance *mShapeInstance = new TSShapeInstance(mShape, false);
+   meshes mesh_detail;
+
+   for (S32 i = 0; i < det_size.size(); i++)
+   {
+      if (det_size[i].indices != NULL)
+         delete(det_size[i].indices);
+      if (det_size[i].piArray != NULL)
+         delete(det_size[i].piArray);
+      if (det_size[i].verts != NULL)
+         delete(det_size[i].verts);
+   }
+   det_size.clear();
+
+   // browsing model for detail levels
+
+   for (U32 i = 0; i < mShape->details.size(); i++)
+   {
+      const TSDetail *detail = &mShape->details[i];
+      mesh_detail.det_size = detail->size;
+      mesh_detail.sub_shape = detail->subShapeNum;
+      mesh_detail.obj_det = detail->objectDetailNum;
+      mesh_detail.verts = NULL;
+      mesh_detail.piArray = NULL;
+      mesh_detail.indices = NULL;
+      if (detail->size >= 0.0f && detail->subShapeNum >= 0)
+         det_size.push_back(mesh_detail);
+   }
+
+   for (U32 i = 0; i < det_size.size(); i++)
+   {
+      const S32 ss = det_size[i].sub_shape;
+      if (ss >= 0)
+      {
+         const S32 start = mShape->subShapeFirstObject[ss];
+         const S32 end = start + mShape->subShapeNumObjects[ss];
+         for (S32 j = start; j < end; j++)
+         {
+            // Loading shape, only the first mesh for each detail will be used!
+            TSShapeInstance::MeshObjectInstance *meshObj = &mShapeInstance->mMeshObjects[j];
+            if (!meshObj)
+               continue;
+            TSMesh *mesh = meshObj->getMesh(det_size[i].obj_det);
+            if (mesh != NULL)
+            {
+               const U32 numNrms = mesh->mNumVerts;
+               GFXVertexPNTT *tmpVerts = NULL;
+               tmpVerts = new GFXVertexPNTT[numNrms];
+               mIsVBDirty = true;
+               for (U32 k = 0; k < numNrms; k++)
+                  {
+                     Point3F norm = mesh->mVertexData[k].normal();
+                     Point3F vert = mesh->mVertexData[k].vert();
+                     Point2F uv = mesh->mVertexData[k].tvert();
+                     tmpVerts[k].point = vert;
+                     tmpVerts[k].texCoord = uv;
+                     tmpVerts[k].normal = norm;
+                  }
+               det_size[i].verts = tmpVerts;
+               det_size[i].num_verts = numNrms;
+
+               det_size[i].piArray = new Vector<GFXPrimitive>();
+               GFXPrimitive pInfo;
+
+               det_size[i].indices = new Vector<U32>();
+
+               for (U32 k = 0; k < mesh->indices.size(); k++)
+                  det_size[i].indices->push_back(mesh->indices[k]);
+
+               U32 primitivesSize = mesh->primitives.size();
+               for (U32 k = 0; k < primitivesSize; k++)
+               {
+                  const TSDrawPrimitive & draw = mesh->primitives[k];
+                  GFXPrimitiveType drawType = GFXdrawTypes[draw.matIndex >> 30];
+                  switch (drawType)
+                  {
+                     case GFXTriangleList:
+                        pInfo.type = drawType;
+                        pInfo.numPrimitives = draw.numElements / 3;
+                        pInfo.startIndex = draw.start;
+                        // Use the first index to determine which 16-bit address space we are operating in
+                        pInfo.startVertex = mesh->indices[draw.start] & 0xFFFF0000;
+                        pInfo.minIndex = pInfo.startVertex;
+                        pInfo.numVertices = getMin((U32)0x10000, mesh->mNumVerts - pInfo.startVertex);
+                        break;
+                     case GFXTriangleStrip:
+                        pInfo.type = drawType;
+                        pInfo.numPrimitives = draw.numElements - 2;
+                        pInfo.startIndex = draw.start;
+                        // Use the first index to determine which 16-bit address space we are operating in
+                        pInfo.startVertex = mesh->indices[draw.start] & 0xFFFF0000;
+                        pInfo.minIndex = pInfo.startVertex;
+                        pInfo.numVertices = getMin((U32)0x10000, mesh->mNumVerts - pInfo.startVertex);
+                        break;
+                     default:
+                        Con::errorf("VolumetricFog::LoadShape Unknown drawtype!?!");
+                        return false;
+                        break;
+                  }
+               det_size[i].piArray->push_back(pInfo);
+               j = end;
+            }
+         }
+         else
+         {
+            Con::errorf("VolumetricFog::LoadShape Error loading mesh from shape!");
+            delete mShapeInstance;
+            return false;
+         }
+         mIsVBDirty = true;
+         mIsPBDirty = true;
+         }
+      }
+   }
+
+   mNumDetailLevels = det_size.size();
+   mCurDetailLevel = 0;
+   UpdateBuffers(mCurDetailLevel);
+   delete mShapeInstance;
+
+   return true;
+}
+
+//-----------------------------------------------------------------------------
+// UpdateBuffers called whenever detaillevel changes (LOD)
+//-----------------------------------------------------------------------------
+
+
+bool VolumetricFog::UpdateBuffers(U32 dl, bool force)
+{
+   if (mVB.isNull() || mIsVBDirty || dl != mCurDetailLevel || force)
+   {
+      mVB.set(GFX, det_size[dl].num_verts, GFXBufferTypeDynamic);
+      mIsVBDirty = false;
+   }
+   GFXVertexPNTT *vertPtr = mVB.lock();
+   if (!vertPtr)
+   {
+      mVB.unlock();
+      return false;
+   }
+   dMemcpy(vertPtr, det_size[dl].verts, sizeof (GFXVertexPNTT)* det_size[dl].num_verts);
+   mVB.unlock();
+
+   if (mIsPBDirty || mPB.isNull() || dl != mCurDetailLevel || force)
+   {
+      #ifdef TORQUE_DEBUG
+      mPB.set(GFX, det_size[dl].indices->size(), det_size[dl].piArray->size(), GFXBufferTypeDynamic, avar("%s() - VolFogPrimBuffer (line %d)", __FUNCTION__, __LINE__));
+      #else
+      mPB.set(GFX, det_size[dl].indices->size(), det_size[dl].piArray->size(), GFXBufferTypeDynamic);
+      #endif
+      U16 *ibIndices = NULL;
+      GFXPrimitive *piInput = NULL;
+      mPB.lock(&ibIndices, &piInput);
+      dCopyArray(ibIndices, det_size[dl].indices->address(), det_size[dl].indices->size());
+      dMemcpy(piInput, det_size[dl].piArray->address(), det_size[dl].piArray->size() * sizeof(GFXPrimitive));
+      mPB.unlock();
+      mIsPBDirty = false;
+   }
+   mCurDetailLevel = dl;
+   return true;
+}
+
+U32 VolumetricFog::packUpdate(NetConnection *con, U32 mask, BitStream *stream)
+{
+   U32 retMask = Parent::packUpdate(con, mask, stream);
+   if (stream->writeFlag(mask & FogColorMask))
+      stream->write(mFogColor);
+   if (stream->writeFlag(mask & FogDensityMask))
+      stream->write(mFogDensity);
+   if (stream->writeFlag(mask & FogModulationMask))
+   {
+      stream->write(mTextureName);
+      mTexTiles = mFabs(mTexTiles);
+      stream->write(mTexTiles);
+      stream->write(mStrength);
+      mathWrite(*stream, mSpeed);
+   }
+   if (stream->writeFlag(mask & FogPostFXMask))
+   {
+      stream->writeFlag(mUseGlow);
+      stream->write(mGlowStrength);
+      stream->writeFlag(mModifLightRays);
+      stream->write(mLightRayMod);
+   }
+   if (stream->writeFlag(mask & VolumetricFogMask))
+   {
+      stream->writeFlag(mIgnoreWater);
+      stream->writeFlag(mReflect);
+      stream->write(mFogReflStrength);
+      stream->writeFlag(mResizing);
+      stream->write(mMinDisplaySize);
+      stream->write(mFadeSize);
+   }
+   if (stream->writeFlag(mask & FogShapeMask))
+   {
+      stream->writeString(mShapeName);
+      mathWrite(*stream, getTransform());
+      mathWrite(*stream, getScale());
+      if (!mShapeName || mShapeName[0] == '\0')
+         return retMask;
+      Resource<TSShape> mShape;
+      mShape = ResourceManager::get().load(mShapeName);
+      if (bool(mShape) == false)
+         return retMask;
+      mObjBox = mShape->bounds;
+      mRadius = mShape->radius;
+      resetWorldBox();
+      mObjSize = mWorldBox.getGreatestDiagonalLength();
+      mObjScale = getScale();
+      mInvScale = (1.0f / getMax(getMax(mObjScale.x, mObjScale.y), mObjScale.z));
+   }
+   return retMask;
+}
+
+void VolumetricFog::unpackUpdate(NetConnection *con, BitStream *stream)
+{
+   Parent::unpackUpdate(con, stream);
+   MatrixF mat;
+   VectorF scale;
+   VectorF mOldScale = getScale();
+   String oldTextureName = mTextureName;
+   StringTableEntry oldShape = mShapeName;
+
+   if (stream->readFlag())// Fog color
+      stream->read(&mFogColor);
+   if (stream->readFlag())// Fog Density
+   {
+      stream->read(&mFogDensity);
+      if (isTicking())
+      {
+         char buf[20];
+         dSprintf(buf, sizeof(buf), "%3.7f", mFogDensity);
+         Con::setVariable("$VolumetricFog::density", buf);
+      }
+   }
+   if (stream->readFlag())// Fog Modulation
+   {
+      stream->read(&mTextureName);
+      stream->read(&mTexTiles);
+      mTexTiles = mFabs(mTexTiles);
+      stream->read(&mStrength);
+      mathRead(*stream, &mSpeed);
+      mSpeed1.set(mSpeed.x, mSpeed.y);
+      mSpeed2.set(mSpeed.z, mSpeed.w);
+
+      if (isProperlyAdded())
+      {
+         if (oldTextureName != mTextureName)
+            InitTexture();
+         if (oldTextureName.isNotEmpty() && mTextureName.isEmpty())
+         {
+            mIsTextured = false;
+            mTexture.free();
+         }
+      }
+   }
+   if (stream->readFlag())//Fog PostFX
+   {
+      mUseGlow = stream->readFlag();
+      stream->read(&mGlowStrength);
+      mModifLightRays = stream->readFlag();
+      stream->read(&mLightRayMod);
+      if (isTicking())
+      {
+         char buf[20];
+         dSprintf(buf, sizeof(buf), "%3.7f", mGlowStrength);
+         Con::setVariable("$VolFogGlowPostFx::glowStrength", buf);
+         if (mUseGlow && !glowFX->isEnabled())
+            glowFX->enable();
+         if (!mUseGlow && glowFX->isEnabled())
+            glowFX->disable();
+         if (mModifLightRays)
+         {
+            char buf[20];
+            dSprintf(buf, sizeof(buf), "%3.7f", mOldLightRayStrength * mLightRayMod);
+            Con::setVariable("$LightRayPostFX::brightScalar", buf);
+         }
+         if (!mModifLightRays)
+         {
+            char buf[20];
+            dSprintf(buf, sizeof(buf), "%3.7f", mOldLightRayStrength);
+            Con::setVariable("$LightRayPostFX::brightScalar", buf);
+         }
+      }
+   }
+   if (stream->readFlag())//Volumetric Fog
+   {
+      mIgnoreWater = stream->readFlag();
+      mReflect = stream->readFlag();
+      stream->read(&mFogReflStrength);
+      mResizing = stream->readFlag();
+      stream->read(&mMinDisplaySize);
+      stream->read(&mFadeSize);
+   }
+   if (stream->readFlag())//Fog shape
+   {
+      mShapeName = stream->readSTString();
+      mathRead(*stream, &mat);
+      mathRead(*stream, &scale);
+      if (strcmp(oldShape, mShapeName) != 0)
+      {
+         mIsVBDirty = true;
+         mShapeLoaded = LoadShape();
+      }
+      setScale(scale);
+      setTransform(mat);
+      ColBox.set(getTransform(), (mObjBox.getExtents() * getScale() * COLBOX_SCALE));
+      mObjSize = mWorldBox.getGreatestDiagonalLength();
+      mObjScale = getScale();
+      mInvScale = (1.0f / getMax(getMax(mObjScale.x, mObjScale.y), mObjScale.z));
+   }
+}
+
+void VolumetricFog::processTick(const Move* move)
+{
+   Parent::processTick(move);
+   mCounter++;
+   if ( mGlowing==1 && mCurGlow < mGlowStrength )
+   {
+      mCurGlow += (mGlowStrength / 10.0);
+      char buf[20];
+      dSprintf(buf, sizeof(buf), "%3.7f", mCurGlow);
+      Con::setVariable("$VolFogGlowPostFx::glowStrength", buf);
+   }
+   else if ( mGlowing == 2 && mCurGlow > 0.0f )
+   {
+      mCurGlow -= (mGlowStrength / 5.0f);
+      if (mCurGlow <= 0.0f)
+      {
+         glowFX->disable();
+         mGlowing = 0;
+         setProcessTick(false);
+         return;
+      }
+      else
+      {
+         char buf[20];
+         dSprintf(buf, sizeof(buf), "%3.7f", mCurGlow);
+         Con::setVariable("$VolFogGlowPostFx::glowStrength", buf);
+      }
+   }
+   if (mCounter == 3)
+   {
+      ShapeBase* control = static_cast<ShapeBase*>(conn->getControlObject());
+      MatrixF xfm;
+      control->getRenderEyeTransform(&xfm);
+      Point3F pos = xfm.getPosition();
+      if (!ColBox.isContained(pos))
+         _leaveFog(control);
+      mCounter = 0;
+   }
+}
+
+void VolumetricFog::_enterFog(ShapeBase *control)
+{
+   if (mUseGlow)
+   {
+      if (glowFX)
+      {
+         mCurGlow = 0.0f;
+         Con::setVariable("$VolFogGlowPostFx::glowStrength", "0.0");
+         glowFX->enable();
+         mGlowing = 1;
+      }
+   }
+   if (mModifLightRays)
+   {
+      char buf[20];
+      dSprintf(buf, sizeof(buf), "%3.7f", mOldLightRayStrength * mLightRayMod);
+      Con::setVariable("$LightRayPostFX::brightScalar", buf);
+   }
+   mCounter = 0;
+   char buf[20];
+   dSprintf(buf, sizeof(buf), "%3.7f", mFogDensity);
+   Con::setVariable("$VolumetricFog::density", buf);
+   setProcessTick(true);
+   if (control)
+      onEnterFog_callback(control->getId());
+}
+
+void VolumetricFog::_leaveFog(ShapeBase *control)
+{
+   mCamInFog = false;
+   Con::setVariable("$VolumetricFog::density", "0.0");
+   if (mModifLightRays)
+   {
+      char buf[20];
+      dSprintf(buf, sizeof(buf), "%3.7f", mOldLightRayStrength);
+      Con::setVariable("$LightRayPostFX::brightScalar", buf);
+   }
+   if (mUseGlow)
+   {
+      if (glowFX && mGlowing != 2)
+      {
+         mCurGlow = mGlowStrength;
+         mGlowing = 2;
+         if (control)
+            onLeaveFog_callback(control->getId());
+      }
+   }
+   else
+   {
+      setProcessTick(false);
+      if (control)
+         onLeaveFog_callback(control->getId());
+   }
+}
+
+//-----------------------------------------------------------------------------
+// Setting up the renderers
+//-----------------------------------------------------------------------------
+
+bool VolumetricFog::setupRenderer()
+{
+   // Search for the prepass rendertarget and shadermacros.
+   mPrepassTarget = NamedTexTarget::find("prepass");
+   if (!mPrepassTarget.isValid())
+   {
+      Con::errorf("VolumetricFog::setupRenderer - could not find PrepassTarget");
+      return false;
+   }
+
+   Vector<GFXShaderMacro> macros;
+   if (mPrepassTarget)
+      mPrepassTarget->getShaderMacros(&macros);
+
+   // Search the depth and frontbuffers which are created by the VolumetricFogRTManager
+
+   mDepthBufferTarget = NamedTexTarget::find("volfogdepth");
+   if (!mDepthBufferTarget.isValid())
+   {
+      Con::errorf("VolumetricFog::setupRenderer - could not find depthbuffer");
+      return false;
+   }
+
+   mFrontBufferTarget = NamedTexTarget::find("volfogfront");
+   if (!mFrontBufferTarget.isValid())
+   {
+      Con::errorf("VolumetricFog::setupRenderer - could not find frontbuffer");
+      return false;
+   }
+
+   // Find and setup the prepass Shader
+
+   ShaderData *shaderData;
+   mPrePassShader = Sim::findObject("VolumetricFogPrePassShader", shaderData) ?
+   shaderData->getShader() : NULL;
+   if (!mPrePassShader)
+   {
+      Con::errorf("VolumetricFog::setupRenderer - could not find VolumetricFogPrePassShader");
+      return false;
+   }
+
+   // Create ShaderConstBuffer and Handles
+
+   mPPShaderConsts = mPrePassShader->allocConstBuffer();
+   if (mPPShaderConsts.isNull())
+   {
+      Con::errorf("VolumetricFog::setupRenderer - could not allocate ShaderConstants 1.");
+      return false;
+   }
+
+   mPPModelViewProjSC = mPrePassShader->getShaderConstHandle("$modelView");
+
+   // Find and setup the VolumetricFog Shader
+
+   shaderData = NULL;
+   mShader = Sim::findObject("VolumetricFogShader", shaderData) ?
+   shaderData->getShader(macros) : NULL;
+   if (!mShader)
+   {
+      Con::errorf("VolumetricFog::setupRenderer - could not find VolumetricFogShader");
+      return false;
+   }
+
+   // Create ShaderConstBuffer and Handles
+
+   mShaderConsts = mShader->allocConstBuffer();
+   if (mShaderConsts.isNull())
+   {
+      Con::errorf("VolumetricFog::setupRenderer - could not allocate ShaderConstants 2.");
+      return false;
+   }
+
+   mModelViewProjSC = mShader->getShaderConstHandle("$modelView");
+   mFadeSizeSC = mShader->getShaderConstHandle("$fadesize");
+   mFogColorSC = mShader->getShaderConstHandle("$fogColor");
+   mFogDensitySC = mShader->getShaderConstHandle("$fogDensity");
+   mPreBias = mShader->getShaderConstHandle("$preBias");
+   mAccumTime = mShader->getShaderConstHandle("$accumTime");
+   mIsTexturedSC = mShader->getShaderConstHandle("$textured");
+   mTexTilesSC = mShader->getShaderConstHandle("$numtiles");
+   mModStrengthSC = mShader->getShaderConstHandle("$modstrength");
+   mModSpeedSC = mShader->getShaderConstHandle("$modspeed");
+   mViewPointSC = mShader->getShaderConstHandle("$viewpoint");
+   mTexScaleSC = mShader->getShaderConstHandle("$texscale");
+   mAmbientColorSC = mShader->getShaderConstHandle("$ambientColor");
+
+   // Find and setup the reflection Shader
+
+   shaderData = NULL;
+   mReflectionShader = Sim::findObject("VolumetricFogReflectionShader", shaderData) ?
+   shaderData->getShader() : NULL;
+   if (!mReflectionShader)
+   {
+      Con::errorf("VolumetricFog::setupRenderer - could not find VolumetricFogReflectionShader");
+      return false;
+   }
+
+   mReflShaderConsts = mReflectionShader->allocConstBuffer();
+   if (mReflShaderConsts.isNull())
+   {
+      Con::errorf("VolumetricFog::setupRenderer - could not allocate ShaderConstants for VolumetricFogReflectionShader.");
+      return false;
+   }
+
+   mReflModelViewProjSC = mReflectionShader->getShaderConstHandle("$modelView");
+   mReflFogColorSC = mReflectionShader->getShaderConstHandle("$fogColor");
+   mReflFogDensitySC = mReflectionShader->getShaderConstHandle("$fogDensity");
+   mReflFogStrengthSC = mReflectionShader->getShaderConstHandle("$reflStrength");
+
+   // Create the prepass StateBlock
+
+   desc_preD.setCullMode(GFXCullCW);
+   desc_preD.setBlend(true);
+   desc_preD.setZReadWrite(false, false);
+   desc_preD.stencilEnable = false;
+   desc_preF.setCullMode(GFXCullCCW);
+   desc_preF.setBlend(true);
+   desc_preF.setZReadWrite(true, false);
+   desc_preF.stencilEnable = false;
+   
+   // Create the VolumetricFog StateBlock
+
+   descD.setCullMode(GFXCullCW);
+   descD.setBlend(true);
+   descD.setZReadWrite(false, false);// desc.setZReadWrite(true, false);
+
+   // prepassBuffer sampler
+   descD.samplersDefined = true;
+   descD.samplers[0].addressModeU = GFXAddressClamp;
+   descD.samplers[0].addressModeV = GFXAddressClamp;
+   descD.samplers[0].addressModeW = GFXAddressClamp;
+   descD.samplers[0].magFilter = GFXTextureFilterLinear;
+   descD.samplers[0].minFilter = GFXTextureFilterLinear;
+   descD.samplers[0].mipFilter = GFXTextureFilterLinear;
+   descD.samplers[0].textureColorOp = GFXTOPDisable;
+
+   // DepthBuffer sampler
+   descD.samplers[1].addressModeU = GFXAddressClamp;
+   descD.samplers[1].addressModeV = GFXAddressClamp;
+   descD.samplers[1].addressModeW = GFXAddressClamp;
+   descD.samplers[1].magFilter = GFXTextureFilterLinear;
+   descD.samplers[1].minFilter = GFXTextureFilterLinear;
+   descD.samplers[1].mipFilter = GFXTextureFilterLinear;
+   descD.samplers[1].textureColorOp = GFXTOPModulate;
+
+   // FrontBuffer sampler
+   descD.samplers[2].addressModeU = GFXAddressClamp;
+   descD.samplers[2].addressModeV = GFXAddressClamp;
+   descD.samplers[2].addressModeW = GFXAddressClamp;
+   descD.samplers[2].magFilter = GFXTextureFilterLinear;
+   descD.samplers[2].minFilter = GFXTextureFilterLinear;
+   descD.samplers[2].mipFilter = GFXTextureFilterLinear;
+   descD.samplers[2].textureColorOp = GFXTOPModulate;
+
+   // animated density modifier map sampler
+   descD.samplers[3].addressModeU = GFXAddressWrap;
+   descD.samplers[3].addressModeV = GFXAddressWrap;
+   descD.samplers[3].addressModeW = GFXAddressWrap;
+   descD.samplers[3].magFilter = GFXTextureFilterLinear;
+   descD.samplers[3].minFilter = GFXTextureFilterLinear;
+   descD.samplers[3].mipFilter = GFXTextureFilterLinear;
+   descD.samplers[3].textureColorOp = GFXTOPModulate;
+
+   dMemcpy(&descF, &descD, sizeof(GFXStateBlockDesc));
+   descF.setCullMode(GFXCullCCW);
+   descF.setBlend(true);
+   descF.setZReadWrite(true, false);
+
+   desc_refl.setCullMode(GFXCullCCW);
+   desc_refl.setBlend(true);
+   desc_refl.setZReadWrite(true, false);
+
+   mStateblock_preD = GFX->createStateBlock(desc_preD);
+   mStateblock_preF = GFX->createStateBlock(desc_preF);
+   mStateblockD = GFX->createStateBlock(descD);
+   mStateblockF = GFX->createStateBlock(descF);
+   mStateblock_refl = GFX->createStateBlock(desc_refl);
+
+   // Create Rendertarget
+
+   z_buf = GFX->allocRenderToTextureTarget();
+   if (z_buf == NULL)
+   {
+      Con::errorf("VolumetricFog::setupRenderer - Could not create Render Target");
+      return false;
+   }
+
+   return true;
+}
+
+void VolumetricFog::prepRenderImage(SceneRenderState *state)
+{
+   if (!mShapeLoaded || mFogDensity <= 0.0f || mResizing)
+      return;
+
+   if (!state->isDiffusePass())
+   {
+      if (!state->isReflectPass())
+      return;
+   }
+   
+   PROFILE_SCOPE(VolumetricFog_prepRenderImage);
+
+   // Time critical therefore static_cast
+   ShapeBase* control = static_cast<ShapeBase*>(conn->getControlObject());
+   if (control->getWaterCoverage() >= 0.9f && !mIgnoreWater)
+      return;
+
+   camPos = state->getCameraPosition();
+   F32 dist = (camPos - getBoxCenter()).len();
+   F32 scaleFactor = dist * mInvScale;
+   if (scaleFactor <= 0.0f)
+   {
+      if (mCurDetailLevel != 0)
+         UpdateBuffers(0);
+   }
+   const F32 pixelScale = state->getViewport().extent.y / 300.0f;
+
+   mPixelSize = (mRadius / scaleFactor) * state->getWorldToScreenScale().y * pixelScale;
+   if (mPixelSize < mMinDisplaySize)
+      return;
+   if (mNumDetailLevels > 1)
+   {
+      if ((det_size[mCurDetailLevel].det_size > mPixelSize) && (mCurDetailLevel < mNumDetailLevels - 1))
+         UpdateBuffers(mCurDetailLevel + 1);
+      else if (mCurDetailLevel > 0)
+      {
+         if (mPixelSize >= det_size[mCurDetailLevel - 1].det_size)
+            UpdateBuffers(mCurDetailLevel - 1);
+      }
+   }
+
+   if (state->isReflectPass() && mReflect)
+   {
+      ObjectRenderInst *ri = state->getRenderPass()->allocInst<ObjectRenderInst>();
+      ri->renderDelegate.bind(this, &VolumetricFog::reflect_render);
+      ri->type = RenderPassManager::RIT_VolumetricFog;
+      ri->translucentSort = true;
+      ri->sortDistSq = getRenderWorldBox().getSqDistanceToPoint(camPos);
+      if (dist < 1.0f)
+         ri->defaultKey = 1;
+      else
+         ri->defaultKey = U32(dist);
+      state->getRenderPass()->addInst(ri);
+      return;
+   }
+   else if (state->isDiffusePass())
+   {
+      viewDist = state->getFarPlane();
+      mFOV = state->getCameraFrustum().getFov() / M_PI_F;
+      Point3F mEyeVec = state->getVectorEye() * viewDist;
+
+      mViewPoint.x = ((mAtan2(mEyeVec.x, mEyeVec.y) / M_PI_F) + 1.0f) * mTexTiles;
+      mViewPoint.y = (0.5f - (mAsin(mEyeVec.z) / M_PI_F)) * mTexTiles;
+
+      bool isInside = ColBox.isContained(camPos);
+      if (isInside && !mCamInFog)
+      {
+         mCamInFog = true;
+         _enterFog(control);
+      }
+      else if (!isInside && mCamInFog)
+         mCamInFog = false;
+
+      ObjectRenderInst *ri = state->getRenderPass()->allocInst<ObjectRenderInst>();
+      ri->renderDelegate.bind(this, &VolumetricFog::render);
+      ri->type = RenderPassManager::RIT_VolumetricFog;
+      ri->translucentSort = true;
+      ri->sortDistSq = getRenderWorldBox().getSqDistanceToPoint(camPos);
+      if (dist < 1.0f)
+         ri->defaultKey = 1;
+      else
+         ri->defaultKey = U32(dist);
+      state->getRenderPass()->addInst(ri);
+      return;
+   }
+   return;
+}
+
+void VolumetricFog::render(ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat)
+{
+   if (overrideMat || !mShapeLoaded || !isClientObject() || mResizing)
+      return;
+
+   PROFILE_SCOPE(VolumetricFog_Render);
+
+   GFXTransformSaver saver;
+   GFX->setVertexBuffer(mVB);
+   GFX->setPrimitiveBuffer(mPB);
+
+   MatrixF mat = getRenderTransform();
+   mat.scale(mObjScale);
+   GFX->multWorld(mat);
+
+   GFX->setShader(mPrePassShader);
+   GFX->setShaderConstBuffer(mPPShaderConsts);
+   GFX->setStateBlock(mStateblock_preD);
+
+   // Set all the shader consts...
+
+   MatrixF xform(GFX->getProjectionMatrix());
+   xform *= GFX->getViewMatrix();
+   xform *= GFX->getWorldMatrix();
+
+   mPPShaderConsts->setSafe(mPPModelViewProjSC, xform);
+
+   LightInfo *lightinfo = LIGHTMGR->getSpecialLight(LightManager::slSunLightType);
+   const ColorF &sunlight = state->getAmbientLightColor();
+
+   Point3F ambientColor(sunlight.red, sunlight.green, sunlight.blue);
+   mShaderConsts->setSafe(mAmbientColorSC, ambientColor);
+
+   GFXTextureObject *mDepthBuffer = mDepthBufferTarget ? mDepthBufferTarget->getTexture(0) : NULL;
+   GFXTextureObject *mFrontBuffer = mFrontBufferTarget ? mFrontBufferTarget->getTexture(0) : NULL;
+
+   GFX->pushActiveRenderTarget();
+
+   //render backside to target mDepthBuffer
+   z_buf->attachTexture(GFXTextureTarget::DepthStencil, GFXTextureTarget::sDefaultDepthStencil);
+   z_buf->attachTexture(GFXTextureTarget::Color0, mDepthBuffer);
+
+   GFX->setActiveRenderTarget(z_buf);
+   GFX->clear(GFXClearStencil | GFXClearTarget , ColorI(0,0,0,0), 1.0f, 0);
+
+   GFX->drawPrimitive(0);
+   z_buf->resolve();
+
+   //render frontside to target mFrontBuffer
+   z_buf->attachTexture(GFXTextureTarget::DepthStencil, GFXTextureTarget::sDefaultDepthStencil);
+   z_buf->attachTexture(GFXTextureTarget::Color0, mFrontBuffer);
+   GFX->clear(GFXClearStencil | GFXClearTarget, ColorI(0, 0, 0, 0), 1.0f, 0);
+
+   GFX->setStateBlock(mStateblock_preF);
+
+   GFX->drawPrimitive(0);
+   z_buf->resolve();
+
+   GFX->popActiveRenderTarget();
+   z_buf->attachTexture(GFXTextureTarget::Color0, NULL);
+
+   //render Volumetric Fog
+   GFX->setShader(mShader);
+   GFX->setShaderConstBuffer(mShaderConsts);
+
+   mShaderConsts->setSafe(mModelViewProjSC, xform);
+   if (mFadeSize > 0.0f)
+      mShaderConsts->setSafe(mFadeSizeSC, mClampF(mPixelSize / mFadeSize, 0.0f, 1.0f));
+   else
+      mShaderConsts->setSafe(mFadeSizeSC, 1.0f);
+   mShaderConsts->setSafe(mFogColorSC, mFogColor);
+   mShaderConsts->setSafe(mFogDensitySC, mFogDensity);
+   mShaderConsts->setSafe(mPreBias, viewDist);
+   mShaderConsts->setSafe(mAccumTime, (F32)Sim::getCurrentTime() / 1000.0f);
+   mShaderConsts->setSafe(mModStrengthSC, mStrength);
+   mShaderConsts->setSafe(mModSpeedSC, mSpeed);
+   mShaderConsts->setSafe(mViewPointSC, mViewPoint);
+   mShaderConsts->setSafe(mTexScaleSC, mTexScale * mFOV);
+   mShaderConsts->setSafe(mTexTilesSC, mTexTiles);
+
+   GFXTextureObject *prepasstex = mPrepassTarget ? mPrepassTarget->getTexture(0) : NULL;
+
+   GFX->setTexture(0, prepasstex);
+   GFX->setTexture(1, mDepthBuffer);
+   GFX->setTexture(2, mFrontBuffer);
+
+   if (mIsTextured && mStrength > 0.0f)
+   {
+      GFX->setTexture(3, mTexture);
+      mShaderConsts->setSafe(mIsTexturedSC, 1.0f);
+   }
+   else
+      mShaderConsts->setSafe(mIsTexturedSC, 0.0f);
+
+   if (mCamInFog)
+   {
+      /*GFXLockedRect *rect=mDepthBuffer->lock();
+      U32 pixoffset = 0;// 1572864 + (512 * 4);
+      U8 red = rect->bits[pixoffset];
+      U8 green = rect->bits[pixoffset+1];
+      U8 blue = rect->bits[pixoffset+2];
+      U8 alpha = rect->bits[pixoffset+3];
+      mDepthBuffer->unlock();
+      S32 lval = ((alpha << 24) + (blue << 16) + (green << 8) + (red));
+      F32 fval = ((F32)lval / S32_MAX);
+      Con::printf("Color %d %d %d %d %d %f", red, green, blue, alpha, lval, fval);*/
+      GFX->setStateBlock(mStateblockD);
+   }
+   else
+      GFX->setStateBlock(mStateblockF);
+
+   GFX->drawPrimitive(0);
+}
+
+void VolumetricFog::reflect_render(ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat)
+{
+   if (overrideMat || !mShapeLoaded || !isClientObject() || mResizing || (mFogReflStrength==0.0f))
+      return;
+
+   GFXTransformSaver saver;
+   GFX->setVertexBuffer(mVB);
+   GFX->setPrimitiveBuffer(mPB);
+
+   MatrixF mat = getRenderTransform();
+   mat.scale(mObjScale);
+   GFX->multWorld(mat);
+
+   GFX->setShader(mReflectionShader);
+   GFX->setShaderConstBuffer(mReflShaderConsts);
+   GFX->setStateBlock(mStateblock_refl);
+
+   // Set all the shader consts...
+   MatrixF xform(GFX->getProjectionMatrix());
+   xform *= GFX->getViewMatrix();
+   xform *= GFX->getWorldMatrix();
+
+   mReflShaderConsts->setSafe(mReflModelViewProjSC, xform);
+   mReflShaderConsts->setSafe(mReflFogColorSC, mFogColor);
+   mReflShaderConsts->setSafe(mReflFogDensitySC, mFogDensity);
+   mReflShaderConsts->setSafe(mReflFogStrengthSC, mFogReflStrength);
+
+   GFX->drawPrimitive(0);
+}
+
+//-----------------------------------------------------------------------------
+// InitTexture is called whenever a modulation texture is added to the object
+//-----------------------------------------------------------------------------
+
+void VolumetricFog::InitTexture()
+{
+   mIsTextured = false;
+
+   if (mTextureName.isNotEmpty())
+      mTexture.set(mTextureName, &GFXDefaultStaticDiffuseProfile, "VolumetricFogMod");
+
+   if (!mTexture.isNull())
+   {
+      mIsTextured = true;
+
+      F32 width = (F32)mPlatformWindow->getClientExtent().x;
+      F32 height = (F32)mPlatformWindow->getClientExtent().y;
+
+      if (!mPlatformWindow->isFullscreen())
+         height -= 20;//subtract caption bar from rendertarget size.
+
+      mTexScale.x = 2.0f - ((F32)mTexture.getWidth() / width);
+      mTexScale.y = 2.0f - ((F32)mTexture.getHeight() / height);
+   }
+}
+
+void VolumetricFog::setFogColor(ColorF color)
+{
+   mFogColor.set(255 * color.red,255 * color.green,255 * color.blue);
+   setMaskBits(FogColorMask);
+}
+
+void VolumetricFog::setFogColor(ColorI color)
+{
+   mFogColor = color;
+   setMaskBits(FogColorMask);
+}
+
+void VolumetricFog::setFogDensity(F32 density)
+{
+   if (density < 0.0f)
+      density = 0.0f;
+   mFogDensity = density;
+   setMaskBits(FogDensityMask);
+}
+
+void VolumetricFog::setFogModulation(F32 strength,Point2F speed1,Point2F speed2)
+{
+   mStrength = strength;
+   mSpeed1 = speed1;
+   mSpeed2 = speed2;
+   mSpeed.set(speed1.x, speed1.y, speed2.x, speed2.y);
+   setMaskBits(FogModulationMask);
+}
+
+void VolumetricFog::setFogGlow(bool on_off, F32 strength)
+{
+   mUseGlow = on_off;
+   mGlowStrength = strength;
+   setMaskBits(FogPostFXMask);
+}
+
+void VolumetricFog::setFogLightray(bool on_off, F32 strength)
+{
+   mModifLightRays = on_off;
+   mLightRayMod = strength;
+   setMaskBits(FogPostFXMask);
+}
+
+bool VolumetricFog::isInsideFog()
+{
+   return mCamInFog;
+}
+
+DefineEngineMethod(VolumetricFog, SetFogColorF, void, (ColorF new_color), ,
+"@brief Changes the color of the fog\n\n."
+"@params new_color the new fog color (rgb 0.0 - 1.0, a is ignored.")
+{
+   object->setFogColor(new_color);
+}
+
+DefineEngineMethod(VolumetricFog, SetFogColor, void, (ColorI new_color), ,
+"@brief Changes the color of the fog\n\n."
+"@params new_color the new fog color (rgb 0-255, a is ignored.")
+{
+   object->setFogColor(new_color);
+}
+
+DefineEngineMethod(VolumetricFog, SetFogDensity, void, (F32 new_density), ,
+"@brief Changes the density of the fog\n\n."
+"@params new_density the new fog density.")
+{
+   object->setFogDensity(new_density);
+}
+
+DefineEngineMethod(VolumetricFog, SetFogModulation, void, (F32 new_strenght, Point2F new_speed1, Point2F new_speed2), ,
+"@brief Changes the modulation of the fog\n\n."
+"@params new_strenght the new strength of the modulation.\n"
+"@params new_speed1 the new speed (x y) of the modulation layer 1.\n"
+"@params new_speed2 the new speed (x y) of the modulation layer 2.\n")
+{
+   object->setFogModulation(new_strenght, new_speed1, new_speed2);
+}
+
+DefineEngineMethod(VolumetricFog, SetFogGlow, void, (bool on_off,F32 strength), ,
+"@brief Changes the glow postfx when inside the fog\n\n."
+"@params on_off set to true to enable glow.\n"
+"@params strength glow strength.\n")
+{
+   object->setFogGlow(on_off, strength);
+}
+
+DefineEngineMethod(VolumetricFog, SetFogLightray, void, (bool on_off, F32 strength), ,
+"@brief Changes the lightrays postfx when inside the fog\n\n."
+"@params on_off set to true to modification of the lightray postfx.\n"
+"@params strength lightray strength.\n")
+{
+   object->setFogLightray(on_off, strength);
+}
+
+DefineEngineMethod(VolumetricFog, isInsideFog, bool, (), ,
+"@brief returns true if control object is inside the fog\n\n.")
+{
+   return object->isInsideFog();
+}

+ 243 - 0
Engine/source/environment/VolumetricFog.h

@@ -0,0 +1,243 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+   
+#ifndef _VolumetricFog_H_
+#define _VolumetricFog_H_
+   
+#ifndef _SCENEOBJECT_H_
+#include "scene/sceneObject.h"
+#endif
+#ifndef _MATTEXTURETARGET_H_
+#include "materials/matTextureTarget.h"
+#endif
+#ifndef _GFXSHADER_H_
+#include "gfx/gfxShader.h"
+#endif
+#ifndef _GFXTARGET_H_
+#include "gfx/gfxTarget.h"
+#endif
+#ifndef _GFXVERTEXBUFFER_H_
+#include "gfx/gfxVertexBuffer.h"
+#endif
+#ifndef _TSSHAPE_H_
+#include "ts/tsShape.h"
+#endif
+#ifndef _POST_EFFECT_H_
+#include "postFx/postEffect.h"
+#endif
+   
+#include "gui/core/guiCanvas.h"
+   
+class VolumetricFogRTManager;
+   
+class VolumetricFog : public SceneObject
+{
+   typedef SceneObject Parent;
+   
+   // Maskbits for updating
+   enum
+   {
+      VolumetricFogMask = Parent::NextFreeMask,
+      FogColorMask = Parent::NextFreeMask << 1,
+      FogDensityMask = Parent::NextFreeMask << 2,
+      FogModulationMask = Parent::NextFreeMask << 3,
+      FogPostFXMask = Parent::NextFreeMask << 4,
+      FogShapeMask = Parent::NextFreeMask << 5,
+      NextFreeMask = Parent::NextFreeMask << 6
+   };
+   
+// Struct which holds the shape details
+   struct meshes
+   {
+      F32 det_size;
+      S32 sub_shape;
+      S32 obj_det;
+      U32 num_verts;
+      GFXVertexPNTT *verts;
+      Vector <GFXPrimitive> *piArray;
+      Vector <U32> *indices;
+   };
+   
+   protected:
+      // Rendertargets;
+      GFXTextureTargetRef z_buf;
+      NamedTexTargetRef mPrepassTarget;
+      NamedTexTargetRef mDepthBufferTarget;
+      NamedTexTargetRef mFrontBufferTarget;
+   
+      // Fog Modulation texture
+      GFXTexHandle mTexture;
+   
+      // Shaders
+      GFXShaderRef mShader;
+      GFXShaderRef mPrePassShader;
+      GFXShaderRef mReflectionShader;
+   
+      // Stateblocks
+      GFXStateBlockDesc descD;
+      GFXStateBlockDesc descF;
+      GFXStateBlockDesc desc_preD;
+      GFXStateBlockDesc desc_preF;
+      GFXStateBlockDesc desc_refl;
+   
+      GFXStateBlockRef mStateblockD;
+      GFXStateBlockRef mStateblockF;
+      GFXStateBlockRef mStateblock_preD;
+      GFXStateBlockRef mStateblock_preF;
+      GFXStateBlockRef mStateblock_refl;
+   
+      // Shaderconstants
+      GFXShaderConstBufferRef mShaderConsts;
+      GFXShaderConstHandle *mModelViewProjSC;
+      GFXShaderConstHandle *mFadeSizeSC;
+      GFXShaderConstHandle *mFogColorSC;
+      GFXShaderConstHandle *mFogDensitySC;
+      GFXShaderConstHandle *mPreBias;
+      GFXShaderConstHandle *mAccumTime;
+      GFXShaderConstHandle *mIsTexturedSC;
+      GFXShaderConstHandle *mModSpeedSC;
+      GFXShaderConstHandle *mModStrengthSC;
+      GFXShaderConstHandle *mViewPointSC;
+      GFXShaderConstHandle *mTexScaleSC;
+      GFXShaderConstHandle *mTexTilesSC;
+   
+      GFXShaderConstBufferRef mPPShaderConsts;
+      GFXShaderConstHandle *mPPModelViewProjSC;
+
+      GFXShaderConstHandle *mAmbientColorSC;
+   
+      GFXShaderConstBufferRef mReflShaderConsts;
+      GFXShaderConstHandle *mReflModelViewProjSC;
+      GFXShaderConstHandle *mReflFogColorSC;
+      GFXShaderConstHandle *mReflFogDensitySC;
+      GFXShaderConstHandle *mReflFogStrengthSC;
+   
+      // Vertex and Prim. Buffer
+      GFXVertexBufferHandle<GFXVertexPNTT> mVB;
+      GFXPrimitiveBufferHandle mPB;
+   
+      // Fog volume data;
+      StringTableEntry mShapeName;
+      ColorI mFogColor;
+      F32 mFogDensity;
+      bool mIgnoreWater;
+      bool mReflect;
+      Vector<meshes> det_size;
+      bool mShapeLoaded;
+      F32 mPixelSize;
+      F32 mFadeSize;
+      U32 mCurDetailLevel;
+      U32 mNumDetailLevels;
+      F32 mObjSize;
+      F32 mRadius;
+      OrientedBox3F ColBox;
+      VectorF mObjScale;
+      F32 mMinDisplaySize;
+      F32 mInvScale;
+   
+      // Fog Modulation data
+      String mTextureName;
+      bool mIsTextured;
+      F32 mTexTiles;
+      F32 mStrength;
+      Point2F mSpeed1;
+      Point2F mSpeed2;
+      Point4F mSpeed;
+      Point2F mTexScale;
+   
+      // Fog Rendering data
+      Point3F camPos;
+      Point2F mViewPoint;
+      F32 mFOV;
+      F32 viewDist;
+      bool mIsVBDirty;
+      bool mIsPBDirty;
+      bool mCamInFog;
+      bool mResizing;
+      PlatformWindow *mPlatformWindow;
+   
+      // Reflections
+      F32 mFogReflStrength;
+   
+      // PostFX
+      PostEffect *glowFX;
+      bool mUseGlow;
+      F32 mGlowStrength;
+      U8 mGlowing;
+      F32 mCurGlow;
+   
+      bool mModifLightRays;
+      F32 mLightRayMod;
+      F32 mOldLightRayStrength;
+   
+      GameConnection* conn;
+      U32 mCounter;
+   
+      void ResizeRT(PlatformWindow *win, bool resize);
+   
+   protected:
+      // Protected methods
+      bool onAdd();
+      void onRemove();
+      void handleResize(VolumetricFogRTManager *RTM, bool resize);
+      void handleCanvasResize(GuiCanvas* canvas);
+   
+      bool LoadShape();
+      bool setupRenderer();
+      void InitTexture();
+      bool UpdateBuffers(U32 dl,bool force=true);
+   
+      void processTick(const Move *move);
+      void _enterFog(ShapeBase *control);
+      void _leaveFog(ShapeBase *control);
+   
+   public:
+      // Public methods
+      VolumetricFog();
+      ~VolumetricFog();
+   
+      static void initPersistFields();
+      virtual void inspectPostApply();
+   
+      U32 packUpdate(NetConnection *conn, U32 mask, BitStream *stream);
+      void unpackUpdate(NetConnection *conn, BitStream *stream);
+   
+      void prepRenderImage(SceneRenderState* state);
+      void render(ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat);
+      void reflect_render(ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *overrideMat);
+   
+      // Methods for modifying & networking various fog elements
+      // Used in script
+      void setFogColor(ColorF color);
+      void setFogColor(ColorI color);
+      void setFogDensity(F32 density);
+      void setFogModulation(F32 strength, Point2F speed1, Point2F speed2);
+      void setFogGlow(bool on_off, F32 strength);
+      void setFogLightray(bool on_off, F32 strength);
+      bool isInsideFog();
+   
+      DECLARE_CONOBJECT(VolumetricFog);
+   
+      DECLARE_CALLBACK(void, onEnterFog, (SimObjectId obj));
+      DECLARE_CALLBACK(void, onLeaveFog, (SimObjectId obj));
+};
+#endif

+ 299 - 0
Engine/source/environment/VolumetricFogRTManager.cpp

@@ -0,0 +1,299 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+   
+//-----------------------------------------------------------------------------
+// Volumetric Fog Rendertarget Manager
+//
+// Creates and maintains one set of rendertargets to be used by every
+// VolumetricFog object in the scene.
+//
+// Will be loaded at startup end removed when ending game.
+//
+//-----------------------------------------------------------------------------
+   
+#include "VolumetricFogRTManager.h"
+#include "core/module.h"
+#include "scene/sceneManager.h"
+#include "windowManager/platformWindowMgr.h"
+#include "console/engineAPI.h"
+#include "gui/core/guiCanvas.h"
+   
+MODULE_BEGIN(VolumetricFogRTManager)
+   
+MODULE_INIT_AFTER(Scene)
+MODULE_SHUTDOWN_BEFORE(Scene)
+   
+MODULE_INIT
+{
+   gVolumetricFogRTManager = new VolumetricFogRTManager;
+   gClientSceneGraph->addObjectToScene(gVolumetricFogRTManager);
+}
+   
+MODULE_SHUTDOWN
+{
+   gClientSceneGraph->removeObjectFromScene(gVolumetricFogRTManager);
+   SAFE_DELETE(gVolumetricFogRTManager);
+}
+   
+MODULE_END;
+   
+ConsoleDocClass( VolumetricFogRTManager,
+"@brief Creates and maintains one set of rendertargets to be used by every\n"
+"VolumetricFog object in the scene.\n\n"
+"Will be loaded at startup end removed when ending game.\n\n"
+"Methods:\n"
+" get() returns the currently loaded VolumetricFogRTManager, also accessible\n"
+" through VFRTM define.\n"
+" Init() Initializes the rendertargets, called when a VolumetricFog object is\n"
+" added to the scene.\n"
+" isInitialed() returns true if Rendertargets are present, false if not, then\n"
+" Init() should be called to create the rendertargets.\n"
+" setQuality(U32 Quality) Normally a rendertarget has the same size as the view,\n"
+" with this method you can scale down the size of it.\n"
+" Be aware that scaling down will introduce renderartefacts.\n"
+"@ingroup Atmosphere"
+);
+   
+VolumetricFogRTMResizeSignal VolumetricFogRTManager::smVolumetricFogRTMResizeSignal;
+   
+VolumetricFogRTManager *gVolumetricFogRTManager = NULL;
+
+S32 VolumetricFogRTManager::mTargetScale = 1;
+   
+IMPLEMENT_CONOBJECT(VolumetricFogRTManager);
+   
+VolumetricFogRTManager::VolumetricFogRTManager()
+{
+   setGlobalBounds();
+   mTypeMask |= EnvironmentObjectType;
+   mNetFlags.set(IsGhost);
+   mIsInitialized = false;
+   mNumFogObjects = 0;
+}
+   
+VolumetricFogRTManager::~VolumetricFogRTManager()
+{
+   if (mFrontTarget.isRegistered())
+      mFrontTarget.unregister();
+   
+   if (mDepthTarget.isRegistered())
+      mDepthTarget.unregister();
+   
+   if (mDepthBuffer.isValid())
+      mDepthBuffer->kill();
+   
+   if (mFrontBuffer.isValid())
+      mFrontBuffer->kill();
+}
+   
+void VolumetricFogRTManager::onSceneRemove()
+{
+   if (mIsInitialized)
+      mPlatformWindow->getScreenResChangeSignal().remove(this, &VolumetricFogRTManager::ResizeRT);
+}
+   
+void VolumetricFogRTManager::onRemove()
+{
+   removeFromScene();
+   Parent::onRemove();
+}
+   
+void VolumetricFogRTManager::consoleInit()
+{
+   Con::addVariable("$pref::VolumetricFog::Quality", TypeS32, &mTargetScale,
+   "The scale of the rendertargets.\n"
+   "@ingroup Rendering\n");
+}
+   
+bool VolumetricFogRTManager::Init()
+{
+   if (mIsInitialized)
+      {
+      Con::errorf("VolumetricFogRTManager allready initialized!!");
+      return true;
+      }
+   
+   GuiCanvas* cv = dynamic_cast<GuiCanvas*>(Sim::findObject("Canvas"));
+   if (cv == NULL)
+   {
+      Con::errorf("VolumetricFogRTManager::Init() - Canvas not found!!");
+      return false;
+   }
+   
+   mPlatformWindow = cv->getPlatformWindow();
+   mPlatformWindow->getScreenResChangeSignal().notify(this,&VolumetricFogRTManager::ResizeRT);
+   
+   if (mTargetScale < 1)
+      mTargetScale = 1;
+   
+   mWidth = mFloor(mPlatformWindow->getClientExtent().x / mTargetScale);
+   mHeight = mPlatformWindow->getClientExtent().y;
+   mFullScreen = mPlatformWindow->isFullscreen();
+   if (!mFullScreen)
+      mHeight -= 20;//subtract caption bar from rendertarget size.
+   mHeight = mFloor(mHeight / mTargetScale);
+   
+   mDepthBuffer = GFXTexHandle(mWidth, mHeight, GFXFormatR32F,
+   &GFXDefaultRenderTargetProfile, avar("%s() - mDepthBuffer (line %d)", __FUNCTION__, __LINE__));
+   if (!mDepthBuffer.isValid())
+   {
+      Con::errorf("VolumetricFogRTManager Fatal Error: Unable to create Depthbuffer");
+      return false;
+   }
+   if (!mDepthTarget.registerWithName("volfogdepth"))
+   {
+      Con::errorf("VolumetricFogRTManager Fatal Error : Unable to register Depthbuffer");
+      return false;
+   }
+   mDepthTarget.setTexture(mDepthBuffer);
+   
+   mFrontBuffer = GFXTexHandle(mWidth, mHeight, GFXFormatR32F,
+   &GFXDefaultRenderTargetProfile, avar("%s() - mFrontBuffer (line %d)", __FUNCTION__, __LINE__));
+   if (!mFrontBuffer.isValid())
+   {
+      Con::errorf("VolumetricFogRTManager Fatal Error: Unable to create front buffer");
+      return false;
+   }
+   if (!mFrontTarget.registerWithName("volfogfront"))
+   {
+      Con::errorf("VolumetricFogRTManager Fatal Error : Unable to register Frontbuffer");
+      return false;
+   }
+   
+   mFrontTarget.setTexture(mFrontBuffer);
+   
+   Con::setVariable("$VolumetricFog::density", "0.0");
+   
+   mIsInitialized = true;
+   
+   return true;
+}
+   
+U32 VolumetricFogRTManager::IncFogObjects()
+{
+   mNumFogObjects++;
+   return mNumFogObjects;
+}
+   
+U32 VolumetricFogRTManager::DecFogObjects()
+{
+   if (mNumFogObjects > 0)
+      mNumFogObjects--;
+   return mNumFogObjects;
+}
+   
+void VolumetricFogRTManager::ResizeRT(PlatformWindow* win,bool resize)
+{
+   mFogHasAnswered = 0;
+   smVolumetricFogRTMResizeSignal.trigger(this, true);
+}
+   
+void VolumetricFogRTManager::FogAnswered()
+{
+   mFogHasAnswered++;
+   if (mFogHasAnswered == mNumFogObjects)
+   {
+      if (Resize())
+         smVolumetricFogRTMResizeSignal.trigger(this, false);
+      else
+         Con::errorf("VolumetricFogRTManager::FogAnswered - Error resizing rendertargets!");
+   }
+}
+   
+bool VolumetricFogRTManager::Resize()
+{
+   if (mTargetScale < 1)
+      mTargetScale = 1;
+   mWidth = mFloor(mPlatformWindow->getClientExtent().x / mTargetScale);
+   mHeight = mPlatformWindow->getClientExtent().y;
+     
+   if (!mPlatformWindow->isFullscreen())
+      mHeight -= 20;//subtract caption bar from rendertarget size.
+   mHeight = mFloor(mHeight / mTargetScale);
+   
+   if (mWidth < 16 || mHeight < 16)
+      return false;
+   
+   if (mFrontTarget.isRegistered())
+      mFrontTarget.setTexture(NULL);
+   
+   if (mDepthTarget.isRegistered())
+      mDepthTarget.setTexture(NULL);
+   
+   if (mDepthBuffer.isValid())
+      mDepthBuffer->kill();
+   
+   if (mFrontBuffer.isValid())
+      mFrontBuffer->kill();
+   
+   mFrontBuffer = GFXTexHandle(mWidth, mHeight, GFXFormatR32F,
+   &GFXDefaultRenderTargetProfile, avar("%s() - mFrontBuffer (line %d)", __FUNCTION__, __LINE__));
+   if (!mFrontBuffer.isValid())
+      {
+      Con::errorf("VolumetricFogRTManager::Resize() Fatal Error: Unable to create front buffer");
+      return false;
+      }
+   mFrontTarget.setTexture(mFrontBuffer);
+   
+   mDepthBuffer = GFXTexHandle(mWidth, mHeight, GFXFormatR32F,
+   &GFXDefaultRenderTargetProfile, avar("%s() - mDepthBuffer (line %d)", __FUNCTION__, __LINE__));
+   if (!mDepthBuffer.isValid())
+      {
+         Con::errorf("VolumetricFogRTManager::Resize() Fatal Error: Unable to create Depthbuffer");
+         return false;
+      }
+   mDepthTarget.setTexture(mDepthBuffer);
+   return true;
+}
+   
+S32 VolumetricFogRTManager::setQuality(U32 Quality)
+{
+   if (!mIsInitialized)
+      return (mTargetScale = Quality);
+      
+   if (Quality < 1)
+      Quality = 1;
+   
+   if (Quality == mTargetScale)
+      return mTargetScale;
+   
+   mTargetScale = Quality;
+   
+   mFogHasAnswered = 0;
+   smVolumetricFogRTMResizeSignal.trigger(this, true);
+   
+   return mTargetScale;
+}
+   
+VolumetricFogRTManager* VolumetricFogRTManager::get()
+{
+   return gVolumetricFogRTManager;
+}
+   
+DefineConsoleFunction(SetFogVolumeQuality, S32, (U32 new_quality), ,
+"@brief Resizes the rendertargets of the Volumetric Fog object.\n"
+"@params new_quality new quality for the rendertargets 1 = full size, 2 = halfsize, 3 = 1/3, 4 = 1/4 ...")
+{
+   if (VFRTM == NULL)
+      return -1;
+   return VFRTM->setQuality(new_quality);
+}

+ 92 - 0
Engine/source/environment/VolumetricFogRTManager.h

@@ -0,0 +1,92 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+   
+#ifndef _VolumetricFogRTManager_H_
+#define _VolumetricFogRTManager_H_
+   
+#ifndef _SCENEOBJECT_H_
+#include "scene/sceneObject.h"
+#endif
+#ifndef _MATTEXTURETARGET_H_
+#include "materials/matTextureTarget.h"
+#endif
+#ifndef _GFXTARGET_H_
+#include "gfx/gfxTarget.h"
+#endif
+#ifndef _SIGNAL_H_
+#include "core/util/tSignal.h"
+#endif
+   
+class VolumetricFogRTManager;
+   
+typedef Signal<void(VolumetricFogRTManager *VolumetricFogRTManager, bool resize)> VolumetricFogRTMResizeSignal;
+   
+#define VFRTM VolumetricFogRTManager::get()
+   
+class VolumetricFogRTManager : public SceneObject
+{
+   public:
+      typedef SceneObject Parent;
+   
+   protected:
+      GFXTexHandle mDepthBuffer;
+      GFXTexHandle mFrontBuffer;
+   
+      NamedTexTarget mDepthTarget;
+      NamedTexTarget mFrontTarget;
+   
+      PlatformWindow* mPlatformWindow;
+   
+      static S32 mTargetScale;
+      bool mIsInitialized;
+      U32 mNumFogObjects;
+      U32 mFogHasAnswered;
+      U32 mWidth;
+      U32 mHeight;
+      bool mFullScreen;
+   
+      void onRemove();
+      void onSceneRemove();
+      void ResizeRT(PlatformWindow *win, bool resize);
+   
+      static VolumetricFogRTMResizeSignal smVolumetricFogRTMResizeSignal;
+
+   public:
+      VolumetricFogRTManager();
+      ~VolumetricFogRTManager();
+      static VolumetricFogRTManager *get();
+      bool Init();
+      bool IsInitialized() { return mIsInitialized; }
+      static void consoleInit();
+      static VolumetricFogRTMResizeSignal& getVolumetricFogRTMResizeSignal() { return smVolumetricFogRTMResizeSignal; }
+      void FogAnswered();
+      S32 setQuality(U32 Quality);
+      bool Resize();
+      U32 IncFogObjects();
+      U32 DecFogObjects();
+   
+   DECLARE_CONOBJECT(VolumetricFogRTManager);
+};
+   
+extern VolumetricFogRTManager* gVolumetricFogRTManager;
+   
+#endif

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

+ 4 - 4
Engine/source/gfx/gfxDrawUtil.cpp

@@ -526,10 +526,10 @@ void GFXDrawUtil::drawRectFill( const Point2F &upperLeft, const Point2F &lowerRi
 
    F32 ulOffset = 0.5f - mDevice->getFillConventionOffset();
    
-   verts[0].point.set( upperLeft.x+nw.x+ulOffset, upperLeft.y+nw.y+ulOffset, 0.0f );
-   verts[1].point.set( lowerRight.x+ne.x, upperLeft.y+ne.y+ulOffset, 0.0f );
-   verts[2].point.set( upperLeft.x-ne.x+ulOffset, lowerRight.y-ne.y, 0.0f );
-   verts[3].point.set( lowerRight.x-nw.x, lowerRight.y-nw.y, 0.0f );
+   verts[0].point.set( upperLeft.x + nw.x + ulOffset, upperLeft.y + nw.y + ulOffset, 0.0f);
+   verts[1].point.set( lowerRight.x + ne.x + ulOffset, upperLeft.y + ne.y + ulOffset, 0.0f);
+   verts[2].point.set( upperLeft.x - ne.x + ulOffset, lowerRight.y - ne.y + ulOffset, 0.0f);
+   verts[3].point.set( lowerRight.x - nw.x + ulOffset, lowerRight.y - nw.y + ulOffset, 0.0f);
 
    for (S32 i=0; i<4; i++)
       verts[i].color = color;

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

+ 3 - 0
Engine/source/gui/core/guiCanvas.cpp

@@ -321,8 +321,11 @@ void GuiCanvas::setWindowTitle(const char *newTitle)
       mPlatformWindow->setCaption(newTitle);
 }
 
+CanvasSizeChangeSignal GuiCanvas::smCanvasSizeChangeSignal;
+
 void GuiCanvas::handleResize( WindowId did, S32 width, S32 height )
 {
+   getCanvasSizeChangeSignal().trigger(this);
 	if (Journal::IsPlaying() && mPlatformWindow)
 	{
 		mPlatformWindow->lockSize(false);

+ 10 - 0
Engine/source/gui/core/guiCanvas.h

@@ -33,6 +33,10 @@
 #include "platform/platformInput.h"
 #endif
 
+#ifndef _SIGNAL_H_
+#include "core/util/tSignal.h"
+#endif
+
 #include "component/interfaces/IProcessInput.h"
 #include "windowManager/platformWindowMgr.h"
 #include "gfx/gfxFence.h"
@@ -74,6 +78,8 @@
 /// screen will be painted normally. If you are making an animated GuiControl
 /// you need to add your control to the dirty areas of the canvas.
 ///
+class guiCanvas;
+typedef Signal<void(GuiCanvas* canvas)> CanvasSizeChangeSignal;
 class GuiCanvas : public GuiControl, public IProcessInput
 {
 
@@ -183,6 +189,8 @@ protected:
    virtual void setupFences();
    
    void checkLockMouseMove( const GuiEvent& event );
+   //Signal used to let others know this canvas has changed size.
+	static CanvasSizeChangeSignal smCanvasSizeChangeSignal;
 
    GuiControl *mMenuBarCtrl;
 
@@ -200,6 +208,8 @@ public:
 
    static void initPersistFields();
 
+   static CanvasSizeChangeSignal& getCanvasSizeChangeSignal() { return smCanvasSizeChangeSignal; }
+
    /// @name Rendering methods
    ///
    /// @{

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

+ 2 - 2
Engine/source/gui/worldEditor/worldEditor.cpp

@@ -2810,7 +2810,7 @@ void WorldEditor::clearSelection()
 
 void WorldEditor::selectObject( SimObject *obj )
 {
-   if ( mSelectionLocked || !mSelected )
+   if ( mSelectionLocked || !mSelected || !obj )
       return;
 
    // Don't check isSelectionEnabled of SceneObjects here as we
@@ -2833,7 +2833,7 @@ void WorldEditor::selectObject( const char* obj )
 
 void WorldEditor::unselectObject( SimObject *obj )
 {
-   if ( mSelectionLocked || !mSelected )
+   if ( mSelectionLocked || !mSelected || !obj )
       return;
 
    if ( !objClassIgnored( obj ) && mSelected->objInSet( obj ) )

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

+ 2 - 0
Engine/source/math/mPoint2.h

@@ -438,6 +438,7 @@ inline Point2I Point2I::operator/(const Point2I &_vec) const
 
 inline Point2I& Point2I::operator/=(const Point2I &_vec)
 {
+   AssertFatal(_vec.x != 0 && _vec.y != 0, "Error, div by zero attempted");
    x /= _vec.x;
    y /= _vec.y;
    return *this;
@@ -645,6 +646,7 @@ inline Point2F Point2F::operator/(const Point2F &_vec) const
 
 inline Point2F& Point2F::operator/=(const Point2F &_vec)
 {
+   AssertFatal(_vec.x != 0 && _vec.y != 0, "Error, div by zero attempted");
    x /= _vec.x;
    y /= _vec.y;
    return *this;

+ 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
 

+ 7 - 7
Engine/source/navigation/navMesh.cpp

@@ -663,7 +663,7 @@ DefineEngineMethod(NavMesh, build, bool, (bool background, bool save), (true, fa
 
 void NavMesh::cancelBuild()
 {
-   while(!mDirtyTiles.empty()) mDirtyTiles.pop();
+   mDirtyTiles.clear();
    ctx->stopTimer(RC_TIMER_TOTAL);
    mBuilding = false;
 }
@@ -733,7 +733,7 @@ void NavMesh::updateTiles(bool dirty)
 
    mTiles.clear();
    mTileData.clear();
-   while(!mDirtyTiles.empty()) mDirtyTiles.pop();
+   mDirtyTiles.clear();
 
    const Box3F &box = DTStoRC(getWorldBox());
    if(box.isEmpty())
@@ -767,7 +767,7 @@ void NavMesh::updateTiles(bool dirty)
                   tileBmin, tileBmax));
 
          if(dirty)
-            mDirtyTiles.push(mTiles.size() - 1);
+            mDirtyTiles.push_back_unique(mTiles.size() - 1);
 
          if(mSaveIntermediates)
             mTileData.increment();
@@ -786,7 +786,7 @@ void NavMesh::buildNextTile()
    {
       // Pop a single dirty tile and process it.
       U32 i = mDirtyTiles.front();
-      mDirtyTiles.pop();
+      mDirtyTiles.pop_front();
       const Tile &tile = mTiles[i];
       // Intermediate data for tile build.
       TileData tempdata;
@@ -1098,7 +1098,7 @@ void NavMesh::buildTiles(const Box3F &box)
       if(!tile.box.isOverlapped(box))
          continue;
       // Mark as dirty.
-      mDirtyTiles.push(i);
+      mDirtyTiles.push_back_unique(i);
    }
    if(mDirtyTiles.size())
       ctx->startTimer(RC_TIMER_TOTAL);
@@ -1114,7 +1114,7 @@ void NavMesh::buildTile(const U32 &tile)
 {
    if(tile < mTiles.size())
    {
-      mDirtyTiles.push(tile);
+      mDirtyTiles.push_back_unique(tile);
       ctx->startTimer(RC_TIMER_TOTAL);
    }
 }
@@ -1136,7 +1136,7 @@ void NavMesh::buildLinks()
             mLinksUnsynced[j])
          {
             // Mark tile for build.
-            mDirtyTiles.push(i);
+            mDirtyTiles.push_back_unique(i);
             // Delete link if necessary
             if(mDeleteLinks[j])
             {

+ 1 - 1
Engine/source/navigation/navMesh.h

@@ -325,7 +325,7 @@ private:
    Vector<TileData> mTileData;
 
    /// List of indices to the tile array which are dirty.
-   std::queue<U32> mDirtyTiles;
+   Vector<U32> mDirtyTiles;
 
    /// Update tile dimensions.
    void updateTiles(bool dirty = false);

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

+ 17 - 6
Engine/source/platformWin32/winFileio.cpp

@@ -1321,6 +1321,7 @@ static bool recurseDumpDirectories(const char *basePath, const char *subPath, Ve
    dsize_t subtrLen = subPath ? dStrlen(subPath) : 0;
    char trail = trLen > 0 ? basePath[ trLen - 1 ] : '\0';
    char subTrail = subtrLen > 0 ? subPath[ subtrLen - 1 ] : '\0';
+   char subLead = subtrLen > 0 ? subPath[0] : '\0';
 
    if( trail == '/' )
    {
@@ -1380,13 +1381,23 @@ static bool recurseDumpDirectories(const char *basePath, const char *subPath, Ve
       {
          if( ( subPath  && ( dStrncmp( subPath, "", 1 ) != 0 ) ) )
          {
-            char szPath [ 1024 ];
-            dMemset( szPath, 0, 1024 );
-            if( trail != '/' )
-               dSprintf( szPath, 1024, "%s%s", basePath, subPath );
+            char szPath[1024];
+            dMemset(szPath, 0, 1024);
+            if (trail == '/')
+            {
+               if (subLead == '/')
+                  dSprintf(szPath, 1024, "%s%s", basePath, &subPath[1]);
+               else
+                  dSprintf(szPath, 1024, "%s%s", basePath, subPath);
+            }
             else
-               dSprintf( szPath, 1024, "%s%s", basePath, &subPath[1] );
-            directoryVector.push_back( StringTable->insert( szPath ) );
+            {
+               if (subLead == '/')
+                  dSprintf(szPath, 1024, "%s%s", basePath, subPath);
+               else
+                  dSprintf(szPath, 1024, "%s/%s", basePath, subPath);
+            }
+            directoryVector.push_back(StringTable->insert(szPath));
          }
          else
             directoryVector.push_back( StringTable->insert( basePath ) );

+ 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 - 0
Engine/source/renderInstance/renderPassManager.cpp

@@ -53,6 +53,7 @@ const RenderInstType RenderPassManager::RIT_ObjectTranslucent("ObjectTranslucent
 const RenderInstType RenderPassManager::RIT_Decal("Decal");
 const RenderInstType RenderPassManager::RIT_Water("Water");
 const RenderInstType RenderPassManager::RIT_Foliage("Foliage");
+const RenderInstType RenderPassManager::RIT_VolumetricFog("ObjectVolumetricFog");
 const RenderInstType RenderPassManager::RIT_Translucent("Translucent");
 const RenderInstType RenderPassManager::RIT_Begin("Begin");
 const RenderInstType RenderPassManager::RIT_Custom("Custom");

+ 1 - 0
Engine/source/renderInstance/renderPassManager.h

@@ -110,6 +110,7 @@ public:
    static const RenderInstType RIT_Decal;
    static const RenderInstType RIT_Water;
    static const RenderInstType RIT_Foliage;
+   static const RenderInstType RIT_VolumetricFog;
    static const RenderInstType RIT_Translucent;
    static const RenderInstType RIT_Begin;
    static const RenderInstType RIT_Custom;

+ 1 - 2
Engine/source/renderInstance/renderTexTargetBinManager.cpp

@@ -107,8 +107,7 @@ void RenderTexTargetBinManager::initPersistFields()
 
 bool RenderTexTargetBinManager::setTargetSize(const Point2I &newTargetSize)
 {
-   if( GFX->getAdapterType() != OpenGL && // Targets need to match up exactly in size on OpenGL.
-       mTargetSize.x >= newTargetSize.x &&
+   if( mTargetSize.x >= newTargetSize.x &&
        mTargetSize.y >= newTargetSize.y )
       return true;
 

+ 10 - 0
Engine/source/renderInstance/renderTranslucentMgr.cpp

@@ -51,6 +51,7 @@ RenderTranslucentMgr::RenderTranslucentMgr()
 {
    notifyType( RenderPassManager::RIT_ObjectTranslucent );
    notifyType( RenderPassManager::RIT_Particle );
+   notifyType( RenderPassManager::RIT_VolumetricFog);
 }
 
 RenderTranslucentMgr::~RenderTranslucentMgr()
@@ -187,6 +188,15 @@ void RenderTranslucentMgr::render( SceneRenderState *state )
          j++;
          continue;
       }
+      else if (baseRI->type == RenderPassManager::RIT_VolumetricFog)
+	   {
+	      ObjectRenderInst* objRI = static_cast<ObjectRenderInst*>(baseRI);
+	      objRI->renderDelegate(objRI, state, NULL);
+	      lastVB = NULL;
+	      lastPB = NULL;
+	      j++;
+	      continue;
+	   }
       else if ( baseRI->type == RenderPassManager::RIT_Particle )
       {
          ParticleRenderInst *ri = static_cast<ParticleRenderInst*>(baseRI);

+ 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 - 1
Engine/source/ts/collada/colladaAppMesh.h

@@ -24,7 +24,7 @@
 #define _COLLADA_APPMESH_H_
 
 #ifndef _TDICTIONARY_H_
-#include "core/tDictionary.h"
+#include "core/util/tDictionary.h"
 #endif
 #ifndef _APPMESH_H_
 #include "ts/loader/appMesh.h"

+ 1 - 1
Engine/source/ts/collada/colladaAppNode.h

@@ -24,7 +24,7 @@
 #define _COLLADA_APPNODE_H_
 
 #ifndef _TDICTIONARY_H_
-#include "core/tDictionary.h"
+#include "core/util/tDictionary.h"
 #endif
 #ifndef _APPNODE_H_
 #include "ts/loader/appNode.h"

+ 1 - 1
Engine/source/ts/tsShapeInstance.cpp

@@ -593,7 +593,7 @@ S32 TSShapeInstance::setDetailFromDistance( const SceneRenderState *state, F32 s
    // 4:3 aspect ratio, we've changed the reference value
    // to 300 to be more compatible with legacy shapes.
    //
-   const F32 pixelScale = state->getViewport().extent.y / 300.0f;
+   const F32 pixelScale = (state->getViewport().extent.x / state->getViewport().extent.y);
 
    // This is legacy DTS support for older "multires" based
    // meshes.  The original crossbow weapon uses this.

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

+ 6 - 1
Engine/source/windowManager/platformWindow.cpp

@@ -22,7 +22,7 @@
 
 #include "windowManager/platformWindow.h"
 
-
+ScreenResChangeSignal PlatformWindow::smScreenResChangeSignal;
 //-----------------------------------------------------------------------------
 
 void PlatformWindow::setFullscreen( const bool fullscreen )
@@ -48,3 +48,8 @@ bool PlatformWindow::shouldNotTranslate( U32 modifiers, U32 keyCode ) const
    else
       return false;
 }
+void PlatformWindow::setVideoMode(const GFXVideoMode &mode)
+{
+   _setVideoMode(mode);
+	getScreenResChangeSignal().trigger(this, true);
+}

+ 8 - 3
Engine/source/windowManager/platformWindow.h

@@ -28,6 +28,9 @@
 #include "core/util/safeDelete.h"
 #include "windowManager/platformCursorController.h"
 #include "windowManager/windowInputGenerator.h"
+#ifndef _SIGNAL_H_ //Volumetric Fog
+#include "core/util/tSignal.h"
+#endif
 
 //forward decl's
 class PlatformWindowManager;
@@ -35,7 +38,7 @@ class GFXDevice;
 struct GFXVideoMode;
 class GFXWindowTarget;
 class IProcessInput;
-
+typedef Signal<void(PlatformWindow *PlatformWindow, bool resize)> ScreenResChangeSignal;
 /// Abstract representation of a native OS window.
 ///
 /// Every windowing system has its own representations and conventions as
@@ -110,7 +113,7 @@ protected:
       // This controller maps window input (Mouse/Keyboard) to a generic input consumer
       mWindowInputGenerator = new WindowInputGenerator( this );
    }
-
+   static ScreenResChangeSignal smScreenResChangeSignal;
 public:
 
    /// To get rid of a window, just delete it. Make sure the GFXDevice is
@@ -158,7 +161,7 @@ public:
    virtual GFXWindowTarget *getGFXTarget()=0;
 
    /// Set the video mode for this window.
-   virtual void setVideoMode(const GFXVideoMode &mode)=0;
+   virtual void setVideoMode(const GFXVideoMode &mode);
 
    /// Get our current video mode - if the window has been resized, it will
    /// reflect this.
@@ -497,6 +500,7 @@ public:
    IdleEvent         idleEvent;
 
    /// @}
+   static ScreenResChangeSignal& getScreenResChangeSignal() { return smScreenResChangeSignal; }
    
    /// Get the platform specific object needed to create or attach an accelerated
    /// graohics drawing context on or to the window
@@ -507,6 +511,7 @@ public:
    virtual void* getPlatformDrawable() const = 0;
 protected:
    virtual void _setFullscreen(const bool fullScreen) {};
+   virtual void _setVideoMode(const GFXVideoMode &mode) {};
 };
 
 #endif

+ 81 - 90
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,40 +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;
+   mSuppressReset = false;
 
-	if(needCurtain)
-		mOwningManager->raiseCurtain();
+   if( needCurtain )
+      mOwningManager->raiseCurtain();
 
-	SetForegroundWindow(getHWND());
+   SetForegroundWindow( getHWND() );
+   getScreenResChangeSignal().trigger( this, true );
 }
 
 bool Win32Window::clearFullscreen()

BIN
Templates/Empty/game/art/environment/FogMod_heavy.dds


BIN
Templates/Empty/game/art/environment/FogMod_light.dds


BIN
Templates/Empty/game/art/environment/FogMod_med.dds


File diff suppressed because it is too large
+ 97 - 0
Templates/Empty/game/art/environment/Fog_Cube.DAE


+ 8 - 0
Templates/Empty/game/art/environment/Fog_Cube.cs

@@ -0,0 +1,8 @@
+
+singleton TSShapeConstructor(Fog_CubeDAE)
+{
+   baseShape = "./Fog_Cube.DAE";
+   lodType = "TrailingNumber";
+   neverImport = "env*";
+   loadLights = "0";
+};

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

+ 76 - 0
Templates/Empty/game/core/scripts/client/postFx/glow.cs

@@ -106,3 +106,79 @@ singleton PostEffect( GlowPostFx )
       target = "$backBuffer";
    };
 };
+
+singleton ShaderData( PFX_VolFogGlowBlurVertShader )
+{
+	DXVertexShaderFile = "shaders/common/postFx/glowBlurV.hlsl";
+	DXPixelShaderFile = "shaders/common/postFx/VolFogGlowP.hlsl";
+	
+	OGLVertexShaderFile = "shaders/common/postFx/gl/glowBlurV.glsl";
+	OGLPixelShaderFile = "shaders/common/postFx/gl/VolFogGlowP.glsl";	
+	
+	defines = "BLUR_DIR=float2(0.0,1.0)";
+	samplerNames[0] = "$diffuseMap";
+	pixVersion = 2.0;
+};
+singleton ShaderData( PFX_VolFogGlowBlurHorzShader : PFX_VolFogGlowBlurVertShader )
+{
+	DXVertexShaderFile = "shaders/common/postFx/glowBlurV.hlsl";
+	DXPixelShaderFile = "shaders/common/postFx/VolFogGlowP.hlsl";
+	
+	OGLVertexShaderFile = "shaders/common/postFx/gl/glowBlurV.glsl";
+	OGLPixelShaderFile = "shaders/common/postFx/gl/VolFogGlowP.glsl";
+	
+	defines = "BLUR_DIR=float2(1.0,0.0)";
+};
+
+$VolFogGlowPostFx::glowStrength = 0.3;
+
+singleton PostEffect( VolFogGlowPostFx )
+{
+	// Do not allow the glow effect to work in reflection
+	// passes by default so we don't do the extra drawing.
+	allowReflectPass = false;
+	renderTime = "PFXAfterBin";
+	renderBin = "FogBin";
+	renderPriority = 1;
+	// First we down sample the glow buffer.
+	shader = PFX_PassthruShader;
+	stateBlock = PFX_DefaultStateBlock;
+	texture[0] = "$backbuffer";
+	target = "$outTex";
+	targetScale = "0.5 0.5";
+	isEnabled = true;
+	// Blur vertically
+	new PostEffect()
+	{
+		shader = PFX_VolFogGlowBlurVertShader;
+		stateBlock = PFX_DefaultStateBlock;
+		internalName = "vert";
+		texture[0] = "$inTex";
+		target = "$outTex";
+	};
+	// Blur horizontally
+	new PostEffect()
+	{
+		shader = PFX_VolFogGlowBlurHorzShader;
+		stateBlock = PFX_DefaultStateBlock;
+		internalName = "hor";
+		texture[0] = "$inTex";
+		target = "$outTex";
+	};
+	// Upsample and combine with the back buffer.
+	new PostEffect()
+	{
+		shader = PFX_PassthruShader;
+		stateBlock = PFX_GlowCombineStateBlock;
+		texture[0] = "$inTex";
+		target = "$backBuffer";
+	};
+};
+
+function VolFogGlowPostFx::setShaderConsts( %this )
+{
+	%vp=%this-->vert;
+	%vp.setShaderConst( "$strength", $VolFogGlowPostFx::glowStrength );
+	%vp=%this-->hor;
+	%vp.setShaderConst( "$strength", $VolFogGlowPostFx::glowStrength );
+}

+ 1 - 0
Templates/Empty/game/core/scripts/client/postFx/postFxManager.gui.settings.cs

@@ -70,6 +70,7 @@ function PostFXManager::settingsSetEnabled(%this, %bEnablePostFX)
       
       postVerbose("% - PostFX Manager - PostFX disabled");
    }
+   VolFogGlowPostFx.disable();
 }
 
 function PostFXManager::settingsEffectSetEnabled(%this, %sName, %bEnable)

+ 2 - 0
Templates/Empty/game/core/scripts/client/renderManager.cs

@@ -75,6 +75,8 @@ function initRenderManager()
 	DiffuseRenderPassManager.addManager( new RenderParticleMgr()            { renderOrder = 1.35; processAddOrder = 1.35; } );
    DiffuseRenderPassManager.addManager( new RenderTranslucentMgr()         { renderOrder = 1.4; processAddOrder = 1.4; } );
    
+   DiffuseRenderPassManager.addManager(new RenderObjectMgr(FogBin){ bintype = "ObjectVolumetricFog"; renderOrder = 1.45; processAddOrder = 1.45; } );
+   
    // Note that the GlowPostFx is triggered after this bin.
    DiffuseRenderPassManager.addManager( new RenderGlowMgr(GlowBin) { renderOrder = 1.5; processAddOrder = 1.5; } );
    

+ 106 - 0
Templates/Empty/game/scripts/server/VolumetricFog.cs

@@ -0,0 +1,106 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+function VolumetricFog::onEnterFog(%this,%obj)
+{
+   // This method is called whenever the control object (Camera or Player)
+   // %obj enters the fog area.
+   
+   // echo("Control Object " @ %obj @ " enters fog " @ %this);
+}
+
+function VolumetricFog::onLeaveFog(%this,%obj)
+{
+   // This method is called whenever the control object (Camera or Player)
+   // %obj leaves the fog area.
+   
+   // echo("Control Object " @ %obj @ " left fog " @ %this);
+}
+
+function VolumetricFog::Dissolve(%this,%speed,%delete)
+{
+   // This method dissolves the fog at speed milliseconds
+   %this.isBuilding = true;
+   if (%this.FogDensity > 0)
+   {
+      %this.setFogDensity(%this.FogDensity - 0.005);
+      %this.schedule(%speed,Dissolve,%speed,%delete);
+   }
+   else
+   {
+      %this.isBuilding = false;
+      %this.SetFogDensity(0.0);
+      if (%delete !$= "" && %delete !$="0" && %delete !$="false")
+         %this.schedule(250,delete);
+   }
+}
+
+function VolumetricFog::Thicken(%this,%speed, %end_density)
+{
+   // This method thickens the fog at speed milliseconds to a density of %end_density
+
+   %this.isBuilding = true;
+   if (%this.FogDensity + 0.005 < %end_density)
+   {
+      %this.setFogDensity(%this.FogDensity + 0.005);
+      %this.schedule(%speed,Thicken,%speed, %end_density);
+   }
+   else
+   {
+      %this.setFogDensity(%end_density);
+      %this.isBuilding = false;
+   }
+}
+ 
+function GenerateFog(%pos,%scale,%color,%density)
+{
+   // This function can be used to generate some fog caused by massive gunfire etc.
+   // Change shape and modulation data to your likings.
+   
+   %fog=new VolumetricFog() {
+      shapeName = "art/environment/Fog_Sphere.dts";
+      fogColor = %color;
+      fogDensity = "0.0";
+      ignoreWater = "0";
+      MinSize = "250";
+      FadeSize = "750";
+      texture = "art/environment/FogMod_heavy.dds";
+      tiles = "1";
+      modStrength = "0.2";
+      PrimSpeed = "-0.01 0.04";
+      SecSpeed = "0.02 0.02";
+      position = %pos;
+      rotation = "0 0 1 20.354";
+      scale = %scale;
+      canSave = "1";
+      canSaveDynamicFields = "1";
+   };
+   
+   if (isObject(%fog))
+   {
+      MissionCleanup.add(%fog);
+      
+      %fog.Thicken(500,%density);
+   }
+   
+   return %fog;
+}

+ 1 - 0
Templates/Empty/game/scripts/server/scriptExec.cs

@@ -22,3 +22,4 @@
 
 // Load up all scripts.  This function is called when
 // a server is constructed.
+exec("./VolumetricFog.cs");

+ 87 - 0
Templates/Empty/game/shaders/common/VolumetricFog/VFogP.hlsl

@@ -0,0 +1,87 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+// Volumetric Fog final pixel shader V2.00
+
+#include "shadergen:/autogenConditioners.h"
+#include "../torque.hlsl"
+
+uniform sampler2D prepassTex : register(S0);
+uniform sampler2D depthBuffer : register(S1);
+uniform sampler2D frontBuffer : register(S2);
+uniform sampler2D density : register(S3);
+  
+uniform float accumTime;
+uniform float4 fogColor;
+uniform float fogDensity;
+uniform float preBias;
+uniform float textured;
+uniform float modstrength;
+uniform float4 modspeed;//xy speed layer 1, zw speed layer 2
+uniform float2 viewpoint;
+uniform float2 texscale;
+uniform float3 ambientColor;
+uniform float numtiles;
+uniform float fadesize;
+uniform float2 PixelSize;
+
+struct ConnectData
+{
+   float4 hpos : POSITION;
+   float4 htpos : TEXCOORD0;
+   float2 uv0 : TEXCOORD1;
+};
+
+float4 main( ConnectData IN ) : COLOR0
+{
+	float2 uvscreen=((IN.htpos.xy/IN.htpos.w) + 1.0 ) / 2.0;
+	uvscreen.y = 1.0 - uvscreen.y;
+	
+	float obj_test = prepassUncondition( prepassTex, uvscreen).w * preBias;
+	float depth = tex2D(depthBuffer,uvscreen).r;
+	float front = tex2D(frontBuffer,uvscreen).r;
+
+	if (depth <= front)
+		return float4(0,0,0,0);
+	else if ( obj_test < depth )
+		depth = obj_test;
+	if ( front >= 0.0)
+		depth -= front;
+
+	float diff = 1.0;
+	float3 col = fogColor.rgb;
+	if (textured != 0.0)
+	{
+		float2 offset = viewpoint + ((-0.5 + (texscale * uvscreen)) * numtiles);
+
+		float2 mod1 = tex2D(density,(offset + (modspeed.xy*accumTime))).rg;
+		float2 mod2= tex2D(density,(offset + (modspeed.zw*accumTime))).rg;
+		diff = (mod2.r + mod1.r) * modstrength;
+		col *= (2.0 - ((mod1.g + mod2.g) * fadesize))/2.0;
+	}
+
+	col *= ambientColor;
+
+	float4 resultColor = float4(col, 1.0 - saturate(exp(-fogDensity  * depth * diff * fadesize)));
+
+	return hdrEncode(resultColor);
+}

+ 39 - 0
Templates/Empty/game/shaders/common/VolumetricFog/VFogPreP.hlsl

@@ -0,0 +1,39 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+// Volumetric Fog prepass pixel shader V1.00
+
+struct ConnectData
+{
+   float4 hpos : POSITION;
+   float4 pos : TEXCOORD0;
+};
+
+float4 main( ConnectData IN ) : COLOR0
+{
+   float OUT;
+   
+   clip( IN.pos.w );
+   OUT = IN.pos.w;
+
+   return float4(OUT,0,0,1);
+}

+ 46 - 0
Templates/Empty/game/shaders/common/VolumetricFog/VFogPreV.hlsl

@@ -0,0 +1,46 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+// Volumetric Fog prepass vertex shader V1.00
+
+#include "shaders/common/hlslstructs.h"
+
+struct ConnectData
+{
+   float4 hpos : POSITION;
+   float4 pos : TEXCOORD0;
+};
+
+uniform float4x4 modelView;
+
+ConnectData main( VertexIn_P IN)    
+{
+	ConnectData OUT;
+	
+	float4 inPos = IN.pos;
+	inPos.w = 1.0;
+ 
+	OUT.hpos = mul( modelView, inPos );
+    OUT.pos = OUT.hpos;
+
+    return OUT;  
+}

+ 36 - 0
Templates/Empty/game/shaders/common/VolumetricFog/VFogRefl.hlsl

@@ -0,0 +1,36 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+uniform float4 fogColor;
+uniform float fogDensity;
+uniform float reflStrength;
+
+struct ConnectData
+{
+   float4 hpos : POSITION;
+   float4 pos : TEXCOORD0;
+};
+
+float4 main( ConnectData IN ) : COLOR0
+{
+   return float4(fogColor.rgb,saturate(fogDensity*reflStrength));
+}

+ 45 - 0
Templates/Empty/game/shaders/common/VolumetricFog/VFogV.hlsl

@@ -0,0 +1,45 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+// Volumetric Fog final vertex shader V1.00
+
+#include "shaders/common/hlslstructs.h"
+
+struct ConnectData
+{
+   float4 hpos : POSITION;
+   float4 htpos : TEXCOORD0;
+   float2 uv0 : TEXCOORD1;
+};
+
+uniform float4x4 modelView;
+
+ConnectData main( VertexIn_PNT IN)    
+{  
+    ConnectData OUT;
+	
+	OUT.hpos = mul(modelView, IN.pos);
+	OUT.htpos = OUT.hpos;
+	OUT.uv0 = IN.uv0;
+	
+    return OUT;  
+}

+ 87 - 0
Templates/Empty/game/shaders/common/VolumetricFog/gl/VFogP.glsl

@@ -0,0 +1,87 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+#include "../../gl/hlslCompat.glsl"
+#include "shadergen:/autogenConditioners.h"
+#include "../../gl/torque.glsl"
+
+uniform sampler2D prepassTex;
+uniform sampler2D depthBuffer;
+uniform sampler2D frontBuffer;
+uniform sampler2D density;
+  
+uniform float accumTime;
+uniform vec4 fogColor;
+uniform float fogDensity;
+uniform float preBias;
+uniform float textured;
+uniform float modstrength;
+uniform vec4 modspeed;//xy speed layer 1, zw speed layer 2
+uniform vec2 viewpoint;
+uniform vec2 texscale;
+uniform vec3 ambientColor;
+uniform float numtiles;
+uniform float fadesize;
+uniform vec2 PixelSize;
+
+in vec4 _hpos;
+#define IN_hpos _hpos
+out vec4 OUT_col;
+
+void main()
+{
+	vec2 uvscreen=((IN_hpos.xy/IN_hpos.w) + 1.0 ) / 2.0;
+	uvscreen.y = 1.0 - uvscreen.y;
+	
+	float obj_test = prepassUncondition( prepassTex, uvscreen).w * preBias;
+	float depth = tex2D(depthBuffer,uvscreen).r;
+	float front = tex2D(frontBuffer,uvscreen).r;
+
+	if (depth <= front)
+	{
+		OUT_col = vec4(0,0,0,0);
+		return;
+	}
+	
+	else if ( obj_test < depth )
+		depth = obj_test;
+	if ( front >= 0.0)
+		depth -= front;
+
+	float diff = 1.0;
+	vec3 col = fogColor.rgb;
+	if (textured != 0.0)
+	{
+		vec2 offset = viewpoint + ((-0.5 + (texscale * uvscreen)) * numtiles);
+
+		vec2 mod1 = tex2D(density,(offset + (modspeed.xy*accumTime))).rg;
+		vec2 mod2= tex2D(density,(offset + (modspeed.zw*accumTime))).rg;
+		diff = (mod2.r + mod1.r) * modstrength;
+		col *= (2.0 - ((mod1.g + mod2.g) * fadesize))/2.0;
+	}
+
+   col *= ambientColor;
+
+   vec4 returnColor = vec4(col, 1.0 - saturate(exp(-fogDensity  * depth * diff * fadesize)));
+
+	OUT_col = hdrEncode(returnColor);
+}

+ 37 - 0
Templates/Empty/game/shaders/common/VolumetricFog/gl/VFogPreP.glsl

@@ -0,0 +1,37 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+#include "../../gl/hlslCompat.glsl"
+
+in vec4 _hpos;
+#define IN_hpos _hpos
+
+out vec4 OUT_col;
+
+void main()
+{
+   float OUT;
+   clip( IN_hpos.w );
+   OUT = IN_hpos.w;
+
+   OUT_col = vec4(OUT,0,0,1);
+}

+ 42 - 0
Templates/Empty/game/shaders/common/VolumetricFog/gl/VFogPreV.glsl

@@ -0,0 +1,42 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+#include "../../gl/hlslCompat.glsl"
+
+in vec4 vPosition;
+#define IN_position vPosition
+
+out vec4 _hpos;
+#define OUT_hpos _hpos
+
+uniform mat4 modelView;
+
+void main()
+{
+	vec4 inPos = IN_position;
+	inPos.w = 1.0;
+ 
+	OUT_hpos = tMul( modelView, inPos );
+
+	gl_Position = OUT_hpos;
+	correctSSP(gl_Position);
+}

+ 33 - 0
Templates/Empty/game/shaders/common/VolumetricFog/gl/VFogRefl.glsl

@@ -0,0 +1,33 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+#include "../../gl/hlslCompat.glsl"
+
+uniform vec4 fogColor;
+uniform float fogDensity;
+uniform float reflStrength;
+out vec4 OUT_col;
+
+void main()
+{
+   OUT_col = vec4(fogColor.rgb,saturate(fogDensity*reflStrength));
+}

+ 38 - 0
Templates/Empty/game/shaders/common/VolumetricFog/gl/VFogV.glsl

@@ -0,0 +1,38 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+#include "../../gl/hlslCompat.glsl"
+
+in vec4 vPosition;
+#define IN_position vPosition
+
+out vec4 _hpos;
+#define OUT_hpos _hpos
+
+uniform mat4 modelView;
+
+void main()    
+{  
+	OUT_hpos = tMul(modelView, IN_position);
+	gl_Position = OUT_hpos;
+	correctSSP(gl_Position);
+}

Some files were not shown because too many files changed in this diff