浏览代码

Merge pull request #2023 from Areloch/sRGB_Implementation

Implementation of sRGB image support
Areloch 8 年之前
父节点
当前提交
597abec447
共有 100 个文件被更改,包括 2207 次插入1629 次删除
  1. 1 1
      Engine/source/T3D/accumulationVolume.cpp
  2. 13 9
      Engine/source/T3D/convexShape.cpp
  3. 6 6
      Engine/source/T3D/fps/guiClockHud.cpp
  4. 4 4
      Engine/source/T3D/fps/guiCrossHairHud.cpp
  5. 6 6
      Engine/source/T3D/fps/guiHealthBarHud.cpp
  6. 8 8
      Engine/source/T3D/fps/guiHealthTextHud.cpp
  7. 10 10
      Engine/source/T3D/fps/guiShapeNameHud.cpp
  8. 2 2
      Engine/source/T3D/fx/explosion.h
  9. 6 6
      Engine/source/T3D/fx/fxFoliageReplicator.cpp
  10. 2 2
      Engine/source/T3D/fx/fxFoliageReplicator.h
  11. 1 1
      Engine/source/T3D/fx/fxShapeReplicator.h
  12. 3 3
      Engine/source/T3D/fx/groundCover.cpp
  13. 1 1
      Engine/source/T3D/fx/lightning.cpp
  14. 2 2
      Engine/source/T3D/fx/lightning.h
  15. 3 3
      Engine/source/T3D/fx/particle.cpp
  16. 2 2
      Engine/source/T3D/fx/particle.h
  17. 57 57
      Engine/source/T3D/fx/particleEmitter.cpp
  18. 7 7
      Engine/source/T3D/fx/particleEmitter.h
  19. 4 4
      Engine/source/T3D/fx/precipitation.cpp
  20. 1 1
      Engine/source/T3D/fx/precipitation.h
  21. 6 6
      Engine/source/T3D/fx/ribbon.cpp
  22. 1 1
      Engine/source/T3D/fx/ribbon.h
  23. 1 1
      Engine/source/T3D/fx/splash.cpp
  24. 3 3
      Engine/source/T3D/fx/splash.h
  25. 8 8
      Engine/source/T3D/guiMaterialPreview.cpp
  26. 4 4
      Engine/source/T3D/guiObjectView.cpp
  27. 4 4
      Engine/source/T3D/guiObjectView.h
  28. 1 1
      Engine/source/T3D/item.h
  29. 1 1
      Engine/source/T3D/levelInfo.cpp
  30. 1 1
      Engine/source/T3D/lightAnimData.cpp
  31. 1 1
      Engine/source/T3D/lightAnimData.h
  32. 1 1
      Engine/source/T3D/lightBase.cpp
  33. 1 1
      Engine/source/T3D/lightBase.h
  34. 1 1
      Engine/source/T3D/lightDescription.cpp
  35. 1 1
      Engine/source/T3D/lightDescription.h
  36. 9 8
      Engine/source/T3D/lightFlareData.cpp
  37. 1 1
      Engine/source/T3D/lightFlareData.h
  38. 1 1
      Engine/source/T3D/physicalZone.cpp
  39. 1 1
      Engine/source/T3D/player.cpp
  40. 1 1
      Engine/source/T3D/pointLight.cpp
  41. 1 1
      Engine/source/T3D/portal.cpp
  42. 1 1
      Engine/source/T3D/proximityMine.cpp
  43. 1 1
      Engine/source/T3D/shapeBase.cpp
  44. 1 1
      Engine/source/T3D/shapeBase.h
  45. 1 1
      Engine/source/T3D/spotLight.cpp
  46. 1 1
      Engine/source/T3D/vehicles/guiSpeedometer.cpp
  47. 1 1
      Engine/source/T3D/vehicles/wheeledVehicle.cpp
  48. 5 7
      Engine/source/console/consoleFunctions.cpp
  49. 4 4
      Engine/source/console/consoleTypes.cpp
  50. 1 1
      Engine/source/console/consoleTypes.h
  51. 2 2
      Engine/source/console/engineStructs.cpp
  52. 2 2
      Engine/source/console/engineStructs.h
  53. 2 2
      Engine/source/console/propertyParsing.cpp
  54. 3 3
      Engine/source/console/propertyParsing.h
  55. 87 16
      Engine/source/core/color.cpp
  56. 188 298
      Engine/source/core/color.h
  57. 3 3
      Engine/source/core/stream/stream.cpp
  58. 3 3
      Engine/source/core/stream/stream.h
  59. 5 5
      Engine/source/core/util/rgb2luv.cpp
  60. 3 3
      Engine/source/core/util/rgb2luv.h
  61. 4 4
      Engine/source/core/util/rgb2xyz.cpp
  62. 2 2
      Engine/source/core/util/rgb2xyz.h
  63. 4 4
      Engine/source/environment/VolumetricFog.cpp
  64. 1 1
      Engine/source/environment/VolumetricFog.h
  65. 4 4
      Engine/source/environment/VolumetricFogRTManager.cpp
  66. 2 2
      Engine/source/environment/basicClouds.cpp
  67. 4 4
      Engine/source/environment/cloudLayer.cpp
  68. 1 1
      Engine/source/environment/cloudLayer.h
  69. 1 1
      Engine/source/environment/river.cpp
  70. 16 16
      Engine/source/environment/scatterSky.cpp
  71. 15 15
      Engine/source/environment/scatterSky.h
  72. 1 1
      Engine/source/environment/skyBox.cpp
  73. 1 1
      Engine/source/environment/skyBox.h
  74. 3 3
      Engine/source/environment/sun.cpp
  75. 4 4
      Engine/source/environment/sun.h
  76. 4 4
      Engine/source/environment/timeOfDay.cpp
  77. 7 7
      Engine/source/environment/timeOfDay.h
  78. 1 1
      Engine/source/environment/waterBlock.cpp
  79. 8 8
      Engine/source/environment/waterObject.cpp
  80. 1 1
      Engine/source/environment/waterObject.h
  81. 1 1
      Engine/source/environment/waterPlane.cpp
  82. 52 32
      Engine/source/gfx/D3D11/gfxD3D11Cubemap.cpp
  83. 0 1
      Engine/source/gfx/D3D11/gfxD3D11Cubemap.h
  84. 257 109
      Engine/source/gfx/D3D11/gfxD3D11Device.cpp
  85. 14 5
      Engine/source/gfx/D3D11/gfxD3D11Device.h
  86. 12 6
      Engine/source/gfx/D3D11/gfxD3D11EnumTranslate.cpp
  87. 25 51
      Engine/source/gfx/D3D11/gfxD3D11Shader.cpp
  88. 4 2
      Engine/source/gfx/D3D11/gfxD3D11Shader.h
  89. 12 9
      Engine/source/gfx/D3D11/gfxD3D11StateBlock.cpp
  90. 21 202
      Engine/source/gfx/D3D11/gfxD3D11Target.cpp
  91. 2 18
      Engine/source/gfx/D3D11/gfxD3D11Target.h
  92. 12 8
      Engine/source/gfx/D3D11/gfxD3D11TextureManager.cpp
  93. 5 4
      Engine/source/gfx/D3D11/gfxD3D11TextureObject.cpp
  94. 2 2
      Engine/source/gfx/Null/gfxNullDevice.h
  95. 779 0
      Engine/source/gfx/bitmap/ddsData.h
  96. 265 405
      Engine/source/gfx/bitmap/ddsFile.cpp
  97. 4 3
      Engine/source/gfx/bitmap/ddsFile.h
  98. 0 113
      Engine/source/gfx/bitmap/ddsUtils.cpp
  99. 0 34
      Engine/source/gfx/bitmap/ddsUtils.h
  100. 154 2
      Engine/source/gfx/bitmap/gBitmap.cpp

+ 1 - 1
Engine/source/T3D/accumulationVolume.cpp

@@ -265,7 +265,7 @@ void AccumulationVolume::setTexture( const String& name )
    mTextureName = name;
    mTextureName = name;
    if ( isClientObject() && mTextureName.isNotEmpty() )
    if ( isClientObject() && mTextureName.isNotEmpty() )
    {
    {
-      mAccuTexture.set(mTextureName, &GFXDefaultStaticDiffuseProfile, "AccumulationVolume::mAccuTexture");
+      mAccuTexture.set(mTextureName, &GFXStaticTextureSRGBProfile, "AccumulationVolume::mAccuTexture");
       if ( mAccuTexture.isNull() )
       if ( mAccuTexture.isNull() )
          Con::warnf( "AccumulationVolume::setTexture - Unable to load texture: %s", mTextureName.c_str() );
          Con::warnf( "AccumulationVolume::setTexture - Unable to load texture: %s", mTextureName.c_str() );
    }
    }

+ 13 - 9
Engine/source/T3D/convexShape.cpp

@@ -1226,7 +1226,7 @@ void ConvexShape::_renderDebug( ObjectRenderInst *ri, SceneRenderState *state, B
 
 
          PrimBuild::begin( GFXLineList, edgeList.size() * 2 );
          PrimBuild::begin( GFXLineList, edgeList.size() * 2 );
          
          
-         PrimBuild::color( ColorI::WHITE * 0.8f );
+         PrimBuild::color( LinearColorF(ColorI::WHITE) * 0.8f );
 
 
          for ( S32 j = 0; j < edgeList.size(); j++ )         
          for ( S32 j = 0; j < edgeList.size(); j++ )         
          {
          {
@@ -1260,11 +1260,13 @@ void ConvexShape::_renderDebug( ObjectRenderInst *ri, SceneRenderState *state, B
       for ( S32 i = 0; i < faceList.size(); i++ )
       for ( S32 i = 0; i < faceList.size(); i++ )
       {
       {
          ColorI color = faceColorsx[ i % 4 ];
          ColorI color = faceColorsx[ i % 4 ];
+         LinearColorF tCol = LinearColorF(color);
          S32 div = ( i / 4 ) * 4;
          S32 div = ( i / 4 ) * 4;
          if ( div > 0 )
          if ( div > 0 )
-            color /= div;
-         color.alpha = 255;
-         
+            tCol /= div;
+         tCol.alpha = 1;
+         color = tCol.toColorI();
+
          Point3F pnt;
          Point3F pnt;
          objToWorld.mulP( faceList[i].centroid, &pnt );
          objToWorld.mulP( faceList[i].centroid, &pnt );
          drawer->drawCube( desc, size, pnt, color, NULL );
          drawer->drawCube( desc, size, pnt, color, NULL );
@@ -1295,11 +1297,13 @@ void ConvexShape::_renderDebug( ObjectRenderInst *ri, SceneRenderState *state, B
             objToWorld.mulP( p0 );
             objToWorld.mulP( p0 );
             objToWorld.mulP( p1 );
             objToWorld.mulP( p1 );
 
 
-            ColorI color = faceColorsx[ j % 4 ];
-            S32 div = ( j / 4 ) * 4;
-            if ( div > 0 )
-               color /= div;
-            color.alpha = 255;
+            ColorI color = faceColorsx[j % 4];
+            LinearColorF tCol = LinearColorF(color);
+            S32 div = (j / 4) * 4;
+            if (div > 0)
+               tCol /= div;
+            tCol.alpha = 1;
+            color = tCol.toColorI();
             
             
             PrimBuild::color( color );
             PrimBuild::color( color );
             PrimBuild::vertex3fv( p0 );            
             PrimBuild::vertex3fv( p0 );            

+ 6 - 6
Engine/source/T3D/fps/guiClockHud.cpp

@@ -42,9 +42,9 @@ class GuiClockHud : public GuiControl
    bool     mShowFill;
    bool     mShowFill;
    bool     mTimeReversed;
    bool     mTimeReversed;
 
 
-   ColorF   mFillColor;
-   ColorF   mFrameColor;
-   ColorF   mTextColor;
+   LinearColorF   mFillColor;
+   LinearColorF   mFrameColor;
+   LinearColorF   mTextColor;
 
 
    S32      mTimeOffset;
    S32      mTimeOffset;
 
 
@@ -117,7 +117,7 @@ void GuiClockHud::onRender(Point2I offset, const RectI &updateRect)
 
 
    // Background first
    // Background first
    if (mShowFill)
    if (mShowFill)
-      drawUtil->drawRectFill(updateRect, mFillColor);
+      drawUtil->drawRectFill(updateRect, mFillColor.toColorI());
 
 
    // Convert ms time into hours, minutes and seconds.
    // Convert ms time into hours, minutes and seconds.
    S32 time = S32(getTime());
    S32 time = S32(getTime());
@@ -131,13 +131,13 @@ void GuiClockHud::onRender(Point2I offset, const RectI &updateRect)
    // Center the text
    // Center the text
    offset.x += (getWidth() - mProfile->mFont->getStrWidth((const UTF8 *)buf)) / 2;
    offset.x += (getWidth() - mProfile->mFont->getStrWidth((const UTF8 *)buf)) / 2;
    offset.y += (getHeight() - mProfile->mFont->getHeight()) / 2;
    offset.y += (getHeight() - mProfile->mFont->getHeight()) / 2;
-   drawUtil->setBitmapModulation(mTextColor);
+   drawUtil->setBitmapModulation(mTextColor.toColorI());
    drawUtil->drawText(mProfile->mFont, offset, buf);
    drawUtil->drawText(mProfile->mFont, offset, buf);
    drawUtil->clearBitmapModulation();
    drawUtil->clearBitmapModulation();
 
 
    // Border last
    // Border last
    if (mShowFrame)
    if (mShowFrame)
-      drawUtil->drawRect(updateRect, mFrameColor);
+      drawUtil->drawRect(updateRect, mFrameColor.toColorI());
 }
 }
 
 
 
 

+ 4 - 4
Engine/source/T3D/fps/guiCrossHairHud.cpp

@@ -42,8 +42,8 @@ class GuiCrossHairHud : public GuiBitmapCtrl
 {
 {
    typedef GuiBitmapCtrl Parent;
    typedef GuiBitmapCtrl Parent;
 
 
-   ColorF   mDamageFillColor;
-   ColorF   mDamageFrameColor;
+   LinearColorF   mDamageFillColor;
+   LinearColorF   mDamageFrameColor;
    Point2I  mDamageRectSize;
    Point2I  mDamageRectSize;
    Point2I  mDamageOffset;
    Point2I  mDamageOffset;
 
 
@@ -178,7 +178,7 @@ void GuiCrossHairHud::drawDamage(Point2I offset, F32 damage, F32 opacity)
    rect.point.x -= mDamageRectSize.x / 2;
    rect.point.x -= mDamageRectSize.x / 2;
 
 
    // Draw the border
    // Draw the border
-   GFX->getDrawUtil()->drawRect(rect, mDamageFrameColor);
+   GFX->getDrawUtil()->drawRect(rect, mDamageFrameColor.toColorI());
 
 
    // Draw the damage % fill
    // Draw the damage % fill
    rect.point += Point2I(1, 1);
    rect.point += Point2I(1, 1);
@@ -187,5 +187,5 @@ void GuiCrossHairHud::drawDamage(Point2I offset, F32 damage, F32 opacity)
    if (rect.extent.x == 1)
    if (rect.extent.x == 1)
       rect.extent.x = 2;
       rect.extent.x = 2;
    if (rect.extent.x > 0)
    if (rect.extent.x > 0)
-      GFX->getDrawUtil()->drawRectFill(rect, mDamageFillColor);
+      GFX->getDrawUtil()->drawRectFill(rect, mDamageFillColor.toColorI());
 }
 }

+ 6 - 6
Engine/source/T3D/fps/guiHealthBarHud.cpp

@@ -45,9 +45,9 @@ class GuiHealthBarHud : public GuiControl
    bool     mDisplayEnergy;
    bool     mDisplayEnergy;
    bool     mFlip;
    bool     mFlip;
 
 
-   ColorF   mFillColor;
-   ColorF   mFrameColor;
-   ColorF   mDamageFillColor;
+   LinearColorF   mFillColor;
+   LinearColorF   mFrameColor;
+   LinearColorF   mDamageFillColor;
 
 
    S32      mPulseRate;
    S32      mPulseRate;
    F32      mPulseThreshold;
    F32      mPulseThreshold;
@@ -163,7 +163,7 @@ void GuiHealthBarHud::onRender(Point2I offset, const RectI &updateRect)
 
 
    // Background first
    // Background first
    if (mShowFill)
    if (mShowFill)
-      GFX->getDrawUtil()->drawRectFill(updateRect, mFillColor);
+      GFX->getDrawUtil()->drawRectFill(updateRect, mFillColor.toColorI());
 
 
    // Pulse the damage fill if it's below the threshold
    // Pulse the damage fill if it's below the threshold
    if (mPulseRate != 0)
    if (mPulseRate != 0)
@@ -196,9 +196,9 @@ void GuiHealthBarHud::onRender(Point2I offset, const RectI &updateRect)
       else
       else
          rect.point.y = bottomY - rect.extent.y;
          rect.point.y = bottomY - rect.extent.y;
    }
    }
-   GFX->getDrawUtil()->drawRectFill(rect, mDamageFillColor);
+   GFX->getDrawUtil()->drawRectFill(rect, mDamageFillColor.toColorI());
 
 
    // Border last
    // Border last
    if (mShowFrame)
    if (mShowFrame)
-      GFX->getDrawUtil()->drawRect(updateRect, mFrameColor);
+      GFX->getDrawUtil()->drawRect(updateRect, mFrameColor.toColorI());
 }
 }

+ 8 - 8
Engine/source/T3D/fps/guiHealthTextHud.cpp

@@ -41,10 +41,10 @@ class GuiHealthTextHud : public GuiControl
    bool mShowEnergy;  
    bool mShowEnergy;  
    bool mShowTrueHealth;  
    bool mShowTrueHealth;  
   
   
-   ColorF mFillColor;  
-   ColorF mFrameColor;  
-   ColorF mTextColor;  
-   ColorF mWarnColor;  
+   LinearColorF mFillColor;  
+   LinearColorF mFrameColor;  
+   LinearColorF mTextColor;  
+   LinearColorF mWarnColor;  
   
   
    F32 mWarnLevel;  
    F32 mWarnLevel;  
    F32 mPulseThreshold;  
    F32 mPulseThreshold;  
@@ -167,7 +167,7 @@ void GuiHealthTextHud::onRender(Point2I offset, const RectI &updateRect)
   
   
    // If enabled draw background first  
    // If enabled draw background first  
    if (mShowFill)  
    if (mShowFill)  
-      drawUtil->drawRectFill(updateRect, mFillColor);  
+      drawUtil->drawRectFill(updateRect, mFillColor.toColorI());
   
   
    // Prepare text and center it  
    // Prepare text and center it  
    S32 val = (S32)mValue;    
    S32 val = (S32)mValue;    
@@ -176,7 +176,7 @@ void GuiHealthTextHud::onRender(Point2I offset, const RectI &updateRect)
    offset.x += (getBounds().extent.x - mProfile->mFont->getStrWidth((const UTF8 *)buf)) / 2;    
    offset.x += (getBounds().extent.x - mProfile->mFont->getStrWidth((const UTF8 *)buf)) / 2;    
    offset.y += (getBounds().extent.y - mProfile->mFont->getHeight()) / 2;    
    offset.y += (getBounds().extent.y - mProfile->mFont->getHeight()) / 2;    
   
   
-   ColorF tColor = mTextColor;   
+   LinearColorF tColor = mTextColor;   
   
   
    // If warning level is exceeded switch to warning color  
    // If warning level is exceeded switch to warning color  
    if(mValue < mWarnLevel)   
    if(mValue < mWarnLevel)   
@@ -192,11 +192,11 @@ void GuiHealthTextHud::onRender(Point2I offset, const RectI &updateRect)
       }  
       }  
    }  
    }  
   
   
-   drawUtil->setBitmapModulation(tColor);    
+   drawUtil->setBitmapModulation(tColor.toColorI());
    drawUtil->drawText(mProfile->mFont, offset, buf);    
    drawUtil->drawText(mProfile->mFont, offset, buf);    
    drawUtil->clearBitmapModulation();    
    drawUtil->clearBitmapModulation();    
   
   
    // If enabled draw the border last  
    // If enabled draw the border last  
    if (mShowFrame)  
    if (mShowFrame)  
-      drawUtil->drawRect(updateRect, mFrameColor);  
+      drawUtil->drawRect(updateRect, mFrameColor.toColorI());
 }  
 }  

+ 10 - 10
Engine/source/T3D/fps/guiShapeNameHud.cpp

@@ -47,11 +47,11 @@ class GuiShapeNameHud : public GuiControl {
    typedef GuiControl Parent;
    typedef GuiControl Parent;
 
 
    // field data
    // field data
-   ColorF   mFillColor;
-   ColorF   mFrameColor;
-   ColorF   mTextColor;
-   ColorF   mLabelFillColor;
-   ColorF   mLabelFrameColor;
+   LinearColorF   mFillColor;
+   LinearColorF   mFrameColor;
+   LinearColorF   mTextColor;
+   LinearColorF   mLabelFillColor;
+   LinearColorF   mLabelFrameColor;
 
 
    F32      mVerticalOffset;
    F32      mVerticalOffset;
    F32      mDistanceFade;
    F32      mDistanceFade;
@@ -162,7 +162,7 @@ void GuiShapeNameHud::onRender( Point2I, const RectI &updateRect)
 {
 {
    // Background fill first
    // Background fill first
    if (mShowFill)
    if (mShowFill)
-      GFX->getDrawUtil()->drawRectFill(updateRect, mFillColor);
+      GFX->getDrawUtil()->drawRectFill(updateRect, mFillColor.toColorI());
 
 
    // Must be in a TS Control
    // Must be in a TS Control
    GuiTSCtrl *parent = dynamic_cast<GuiTSCtrl*>(getParent());
    GuiTSCtrl *parent = dynamic_cast<GuiTSCtrl*>(getParent());
@@ -274,7 +274,7 @@ void GuiShapeNameHud::onRender( Point2I, const RectI &updateRect)
 
 
    // Border last
    // Border last
    if (mShowFrame)
    if (mShowFrame)
-      GFX->getDrawUtil()->drawRect(updateRect, mFrameColor);
+      GFX->getDrawUtil()->drawRect(updateRect, mFrameColor.toColorI());
 }
 }
 
 
 
 
@@ -302,16 +302,16 @@ void GuiShapeNameHud::drawName(Point2I offset, const char *name, F32 opacity)
 
 
    // Background fill first
    // Background fill first
    if (mShowLabelFill)
    if (mShowLabelFill)
-      drawUtil->drawRectFill(RectI(offset, extent), mLabelFillColor);
+      drawUtil->drawRectFill(RectI(offset, extent), mLabelFillColor.toColorI());
 
 
    // Deal with opacity and draw.
    // Deal with opacity and draw.
    mTextColor.alpha = opacity;
    mTextColor.alpha = opacity;
-   drawUtil->setBitmapModulation(mTextColor);
+   drawUtil->setBitmapModulation(mTextColor.toColorI());
    drawUtil->drawText(mProfile->mFont, offset + mLabelPadding, name);
    drawUtil->drawText(mProfile->mFont, offset + mLabelPadding, name);
    drawUtil->clearBitmapModulation();
    drawUtil->clearBitmapModulation();
 
 
    // Border last
    // Border last
    if (mShowLabelFrame)
    if (mShowLabelFrame)
-      drawUtil->drawRect(RectI(offset, extent), mLabelFrameColor);
+      drawUtil->drawRect(RectI(offset, extent), mLabelFrameColor.toColorI());
 }
 }
 
 

+ 2 - 2
Engine/source/T3D/fx/explosion.h

@@ -113,8 +113,8 @@ class ExplosionData : public GameBaseData {
    // interpolated from start to end time.
    // interpolated from start to end time.
    F32               lightStartRadius;
    F32               lightStartRadius;
    F32               lightEndRadius;
    F32               lightEndRadius;
-   ColorF            lightStartColor;
-   ColorF            lightEndColor;
+   LinearColorF            lightStartColor;
+   LinearColorF            lightEndColor;
    F32               lightStartBrightness;
    F32               lightStartBrightness;
    F32               lightEndBrightness;
    F32               lightEndBrightness;
    F32               lightNormalOffset;
    F32               lightNormalOffset;

+ 6 - 6
Engine/source/T3D/fx/fxFoliageReplicator.cpp

@@ -166,7 +166,7 @@ void fxFoliageRenderList::SetupClipPlanes( SceneRenderState* state, const F32 fa
 //------------------------------------------------------------------------------
 //------------------------------------------------------------------------------
 
 
 
 
-inline void fxFoliageRenderList::DrawQuadBox(const Box3F& QuadBox, const ColorF Colour)
+inline void fxFoliageRenderList::DrawQuadBox(const Box3F& QuadBox, const LinearColorF Colour)
 {
 {
    // Define our debug box.
    // Define our debug box.
    static Point3F BoxPnts[] = {
    static Point3F BoxPnts[] = {
@@ -1260,7 +1260,7 @@ bool fxFoliageReplicator::onAdd()
    {
    {
       // Yes, so load foliage texture.
       // Yes, so load foliage texture.
       if( mFieldData.mFoliageFile != NULL && dStrlen(mFieldData.mFoliageFile) > 0 )
       if( mFieldData.mFoliageFile != NULL && dStrlen(mFieldData.mFoliageFile) > 0 )
-         mFieldData.mFoliageTexture = GFXTexHandle( mFieldData.mFoliageFile, &GFXDefaultStaticDiffuseProfile, avar("%s() - mFieldData.mFoliageTexture (line %d)", __FUNCTION__, __LINE__) );
+         mFieldData.mFoliageTexture = GFXTexHandle( mFieldData.mFoliageFile, &GFXStaticTextureSRGBProfile, avar("%s() - mFieldData.mFoliageTexture (line %d)", __FUNCTION__, __LINE__) );
 
 
       if ((GFXTextureObject*) mFieldData.mFoliageTexture == NULL)
       if ((GFXTextureObject*) mFieldData.mFoliageTexture == NULL)
          Con::printf("fxFoliageReplicator:  %s is an invalid or missing foliage texture file.", mFieldData.mFoliageFile);
          Con::printf("fxFoliageReplicator:  %s is an invalid or missing foliage texture file.", mFieldData.mFoliageFile);
@@ -1407,7 +1407,7 @@ void fxFoliageReplicator::computeAlphaTex()
       ColorI c((U8) (255.0f * ItemAlpha), 0, 0);
       ColorI c((U8) (255.0f * ItemAlpha), 0, 0);
       mAlphaLookup->setColor(i, 0, c);
       mAlphaLookup->setColor(i, 0, c);
    }
    }
-   mAlphaTexture.set(mAlphaLookup, &GFXDefaultStaticDiffuseProfile, false, String("fxFoliage Replicator Alpha Texture") );
+   mAlphaTexture.set(mAlphaLookup, &GFXStaticTextureSRGBProfile, false, String("fxFoliage Replicator Alpha Texture") );
 }
 }
 
 
 // Renders a triangle stripped oval
 // Renders a triangle stripped oval
@@ -1619,7 +1619,7 @@ void fxFoliageReplicator::renderQuad(fxFoliageQuadrantNode* quadNode, const Matr
       {
       {
          // Draw the Quad Box (Debug Only).
          // Draw the Quad Box (Debug Only).
          if (UseDebug) 
          if (UseDebug) 
-            mFrustumRenderSet.DrawQuadBox(quadNode->QuadrantBox, ColorF(0.0f, 1.0f, 0.1f, 1.0f));
+            mFrustumRenderSet.DrawQuadBox(quadNode->QuadrantBox, LinearColorF(0.0f, 1.0f, 0.1f, 1.0f));
          if (quadNode->Level != 0) {
          if (quadNode->Level != 0) {
             for (U32 i = 0; i < 4; i++)
             for (U32 i = 0; i < 4; i++)
                renderQuad(quadNode->QuadrantChildNode[i], RenderTransform, UseDebug);
                renderQuad(quadNode->QuadrantChildNode[i], RenderTransform, UseDebug);
@@ -1632,7 +1632,7 @@ void fxFoliageReplicator::renderQuad(fxFoliageQuadrantNode* quadNode, const Matr
       } else {
       } else {
          // Use a different color to say "I think I'm not visible!"
          // Use a different color to say "I think I'm not visible!"
          if (UseDebug) 
          if (UseDebug) 
-            mFrustumRenderSet.DrawQuadBox(quadNode->QuadrantBox, ColorF(1.0f, 0.8f, 0.1f, 1.0f));
+            mFrustumRenderSet.DrawQuadBox(quadNode->QuadrantBox, LinearColorF(1.0f, 0.8f, 0.1f, 1.0f));
       }
       }
    }
    }
 }
 }
@@ -1791,7 +1791,7 @@ void fxFoliageReplicator::unpackUpdate(NetConnection * con, BitStream * stream)
 
 
       // Load Foliage Texture on the client.
       // Load Foliage Texture on the client.
       if( mFieldData.mFoliageFile != NULL && dStrlen(mFieldData.mFoliageFile) > 0 )
       if( mFieldData.mFoliageFile != NULL && dStrlen(mFieldData.mFoliageFile) > 0 )
-         mFieldData.mFoliageTexture = GFXTexHandle( mFieldData.mFoliageFile, &GFXDefaultStaticDiffuseProfile, avar("%s() - mFieldData.mFoliageTexture (line %d)", __FUNCTION__, __LINE__) );
+         mFieldData.mFoliageTexture = GFXTexHandle( mFieldData.mFoliageFile, &GFXStaticTextureSRGBProfile, avar("%s() - mFieldData.mFoliageTexture (line %d)", __FUNCTION__, __LINE__) );
 
 
       if ((GFXTextureObject*) mFieldData.mFoliageTexture == NULL)
       if ((GFXTextureObject*) mFieldData.mFoliageTexture == NULL)
          Con::printf("fxFoliageReplicator:  %s is an invalid or missing foliage texture file.", mFieldData.mFoliageFile);
          Con::printf("fxFoliageReplicator:  %s is an invalid or missing foliage texture file.", mFieldData.mFoliageFile);

+ 2 - 2
Engine/source/T3D/fx/fxFoliageReplicator.h

@@ -126,7 +126,7 @@ public:
 public:
 public:
    bool IsQuadrantVisible(const Box3F VisBox, const MatrixF& RenderTransform);
    bool IsQuadrantVisible(const Box3F VisBox, const MatrixF& RenderTransform);
    void SetupClipPlanes(SceneRenderState* state, const F32 FarClipPlane);
    void SetupClipPlanes(SceneRenderState* state, const F32 FarClipPlane);
-   void DrawQuadBox(const Box3F& QuadBox, const ColorF Colour);
+   void DrawQuadBox(const Box3F& QuadBox, const LinearColorF Colour);
 };
 };
 
 
 
 
@@ -317,7 +317,7 @@ public:
       bool            mHideFoliage;
       bool            mHideFoliage;
       bool            mShowPlacementArea;
       bool            mShowPlacementArea;
       U32             mPlacementBandHeight;
       U32             mPlacementBandHeight;
-      ColorF          mPlaceAreaColour;
+      LinearColorF          mPlaceAreaColour;
 
 
       tagFieldData()
       tagFieldData()
       {
       {

+ 1 - 1
Engine/source/T3D/fx/fxShapeReplicator.h

@@ -147,7 +147,7 @@ public:
       bool              mHideReplications;
       bool              mHideReplications;
       bool              mShowPlacementArea;
       bool              mShowPlacementArea;
       U32               mPlacementBandHeight;
       U32               mPlacementBandHeight;
-      ColorF            mPlaceAreaColour;
+      LinearColorF            mPlaceAreaColour;
 
 
       tagFieldData()
       tagFieldData()
       {
       {

+ 3 - 3
Engine/source/T3D/fx/groundCover.cpp

@@ -113,7 +113,7 @@ protected:
       U32         type;
       U32         type;
       F32         windAmplitude;
       F32         windAmplitude;
       Box3F       worldBox;
       Box3F       worldBox;
-      ColorF      lmColor;
+      LinearColorF      lmColor;
    };
    };
 
 
    /// This is the x,y index for this cell.
    /// This is the x,y index for this cell.
@@ -239,7 +239,7 @@ void GroundCoverCell::_rebuildVB()
          const S32 &type = (*iter).type;
          const S32 &type = (*iter).type;
          const Point3F &size = (*iter).size;
          const Point3F &size = (*iter).size;
          const F32 &windAmplitude = (*iter).windAmplitude;
          const F32 &windAmplitude = (*iter).windAmplitude;
-         GFXVertexColor color = (ColorI)(*iter).lmColor;
+         color = LinearColorF((*iter).lmColor).toColorI();
          U8 *col = (U8 *)const_cast<U32 *>( (const U32 *)color );
          U8 *col = (U8 *)const_cast<U32 *>( (const U32 *)color );
 
 
          vertPtr->point = position;
          vertPtr->point = position;
@@ -944,7 +944,7 @@ void GroundCover::_initialize( U32 cellCount, U32 cellPlacementCount )
       Material* mat = dynamic_cast<Material*>(mMatInst->getMaterial());
       Material* mat = dynamic_cast<Material*>(mMatInst->getMaterial());
       if(mat)
       if(mat)
       {
       {
-         GFXTexHandle tex(mat->mDiffuseMapFilename[0], &GFXDefaultStaticDiffuseProfile, "GroundCover texture aspect ratio check" );
+         GFXTexHandle tex(mat->mDiffuseMapFilename[0], &GFXStaticTextureSRGBProfile, "GroundCover texture aspect ratio check" );
          if(tex.isValid())
          if(tex.isValid())
          {
          {
             U32 w = tex.getWidth();
             U32 w = tex.getWidth();

+ 1 - 1
Engine/source/T3D/fx/lightning.cpp

@@ -303,7 +303,7 @@ bool LightningData::preload(bool server, String &errorStr)
       {
       {
          if (strikeTextureNames[i][0])
          if (strikeTextureNames[i][0])
          {
          {
-            strikeTextures[i] = GFXTexHandle(strikeTextureNames[i], &GFXDefaultStaticDiffuseProfile, avar("%s() - strikeTextures[%d] (line %d)", __FUNCTION__, i, __LINE__));
+            strikeTextures[i] = GFXTexHandle(strikeTextureNames[i], &GFXStaticTextureProfile, avar("%s() - strikeTextures[%d] (line %d)", __FUNCTION__, i, __LINE__));
             mNumStrikeTextures++;
             mNumStrikeTextures++;
          }
          }
       }
       }

+ 2 - 2
Engine/source/T3D/fx/lightning.h

@@ -191,8 +191,8 @@ class Lightning : public GameBase
    F32      chanceToHitTarget;
    F32      chanceToHitTarget;
    F32      strikeRadius;
    F32      strikeRadius;
    F32      boltStartRadius;
    F32      boltStartRadius;
-   ColorF   color;
-   ColorF   fadeColor;
+   LinearColorF   color;
+   LinearColorF   fadeColor;
    bool     useFog;
    bool     useFog;
 
 
    GFXStateBlockRef  mLightningSB;
    GFXStateBlockRef  mLightningSB;

+ 3 - 3
Engine/source/T3D/fx/particle.cpp

@@ -200,7 +200,7 @@ void ParticleData::initPersistFields()
       "Deprecated. Use textureName instead." );
       "Deprecated. Use textureName instead." );
 
 
    // Interpolation variables
    // Interpolation variables
-   addField( "colors", TYPEID< ColorF >(), Offset(colors, ParticleData), PDC_NUM_KEYS,
+   addField( "colors", TYPEID< LinearColorF >(), Offset(colors, ParticleData), PDC_NUM_KEYS,
       "@brief Particle RGBA color keyframe values.\n\n"
       "@brief Particle RGBA color keyframe values.\n\n"
       "The particle color will linearly interpolate between the color/time keys "
       "The particle color will linearly interpolate between the color/time keys "
       "over the lifetime of the particle." );
       "over the lifetime of the particle." );
@@ -488,7 +488,7 @@ bool ParticleData::preload(bool server, String &errorStr)
       // texture is *not* an error since the emitter may provide one.
       // texture is *not* an error since the emitter may provide one.
       if (textureName && textureName[0])
       if (textureName && textureName[0])
       {
       {
-        textureHandle = GFXTexHandle(textureName, &GFXDefaultStaticDiffuseProfile, avar("%s() - textureHandle (line %d)", __FUNCTION__, __LINE__));
+        textureHandle = GFXTexHandle(textureName, &GFXStaticTextureSRGBProfile, avar("%s() - textureHandle (line %d)", __FUNCTION__, __LINE__));
         if (!textureHandle)
         if (!textureHandle)
         {
         {
           errorStr = String::ToString("Missing particle texture: %s", textureName);
           errorStr = String::ToString("Missing particle texture: %s", textureName);
@@ -613,7 +613,7 @@ bool ParticleData::reload(char errorBuffer[256])
    bool error = false;
    bool error = false;
 	if (textureName && textureName[0])
 	if (textureName && textureName[0])
    {
    {
-        textureHandle = GFXTexHandle(textureName, &GFXDefaultStaticDiffuseProfile, avar("%s() - textureHandle (line %d)", __FUNCTION__, __LINE__));
+        textureHandle = GFXTexHandle(textureName, &GFXStaticTextureSRGBProfile, avar("%s() - textureHandle (line %d)", __FUNCTION__, __LINE__));
         if (!textureHandle)
         if (!textureHandle)
         {
         {
 				dSprintf(errorBuffer, 256, "Missing particle texture: %s", textureName);
 				dSprintf(errorBuffer, 256, "Missing particle texture: %s", textureName);

+ 2 - 2
Engine/source/T3D/fx/particle.h

@@ -67,7 +67,7 @@ class ParticleData : public SimDataBlock
    U32   numFrames;
    U32   numFrames;
    U32   framesPerSec;
    U32   framesPerSec;
 
 
-   ColorF colors[ PDC_NUM_KEYS ];
+   LinearColorF colors[ PDC_NUM_KEYS ];
    F32    sizes[ PDC_NUM_KEYS ];
    F32    sizes[ PDC_NUM_KEYS ];
    F32    times[ PDC_NUM_KEYS ];
    F32    times[ PDC_NUM_KEYS ];
 
 
@@ -118,7 +118,7 @@ struct Particle
 
 
 
 
    // are these necessary to store here? - they are interpolated in real time
    // are these necessary to store here? - they are interpolated in real time
-   ColorF           color;
+   LinearColorF           color;
    F32              size;
    F32              size;
 
 
    F32              spinSpeed;
    F32              spinSpeed;

+ 57 - 57
Engine/source/T3D/fx/particleEmitter.cpp

@@ -603,7 +603,7 @@ bool ParticleEmitterData::preload(bool server, String &errorStr)
      // load emitter texture if specified
      // load emitter texture if specified
      if (textureName && textureName[0])
      if (textureName && textureName[0])
      {
      {
-       textureHandle = GFXTexHandle(textureName, &GFXDefaultStaticDiffuseProfile, avar("%s() - textureHandle (line %d)", __FUNCTION__, __LINE__));
+       textureHandle = GFXTexHandle(textureName, &GFXStaticTextureSRGBProfile, avar("%s() - textureHandle (line %d)", __FUNCTION__, __LINE__));
        if (!textureHandle)
        if (!textureHandle)
        {
        {
          errorStr = String::ToString("Missing particle emitter texture: %s", textureName);
          errorStr = String::ToString("Missing particle emitter texture: %s", textureName);
@@ -833,10 +833,10 @@ bool ParticleEmitter::onNewDataBlock( GameBaseData *dptr, bool reload )
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 // getCollectiveColor
 // getCollectiveColor
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
-ColorF ParticleEmitter::getCollectiveColor()
+LinearColorF ParticleEmitter::getCollectiveColor()
 {
 {
 	U32 count = 0;
 	U32 count = 0;
-	ColorF color = ColorF(0.0f, 0.0f, 0.0f);
+	LinearColorF color = LinearColorF(0.0f, 0.0f, 0.0f);
 
 
    count = n_parts;
    count = n_parts;
    for( Particle* part = part_list_head.next; part != NULL; part = part->next )
    for( Particle* part = part_list_head.next; part != NULL; part = part->next )
@@ -937,7 +937,7 @@ void ParticleEmitter::setSizes( F32 *sizeList )
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 // setColors
 // setColors
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
-void ParticleEmitter::setColors( ColorF *colorList )
+void ParticleEmitter::setColors( LinearColorF *colorList )
 {
 {
    for( S32 i=0; i<ParticleData::PDC_NUM_KEYS; i++ )
    for( S32 i=0; i<ParticleData::PDC_NUM_KEYS; i++ )
    {
    {
@@ -1467,7 +1467,7 @@ S32 QSORT_CALLBACK cmpSortParticles(const void* p1, const void* p2)
       return -1;
       return -1;
 }
 }
 
 
-void ParticleEmitter::copyToVB( const Point3F &camPos, const ColorF &ambientColor )
+void ParticleEmitter::copyToVB( const Point3F &camPos, const LinearColorF &ambientColor )
 {
 {
    static Vector<SortParticle> orderedVector(__FILE__, __LINE__);
    static Vector<SortParticle> orderedVector(__FILE__, __LINE__);
 
 
@@ -1653,7 +1653,7 @@ void ParticleEmitter::copyToVB( const Point3F &camPos, const ColorF &ambientColo
 void ParticleEmitter::setupBillboard( Particle *part,
 void ParticleEmitter::setupBillboard( Particle *part,
                                       Point3F *basePts,
                                       Point3F *basePts,
                                       const MatrixF &camView,
                                       const MatrixF &camView,
-                                      const ColorF &ambientColor,
+                                      const LinearColorF &ambientColor,
                                       ParticleVertexType *lVerts )
                                       ParticleVertexType *lVerts )
 {
 {
    F32 width     = part->size * 0.5f;
    F32 width     = part->size * 0.5f;
@@ -1663,7 +1663,7 @@ void ParticleEmitter::setupBillboard( Particle *part,
    mSinCos(spinAngle, sy, cy);
    mSinCos(spinAngle, sy, cy);
 
 
    const F32 ambientLerp = mClampF( mDataBlock->ambientFactor, 0.0f, 1.0f );
    const F32 ambientLerp = mClampF( mDataBlock->ambientFactor, 0.0f, 1.0f );
-   ColorF partCol = mLerp( part->color, ( part->color * ambientColor ), ambientLerp );
+   LinearColorF partCol = mLerp( part->color, ( part->color * ambientColor ), ambientLerp );
 
 
    // fill four verts, use macro and unroll loop
    // fill four verts, use macro and unroll loop
    #define fillVert(){ \
    #define fillVert(){ \
@@ -1673,7 +1673,7 @@ void ParticleEmitter::setupBillboard( Particle *part,
       camView.mulV( lVerts->point );                        \
       camView.mulV( lVerts->point );                        \
       lVerts->point *= width;                               \
       lVerts->point *= width;                               \
       lVerts->point += part->pos;                           \
       lVerts->point += part->pos;                           \
-      lVerts->color = partCol; } \
+      lVerts->color = partCol.toColorI(); } \
 
 
    // Here we deal with UVs for animated particle (billboard)
    // Here we deal with UVs for animated particle (billboard)
    if (part->dataBlock->animateTexture && !part->dataBlock->animTexFrames.empty())
    if (part->dataBlock->animateTexture && !part->dataBlock->animTexFrames.empty())
@@ -1737,7 +1737,7 @@ void ParticleEmitter::setupBillboard( Particle *part,
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 void ParticleEmitter::setupOriented( Particle *part,
 void ParticleEmitter::setupOriented( Particle *part,
                                      const Point3F &camPos,
                                      const Point3F &camPos,
-                                     const ColorF &ambientColor,
+                                     const LinearColorF &ambientColor,
                                      ParticleVertexType *lVerts )
                                      ParticleVertexType *lVerts )
 {
 {
    Point3F dir;
    Point3F dir;
@@ -1766,8 +1766,8 @@ void ParticleEmitter::setupOriented( Particle *part,
    Point3F end = part->pos + dir;
    Point3F end = part->pos + dir;
 
 
    const F32 ambientLerp = mClampF( mDataBlock->ambientFactor, 0.0f, 1.0f );
    const F32 ambientLerp = mClampF( mDataBlock->ambientFactor, 0.0f, 1.0f );
-   ColorF partCol = mLerp( part->color, ( part->color * ambientColor ), ambientLerp );
-
+   LinearColorF partCol = mLerp( part->color, ( part->color * ambientColor ), ambientLerp );
+   const ColorI color = partCol.toColorI();
    // Here we deal with UVs for animated particle (oriented)
    // Here we deal with UVs for animated particle (oriented)
    if (part->dataBlock->animateTexture)
    if (part->dataBlock->animateTexture)
    { 
    { 
@@ -1779,55 +1779,55 @@ void ParticleEmitter::setupOriented( Particle *part,
       uv[1] = uv[0] + (part->dataBlock->animTexTiling.x + 1);
       uv[1] = uv[0] + (part->dataBlock->animTexTiling.x + 1);
       uv[2] = uv[1] + 1;
       uv[2] = uv[1] + 1;
       uv[3] = uv[0] + 1;
       uv[3] = uv[0] + 1;
+      
+      lVerts->point = start + crossDir;
+      lVerts->color = color;
+      // Here and below, we copy UVs from particle datablock's current frame's UVs (oriented)
+      lVerts->texCoord = part->dataBlock->animTexUVs[uv[0]];
+      ++lVerts;
 
 
-     lVerts->point = start + crossDir;
-     lVerts->color = partCol;
-     // Here and below, we copy UVs from particle datablock's current frame's UVs (oriented)
-     lVerts->texCoord = part->dataBlock->animTexUVs[uv[0]];
-     ++lVerts;
-
-     lVerts->point = start - crossDir;
-     lVerts->color = partCol;
-     lVerts->texCoord = part->dataBlock->animTexUVs[uv[1]];
-     ++lVerts;
+      lVerts->point = start - crossDir;
+      lVerts->color = color;
+      lVerts->texCoord = part->dataBlock->animTexUVs[uv[1]];
+      ++lVerts;
 
 
-     lVerts->point = end - crossDir;
-     lVerts->color = partCol;
-     lVerts->texCoord = part->dataBlock->animTexUVs[uv[2]];
-     ++lVerts;
+      lVerts->point = end - crossDir;
+      lVerts->color = color;
+      lVerts->texCoord = part->dataBlock->animTexUVs[uv[2]];
+      ++lVerts;
 
 
-     lVerts->point = end + crossDir;
-     lVerts->color = partCol;
-     lVerts->texCoord = part->dataBlock->animTexUVs[uv[3]];
-     ++lVerts;
+      lVerts->point = end + crossDir;
+      lVerts->color = color;
+      lVerts->texCoord = part->dataBlock->animTexUVs[uv[3]];
+      ++lVerts;
 
 
-     return;
+      return;
    }
    }
 
 
    lVerts->point = start + crossDir;
    lVerts->point = start + crossDir;
-   lVerts->color = partCol;
+   lVerts->color = color;
    // Here and below, we copy UVs from particle datablock's texCoords (oriented)
    // Here and below, we copy UVs from particle datablock's texCoords (oriented)
    lVerts->texCoord = part->dataBlock->texCoords[1];
    lVerts->texCoord = part->dataBlock->texCoords[1];
    ++lVerts;
    ++lVerts;
 
 
    lVerts->point = start - crossDir;
    lVerts->point = start - crossDir;
-   lVerts->color = partCol;
+   lVerts->color = color;
    lVerts->texCoord = part->dataBlock->texCoords[2];
    lVerts->texCoord = part->dataBlock->texCoords[2];
    ++lVerts;
    ++lVerts;
 
 
    lVerts->point = end - crossDir;
    lVerts->point = end - crossDir;
-   lVerts->color = partCol;
+   lVerts->color = color;
    lVerts->texCoord = part->dataBlock->texCoords[3];
    lVerts->texCoord = part->dataBlock->texCoords[3];
    ++lVerts;
    ++lVerts;
 
 
    lVerts->point = end + crossDir;
    lVerts->point = end + crossDir;
-   lVerts->color = partCol;
+   lVerts->color = color;
    lVerts->texCoord = part->dataBlock->texCoords[0];
    lVerts->texCoord = part->dataBlock->texCoords[0];
    ++lVerts;
    ++lVerts;
 }
 }
 
 
 void ParticleEmitter::setupAligned( const Particle *part, 
 void ParticleEmitter::setupAligned( const Particle *part, 
-                                    const ColorF &ambientColor,
+                                    const LinearColorF &ambientColor,
                                     ParticleVertexType *lVerts )
                                     ParticleVertexType *lVerts )
 {
 {
    // The aligned direction will always be normalized.
    // The aligned direction will always be normalized.
@@ -1877,8 +1877,8 @@ void ParticleEmitter::setupAligned( const Particle *part,
    Point3F end = part->pos + right;
    Point3F end = part->pos + right;
 
 
    const F32 ambientLerp = mClampF( mDataBlock->ambientFactor, 0.0f, 1.0f );
    const F32 ambientLerp = mClampF( mDataBlock->ambientFactor, 0.0f, 1.0f );
-   ColorF partCol = mLerp( part->color, ( part->color * ambientColor ), ambientLerp );
-
+   LinearColorF partCol = mLerp( part->color, ( part->color * ambientColor ), ambientLerp );
+   const ColorI color = partCol.toColorI();
    // Here we deal with UVs for animated particle
    // Here we deal with UVs for animated particle
    if (part->dataBlock->animateTexture)
    if (part->dataBlock->animateTexture)
    { 
    { 
@@ -1891,46 +1891,46 @@ void ParticleEmitter::setupAligned( const Particle *part,
       uv[2] = uv[1] + 1;
       uv[2] = uv[1] + 1;
       uv[3] = uv[0] + 1;
       uv[3] = uv[0] + 1;
 
 
-     lVerts->point = start + cross;
-      lVerts->color = partCol;
-     lVerts->texCoord = part->dataBlock->animTexUVs[uv[0]];
-     ++lVerts;
+      lVerts->point = start + cross;
+      lVerts->color = color;
+      lVerts->texCoord = part->dataBlock->animTexUVs[uv[0]];
+      ++lVerts;
 
 
-     lVerts->point = start - cross;
-      lVerts->color = partCol;
-     lVerts->texCoord = part->dataBlock->animTexUVs[uv[1]];
-     ++lVerts;
+      lVerts->point = start - cross;
+      lVerts->color = color;
+      lVerts->texCoord = part->dataBlock->animTexUVs[uv[1]];
+      ++lVerts;
 
 
-     lVerts->point = end - cross;
-      lVerts->color = partCol;
-     lVerts->texCoord = part->dataBlock->animTexUVs[uv[2]];
-     ++lVerts;
+      lVerts->point = end - cross;
+      lVerts->color = color;
+      lVerts->texCoord = part->dataBlock->animTexUVs[uv[2]];
+      ++lVerts;
 
 
-     lVerts->point = end + cross;
-      lVerts->color = partCol;
-     lVerts->texCoord = part->dataBlock->animTexUVs[uv[3]];
-     ++lVerts;
+      lVerts->point = end + cross;
+      lVerts->color = color;
+      lVerts->texCoord = part->dataBlock->animTexUVs[uv[3]];
+      ++lVerts;
    }
    }
    else
    else
    {
    {
       // Here and below, we copy UVs from particle datablock's texCoords
       // Here and below, we copy UVs from particle datablock's texCoords
       lVerts->point = start + cross;
       lVerts->point = start + cross;
-      lVerts->color = partCol;
+      lVerts->color = color;
       lVerts->texCoord = part->dataBlock->texCoords[0];
       lVerts->texCoord = part->dataBlock->texCoords[0];
       ++lVerts;
       ++lVerts;
 
 
       lVerts->point = start - cross;
       lVerts->point = start - cross;
-      lVerts->color = partCol;
+      lVerts->color = color;
       lVerts->texCoord = part->dataBlock->texCoords[1];
       lVerts->texCoord = part->dataBlock->texCoords[1];
       ++lVerts;
       ++lVerts;
 
 
       lVerts->point = end - cross;
       lVerts->point = end - cross;
-      lVerts->color = partCol;
+      lVerts->color = color;
       lVerts->texCoord = part->dataBlock->texCoords[2];
       lVerts->texCoord = part->dataBlock->texCoords[2];
       ++lVerts;
       ++lVerts;
 
 
       lVerts->point = end + cross;
       lVerts->point = end + cross;
-      lVerts->color = partCol;
+      lVerts->color = color;
       lVerts->texCoord = part->dataBlock->texCoords[3];
       lVerts->texCoord = part->dataBlock->texCoords[3];
       ++lVerts;
       ++lVerts;
    }
    }

+ 7 - 7
Engine/source/T3D/fx/particleEmitter.h

@@ -134,7 +134,7 @@ class ParticleEmitter : public GameBase
    static Point3F mWindVelocity;
    static Point3F mWindVelocity;
    static void setWindVelocity( const Point3F &vel ){ mWindVelocity = vel; }
    static void setWindVelocity( const Point3F &vel ){ mWindVelocity = vel; }
    
    
-   ColorF getCollectiveColor();
+   LinearColorF getCollectiveColor();
 
 
    /// Sets sizes of particles based on sizelist provided
    /// Sets sizes of particles based on sizelist provided
    /// @param   sizeList   List of sizes
    /// @param   sizeList   List of sizes
@@ -142,7 +142,7 @@ class ParticleEmitter : public GameBase
 
 
    /// Sets colors for particles based on color list provided
    /// Sets colors for particles based on color list provided
    /// @param   colorList   List of colors
    /// @param   colorList   List of colors
-   void setColors( ColorF *colorList );
+   void setColors( LinearColorF *colorList );
 
 
    ParticleEmitterData *getDataBlock(){ return mDataBlock; }
    ParticleEmitterData *getDataBlock(){ return mDataBlock; }
    bool onNewDataBlock( GameBaseData *dptr, bool reload );
    bool onNewDataBlock( GameBaseData *dptr, bool reload );
@@ -196,16 +196,16 @@ class ParticleEmitter : public GameBase
    inline void setupBillboard( Particle *part,
    inline void setupBillboard( Particle *part,
                                Point3F *basePts,
                                Point3F *basePts,
                                const MatrixF &camView,
                                const MatrixF &camView,
-                               const ColorF &ambientColor,
+                               const LinearColorF &ambientColor,
                                ParticleVertexType *lVerts );
                                ParticleVertexType *lVerts );
 
 
    inline void setupOriented( Particle *part,
    inline void setupOriented( Particle *part,
                               const Point3F &camPos,
                               const Point3F &camPos,
-                              const ColorF &ambientColor,
+                              const LinearColorF &ambientColor,
                               ParticleVertexType *lVerts );
                               ParticleVertexType *lVerts );
 
 
    inline void setupAligned(  const Particle *part, 
    inline void setupAligned(  const Particle *part, 
-                              const ColorF &ambientColor,
+                              const LinearColorF &ambientColor,
                               ParticleVertexType *lVerts );
                               ParticleVertexType *lVerts );
 
 
    /// Updates the bounding box for the particle system
    /// Updates the bounding box for the particle system
@@ -222,7 +222,7 @@ class ParticleEmitter : public GameBase
    // Rendering
    // Rendering
   protected:
   protected:
    void prepRenderImage( SceneRenderState *state );
    void prepRenderImage( SceneRenderState *state );
-   void copyToVB( const Point3F &camPos, const ColorF &ambientColor );
+   void copyToVB( const Point3F &camPos, const LinearColorF &ambientColor );
 
 
    // PEngine interface
    // PEngine interface
   private:
   private:
@@ -254,7 +254,7 @@ class ParticleEmitter : public GameBase
    S32       mElapsedTimeMS;
    S32       mElapsedTimeMS;
 
 
    F32       sizes[ ParticleData::PDC_NUM_KEYS ];
    F32       sizes[ ParticleData::PDC_NUM_KEYS ];
-   ColorF    colors[ ParticleData::PDC_NUM_KEYS ];
+   LinearColorF    colors[ ParticleData::PDC_NUM_KEYS ];
 
 
    GFXVertexBufferHandle<ParticleVertexType> mVertBuff;
    GFXVertexBufferHandle<ParticleVertexType> mVertBuff;
 
 

+ 4 - 4
Engine/source/T3D/fx/precipitation.cpp

@@ -248,7 +248,7 @@ Precipitation::Precipitation()
    mDropAnimateMS    = 0;
    mDropAnimateMS    = 0;
 
 
    mUseLighting = false;
    mUseLighting = false;
-   mGlowIntensity = ColorF( 0,0,0,0 );
+   mGlowIntensity = LinearColorF( 0,0,0,0 );
 
 
    mReflect = false;
    mReflect = false;
 
 
@@ -604,7 +604,7 @@ void Precipitation::initMaterials()
    mDropShader = NULL;
    mDropShader = NULL;
    mSplashShader = NULL;
    mSplashShader = NULL;
 
 
-   if( dStrlen(pd->mDropName) > 0 && !mDropHandle.set(pd->mDropName, &GFXDefaultStaticDiffuseProfile, avar("%s() - mDropHandle (line %d)", __FUNCTION__, __LINE__)) )
+   if( dStrlen(pd->mDropName) > 0 && !mDropHandle.set(pd->mDropName, &GFXStaticTextureSRGBProfile, avar("%s() - mDropHandle (line %d)", __FUNCTION__, __LINE__)) )
       Con::warnf("Precipitation::initMaterials - failed to locate texture '%s'!", pd->mDropName);
       Con::warnf("Precipitation::initMaterials - failed to locate texture '%s'!", pd->mDropName);
 
 
    if ( dStrlen(pd->mDropShaderName) > 0 )
    if ( dStrlen(pd->mDropShaderName) > 0 )
@@ -625,7 +625,7 @@ void Precipitation::initMaterials()
       }
       }
    }
    }
 
 
-   if( dStrlen(pd->mSplashName) > 0 && !mSplashHandle.set(pd->mSplashName, &GFXDefaultStaticDiffuseProfile, avar("%s() - mSplashHandle (line %d)", __FUNCTION__, __LINE__)) )
+   if( dStrlen(pd->mSplashName) > 0 && !mSplashHandle.set(pd->mSplashName, &GFXStaticTextureSRGBProfile, avar("%s() - mSplashHandle (line %d)", __FUNCTION__, __LINE__)) )
       Con::warnf("Precipitation::initMaterials - failed to locate texture '%s'!", pd->mSplashName);
       Con::warnf("Precipitation::initMaterials - failed to locate texture '%s'!", pd->mSplashName);
 
 
    if ( dStrlen(pd->mSplashShaderName) > 0 )
    if ( dStrlen(pd->mSplashShaderName) > 0 )
@@ -1581,7 +1581,7 @@ void Precipitation::renderObject(ObjectRenderInst *ri, SceneRenderState *state,
    // shader.  Once the lighting and shadow systems
    // shader.  Once the lighting and shadow systems
    // are added into TSE we can expand this to include
    // are added into TSE we can expand this to include
    // the N nearest lights to the camera + the ambient.
    // the N nearest lights to the camera + the ambient.
-   ColorF ambient( 1, 1, 1 );
+   LinearColorF ambient( 1, 1, 1 );
    if ( mUseLighting )
    if ( mUseLighting )
    {
    {
       const LightInfo *sunlight = LIGHTMGR->getSpecialLight(LightManager::slSunLightType);
       const LightInfo *sunlight = LIGHTMGR->getSpecialLight(LightManager::slSunLightType);

+ 1 - 1
Engine/source/T3D/fx/precipitation.h

@@ -160,7 +160,7 @@ class Precipitation : public GameBase
    bool mUseLighting;            ///< This enables shading of the drops and splashes
    bool mUseLighting;            ///< This enables shading of the drops and splashes
                                  ///< by the sun color.
                                  ///< by the sun color.
 
 
-   ColorF mGlowIntensity;        ///< Set it to 0 to disable the glow or use it to control 
+   LinearColorF mGlowIntensity;        ///< Set it to 0 to disable the glow or use it to control 
                                  ///< the intensity of each channel.
                                  ///< the intensity of each channel.
 
 
    bool mReflect;                ///< This enables the precipitation to be rendered
    bool mReflect;                ///< This enables the precipitation to be rendered

+ 6 - 6
Engine/source/T3D/fx/ribbon.cpp

@@ -562,16 +562,16 @@ void Ribbon::createBuffers(SceneRenderState *state, GFXVertexBufferHandle<GFXVer
       Point3F leftvert = mSegmentPoints[i];
       Point3F leftvert = mSegmentPoints[i];
       Point3F rightvert = mSegmentPoints[i];
       Point3F rightvert = mSegmentPoints[i];
       F32 tRadius = mDataBlock->mSizes[0];
       F32 tRadius = mDataBlock->mSizes[0];
-      ColorF tColor = mDataBlock->mColours[0];
+      LinearColorF tColor = mDataBlock->mColours[0];
 
 
       for (U8 j = 0; j < RibbonData::NumFields-1; j++) {
       for (U8 j = 0; j < RibbonData::NumFields-1; j++) {
 
 
          F32 curPosition = mDataBlock->mTimes[j];
          F32 curPosition = mDataBlock->mTimes[j];
          F32 curRadius = mDataBlock->mSizes[j];
          F32 curRadius = mDataBlock->mSizes[j];
-         ColorF curColor = mDataBlock->mColours[j];
+         LinearColorF curColor = mDataBlock->mColours[j];
          F32 nextPosition = mDataBlock->mTimes[j+1];
          F32 nextPosition = mDataBlock->mTimes[j+1];
          F32 nextRadius = mDataBlock->mSizes[j+1];
          F32 nextRadius = mDataBlock->mSizes[j+1];
-         ColorF nextColor = mDataBlock->mColours[j+1];
+         LinearColorF nextColor = mDataBlock->mColours[j+1];
 
 
          if (  curPosition < 0
          if (  curPosition < 0
             || curPosition > interpol )
             || curPosition > interpol )
@@ -603,7 +603,7 @@ void Ribbon::createBuffers(SceneRenderState *state, GFXVertexBufferHandle<GFXVer
       perpendicular += mSegmentPoints[i];
       perpendicular += mSegmentPoints[i];
 
 
       verts[count].point.set(perpendicular);
       verts[count].point.set(perpendicular);
-      ColorF color = tColor;
+      LinearColorF color = tColor;
 
 
       if (mDataBlock->mUseFadeOut)
       if (mDataBlock->mUseFadeOut)
          color.alpha *= mFadeOut;
          color.alpha *= mFadeOut;
@@ -623,7 +623,7 @@ void Ribbon::createBuffers(SceneRenderState *state, GFXVertexBufferHandle<GFXVer
       else
       else
          texCoords = (1.0f - interpol)*mDataBlock->mTileScale;
          texCoords = (1.0f - interpol)*mDataBlock->mTileScale;
 
 
-      verts[count].color = color;
+      verts[count].color = color.toColorI();
       verts[count].texCoord[1] = Point2F(interpol, 0);
       verts[count].texCoord[1] = Point2F(interpol, 0);
       verts[count].texCoord[0] = Point2F(0.0f, texCoords);
       verts[count].texCoord[0] = Point2F(0.0f, texCoords);
       verts[count].normal.set(diff);
       verts[count].normal.set(diff);
@@ -651,7 +651,7 @@ void Ribbon::createBuffers(SceneRenderState *state, GFXVertexBufferHandle<GFXVer
       if (mDataBlock->mUseFadeOut)
       if (mDataBlock->mUseFadeOut)
          color.alpha *= mFadeOut;
          color.alpha *= mFadeOut;
 
 
-      verts[count].color = color;
+      verts[count].color = color.toColorI();
       verts[count].texCoord[1] = Point2F(interpol, 1);
       verts[count].texCoord[1] = Point2F(interpol, 1);
       verts[count].texCoord[0] = Point2F(1.0f, texCoords);
       verts[count].texCoord[0] = Point2F(1.0f, texCoords);
       verts[count].normal.set(diff);
       verts[count].normal.set(diff);

+ 1 - 1
Engine/source/T3D/fx/ribbon.h

@@ -54,7 +54,7 @@ public:
    };
    };
 
 
    F32 mSizes[NumFields];      ///< The radius for each keyframe.
    F32 mSizes[NumFields];      ///< The radius for each keyframe.
-   ColorF mColours[NumFields]; ///< The colour of the ribbon for each keyframe.
+   LinearColorF mColours[NumFields]; ///< The colour of the ribbon for each keyframe.
    F32 mTimes[NumFields];      ///< The relative time for each keyframe.
    F32 mTimes[NumFields];      ///< The relative time for each keyframe.
 
 
    U32 mRibbonLength;      ///< The amount of segments that will make up the ribbon.
    U32 mRibbonLength;      ///< The amount of segments that will make up the ribbon.

+ 1 - 1
Engine/source/T3D/fx/splash.cpp

@@ -282,7 +282,7 @@ bool SplashData::preload(bool server, String &errorStr)
       {
       {
          if (textureName[i] && textureName[i][0])
          if (textureName[i] && textureName[i][0])
          {
          {
-            textureHandle[i] = GFXTexHandle(textureName[i], &GFXDefaultStaticDiffuseProfile, avar("%s() - textureHandle[%d] (line %d)", __FUNCTION__, i, __LINE__) );
+            textureHandle[i] = GFXTexHandle(textureName[i], &GFXStaticTextureSRGBProfile, avar("%s() - textureHandle[%d] (line %d)", __FUNCTION__, i, __LINE__) );
          }
          }
       }
       }
    }
    }

+ 3 - 3
Engine/source/T3D/fx/splash.h

@@ -54,7 +54,7 @@ struct SplashRingPoint
 struct SplashRing
 struct SplashRing
 {
 {
    Vector <SplashRingPoint> points;
    Vector <SplashRingPoint> points;
-   ColorF   color;
+   LinearColorF   color;
    F32      lifetime;
    F32      lifetime;
    F32      elapsedTime;
    F32      elapsedTime;
    F32      v;
    F32      v;
@@ -114,7 +114,7 @@ public:
    F32               startRadius;
    F32               startRadius;
 
 
    F32               times[ NUM_TIME_KEYS ];
    F32               times[ NUM_TIME_KEYS ];
-   ColorF            colors[ NUM_TIME_KEYS ];
+   LinearColorF            colors[ NUM_TIME_KEYS ];
 
 
    StringTableEntry  textureName[NUM_TEX];
    StringTableEntry  textureName[NUM_TEX];
    GFXTexHandle      textureHandle[NUM_TEX];
    GFXTexHandle      textureHandle[NUM_TEX];
@@ -152,7 +152,7 @@ private:
    F32         mRadius;
    F32         mRadius;
    F32         mVelocity;
    F32         mVelocity;
    F32         mHeight;
    F32         mHeight;
-   ColorF      mColor;
+   LinearColorF      mColor;
    F32         mTimeSinceLastRing;
    F32         mTimeSinceLastRing;
    bool        mDead;
    bool        mDead;
    F32         mElapsedTime;
    F32         mElapsedTime;

+ 8 - 8
Engine/source/T3D/guiMaterialPreview.cpp

@@ -77,8 +77,8 @@ bool GuiMaterialPreview::onWake()
    if (!mFakeSun)
    if (!mFakeSun)
       mFakeSun = LightManager::createLightInfo();
       mFakeSun = LightManager::createLightInfo();
 
 
-   mFakeSun->setColor( ColorF( 1.0f, 1.0f, 1.0f ) );
-   mFakeSun->setAmbient( ColorF( 0.5f, 0.5f, 0.5f ) );
+   mFakeSun->setColor( LinearColorF( 1.0f, 1.0f, 1.0f ) );
+   mFakeSun->setAmbient( LinearColorF( 0.5f, 0.5f, 0.5f ) );
    mFakeSun->setDirection( VectorF( 0.0f, 0.707f, -0.707f ) );
    mFakeSun->setDirection( VectorF( 0.0f, 0.707f, -0.707f ) );
 	mFakeSun->setPosition( mFakeSun->getDirection() * -10000.0f );
 	mFakeSun->setPosition( mFakeSun->getDirection() * -10000.0f );
    mFakeSun->setRange( 2000000.0f );
    mFakeSun->setRange( 2000000.0f );
@@ -89,7 +89,7 @@ bool GuiMaterialPreview::onWake()
 // This function allows the viewport's ambient color to be changed. This is exposed to script below.
 // This function allows the viewport's ambient color to be changed. This is exposed to script below.
 void GuiMaterialPreview::setAmbientLightColor( F32 r, F32 g, F32 b )
 void GuiMaterialPreview::setAmbientLightColor( F32 r, F32 g, F32 b )
 {
 {
-   ColorF temp(r, g, b);
+   LinearColorF temp(r, g, b);
    temp.clamp();
    temp.clamp();
 	GuiMaterialPreview::mFakeSun->setAmbient( temp );
 	GuiMaterialPreview::mFakeSun->setAmbient( temp );
 }
 }
@@ -97,7 +97,7 @@ void GuiMaterialPreview::setAmbientLightColor( F32 r, F32 g, F32 b )
 // This function allows the light's color to be changed. This is exposed to script below.
 // This function allows the light's color to be changed. This is exposed to script below.
 void GuiMaterialPreview::setLightColor( F32 r, F32 g, F32 b )
 void GuiMaterialPreview::setLightColor( F32 r, F32 g, F32 b )
 {
 {
-   ColorF temp(r, g, b);
+   LinearColorF temp(r, g, b);
    temp.clamp();
    temp.clamp();
 	GuiMaterialPreview::mFakeSun->setColor( temp );
 	GuiMaterialPreview::mFakeSun->setColor( temp );
 }
 }
@@ -437,8 +437,8 @@ void GuiMaterialPreview::resetViewport()
    mOrbitPos = mModel->getShape()->center;
    mOrbitPos = mModel->getShape()->center;
 
 
    // Reset the viewport's lighting.
    // Reset the viewport's lighting.
-   GuiMaterialPreview::mFakeSun->setColor( ColorF( 1.0f, 1.0f, 1.0f ) );
-   GuiMaterialPreview::mFakeSun->setAmbient( ColorF( 0.5f, 0.5f, 0.5f ) );
+   GuiMaterialPreview::mFakeSun->setColor( LinearColorF( 1.0f, 1.0f, 1.0f ) );
+   GuiMaterialPreview::mFakeSun->setAmbient( LinearColorF( 0.5f, 0.5f, 0.5f ) );
    GuiMaterialPreview::mFakeSun->setDirection( VectorF( 0.0f, 0.707f, -0.707f ) );
    GuiMaterialPreview::mFakeSun->setDirection( VectorF( 0.0f, 0.707f, -0.707f ) );
 }
 }
 
 
@@ -482,14 +482,14 @@ DefineEngineMethod(GuiMaterialPreview, reset, void, (),,
 }
 }
 
 
 // This function allows the user to change the light's color.
 // This function allows the user to change the light's color.
-DefineEngineMethod(GuiMaterialPreview, setLightColor, void, ( ColorF color ),,
+DefineEngineMethod(GuiMaterialPreview, setLightColor, void, ( LinearColorF color ),,
    "Sets the color of the light in the scene.\n")
    "Sets the color of the light in the scene.\n")
 {
 {
    object->setLightColor( color.red, color.green, color.blue );
    object->setLightColor( color.red, color.green, color.blue );
 }
 }
 
 
 // This function allows the user to change the viewports's ambient color.
 // This function allows the user to change the viewports's ambient color.
-DefineEngineMethod(GuiMaterialPreview, setAmbientLightColor, void, ( ColorF color ),,
+DefineEngineMethod(GuiMaterialPreview, setAmbientLightColor, void, ( LinearColorF color ),,
    "Sets the color of the ambient light in the scene.\n")
    "Sets the color of the ambient light in the scene.\n")
 {
 {
    object->setAmbientLightColor( color.red, color.green, color.blue );
    object->setAmbientLightColor( color.red, color.green, color.blue );

+ 4 - 4
Engine/source/T3D/guiObjectView.cpp

@@ -590,7 +590,7 @@ void GuiObjectView::setCameraRotation( const EulerF& rotation )
 }
 }
 
 
 //------------------------------------------------------------------------------
 //------------------------------------------------------------------------------
-void GuiObjectView::setLightColor( const ColorF& color )
+void GuiObjectView::setLightColor( const LinearColorF& color )
 {
 {
    mLightColor = color;
    mLightColor = color;
    if( mLight )
    if( mLight )
@@ -599,7 +599,7 @@ void GuiObjectView::setLightColor( const ColorF& color )
 
 
 //------------------------------------------------------------------------------
 //------------------------------------------------------------------------------
 
 
-void GuiObjectView::setLightAmbient( const ColorF& color )
+void GuiObjectView::setLightAmbient( const LinearColorF& color )
 {
 {
    mLightAmbient = color;
    mLightAmbient = color;
    if( mLight )
    if( mLight )
@@ -952,7 +952,7 @@ DefineEngineMethod( GuiObjectView, setCameraSpeed, void, (F32 factor),,
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 
 
-DefineEngineMethod( GuiObjectView, setLightColor, void, ( ColorF color),,
+DefineEngineMethod( GuiObjectView, setLightColor, void, ( LinearColorF color),,
    "@brief Set the light color on the sun object used to render the model.\n\n"
    "@brief Set the light color on the sun object used to render the model.\n\n"
    "@param color Color of sunlight.\n"
    "@param color Color of sunlight.\n"
    "@tsexample\n"
    "@tsexample\n"
@@ -968,7 +968,7 @@ DefineEngineMethod( GuiObjectView, setLightColor, void, ( ColorF color),,
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 
 
-DefineEngineMethod( GuiObjectView, setLightAmbient, void, (ColorF color),,
+DefineEngineMethod( GuiObjectView, setLightAmbient, void, (LinearColorF color),,
    "@brief Set the light ambient color on the sun object used to render the model.\n\n"
    "@brief Set the light ambient color on the sun object used to render the model.\n\n"
    "@param color Ambient color of sunlight.\n"
    "@param color Ambient color of sunlight.\n"
    "@tsexample\n"
    "@tsexample\n"

+ 4 - 4
Engine/source/T3D/guiObjectView.h

@@ -145,10 +145,10 @@ class GuiObjectView : public GuiTSCtrl
       LightInfo* mLight;
       LightInfo* mLight;
       
       
       ///
       ///
-      ColorF mLightColor;
+      LinearColorF mLightColor;
       
       
       ///
       ///
-      ColorF mLightAmbient;
+      LinearColorF mLightAmbient;
       
       
       ///
       ///
       Point3F mLightDirection;
       Point3F mLightDirection;
@@ -255,10 +255,10 @@ class GuiObjectView : public GuiTSCtrl
       /// @{
       /// @{
       
       
       ///
       ///
-      void setLightColor( const ColorF& color );
+      void setLightColor( const LinearColorF& color );
       
       
       ///
       ///
-      void setLightAmbient( const ColorF& color );
+      void setLightAmbient( const LinearColorF& color );
       
       
       ///
       ///
       void setLightDirection( const Point3F& direction );
       void setLightDirection( const Point3F& direction );

+ 1 - 1
Engine/source/T3D/item.h

@@ -51,7 +51,7 @@ struct ItemData: public ShapeBaseData {
 
 
    bool        lightOnlyStatic;
    bool        lightOnlyStatic;
    S32         lightType;
    S32         lightType;
-   ColorF      lightColor;
+   LinearColorF      lightColor;
    S32         lightTime;
    S32         lightTime;
    F32         lightRadius;
    F32         lightRadius;
 
 

+ 1 - 1
Engine/source/T3D/levelInfo.cpp

@@ -371,7 +371,7 @@ void LevelInfo::setLevelAccuTexture(const String& name)
    mAccuTextureName = name;
    mAccuTextureName = name;
    if (isClientObject() && mAccuTextureName.isNotEmpty())
    if (isClientObject() && mAccuTextureName.isNotEmpty())
    {
    {
-      mAccuTexture.set(mAccuTextureName, &GFXDefaultStaticDiffuseProfile, "AccumulationVolume::mAccuTexture");
+      mAccuTexture.set(mAccuTextureName, &GFXStaticTextureSRGBProfile, "AccumulationVolume::mAccuTexture");
       if (mAccuTexture.isNull())
       if (mAccuTexture.isNull())
          Con::warnf("AccumulationVolume::setTexture - Unable to load texture: %s", mAccuTextureName.c_str());
          Con::warnf("AccumulationVolume::setTexture - Unable to load texture: %s", mAccuTextureName.c_str());
       else
       else

+ 1 - 1
Engine/source/T3D/lightAnimData.cpp

@@ -302,7 +302,7 @@ void LightAnimData::animate( LightInfo *lightInfo, LightAnimState *state )
 
 
    lightInfo->setTransform( transform );
    lightInfo->setTransform( transform );
 
 
-   ColorF color = state->color;
+   LinearColorF color = state->color;
    mColor.animate( time, color );
    mColor.animate( time, color );
    lightInfo->setColor( color );
    lightInfo->setColor( color );
 
 

+ 1 - 1
Engine/source/T3D/lightAnimData.h

@@ -74,7 +74,7 @@ struct LightAnimState
    MatrixF transform;
    MatrixF transform;
 
 
    /// The set light color before animation occurs.
    /// The set light color before animation occurs.
-   ColorF color;
+   LinearColorF color;
 };
 };
 
 
 
 

+ 1 - 1
Engine/source/T3D/lightBase.cpp

@@ -57,7 +57,7 @@ ConsoleDocClass( LightBase,
 
 
 LightBase::LightBase()
 LightBase::LightBase()
    :  mIsEnabled( true ),
    :  mIsEnabled( true ),
-      mColor( ColorF::WHITE ),
+      mColor( LinearColorF::WHITE ),
       mBrightness( 1.0f ),
       mBrightness( 1.0f ),
       mCastShadows( false ),
       mCastShadows( false ),
       mStaticRefreshFreq( 250 ),
       mStaticRefreshFreq( 250 ),

+ 1 - 1
Engine/source/T3D/lightBase.h

@@ -51,7 +51,7 @@ protected:
 
 
    bool mIsEnabled;
    bool mIsEnabled;
 
 
-   ColorF mColor;
+   LinearColorF mColor;
 
 
    F32 mBrightness;
    F32 mBrightness;
 
 

+ 1 - 1
Engine/source/T3D/lightDescription.cpp

@@ -32,7 +32,7 @@
 
 
 
 
 LightDescription::LightDescription()
 LightDescription::LightDescription()
- : color( ColorF::WHITE ),
+ : color( LinearColorF::WHITE ),
    brightness( 1.0f ),
    brightness( 1.0f ),
    range( 5.0f ),
    range( 5.0f ),
    castShadows( false ),
    castShadows( false ),

+ 1 - 1
Engine/source/T3D/lightDescription.h

@@ -97,7 +97,7 @@ public:
 
 
    bool _preload( bool server, String &errorStr );
    bool _preload( bool server, String &errorStr );
    
    
-   ColorF color;
+   LinearColorF color;
    F32 brightness;
    F32 brightness;
    F32 range;
    F32 range;
    bool castShadows;
    bool castShadows;

+ 9 - 8
Engine/source/T3D/lightFlareData.cpp

@@ -126,7 +126,7 @@ LightFlareData::LightFlareData()
 {
 {
    dMemset( mElementRect, 0, sizeof( RectF ) * MAX_ELEMENTS );   
    dMemset( mElementRect, 0, sizeof( RectF ) * MAX_ELEMENTS );   
    dMemset( mElementScale, 0, sizeof( F32 ) * MAX_ELEMENTS );
    dMemset( mElementScale, 0, sizeof( F32 ) * MAX_ELEMENTS );
-   dMemset( mElementTint, 0, sizeof( ColorF ) * MAX_ELEMENTS );
+   dMemset( mElementTint, 0, sizeof( LinearColorF ) * MAX_ELEMENTS );
    dMemset( mElementRotate, 0, sizeof( bool ) * MAX_ELEMENTS );
    dMemset( mElementRotate, 0, sizeof( bool ) * MAX_ELEMENTS );
    dMemset( mElementUseLightColor, 0, sizeof( bool ) * MAX_ELEMENTS );   
    dMemset( mElementUseLightColor, 0, sizeof( bool ) * MAX_ELEMENTS );   
 
 
@@ -524,7 +524,7 @@ void LightFlareData::prepRender(SceneRenderState *state, LightFlareState *flareS
    //
    //
    // These are the factors which affect the "alpha" of the flare effect.
    // These are the factors which affect the "alpha" of the flare effect.
    // Modulate more in as appropriate.
    // Modulate more in as appropriate.
-   ColorF baseColor = ColorF::WHITE * lightSourceBrightnessScale * occlusionFade;
+   LinearColorF baseColor = LinearColorF::WHITE * lightSourceBrightnessScale * occlusionFade;
 
 
    // Setup the vertex buffer for the maximum flare elements.
    // Setup the vertex buffer for the maximum flare elements.
    const U32 vertCount = 4 * mElementCount;
    const U32 vertCount = 4 * mElementCount;
@@ -544,7 +544,7 @@ void LightFlareData::prepRender(SceneRenderState *state, LightFlareState *flareS
 
 
       Point3F *basePos = mElementRotate[i] ? rotatedBasePoints : sBasePoints;
       Point3F *basePos = mElementRotate[i] ? rotatedBasePoints : sBasePoints;
 
 
-      ColorF color( baseColor * mElementTint[i] );
+      LinearColorF color( baseColor * mElementTint[i] );
       if ( mElementUseLightColor[i] )
       if ( mElementUseLightColor[i] )
          color *= lightInfo->getColor();
          color *= lightInfo->getColor();
       color.clamp();
       color.clamp();
@@ -571,22 +571,23 @@ void LightFlareData::prepRender(SceneRenderState *state, LightFlareState *flareS
       size.y = getMax( size.y, 1.0f );
       size.y = getMax( size.y, 1.0f );
       size *= oneOverViewportExtent;
       size *= oneOverViewportExtent;
 
 
-      vert->color = color;
+      const ColorI colori = color.toColorI();
+      vert->color = colori;
       vert->point = ( basePos[0] * size ) + pos;      
       vert->point = ( basePos[0] * size ) + pos;      
       vert->texCoord.set( texCoordMin.x, texCoordMax.y );
       vert->texCoord.set( texCoordMin.x, texCoordMax.y );
       vert++;
       vert++;
 
 
-      vert->color = color;
+      vert->color = colori;
       vert->point = ( basePos[1] * size ) + pos;
       vert->point = ( basePos[1] * size ) + pos;
       vert->texCoord.set( texCoordMax.x, texCoordMax.y );
       vert->texCoord.set( texCoordMax.x, texCoordMax.y );
       vert++;
       vert++;
 
 
-      vert->color = color;
+      vert->color = colori;
       vert->point = ( basePos[2] * size ) + pos;
       vert->point = ( basePos[2] * size ) + pos;
       vert->texCoord.set( texCoordMax.x, texCoordMin.y );
       vert->texCoord.set( texCoordMax.x, texCoordMin.y );
       vert++;
       vert++;
 
 
-      vert->color = color;
+      vert->color = colori;
       vert->point = ( basePos[3] * size ) + pos;
       vert->point = ( basePos[3] * size ) + pos;
       vert->texCoord.set( texCoordMin.x, texCoordMin.y );
       vert->texCoord.set( texCoordMin.x, texCoordMin.y );
       vert++;
       vert++;
@@ -633,7 +634,7 @@ bool LightFlareData::_preload( bool server, String &errorStr )
    if ( !server )
    if ( !server )
    {
    {
       if ( mFlareTextureName.isNotEmpty() )      
       if ( mFlareTextureName.isNotEmpty() )      
-         mFlareTexture.set( mFlareTextureName, &GFXDefaultStaticDiffuseProfile, "FlareTexture" );  
+         mFlareTexture.set( mFlareTextureName, &GFXStaticTextureSRGBProfile, "FlareTexture" );
    }
    }
 
 
    return true;
    return true;

+ 1 - 1
Engine/source/T3D/lightFlareData.h

@@ -123,7 +123,7 @@ protected:
    RectF mElementRect[MAX_ELEMENTS];
    RectF mElementRect[MAX_ELEMENTS];
    F32 mElementDist[MAX_ELEMENTS];
    F32 mElementDist[MAX_ELEMENTS];
    F32 mElementScale[MAX_ELEMENTS];
    F32 mElementScale[MAX_ELEMENTS];
-   ColorF mElementTint[MAX_ELEMENTS];
+   LinearColorF mElementTint[MAX_ELEMENTS];
    bool mElementRotate[MAX_ELEMENTS];
    bool mElementRotate[MAX_ELEMENTS];
    bool mElementUseLightColor[MAX_ELEMENTS];   
    bool mElementUseLightColor[MAX_ELEMENTS];   
 
 

+ 1 - 1
Engine/source/T3D/physicalZone.cpp

@@ -233,7 +233,7 @@ void PhysicalZone::renderObject( ObjectRenderInst *ri,
    drawer->drawPolyhedron( desc, mPolyhedron, ColorI( 0, 255, 0, 45 ) );
    drawer->drawPolyhedron( desc, mPolyhedron, ColorI( 0, 255, 0, 45 ) );
 
 
    desc.setFillModeWireframe();
    desc.setFillModeWireframe();
-   drawer->drawPolyhedron( desc, mPolyhedron, ColorF::BLACK );
+   drawer->drawPolyhedron( desc, mPolyhedron, ColorI::BLACK );
 }
 }
 
 
 //--------------------------------------------------------------------------
 //--------------------------------------------------------------------------

+ 1 - 1
Engine/source/T3D/player.cpp

@@ -3893,7 +3893,7 @@ void Player::updateActionThread()
                ParticleEmitter * emitter = new ParticleEmitter;
                ParticleEmitter * emitter = new ParticleEmitter;
                emitter->onNewDataBlock( mDataBlock->footPuffEmitter, false );
                emitter->onNewDataBlock( mDataBlock->footPuffEmitter, false );
 
 
-               ColorF colorList[ ParticleData::PDC_NUM_KEYS];
+               LinearColorF colorList[ ParticleData::PDC_NUM_KEYS];
 
 
                for( U32 x = 0; x < getMin( Material::NUM_EFFECT_COLOR_STAGES, ParticleData::PDC_NUM_KEYS ); ++ x )
                for( U32 x = 0; x < getMin( Material::NUM_EFFECT_COLOR_STAGES, ParticleData::PDC_NUM_KEYS ); ++ x )
                   colorList[ x ].set( material->mEffectColor[ x ].red,
                   colorList[ x ].set( material->mEffectColor[ x ].red,

+ 1 - 1
Engine/source/T3D/pointLight.cpp

@@ -167,7 +167,7 @@ void PointLight::_renderViz( SceneRenderState *state )
    desc.setBlend( true );
    desc.setBlend( true );
 
 
    // Base the sphere color on the light color.
    // Base the sphere color on the light color.
-   ColorI color( mColor );
+   ColorI color = mColor.toColorI();
    color.alpha = 16;
    color.alpha = 16;
 
 
    draw->drawSphere( desc, mRadius, getPosition(), color );
    draw->drawSphere( desc, mRadius, getPosition(), color );

+ 1 - 1
Engine/source/T3D/portal.cpp

@@ -294,7 +294,7 @@ void Portal::_renderObject( ObjectRenderInst *ri, SceneRenderState *state, BaseM
    GFX->getDrawUtil()->drawPolygon( desc, mPortalPolygonWS.address(), mPortalPolygonWS.size(), color );
    GFX->getDrawUtil()->drawPolygon( desc, mPortalPolygonWS.address(), mPortalPolygonWS.size(), color );
 
 
    desc.setFillModeWireframe();
    desc.setFillModeWireframe();
-   GFX->getDrawUtil()->drawPolygon( desc, mPortalPolygonWS.address(), mPortalPolygonWS.size(), ColorF::RED );
+   GFX->getDrawUtil()->drawPolygon( desc, mPortalPolygonWS.address(), mPortalPolygonWS.size(), ColorI::RED );
 
 
    // Render rest.
    // Render rest.
 
 

+ 1 - 1
Engine/source/T3D/proximityMine.cpp

@@ -653,7 +653,7 @@ void ProximityMine::renderObject( ObjectRenderInst* ri,
    // Render the trigger area
    // Render the trigger area
    if ( mState == Armed || mState == Triggered )
    if ( mState == Armed || mState == Triggered )
    {
    {
-      const ColorF drawColor(1, 0, 0, 0.05f);
+      const LinearColorF drawColor(1, 0, 0, 0.05f);
       if ( drawColor.alpha > 0 )
       if ( drawColor.alpha > 0 )
       {
       {
          GFXStateBlockDesc desc;
          GFXStateBlockDesc desc;

+ 1 - 1
Engine/source/T3D/shapeBase.cpp

@@ -2389,7 +2389,7 @@ void ShapeBase::emitDust( ParticleEmitter* emitter, F32 triggerHeight, const Poi
       Material* material = ( rayInfo.material ? dynamic_cast< Material* >( rayInfo.material->getMaterial() ) : 0 );
       Material* material = ( rayInfo.material ? dynamic_cast< Material* >( rayInfo.material->getMaterial() ) : 0 );
       if( material && material->mShowDust )
       if( material && material->mShowDust )
       {
       {
-         ColorF colorList[ ParticleData::PDC_NUM_KEYS ];
+         LinearColorF colorList[ ParticleData::PDC_NUM_KEYS ];
 
 
          for( U32 x = 0; x < getMin( Material::NUM_EFFECT_COLOR_STAGES, ParticleData::PDC_NUM_KEYS ); ++ x )
          for( U32 x = 0; x < getMin( Material::NUM_EFFECT_COLOR_STAGES, ParticleData::PDC_NUM_KEYS ); ++ x )
             colorList[ x ] = material->mEffectColor[ x ];
             colorList[ x ] = material->mEffectColor[ x ];

+ 1 - 1
Engine/source/T3D/shapeBase.h

@@ -390,7 +390,7 @@ struct ShapeBaseImageData: public GameBaseData {
    S32         lightType;           ///< Indicates the type of the light.
    S32         lightType;           ///< Indicates the type of the light.
                                     ///
                                     ///
                                     ///  One of: ConstantLight, PulsingLight, WeaponFireLight.
                                     ///  One of: ConstantLight, PulsingLight, WeaponFireLight.
-   ColorF      lightColor;
+   LinearColorF      lightColor;
    S32         lightDuration;       ///< The duration in SimTime of Pulsing or WeaponFire type lights.
    S32         lightDuration;       ///< The duration in SimTime of Pulsing or WeaponFire type lights.
    F32         lightRadius;         ///< Extent of light.
    F32         lightRadius;         ///< Extent of light.
    F32         lightBrightness;     ///< Brightness of the light ( if it is WeaponFireLight ).
    F32         lightBrightness;     ///< Brightness of the light ( if it is WeaponFireLight ).

+ 1 - 1
Engine/source/T3D/spotLight.cpp

@@ -202,7 +202,7 @@ void SpotLight::_renderViz( SceneRenderState *state )
    desc.setBlend( true );
    desc.setBlend( true );
 
 
    // Base the color on the light color.
    // Base the color on the light color.
-   ColorI color( mColor );
+   ColorI color = mColor.toColorI();
    color.alpha = 16;
    color.alpha = 16;
 
 
    F32 radius = mRange * mSin( mDegToRad( mOuterConeAngle * 0.5f ) );
    F32 radius = mRange * mSin( mDegToRad( mOuterConeAngle * 0.5f ) );

+ 1 - 1
Engine/source/T3D/vehicles/guiSpeedometer.cpp

@@ -41,7 +41,7 @@ class GuiSpeedometerHud : public GuiBitmapCtrl
    F32   mMaxAngle;     ///< Max pos of needle
    F32   mMaxAngle;     ///< Max pos of needle
    F32   mMinAngle;     ///< Min pos of needle
    F32   mMinAngle;     ///< Min pos of needle
    Point2F mCenter;     ///< Center of needle rotation
    Point2F mCenter;     ///< Center of needle rotation
-   ColorF mColor;       ///< Needle Color
+   LinearColorF mColor;       ///< Needle Color
    F32   mNeedleLength;
    F32   mNeedleLength;
    F32   mNeedleWidth;
    F32   mNeedleWidth;
    F32   mTailLength;
    F32   mTailLength;

+ 1 - 1
Engine/source/T3D/vehicles/wheeledVehicle.cpp

@@ -1235,7 +1235,7 @@ void WheeledVehicle::updateWheelParticles(F32 dt)
 
 
             if( material)//&& material->mShowDust )
             if( material)//&& material->mShowDust )
             {
             {
-               ColorF colorList[ ParticleData::PDC_NUM_KEYS ];
+               LinearColorF colorList[ ParticleData::PDC_NUM_KEYS ];
 
 
                for( U32 x = 0; x < getMin( Material::NUM_EFFECT_COLOR_STAGES, ParticleData::PDC_NUM_KEYS ); ++ x )
                for( U32 x = 0; x < getMin( Material::NUM_EFFECT_COLOR_STAGES, ParticleData::PDC_NUM_KEYS ); ++ x )
                   colorList[ x ] = material->mEffectColor[ x ];
                   colorList[ x ] = material->mEffectColor[ x ];

+ 5 - 7
Engine/source/console/consoleFunctions.cpp

@@ -1021,7 +1021,7 @@ DefineConsoleFunction( strrchrpos, S32, ( const char* str, const char* chr, S32
 
 
 //----------------------------------------------------------------
 //----------------------------------------------------------------
 
 
-DefineConsoleFunction(ColorFloatToInt, ColorI, (ColorF color), ,
+DefineConsoleFunction(ColorFloatToInt, ColorI, (LinearColorF color), ,
    "Convert from a float color to an integer color (0.0 - 1.0 to 0 to 255).\n"
    "Convert from a float color to an integer color (0.0 - 1.0 to 0 to 255).\n"
    "@param color Float color value to be converted in the form \"R G B A\", where R is red, G is green, B is blue, and A is alpha.\n"
    "@param color Float color value to be converted in the form \"R G B A\", where R is red, G is green, B is blue, and A is alpha.\n"
    "@return Converted color value (0 - 255)\n\n"
    "@return Converted color value (0 - 255)\n\n"
@@ -1030,10 +1030,10 @@ DefineConsoleFunction(ColorFloatToInt, ColorI, (ColorF color), ,
    "@endtsexample\n"
    "@endtsexample\n"
    "@ingroup Strings")
    "@ingroup Strings")
 {
 {
-   return (ColorI)color;
+   return color.toColorI();
 }
 }
 
 
-DefineConsoleFunction(ColorIntToFloat, ColorF, (ColorI color), ,
+DefineConsoleFunction(ColorIntToFloat, LinearColorF, (ColorI color), ,
    "Convert from a integer color to an float color (0 to 255 to 0.0 - 1.0).\n"
    "Convert from a integer color to an float color (0 to 255 to 0.0 - 1.0).\n"
    "@param color Integer color value to be converted in the form \"R G B A\", where R is red, G is green, B is blue, and A is alpha.\n"
    "@param color Integer color value to be converted in the form \"R G B A\", where R is red, G is green, B is blue, and A is alpha.\n"
    "@return Converted color value (0.0 - 1.0)\n\n"
    "@return Converted color value (0.0 - 1.0)\n\n"
@@ -1042,7 +1042,7 @@ DefineConsoleFunction(ColorIntToFloat, ColorF, (ColorI color), ,
    "@endtsexample\n"
    "@endtsexample\n"
    "@ingroup Strings")
    "@ingroup Strings")
 {
 {
-   return (ColorF)color;
+   return LinearColorF(color);
 }
 }
 
 
 DefineConsoleFunction(ColorRGBToHEX, const char*, (ColorI color), ,
 DefineConsoleFunction(ColorRGBToHEX, const char*, (ColorI color), ,
@@ -1080,10 +1080,8 @@ DefineConsoleFunction(ColorHEXToRGB, ColorI, (const char* hex), ,
    "@endtsexample\n"
    "@endtsexample\n"
    "@ingroup Strings")
    "@ingroup Strings")
 {
 {
-   S32 rgb = dAtoui(hex, 16);
-
    ColorI color;
    ColorI color;
-   color.set(rgb & 0x000000FF, (rgb & 0x0000FF00) >> 8, (rgb & 0x00FF0000) >> 16);
+   color.set(String(hex));
    return color;
    return color;
 }
 }
 
 

+ 4 - 4
Engine/source/console/consoleTypes.cpp

@@ -567,13 +567,13 @@ ConsoleSetType( TypeFlag )
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 // TypeColorF
 // TypeColorF
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
-ConsoleType(ColorF, TypeColorF, ColorF, "")
-ImplementConsoleTypeCasters( TypeColorF, ColorF )
+ConsoleType(LinearColorF, TypeColorF, LinearColorF, "")
+ImplementConsoleTypeCasters( TypeColorF, LinearColorF )
 
 
 ConsoleGetType( TypeColorF )
 ConsoleGetType( TypeColorF )
 {
 {
    // Fetch color.
    // Fetch color.
-   const ColorF* color = (ColorF*)dptr;
+   const LinearColorF* color = (LinearColorF*)dptr;
 
 
    // Fetch stock color name.
    // Fetch stock color name.
    StringTableEntry colorName = StockColor::name( *color );
    StringTableEntry colorName = StockColor::name( *color );
@@ -591,7 +591,7 @@ ConsoleGetType( TypeColorF )
 
 
 ConsoleSetType( TypeColorF )
 ConsoleSetType( TypeColorF )
 {
 {
-   ColorF *tmpColor = (ColorF *) dptr;
+   LinearColorF *tmpColor = (LinearColorF *) dptr;
    if(argc == 1)
    if(argc == 1)
    {
    {
       // Is only a single argument passed?
       // Is only a single argument passed?

+ 1 - 1
Engine/source/console/consoleTypes.h

@@ -122,7 +122,7 @@ DefineConsoleType( TypeParticleParameterString, const char * )
 
 
 DefineConsoleType( TypeFlag, S32 )
 DefineConsoleType( TypeFlag, S32 )
 DefineConsoleType( TypeColorI, ColorI )
 DefineConsoleType( TypeColorI, ColorI )
-DefineConsoleType( TypeColorF, ColorF )
+DefineConsoleType( TypeColorF, LinearColorF )
 DefineConsoleType( TypeSimObjectName, SimObject* )
 DefineConsoleType( TypeSimObjectName, SimObject* )
 DefineConsoleType( TypeShader, GFXShader * )
 DefineConsoleType( TypeShader, GFXShader * )
 
 

+ 2 - 2
Engine/source/console/engineStructs.cpp

@@ -63,8 +63,8 @@ IMPLEMENT_STRUCT( ColorI,
 END_IMPLEMENT_STRUCT;
 END_IMPLEMENT_STRUCT;
 
 
 
 
-IMPLEMENT_STRUCT( ColorF,
-   ColorF,,
+IMPLEMENT_STRUCT( LinearColorF,
+   LinearColorF,,
    "RGBA color quadruple in 32bit floating-point precision per channel." )
    "RGBA color quadruple in 32bit floating-point precision per channel." )
 
 
    FIELD( red, red, 1, "Red channel value." )
    FIELD( red, red, 1, "Red channel value." )

+ 2 - 2
Engine/source/console/engineStructs.h

@@ -38,7 +38,7 @@ namespace Torque {
 }
 }
 
 
 class ColorI;
 class ColorI;
-class ColorF;
+class LinearColorF;
 
 
 
 
 DECLARE_STRUCT_R(Vector< bool >);
 DECLARE_STRUCT_R(Vector< bool >);
@@ -46,6 +46,6 @@ DECLARE_STRUCT_R(Vector< S32 >);
 DECLARE_STRUCT_R(Vector< F32 >);
 DECLARE_STRUCT_R(Vector< F32 >);
 DECLARE_STRUCT_R(Torque::UUID);
 DECLARE_STRUCT_R(Torque::UUID);
 DECLARE_STRUCT_R(ColorI);
 DECLARE_STRUCT_R(ColorI);
-DECLARE_STRUCT_R(ColorF);
+DECLARE_STRUCT_R(LinearColorF);
 
 
 #endif // !_ENGINESTRUCTS_H_
 #endif // !_ENGINESTRUCTS_H_

+ 2 - 2
Engine/source/console/propertyParsing.cpp

@@ -377,7 +377,7 @@ namespace PropertyInfo
    //-----------------------------------------------------------------------------
    //-----------------------------------------------------------------------------
    // Colors
    // Colors
    //-----------------------------------------------------------------------------
    //-----------------------------------------------------------------------------
-   bool default_scan(const String &data, ColorF & result)
+   bool default_scan(const String &data, LinearColorF & result)
    {
    {
       if(StringUnit::getUnitCount(data," ") == 3)
       if(StringUnit::getUnitCount(data," ") == 3)
       {
       {
@@ -389,7 +389,7 @@ namespace PropertyInfo
       return true;
       return true;
    }
    }
 
 
-   bool default_print(String & result, ColorF const & data)
+   bool default_print(String & result, LinearColorF const & data)
    {
    {
       if(data.alpha == 1.0f)
       if(data.alpha == 1.0f)
          result = String::ToString("%g %g %g",data.red,data.green,data.blue);
          result = String::ToString("%g %g %g",data.red,data.green,data.blue);

+ 3 - 3
Engine/source/console/propertyParsing.h

@@ -24,7 +24,7 @@
 #define _PROPERTYPARSING_H_
 #define _PROPERTYPARSING_H_
 
 
 class ColorI;
 class ColorI;
-class ColorF;
+class LinearColorF;
 class Point2I;
 class Point2I;
 class Point2F;
 class Point2F;
 class Point3F;
 class Point3F;
@@ -110,8 +110,8 @@ namespace PropertyInfo
    bool default_print( String & result, const MatrixF & data );
    bool default_print( String & result, const MatrixF & data );
 
 
    // Colors
    // Colors
-   bool default_scan(const String &data, ColorF & result);
-   bool default_print(String & result, const ColorF & data);
+   bool default_scan(const String &data, LinearColorF & result);
+   bool default_print(String & result, const LinearColorF & data);
    bool default_scan(const String &data, ColorI & result);
    bool default_scan(const String &data, ColorI & result);
    bool default_print(String & result, const ColorI & data);
    bool default_print(String & result, const ColorI & data);
 
 

+ 87 - 16
Engine/source/core/color.cpp

@@ -23,13 +23,13 @@
 #include "platform/platform.h"
 #include "platform/platform.h"
 #include "core/color.h"
 #include "core/color.h"
 
 
-const ColorF ColorF::ZERO( 0, 0, 0, 0 );
-const ColorF ColorF::ONE( 1, 1, 1, 1 );
-const ColorF ColorF::WHITE( 1, 1, 1 );
-const ColorF ColorF::BLACK( 0, 0, 0 );
-const ColorF ColorF::RED( 1, 0, 0 );
-const ColorF ColorF::GREEN( 0, 1, 0 );
-const ColorF ColorF::BLUE( 0, 0, 1 );
+const LinearColorF LinearColorF::ZERO( 0, 0, 0, 0 );
+const LinearColorF LinearColorF::ONE( 1, 1, 1, 1 );
+const LinearColorF LinearColorF::WHITE( 1, 1, 1 );
+const LinearColorF LinearColorF::BLACK( 0, 0, 0 );
+const LinearColorF LinearColorF::RED( 1, 0, 0 );
+const LinearColorF LinearColorF::GREEN( 0, 1, 0 );
+const LinearColorF LinearColorF::BLUE( 0, 0, 1 );
 
 
 const ColorI ColorI::ZERO( 0, 0, 0, 0 );
 const ColorI ColorI::ZERO( 0, 0, 0, 0 );
 const ColorI ColorI::ONE( 255, 255, 255, 255 );
 const ColorI ColorI::ONE( 255, 255, 255, 255 );
@@ -54,9 +54,9 @@ const ColorI ColorI::BLUE( 0, 0, 255 );
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 
 
-typedef HashTable<StringTableEntry, ColorF> typeNameToColorFHash;
+typedef HashTable<StringTableEntry, LinearColorF> typeNameToColorFHash;
 typedef HashTable<StringTableEntry, ColorI> typeNameToColorIHash;
 typedef HashTable<StringTableEntry, ColorI> typeNameToColorIHash;
-typedef HashTable<ColorF, StringTableEntry> typeColorFToNameHash;
+typedef HashTable<LinearColorF, StringTableEntry> typeColorFToNameHash;
 typedef HashTable<ColorI, StringTableEntry> typeColorIToNameHash;
 typedef HashTable<ColorI, StringTableEntry> typeColorIToNameHash;
 
 
 static typeNameToColorFHash    mNameToColorF;
 static typeNameToColorFHash    mNameToColorF;
@@ -299,7 +299,7 @@ bool StockColor::isColor( const char* pStockColorName )
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 
 
-const ColorF& StockColor::colorF( const char* pStockColorName )
+const LinearColorF& StockColor::colorF( const char* pStockColorName )
 {
 {
    // Sanity!
    // Sanity!
    AssertFatal( pStockColorName != NULL, "Cannot fetch a NULL stock color name." );
    AssertFatal( pStockColorName != NULL, "Cannot fetch a NULL stock color name." );
@@ -347,7 +347,7 @@ const ColorI& StockColor::colorI( const char* pStockColorName )
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 
 
-StringTableEntry StockColor::name( const ColorF& color )
+StringTableEntry StockColor::name( const LinearColorF& color )
 {
 {
    // Find stock color name.
    // Find stock color name.
    typeColorFToNameHash::Iterator colorNameItr = mColorFToName.find( color );
    typeColorFToNameHash::Iterator colorNameItr = mColorFToName.find( color );
@@ -403,7 +403,7 @@ const StockColorItem* StockColor::getColorItem( const S32 index )
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 
 
-ColorF::ColorF( const char* pStockColorName )
+LinearColorF::LinearColorF( const char* pStockColorName )
 {
 {
    // Set stock color.
    // Set stock color.
    *this = StockColor::colorF( pStockColorName );
    *this = StockColor::colorF( pStockColorName );
@@ -411,7 +411,7 @@ ColorF::ColorF( const char* pStockColorName )
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 
 
-void ColorF::set( const char* pStockColorName )
+void LinearColorF::set( const char* pStockColorName )
 {
 {
    // Set stock color.
    // Set stock color.
    *this = StockColor::colorF( pStockColorName );
    *this = StockColor::colorF( pStockColorName );
@@ -419,14 +419,14 @@ void ColorF::set( const char* pStockColorName )
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 
 
-const ColorF& ColorF::StockColor( const char* pStockColorName )
+const LinearColorF& LinearColorF::StockColor( const char* pStockColorName )
 {
 {
    return StockColor::colorF( pStockColorName );
    return StockColor::colorF( pStockColorName );
 }
 }
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 
 
-StringTableEntry ColorF::StockColor( void )
+StringTableEntry LinearColorF::StockColor( void )
 {
 {
    // Return stock color name.
    // Return stock color name.
    return StockColor::name( *this );
    return StockColor::name( *this );
@@ -465,6 +465,77 @@ StringTableEntry ColorI::StockColor( void )
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 
 
+#ifdef TORQUE_USE_LEGACY_GAMMA
+//legacy pow 2.2 - powf(color, 2.2f);
+float LinearColorF::sSrgbToLinear[256] =
+{
+   0.000000f,  0.000005f,  0.000023f,  0.000057f,  0.000107f,  0.000175f,  0.000262f,  0.000367f,  0.000493f,
+   0.000638f,  0.000805f,  0.000992f,  0.001202f,  0.001433f,  0.001687f,  0.001963f,  0.002263f,  0.002586f,
+   0.002932f,  0.003303f,  0.003697f,  0.004116f,  0.004560f,  0.005028f,  0.005522f,  0.006041f,  0.006585f,
+   0.007155f,  0.007751f,  0.008373f,  0.009021f,  0.009696f,  0.010398f,  0.011126f,  0.011881f,  0.012664f,
+   0.013473f,  0.014311f,  0.015175f,  0.016068f,  0.016988f,  0.017936f,  0.018913f,  0.019918f,  0.020951f,
+   0.022013f,  0.023104f,  0.024223f,  0.025371f,  0.026549f,  0.027755f,  0.028991f,  0.030257f,  0.031551f,
+   0.032876f,  0.034230f,  0.035614f,  0.037029f,  0.038473f,  0.039947f,  0.041452f,  0.042987f,  0.044553f,
+   0.046149f,  0.047776f,  0.049433f,  0.051122f,  0.052842f,  0.054592f,  0.056374f,  0.058187f,  0.060032f,
+   0.061907f,  0.063815f,  0.065754f,  0.067725f,  0.069727f,  0.071761f,  0.073828f,  0.075926f,  0.078057f,
+   0.080219f,  0.082414f,  0.084642f,  0.086901f,  0.089194f,  0.091518f,  0.093876f,  0.096266f,  0.098689f,
+   0.101145f,  0.103634f,  0.106156f,  0.108711f,  0.111299f,  0.113921f,  0.116576f,  0.119264f,  0.121986f,
+   0.124741f,  0.127530f,  0.130352f,  0.133209f,  0.136099f,  0.139022f,  0.141980f,  0.144972f,  0.147998f,
+   0.151058f,  0.154152f,  0.157281f,  0.160444f,  0.163641f,  0.166872f,  0.170138f,  0.173439f,  0.176774f,
+   0.180144f,  0.183549f,  0.186989f,  0.190463f,  0.193972f,  0.197516f,  0.201096f,  0.204710f,  0.208360f,
+   0.212044f,  0.215764f,  0.219520f,  0.223310f,  0.227137f,  0.230998f,  0.234895f,  0.238828f,  0.242796f,
+   0.246800f,  0.250840f,  0.254916f,  0.259027f,  0.263175f,  0.267358f,  0.271577f,  0.275833f,  0.280124f,
+   0.284452f,  0.288816f,  0.293216f,  0.297653f,  0.302126f,  0.306635f,  0.311181f,  0.315763f,  0.320382f,
+   0.325037f,  0.329729f,  0.334458f,  0.339223f,  0.344026f,  0.348865f,  0.353741f,  0.358654f,  0.363604f,
+   0.368591f,  0.373615f,  0.378676f,  0.383775f,  0.388910f,  0.394083f,  0.399293f,  0.404541f,  0.409826f,
+   0.415148f,  0.420508f,  0.425905f,  0.431340f,  0.436813f,  0.442323f,  0.447871f,  0.453456f,  0.459080f,
+   0.464741f,  0.470440f,  0.476177f,  0.481952f,  0.487765f,  0.493616f,  0.499505f,  0.505432f,  0.511398f,
+   0.517401f,  0.523443f,  0.529523f,  0.535642f,  0.541798f,  0.547994f,  0.554227f,  0.560499f,  0.566810f,
+   0.573159f,  0.579547f,  0.585973f,  0.592438f,  0.598942f,  0.605484f,  0.612066f,  0.618686f,  0.625345f,
+   0.632043f,  0.638779f,  0.645555f,  0.652370f,  0.659224f,  0.666117f,  0.673049f,  0.680020f,  0.687031f,
+   0.694081f,  0.701169f,  0.708298f,  0.715465f,  0.722672f,  0.729919f,  0.737205f,  0.744530f,  0.751895f,
+   0.759300f,  0.766744f,  0.774227f,  0.781751f,  0.789314f,  0.796917f,  0.804559f,  0.812241f,  0.819964f,
+   0.827726f,  0.835528f,  0.843370f,  0.851252f,  0.859174f,  0.867136f,  0.875138f,  0.883180f,  0.891262f,
+   0.899384f,  0.907547f,  0.915750f,  0.923993f,  0.932277f,  0.940601f,  0.948965f,  0.957370f,  0.965815f,
+   0.974300f,  0.982826f,  0.991393f,  1.000000f
+};
+#else
+//sRGB - color < 0.04045f ? (1.0f / 12.92f) * color : powf((color + 0.055f) * (1.0f / 1.055f), 2.4f);
+float LinearColorF::sSrgbToLinear[256] =
+{
+   0.000000f,  0.000304f,  0.000607f,  0.000911f,  0.001214f,  0.001518f,  0.001821f,  0.002125f,  0.002428f,
+   0.002732f,  0.003035f,  0.003347f,  0.003677f,  0.004025f,  0.004391f,  0.004777f,  0.005182f,  0.005605f,
+   0.006049f,  0.006512f,  0.006995f,  0.007499f,  0.008023f,  0.008568f,  0.009134f,  0.009721f,  0.010330f,
+   0.010960f,  0.011612f,  0.012286f,  0.012983f,  0.013702f,  0.014444f,  0.015209f,  0.015996f,  0.016807f,
+   0.017642f,  0.018500f,  0.019382f,  0.020289f,  0.021219f,  0.022174f,  0.023153f,  0.024158f,  0.025187f,
+   0.026241f,  0.027321f,  0.028426f,  0.029557f,  0.030713f,  0.031896f,  0.033105f,  0.034340f,  0.035601f,
+   0.036889f,  0.038204f,  0.039546f,  0.040915f,  0.042311f,  0.043735f,  0.045186f,  0.046665f,  0.048172f,
+   0.049707f,  0.051269f,  0.052861f,  0.054480f,  0.056128f,  0.057805f,  0.059511f,  0.061246f,  0.063010f,
+   0.064803f,  0.066626f,  0.068478f,  0.070360f,  0.072272f,  0.074214f,  0.076185f,  0.078187f,  0.080220f,
+   0.082283f,  0.084376f,  0.086500f,  0.088656f,  0.090842f,  0.093059f,  0.095307f,  0.097587f,  0.099899f,
+   0.102242f,  0.104616f,  0.107023f,  0.109462f,  0.111932f,  0.114435f,  0.116971f,  0.119538f,  0.122139f,
+   0.124772f,  0.127438f,  0.130136f,  0.132868f,  0.135633f,  0.138432f,  0.141263f,  0.144128f,  0.147027f,
+   0.149960f,  0.152926f,  0.155926f,  0.158961f,  0.162029f,  0.165132f,  0.168269f,  0.171441f,  0.174647f,
+   0.177888f,  0.181164f,  0.184475f,  0.187821f,  0.191202f,  0.194618f,  0.198069f,  0.201556f,  0.205079f,
+   0.208637f,  0.212231f,  0.215861f,  0.219526f,  0.223228f,  0.226966f,  0.230740f,  0.234551f,  0.238398f,
+   0.242281f,  0.246201f,  0.250158f,  0.254152f,  0.258183f,  0.262251f,  0.266356f,  0.270498f,  0.274677f,
+   0.278894f,  0.283149f,  0.287441f,  0.291771f,  0.296138f,  0.300544f,  0.304987f,  0.309469f,  0.313989f,
+   0.318547f,  0.323143f,  0.327778f,  0.332452f,  0.337164f,  0.341914f,  0.346704f,  0.351533f,  0.356400f,
+   0.361307f,  0.366253f,  0.371238f,  0.376262f,  0.381326f,  0.386430f,  0.391573f,  0.396755f,  0.401978f,
+   0.407240f,  0.412543f,  0.417885f,  0.423268f,  0.428691f,  0.434154f,  0.439657f,  0.445201f,  0.450786f,
+   0.456411f,  0.462077f,  0.467784f,  0.473532f,  0.479320f,  0.485150f,  0.491021f,  0.496933f,  0.502886f,
+   0.508881f,  0.514918f,  0.520996f,  0.527115f,  0.533276f,  0.539480f,  0.545725f,  0.552011f,  0.558340f,
+   0.564712f,  0.571125f,  0.577581f,  0.584078f,  0.590619f,  0.597202f,  0.603827f,  0.610496f,  0.617207f,
+   0.623960f,  0.630757f,  0.637597f,  0.644480f,  0.651406f,  0.658375f,  0.665387f,  0.672443f,  0.679543f,
+   0.686685f,  0.693872f,  0.701102f,  0.708376f,  0.715694f,  0.723055f,  0.730461f,  0.737911f,  0.745404f,
+   0.752942f,  0.760525f,  0.768151f,  0.775822f,  0.783538f,  0.791298f,  0.799103f,  0.806952f,  0.814847f,
+   0.822786f,  0.830770f,  0.838799f,  0.846873f,  0.854993f,  0.863157f,  0.871367f,  0.879622f,  0.887923f,
+   0.896269f,  0.904661f,  0.913099f,  0.921582f,  0.930111f,  0.938686f,  0.947307f,  0.955974f,  0.964686f,
+   0.973445f,  0.982251f,  0.991102f,  1.000000f
+};
+#endif
+//-----------------------------------------------------------------------------
+
 ConsoleFunction( getStockColorCount, S32, 1, 1, "() - Gets a count of available stock colors.\n"
 ConsoleFunction( getStockColorCount, S32, 1, 1, "() - Gets a count of available stock colors.\n"
    "@return A count of available stock colors." )
    "@return A count of available stock colors." )
 {
 {
@@ -513,7 +584,7 @@ ConsoleFunction( getStockColorF, const char*, 2, 2, "(stockColorName) - Gets a f
       return StringTable->EmptyString();
       return StringTable->EmptyString();
 
 
    // Fetch stock color.
    // Fetch stock color.
-   const ColorF& color = StockColor::colorF( pStockColorName );
+   const LinearColorF& color = StockColor::colorF( pStockColorName );
 
 
    // Format stock color.
    // Format stock color.
    char* returnBuffer = Con::getReturnBuffer(256);
    char* returnBuffer = Con::getReturnBuffer(256);

+ 188 - 298
Engine/source/core/color.h

@@ -36,54 +36,48 @@
 
 
 const F32 gGamma = 2.2f;
 const F32 gGamma = 2.2f;
 const F32 gOneOverGamma = 1.f / 2.2f;
 const F32 gOneOverGamma = 1.f / 2.2f;
+const F32 gOneOver255 = 1.f / 255.f;
 
 
 class ColorI;
 class ColorI;
 
 
-
-class ColorF
+//32bit color in linear space
+class LinearColorF
 {
 {
-  public:
+public:
    F32 red;
    F32 red;
    F32 green;
    F32 green;
    F32 blue;
    F32 blue;
    F32 alpha;
    F32 alpha;
 
 
-  public:
-   ColorF() { }
-   ColorF(const ColorF& in_rCopy);
-   ColorF(const F32 in_r,
-          const F32 in_g,
-          const F32 in_b,
-          const F32 in_a = 1.0f);
-
-   ColorF( const char* pStockColorName );
-
-   void set(const F32 in_r,
-            const F32 in_g,
-            const F32 in_b,
-            const F32 in_a = 1.0f);
+public:
+   LinearColorF() : red(0), green(0), blue(0), alpha(0) {}
+   LinearColorF(const LinearColorF& in_rCopy);
+   LinearColorF(const F32 in_r, const F32 in_g, const F32 in_b, const F32 in_a = 1.0f);
+   LinearColorF(const ColorI &color);
+   LinearColorF(const char* pStockColorName);
 
 
+   void set( const F32 in_r, const F32 in_g, const F32 in_b, const F32 in_a = 1.0f );
    void set( const char* pStockColorName );
    void set( const char* pStockColorName );
 
 
-   static const ColorF& StockColor( const char* pStockColorName );
+   static const LinearColorF& StockColor( const char* pStockColorName );
    StringTableEntry StockColor( void );
    StringTableEntry StockColor( void );
 
 
-   ColorF& operator*=(const ColorF& in_mul);       // Can be useful for lighting
-   ColorF  operator*(const ColorF& in_mul) const;
-   ColorF& operator+=(const ColorF& in_rAdd);
-   ColorF  operator+(const ColorF& in_rAdd) const;
-   ColorF& operator-=(const ColorF& in_rSub);
-   ColorF  operator-(const ColorF& in_rSub) const;
+   LinearColorF& operator*=(const LinearColorF& in_mul);       // Can be useful for lighting
+   LinearColorF  operator*(const LinearColorF& in_mul) const;
+   LinearColorF& operator+=(const LinearColorF& in_rAdd);
+   LinearColorF  operator+(const LinearColorF& in_rAdd) const;
+   LinearColorF& operator-=(const LinearColorF& in_rSub);
+   LinearColorF  operator-(const LinearColorF& in_rSub) const;
 
 
-   ColorF& operator*=(const F32 in_mul);
-   ColorF  operator*(const F32 in_mul) const;
-   ColorF& operator/=(const F32 in_div);
-   ColorF  operator/(const F32 in_div) const;
+   LinearColorF& operator*=(const F32 in_mul);
+   LinearColorF  operator*(const F32 in_mul) const;
+   LinearColorF& operator/=(const F32 in_div);
+   LinearColorF  operator/(const F32 in_div) const;
 
 
-   ColorF  operator-() const;
+   LinearColorF  operator-() const;
 
 
-   bool operator==(const ColorF&) const;
-   bool operator!=(const ColorF&) const;
+   bool operator==(const LinearColorF&) const;
+   bool operator!=(const LinearColorF&) const;
 
 
    operator F32*() { return &red; }
    operator F32*() { return &red; }
    operator const F32*() const { return &red; }
    operator const F32*() const { return &red; }
@@ -95,39 +89,38 @@ class ColorF
    U32 getRGBAPack() const;
    U32 getRGBAPack() const;
    U32 getABGRPack() const;
    U32 getABGRPack() const;
 
 
-   operator ColorI() const;
-
-   void interpolate(const ColorF& in_rC1,
-                    const ColorF& in_rC2,
+   void interpolate(const LinearColorF& in_rC1,
+                    const LinearColorF& in_rC2,
                     const F32 in_factor);
                     const F32 in_factor);
 
 
-   bool isValidColor() const { return (red   >= 0.0f && red   <= 1.0f) &&
-                                      (green >= 0.0f && green <= 1.0f) &&
-                                      (blue  >= 0.0f && blue  <= 1.0f) &&
-                                      (alpha >= 0.0f && alpha <= 1.0f); }
+   bool isClamped() const { return (red >= 0.0f && red <= 1.0f) &&
+                                   (green >= 0.0f && green <= 1.0f) &&
+                                   (blue  >= 0.0f && blue  <= 1.0f) &&
+                                   (alpha >= 0.0f && alpha <= 1.0f); }
    void clamp();
    void clamp();
-
-   ColorF toLinear();
-   ColorF toGamma();
-   //calculate luminance, make sure color is linear first
+   
+   //calculate luminance
    F32 luminance();
    F32 luminance();
 
 
-   static const ColorF ZERO;
-   static const ColorF ONE;
-   static const ColorF WHITE;
-   static const ColorF BLACK;
-   static const ColorF RED;
-   static const ColorF GREEN;
-   static const ColorF BLUE;
+   //convert to ColorI - slow operation, avoid when possible
+   ColorI toColorI(const bool keepAsLinear = false);
+   
+   static const LinearColorF ZERO;
+   static const LinearColorF ONE;
+   static const LinearColorF WHITE;
+   static const LinearColorF BLACK;
+   static const LinearColorF RED;
+   static const LinearColorF GREEN;
+   static const LinearColorF BLUE;
+
+   static F32 sSrgbToLinear[256];
 };
 };
 
 
 
 
-//-------------------------------------- ColorI's are missing some of the operations
-//                                        present in ColorF since they cannot recover
-//                                        properly from over/underflow.
+//8bit color in srgb space
 class ColorI
 class ColorI
 {
 {
-  public:
+public:
    U8 red;
    U8 red;
    U8 green;
    U8 green;
    U8 blue;
    U8 blue;
@@ -143,17 +136,13 @@ class ColorI
       U32 brightness;   //Brightness/Value/Lightness
       U32 brightness;   //Brightness/Value/Lightness
    };
    };
 
 
-  public:
-   ColorI() { }
+public:
+   ColorI() : red(0), green(0), blue(0), alpha(0) {}
    ColorI(const ColorI& in_rCopy);
    ColorI(const ColorI& in_rCopy);
    ColorI(const Hsb& color);
    ColorI(const Hsb& color);
-   ColorI(const U8 in_r,
-          const U8 in_g,
-          const U8 in_b,
-          const U8 in_a = U8(255));
+   ColorI(const U8 in_r, const U8 in_g, const U8 in_b, const U8 in_a = U8(255));
    ColorI(const ColorI& in_rCopy, const U8 in_a);
    ColorI(const ColorI& in_rCopy, const U8 in_a);
-
-   ColorI( const char* pStockColorName );
+   ColorI(const char* pStockColorName);
 
 
    void set(const Hsb& color);
    void set(const Hsb& color);
 
 
@@ -173,25 +162,10 @@ class ColorI
 
 
    static const ColorI& StockColor( const char* pStockColorName );
    static const ColorI& StockColor( const char* pStockColorName );
    StringTableEntry StockColor( void );
    StringTableEntry StockColor( void );
-
-   ColorI& operator*=(const F32 in_mul);
-   ColorI  operator*(const F32 in_mul) const;
-
-   ColorI  operator+(const ColorI& in_rAdd) const;
-   ColorI&  operator+=(const ColorI& in_rAdd);
-
-   ColorI& operator*=(const S32 in_mul);
-   ColorI& operator/=(const S32 in_mul);
-   ColorI  operator*(const S32 in_mul) const;
-   ColorI  operator/(const S32 in_mul) const;
-
+   
    bool operator==(const ColorI&) const;
    bool operator==(const ColorI&) const;
    bool operator!=(const ColorI&) const;
    bool operator!=(const ColorI&) const;
-
-   void interpolate(const ColorI& in_rC1,
-                    const ColorI& in_rC2,
-                    const F32  in_factor);
-
+   
    U32 getARGBPack() const;
    U32 getARGBPack() const;
    U32 getRGBAPack() const;
    U32 getRGBAPack() const;
    U32 getABGRPack() const;
    U32 getABGRPack() const;
@@ -210,13 +184,11 @@ class ColorI
    String getHex() const;
    String getHex() const;
    S32 convertFromHex(const String& hex) const;
    S32 convertFromHex(const String& hex) const;
 
 
-   operator ColorF() const;
-
    operator const U8*() const { return &red; }
    operator const U8*() const { return &red; }
 
 
-   ColorI toLinear();
-   ColorI toGamma();
-
+   //convert linear color to srgb - slow operation, avoid when possible
+   ColorI fromLinear();
+   
    static const ColorI ZERO;
    static const ColorI ZERO;
    static const ColorI ONE;
    static const ColorI ONE;
    static const ColorI WHITE;
    static const ColorI WHITE;
@@ -247,11 +219,11 @@ public:
    }
    }
 
 
    inline const char*      getColorName( void ) const { return mColorName; }
    inline const char*      getColorName( void ) const { return mColorName; }
-   inline const ColorF&    getColorF( void ) const { return mColorF; }
+   inline const LinearColorF&    getColorF( void ) const { return mColorF; }
    inline const ColorI&    getColorI( void ) const { return mColorI; }
    inline const ColorI&    getColorI( void ) const { return mColorI; }
 
 
    const char*         mColorName;
    const char*         mColorName;
-   ColorF              mColorF;
+   LinearColorF              mColorF;
    ColorI              mColorI;
    ColorI              mColorI;
 };
 };
 
 
@@ -261,9 +233,9 @@ class StockColor
 {
 {
 public:
 public:
    static bool isColor( const char* pStockColorName );
    static bool isColor( const char* pStockColorName );
-   static const ColorF& colorF( const char* pStockColorName );
+   static const LinearColorF& colorF( const char* pStockColorName );
    static const ColorI& colorI( const char* pStockColorName );
    static const ColorI& colorI( const char* pStockColorName );
-   static StringTableEntry name( const ColorF& color );
+   static StringTableEntry name( const LinearColorF& color );
    static StringTableEntry name( const ColorI& color );
    static StringTableEntry name( const ColorI& color );
 
 
    static S32 getCount( void );
    static S32 getCount( void );
@@ -274,12 +246,9 @@ public:
 };
 };
 
 
 //------------------------------------------------------------------------------
 //------------------------------------------------------------------------------
-//-------------------------------------- INLINES (ColorF)
+//-------------------------------------- INLINES (LinearColorF)
 //
 //
-inline void ColorF::set(const F32 in_r,
-            const F32 in_g,
-            const F32 in_b,
-            const F32 in_a)
+inline void LinearColorF::set(const F32 in_r, const F32 in_g, const F32 in_b, const F32 in_a)
 {
 {
    red   = in_r;
    red   = in_r;
    green = in_g;
    green = in_g;
@@ -287,7 +256,7 @@ inline void ColorF::set(const F32 in_r,
    alpha = in_a;
    alpha = in_a;
 }
 }
 
 
-inline ColorF::ColorF(const ColorF& in_rCopy)
+inline LinearColorF::LinearColorF(const LinearColorF& in_rCopy)
 {
 {
    red   = in_rCopy.red;
    red   = in_rCopy.red;
    green = in_rCopy.green;
    green = in_rCopy.green;
@@ -295,15 +264,12 @@ inline ColorF::ColorF(const ColorF& in_rCopy)
    alpha = in_rCopy.alpha;
    alpha = in_rCopy.alpha;
 }
 }
 
 
-inline ColorF::ColorF(const F32 in_r,
-               const F32 in_g,
-               const F32 in_b,
-               const F32 in_a)
+inline LinearColorF::LinearColorF(const F32 in_r, const F32 in_g, const F32 in_b, const F32 in_a)
 {
 {
    set(in_r, in_g, in_b, in_a);
    set(in_r, in_g, in_b, in_a);
 }
 }
 
 
-inline ColorF& ColorF::operator*=(const ColorF& in_mul)
+inline LinearColorF& LinearColorF::operator*=(const LinearColorF& in_mul)
 {
 {
    red   *= in_mul.red;
    red   *= in_mul.red;
    green *= in_mul.green;
    green *= in_mul.green;
@@ -313,108 +279,98 @@ inline ColorF& ColorF::operator*=(const ColorF& in_mul)
    return *this;
    return *this;
 }
 }
 
 
-inline ColorF ColorF::operator*(const ColorF& in_mul) const
+inline LinearColorF LinearColorF::operator*(const LinearColorF& in_mul) const
 {
 {
-   return ColorF(red   * in_mul.red,
-                 green * in_mul.green,
-                 blue  * in_mul.blue,
-                 alpha * in_mul.alpha);
+   LinearColorF tmp(*this);
+   tmp *= in_mul;
+   return tmp;
 }
 }
 
 
-inline ColorF& ColorF::operator+=(const ColorF& in_rAdd)
+inline LinearColorF& LinearColorF::operator+=(const LinearColorF& in_rAdd)
 {
 {
-   red   += in_rAdd.red;
+   red += in_rAdd.red;
    green += in_rAdd.green;
    green += in_rAdd.green;
-   blue  += in_rAdd.blue;
+   blue += in_rAdd.blue;
    alpha += in_rAdd.alpha;
    alpha += in_rAdd.alpha;
-
    return *this;
    return *this;
 }
 }
 
 
-inline ColorF ColorF::operator+(const ColorF& in_rAdd) const
+inline LinearColorF LinearColorF::operator+(const LinearColorF& in_rAdd) const
 {
 {
-   return ColorF(red   + in_rAdd.red,
-                  green + in_rAdd.green,
-                  blue  + in_rAdd.blue,
-                  alpha + in_rAdd.alpha);
+   LinearColorF temp(*this);
+   temp += in_rAdd;
+   return temp;
 }
 }
 
 
-inline ColorF& ColorF::operator-=(const ColorF& in_rSub)
+inline LinearColorF& LinearColorF::operator-=(const LinearColorF& in_rSub)
 {
 {
-   red   -= in_rSub.red;
+   red -= in_rSub.red;
    green -= in_rSub.green;
    green -= in_rSub.green;
-   blue  -= in_rSub.blue;
+   blue -= in_rSub.blue;
    alpha -= in_rSub.alpha;
    alpha -= in_rSub.alpha;
-
    return *this;
    return *this;
 }
 }
 
 
-inline ColorF ColorF::operator-(const ColorF& in_rSub) const
+inline LinearColorF LinearColorF::operator-(const LinearColorF& in_rSub) const
 {
 {
-   return ColorF(red   - in_rSub.red,
-                 green - in_rSub.green,
-                 blue  - in_rSub.blue,
-                 alpha - in_rSub.alpha);
+   LinearColorF tmp(*this);
+   tmp -= in_rSub;
+   return tmp;
 }
 }
 
 
-inline ColorF& ColorF::operator*=(const F32 in_mul)
+inline LinearColorF& LinearColorF::operator*=(const F32 in_mul)
 {
 {
    red   *= in_mul;
    red   *= in_mul;
    green *= in_mul;
    green *= in_mul;
    blue  *= in_mul;
    blue  *= in_mul;
    alpha *= in_mul;
    alpha *= in_mul;
-
    return *this;
    return *this;
 }
 }
 
 
-inline ColorF ColorF::operator*(const F32 in_mul) const
+inline LinearColorF LinearColorF::operator*(const F32 in_mul) const
 {
 {
-   return ColorF(red   * in_mul,
-                  green * in_mul,
-                  blue  * in_mul,
-                  alpha * in_mul);
+   LinearColorF tmp(*this);
+   tmp *= in_mul;
+   return tmp;
 }
 }
 
 
-inline ColorF& ColorF::operator/=(const F32 in_div)
+inline LinearColorF& LinearColorF::operator/=(const F32 in_div)
 {
 {
    AssertFatal(in_div != 0.0f, "Error, div by zero...");
    AssertFatal(in_div != 0.0f, "Error, div by zero...");
    F32 inv = 1.0f / in_div;
    F32 inv = 1.0f / in_div;
 
 
-   red   *= inv;
+   red *= inv;
    green *= inv;
    green *= inv;
-   blue  *= inv;
+   blue *= inv;
    alpha *= inv;
    alpha *= inv;
-
    return *this;
    return *this;
 }
 }
 
 
-inline ColorF ColorF::operator/(const F32 in_div) const
+inline LinearColorF LinearColorF::operator/(const F32 in_div) const
 {
 {
    AssertFatal(in_div != 0.0f, "Error, div by zero...");
    AssertFatal(in_div != 0.0f, "Error, div by zero...");
    F32 inv = 1.0f / in_div;
    F32 inv = 1.0f / in_div;
-
-   return ColorF(red * inv,
-                  green * inv,
-                  blue  * inv,
-                  alpha * inv);
+   LinearColorF tmp(*this);
+   tmp /= inv;
+   return tmp;
 }
 }
 
 
-inline ColorF ColorF::operator-() const
+inline LinearColorF LinearColorF::operator-() const
 {
 {
-   return ColorF(-red, -green, -blue, -alpha);
+   return LinearColorF(-red, -green, -blue, -alpha);
 }
 }
 
 
-inline bool ColorF::operator==(const ColorF& in_Cmp) const
+inline bool LinearColorF::operator==(const LinearColorF& in_Cmp) const
 {
 {
    return (red == in_Cmp.red && green == in_Cmp.green && blue == in_Cmp.blue && alpha == in_Cmp.alpha);
    return (red == in_Cmp.red && green == in_Cmp.green && blue == in_Cmp.blue && alpha == in_Cmp.alpha);
 }
 }
 
 
-inline bool ColorF::operator!=(const ColorF& in_Cmp) const
+inline bool LinearColorF::operator!=(const LinearColorF& in_Cmp) const
 {
 {
    return (red != in_Cmp.red || green != in_Cmp.green || blue != in_Cmp.blue || alpha != in_Cmp.alpha);
    return (red != in_Cmp.red || green != in_Cmp.green || blue != in_Cmp.blue || alpha != in_Cmp.alpha);
 }
 }
 
 
-inline U32 ColorF::getARGBPack() const
+inline U32 LinearColorF::getARGBPack() const
 {
 {
    return (U32(alpha * 255.0f + 0.5) << 24) |
    return (U32(alpha * 255.0f + 0.5) << 24) |
           (U32(red   * 255.0f + 0.5) << 16) |
           (U32(red   * 255.0f + 0.5) << 16) |
@@ -422,7 +378,7 @@ inline U32 ColorF::getARGBPack() const
           (U32(blue  * 255.0f + 0.5) <<  0);
           (U32(blue  * 255.0f + 0.5) <<  0);
 }
 }
 
 
-inline U32 ColorF::getRGBAPack() const
+inline U32 LinearColorF::getRGBAPack() const
 {
 {
    return ( U32( red   * 255.0f + 0.5) <<  0 ) |
    return ( U32( red   * 255.0f + 0.5) <<  0 ) |
           ( U32( green * 255.0f + 0.5) <<  8 ) |
           ( U32( green * 255.0f + 0.5) <<  8 ) |
@@ -430,7 +386,7 @@ inline U32 ColorF::getRGBAPack() const
           ( U32( alpha * 255.0f + 0.5) << 24 );
           ( U32( alpha * 255.0f + 0.5) << 24 );
 }
 }
 
 
-inline U32 ColorF::getABGRPack() const
+inline U32 LinearColorF::getABGRPack() const
 {
 {
    return (U32(alpha * 255.0f + 0.5) << 24) |
    return (U32(alpha * 255.0f + 0.5) << 24) |
           (U32(blue  * 255.0f + 0.5) << 16) |
           (U32(blue  * 255.0f + 0.5) << 16) |
@@ -439,61 +395,43 @@ inline U32 ColorF::getABGRPack() const
 
 
 }
 }
 
 
-inline void ColorF::interpolate(const ColorF& in_rC1,
-                    const ColorF& in_rC2,
+inline void LinearColorF::interpolate(const LinearColorF& in_rC1,
+                    const LinearColorF& in_rC2,
                     const F32  in_factor)
                     const F32  in_factor)
 {
 {
+   if (in_factor <= 0 || in_rC1 == in_rC2)
+   {
+      red = in_rC1.red;
+      green = in_rC1.green;
+      blue =in_rC1.blue;
+      alpha = in_rC1.alpha;
+      return;
+   }
+   else if (in_factor >= 1)
+   {
+      red = in_rC2.red;
+      green = in_rC2.green;
+      blue = in_rC2.blue;
+      alpha = in_rC2.alpha;
+      return;
+   }
+
    F32 f2 = 1.0f - in_factor;
    F32 f2 = 1.0f - in_factor;
-   red   = (in_rC1.red   * f2) + (in_rC2.red   * in_factor);
+   red = (in_rC1.red   * f2) + (in_rC2.red   * in_factor);
    green = (in_rC1.green * f2) + (in_rC2.green * in_factor);
    green = (in_rC1.green * f2) + (in_rC2.green * in_factor);
-   blue  = (in_rC1.blue  * f2) + (in_rC2.blue  * in_factor);
+   blue = (in_rC1.blue  * f2) + (in_rC2.blue  * in_factor);
    alpha = (in_rC1.alpha * f2) + (in_rC2.alpha * in_factor);
    alpha = (in_rC1.alpha * f2) + (in_rC2.alpha * in_factor);
 }
 }
 
 
-inline void ColorF::clamp()
+inline void LinearColorF::clamp()
 {
 {
-   if (red > 1.0f)
-      red = 1.0f;
-   else if (red < 0.0f)
-      red = 0.0f;
-
-   if (green > 1.0f)
-      green = 1.0f;
-   else if (green < 0.0f)
-      green = 0.0f;
-
-   if (blue > 1.0f)
-      blue = 1.0f;
-   else if (blue < 0.0f)
-      blue = 0.0f;
-
-   if (alpha > 1.0f)
-      alpha = 1.0f;
-   else if (alpha < 0.0f)
-      alpha = 0.0f;
+   red = mClampF(red, 0.0f, 1.0f);
+   green = mClampF(green, 0.0f, 1.0f);
+   blue = mClampF(blue, 0.0f, 1.0f);
+   alpha = mClampF(alpha, 0.0f, 1.0f);
 }
 }
 
 
-inline ColorF ColorF::toGamma()
-{
-   ColorF color;
-   color.red = mPow(red,gOneOverGamma);
-   color.green = mPow(green, gOneOverGamma);
-   color.blue = mPow(blue, gOneOverGamma);
-   color.alpha = alpha;
-   return color;
-}
-
-inline ColorF ColorF::toLinear()
-{
-   ColorF color;
-   color.red = mPow(red,gGamma);
-   color.green = mPow(green, gGamma);
-   color.blue = mPow(blue, gGamma);
-   color.alpha = alpha;
-   return color;
-}
-
-inline F32 ColorF::luminance()
+inline F32 LinearColorF::luminance()
 {
 {
    // ITU BT.709
    // ITU BT.709
    //return red * 0.2126f + green * 0.7152f + blue * 0.0722f;
    //return red * 0.2126f + green * 0.7152f + blue * 0.0722f;
@@ -719,70 +657,6 @@ inline ColorI::ColorI(const ColorI& in_rCopy,
    set(in_rCopy, in_a);
    set(in_rCopy, in_a);
 }
 }
 
 
-inline ColorI& ColorI::operator*=(const F32 in_mul)
-{
-   red   = U8((F32(red)   * in_mul) + 0.5f);
-   green = U8((F32(green) * in_mul) + 0.5f);
-   blue  = U8((F32(blue)  * in_mul) + 0.5f);
-   alpha = U8((F32(alpha) * in_mul) + 0.5f);
-
-   return *this;
-}
-
-inline ColorI& ColorI::operator*=(const S32 in_mul)
-{
-   red   = red    * in_mul;
-   green = green  * in_mul;
-   blue  = blue   * in_mul;
-   alpha = alpha  * in_mul;
-
-   return *this;
-}
-
-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;
-   alpha = alpha  / in_mul;
-
-   return *this;
-}
-
-inline ColorI ColorI::operator+(const ColorI &in_add) const
-{
-   ColorI tmp;
-
-   tmp.red   = red   + in_add.red;
-   tmp.green = green + in_add.green;
-   tmp.blue  = blue  + in_add.blue;
-   tmp.alpha = alpha + in_add.alpha;
-
-   return tmp;
-}
-
-inline ColorI ColorI::operator*(const F32 in_mul) const
-{
-   ColorI temp(*this);
-   temp *= in_mul;
-   return temp;
-}
-
-inline ColorI ColorI::operator*(const S32 in_mul) const
-{
-   ColorI temp(*this);
-   temp *= in_mul;
-   return temp;
-}
-
-inline ColorI ColorI::operator/(const S32 in_mul) const
-{
-   ColorI temp(*this);
-   temp /= in_mul;
-   return temp;
-}
-
 inline bool ColorI::operator==(const ColorI& in_Cmp) const
 inline bool ColorI::operator==(const ColorI& in_Cmp) const
 {
 {
 	return (red == in_Cmp.red && green == in_Cmp.green && blue == in_Cmp.blue && alpha == in_Cmp.alpha);
 	return (red == in_Cmp.red && green == in_Cmp.green && blue == in_Cmp.blue && alpha == in_Cmp.alpha);
@@ -793,27 +667,6 @@ inline bool ColorI::operator!=(const ColorI& in_Cmp) const
 	return (red != in_Cmp.red || green != in_Cmp.green || blue != in_Cmp.blue || alpha != in_Cmp.alpha);
 	return (red != in_Cmp.red || green != in_Cmp.green || blue != in_Cmp.blue || alpha != in_Cmp.alpha);
 }
 }
 
 
-inline ColorI& ColorI::operator+=(const ColorI& in_rAdd)
-{
-   red   += in_rAdd.red;
-   green += in_rAdd.green;
-   blue  += in_rAdd.blue;
-   alpha += in_rAdd.alpha;
-
-   return *this;
-}
-
-inline void ColorI::interpolate(const ColorI& in_rC1,
-                    const ColorI& in_rC2,
-                    const F32  in_factor)
-{
-   F32 f2= 1.0f - in_factor;
-   red   = U8(((F32(in_rC1.red)   * f2) + (F32(in_rC2.red)   * in_factor)) + 0.5f);
-   green = U8(((F32(in_rC1.green) * f2) + (F32(in_rC2.green) * in_factor)) + 0.5f);
-   blue  = U8(((F32(in_rC1.blue)  * f2) + (F32(in_rC2.blue)  * in_factor)) + 0.5f);
-   alpha = U8(((F32(in_rC1.alpha) * f2) + (F32(in_rC2.alpha) * in_factor)) + 0.5f);
-}
-
 inline U32 ColorI::getARGBPack() const
 inline U32 ColorI::getARGBPack() const
 {
 {
    return (U32(alpha) << 24) |
    return (U32(alpha) << 24) |
@@ -971,35 +824,72 @@ inline String ColorI::getHex() const
 	return result;
 	return result;
 }
 }
 
 
-inline ColorI ColorI::toGamma()
-{
-   ColorF color = (ColorF)*this;
-   return (ColorI)color.toGamma();
-}
-
-inline ColorI ColorI::toLinear()
+inline LinearColorF::LinearColorF( const ColorI &color)
 {
 {
-   ColorF color = (ColorF)*this;
-   return (ColorI)color.toLinear();
+   red = sSrgbToLinear[color.red],
+   green = sSrgbToLinear[color.green],
+   blue = sSrgbToLinear[color.blue],
+   alpha = F32(color.alpha * gOneOver255);
 }
 }
 
 
-//-------------------------------------- INLINE CONVERSION OPERATORS
-inline ColorF::operator ColorI() const
+inline ColorI LinearColorF::toColorI(const bool keepAsLinear)
 {
 {
-   return ColorI(U8(red   * 255.0f + 0.5),
-                  U8(green * 255.0f + 0.5),
-                  U8(blue  * 255.0f + 0.5),
-                  U8(alpha * 255.0f + 0.5));
+   if (isClamped())
+   {
+      if (keepAsLinear)
+      {
+         return ColorI(U8(red * 255.0f + 0.5), U8(green * 255.0f + 0.5), U8(blue * 255.0f + 0.5), U8(alpha * 255.0f + 0.5));
+      }
+      else
+      {
+   #ifdef TORQUE_USE_LEGACY_GAMMA
+         float r = mPow(red, gOneOverGamma);
+         float g = mPow(green, gOneOverGamma);
+         float b = mPow(blue, gOneOverGamma);
+         return ColorI(U8(r * 255.0f + 0.5), U8(g * 255.0f + 0.5), U8(b * 255.0f + 0.5), U8(alpha * 255.0f + 0.5));
+   #else
+         float r = red < 0.0031308f ? 12.92f * red : 1.055 * mPow(red, 1.0f / 2.4f) - 0.055f;
+         float g = green < 0.0031308f ? 12.92f * green : 1.055 * mPow(green, 1.0f / 2.4f) - 0.055f;
+         float b = blue < 0.0031308f ? 12.92f * blue : 1.055 * mPow(blue, 1.0f / 2.4f) - 0.055f;
+         return ColorI(U8(r * 255.0f + 0.5), U8(g * 255.0f + 0.5), U8(b * 255.0f + 0.5), U8(alpha * 255.0f + 0.5));
+   #endif
+      }
+   }
+   else
+   {
+      LinearColorF color = LinearColorF(*this);
+      color.clamp();
+
+      if (keepAsLinear)
+      {
+         return ColorI(U8(color.red * 255.0f + 0.5), U8(color.green * 255.0f + 0.5), U8(color.blue * 255.0f + 0.5), U8(color.alpha * 255.0f + 0.5));
+      }
+      else
+      {
+   #ifdef TORQUE_USE_LEGACY_GAMMA
+         float r = mPow(red, gOneOverGamma);
+         float g = mPow(green, gOneOverGamma);
+         float b = mPow(blue, gOneOverGamma);
+         return ColorI(U8(r * 255.0f + 0.5), U8(g * 255.0f + 0.5), U8(b * 255.0f + 0.5), U8(alpha * 255.0f + 0.5));
+   #else
+         float r = red < 0.0031308f ? 12.92f * red : 1.055 * mPow(red, 1.0f / 2.4f) - 0.055f;
+         float g = green < 0.0031308f ? 12.92f * green : 1.055 * mPow(green, 1.0f / 2.4f) - 0.055f;
+         float b = blue < 0.0031308f ? 12.92f * blue : 1.055 * mPow(blue, 1.0f / 2.4f) - 0.055f;
+         return ColorI(U8(r * 255.0f + 0.5), U8(g * 255.0f + 0.5), U8(b * 255.0f + 0.5), U8(alpha * 255.0f + 0.5));
+   #endif
+      }
+   }
 }
 }
 
 
-inline ColorI::operator ColorF() const
+inline ColorI ColorI::fromLinear()
 {
 {
-   const F32 inv255 = 1.0f / 255.0f;
-
-   return ColorF(F32(red)   * inv255,
-                 F32(green) * inv255,
-                 F32(blue)  * inv255,
-                 F32(alpha) * inv255);
+   //manually create LinearColorF, otherwise it will try and convert to linear first
+   LinearColorF linearColor = LinearColorF(F32(red) * 255.0f + 0.5f,
+                                           F32(red) * 255.0f + 0.5f,
+                                           F32(red) * 255.0f + 0.5f,
+                                           F32(alpha) * 255.0f + 0.5f);
+   //convert back to srgb
+   return linearColor.toColorI();
 }
 }
 
 
 #endif //_COLOR_H_
 #endif //_COLOR_H_

+ 3 - 3
Engine/source/core/stream/stream.cpp

@@ -271,9 +271,9 @@ bool Stream::write(const ColorI& rColor)
    return success;
    return success;
 }
 }
 
 
-bool Stream::write(const ColorF& rColor)
+bool Stream::write(const LinearColorF& rColor)
 {
 {
-   ColorI temp = rColor;
+   ColorI temp = LinearColorF(rColor).toColorI();
    return write(temp);
    return write(temp);
 }
 }
 
 
@@ -287,7 +287,7 @@ bool Stream::read(ColorI* pColor)
    return success;
    return success;
 }
 }
 
 
-bool Stream::read(ColorF* pColor)
+bool Stream::read(LinearColorF* pColor)
 {
 {
    ColorI temp;
    ColorI temp;
    bool success = read(&temp);
    bool success = read(&temp);

+ 3 - 3
Engine/source/core/stream/stream.h

@@ -41,7 +41,7 @@
 /// @}
 /// @}
 
 
 class ColorI;
 class ColorI;
-class ColorF;
+class LinearColorF;
 struct NetAddress;
 struct NetAddress;
 class RawData;
 class RawData;
 class String;
 class String;
@@ -155,11 +155,11 @@ public:
    /// Write an integral color to the stream.
    /// Write an integral color to the stream.
    bool write(const ColorI&);
    bool write(const ColorI&);
    /// Write a floating point color to the stream.
    /// Write a floating point color to the stream.
-   bool write(const ColorF&);
+   bool write(const LinearColorF&);
    /// Read an integral color from the stream.
    /// Read an integral color from the stream.
    bool read(ColorI*);
    bool read(ColorI*);
    /// Read a floating point color from the stream.
    /// Read a floating point color from the stream.
-   bool read(ColorF*);
+   bool read(LinearColorF*);
 
 
    /// Write a network address to the stream.
    /// Write a network address to the stream.
    bool write(const NetAddress &);
    bool write(const NetAddress &);

+ 5 - 5
Engine/source/core/util/rgb2luv.cpp

@@ -31,12 +31,12 @@
 namespace ConvertRGB
 namespace ConvertRGB
 {
 {
 
 
-ColorF toLUV( const ColorF &rgbColor )
+LinearColorF toLUV( const LinearColorF &rgbColor )
 {
 {
    static const Point3F scXYZLUVDot( 1.0f, 15.0f, 3.0f );
    static const Point3F scXYZLUVDot( 1.0f, 15.0f, 3.0f );
    static const Point2F sc49( 4.0f, 9.0f );
    static const Point2F sc49( 4.0f, 9.0f );
 
 
-   ColorF xyzColor = ConvertRGB::toXYZ( rgbColor );
+   LinearColorF xyzColor = ConvertRGB::toXYZ( rgbColor );
 
 
    const Point2F &xyz_xy = *((Point2F *)&xyzColor);
    const Point2F &xyz_xy = *((Point2F *)&xyzColor);
 
 
@@ -44,12 +44,12 @@ ColorF toLUV( const ColorF &rgbColor )
    uvColor.convolve( xyz_xy );
    uvColor.convolve( xyz_xy );
    uvColor /= mDot( *(Point3F *)&xyzColor, scXYZLUVDot );
    uvColor /= mDot( *(Point3F *)&xyzColor, scXYZLUVDot );
 
 
-   return ColorF( uvColor.x, uvColor.y, xyzColor.green, rgbColor.alpha );
+   return LinearColorF( uvColor.x, uvColor.y, xyzColor.green, rgbColor.alpha );
 }
 }
 
 
-ColorF toLUVScaled( const ColorF &rgbColor )
+LinearColorF toLUVScaled( const LinearColorF &rgbColor )
 {
 {
-   ColorF luvColor = toLUV( rgbColor );
+   LinearColorF luvColor = toLUV( rgbColor );
    luvColor.red /= 0.62f;
    luvColor.red /= 0.62f;
    luvColor.green /= 0.62f;
    luvColor.green /= 0.62f;
    return luvColor;
    return luvColor;

+ 3 - 3
Engine/source/core/util/rgb2luv.h

@@ -29,9 +29,9 @@
 
 
 namespace ConvertRGB
 namespace ConvertRGB
 {
 {
-   ColorF toLUV( const ColorF &rgbColor );
-   ColorF toLUVScaled( const ColorF &rgbColor );
-   ColorF fromLUV( const ColorF &luvColor );
+   LinearColorF toLUV( const LinearColorF &rgbColor );
+   LinearColorF toLUVScaled( const LinearColorF &rgbColor );
+   LinearColorF fromLUV( const LinearColorF &luvColor );
 };
 };
 
 
 #endif
 #endif

+ 4 - 4
Engine/source/core/util/rgb2xyz.cpp

@@ -46,20 +46,20 @@ static const F32 scXYZ2RGB[] =
    0.0f,     0.0f,      0.0f,     1.0f,
    0.0f,     0.0f,      0.0f,     1.0f,
 };
 };
 
 
-ColorF toXYZ( const ColorF &rgbColor )
+LinearColorF toXYZ( const LinearColorF &rgbColor )
 {
 {
    const MatrixF &rgb2xyz = *((MatrixF *)scRGB2XYZ);
    const MatrixF &rgb2xyz = *((MatrixF *)scRGB2XYZ);
 
 
-   ColorF retColor = rgbColor;
+   LinearColorF retColor = rgbColor;
    rgb2xyz.mul( *(Point4F *)&retColor );
    rgb2xyz.mul( *(Point4F *)&retColor );
    return retColor;
    return retColor;
 }
 }
 
 
-ColorF fromXYZ( const ColorF &xyzColor )
+LinearColorF fromXYZ( const LinearColorF &xyzColor )
 {
 {
    const MatrixF &xyz2rgb = *((MatrixF *)scXYZ2RGB);
    const MatrixF &xyz2rgb = *((MatrixF *)scXYZ2RGB);
 
 
-   ColorF retColor = xyzColor;
+   LinearColorF retColor = xyzColor;
    xyz2rgb.mul( *(Point4F *)&retColor );
    xyz2rgb.mul( *(Point4F *)&retColor );
    return retColor;
    return retColor;
 }
 }

+ 2 - 2
Engine/source/core/util/rgb2xyz.h

@@ -27,8 +27,8 @@
 
 
 namespace ConvertRGB
 namespace ConvertRGB
 {
 {
-   ColorF toXYZ( const ColorF &rgbColor );
-   ColorF fromXYZ( const ColorF &xyzColor );
+   LinearColorF toXYZ( const LinearColorF &rgbColor );
+   LinearColorF fromXYZ( const LinearColorF &xyzColor );
 };
 };
 
 
 #endif
 #endif

+ 4 - 4
Engine/source/environment/VolumetricFog.cpp

@@ -1074,7 +1074,7 @@ void VolumetricFog::render(ObjectRenderInst *ri, SceneRenderState *state, BaseMa
 
 
    mPPShaderConsts->setSafe(mPPModelViewProjSC, xform);
    mPPShaderConsts->setSafe(mPPModelViewProjSC, xform);
 
 
-   const ColorF &sunlight = state->getAmbientLightColor();
+   const LinearColorF &sunlight = state->getAmbientLightColor();
 
 
    Point3F ambientColor(sunlight.red, sunlight.green, sunlight.blue);
    Point3F ambientColor(sunlight.red, sunlight.green, sunlight.blue);
    mShaderConsts->setSafe(mAmbientColorSC, ambientColor);
    mShaderConsts->setSafe(mAmbientColorSC, ambientColor);
@@ -1204,7 +1204,7 @@ void VolumetricFog::InitTexture()
    mIsTextured = false;
    mIsTextured = false;
 
 
    if (mTextureName.isNotEmpty())
    if (mTextureName.isNotEmpty())
-      mTexture.set(mTextureName, &GFXDefaultStaticDiffuseProfile, "VolumetricFogMod");
+      mTexture.set(mTextureName, &GFXStaticTextureSRGBProfile, "VolumetricFogMod");
 
 
    if (!mTexture.isNull())
    if (!mTexture.isNull())
    {
    {
@@ -1218,7 +1218,7 @@ void VolumetricFog::InitTexture()
    }
    }
 }
 }
 
 
-void VolumetricFog::setFogColor(ColorF color)
+void VolumetricFog::setFogColor(LinearColorF color)
 {
 {
    mFogColor.set(255 * color.red,255 * color.green,255 * color.blue);
    mFogColor.set(255 * color.red,255 * color.green,255 * color.blue);
    setMaskBits(FogColorMask);
    setMaskBits(FogColorMask);
@@ -1266,7 +1266,7 @@ bool VolumetricFog::isInsideFog()
    return mCamInFog;
    return mCamInFog;
 }
 }
 
 
-DefineEngineMethod(VolumetricFog, SetFogColorF, void, (ColorF new_color), ,
+DefineEngineMethod(VolumetricFog, SetFogColorF, void, (LinearColorF new_color), ,
 "@brief Changes the color of the fog\n\n."
 "@brief Changes the color of the fog\n\n."
 "@params new_color the new fog color (rgb 0.0 - 1.0, a is ignored.")
 "@params new_color the new fog color (rgb 0.0 - 1.0, a is ignored.")
 {
 {

+ 1 - 1
Engine/source/environment/VolumetricFog.h

@@ -227,7 +227,7 @@ class VolumetricFog : public SceneObject
    
    
       // Methods for modifying & networking various fog elements
       // Methods for modifying & networking various fog elements
       // Used in script
       // Used in script
-      void setFogColor(ColorF color);
+      void setFogColor(LinearColorF color);
       void setFogColor(ColorI color);
       void setFogColor(ColorI color);
       void setFogDensity(F32 density);
       void setFogDensity(F32 density);
       void setFogModulation(F32 strength, Point2F speed1, Point2F speed2);
       void setFogModulation(F32 strength, Point2F speed1, Point2F speed2);

+ 4 - 4
Engine/source/environment/VolumetricFogRTManager.cpp

@@ -150,7 +150,7 @@ bool VolumetricFogRTManager::Init()
    mHeight = mFloor(mPlatformWindow->getClientExtent().y / mTargetScale);
    mHeight = mFloor(mPlatformWindow->getClientExtent().y / mTargetScale);
    
    
    mDepthBuffer = GFXTexHandle(mWidth, mHeight, GFXFormatR32F,
    mDepthBuffer = GFXTexHandle(mWidth, mHeight, GFXFormatR32F,
-   &GFXDefaultRenderTargetProfile, avar("%s() - mDepthBuffer (line %d)", __FUNCTION__, __LINE__));
+   &GFXRenderTargetProfile, avar("%s() - mDepthBuffer (line %d)", __FUNCTION__, __LINE__));
    if (!mDepthBuffer.isValid())
    if (!mDepthBuffer.isValid())
    {
    {
       Con::errorf("VolumetricFogRTManager Fatal Error: Unable to create Depthbuffer");
       Con::errorf("VolumetricFogRTManager Fatal Error: Unable to create Depthbuffer");
@@ -164,7 +164,7 @@ bool VolumetricFogRTManager::Init()
    mDepthTarget.setTexture(mDepthBuffer);
    mDepthTarget.setTexture(mDepthBuffer);
    
    
    mFrontBuffer = GFXTexHandle(mWidth, mHeight, GFXFormatR32F,
    mFrontBuffer = GFXTexHandle(mWidth, mHeight, GFXFormatR32F,
-   &GFXDefaultRenderTargetProfile, avar("%s() - mFrontBuffer (line %d)", __FUNCTION__, __LINE__));
+   &GFXRenderTargetProfile, avar("%s() - mFrontBuffer (line %d)", __FUNCTION__, __LINE__));
    if (!mFrontBuffer.isValid())
    if (!mFrontBuffer.isValid())
    {
    {
       Con::errorf("VolumetricFogRTManager Fatal Error: Unable to create front buffer");
       Con::errorf("VolumetricFogRTManager Fatal Error: Unable to create front buffer");
@@ -240,7 +240,7 @@ bool VolumetricFogRTManager::Resize()
       mFrontBuffer->kill();
       mFrontBuffer->kill();
    
    
    mFrontBuffer = GFXTexHandle(mWidth, mHeight, GFXFormatR32F,
    mFrontBuffer = GFXTexHandle(mWidth, mHeight, GFXFormatR32F,
-   &GFXDefaultRenderTargetProfile, avar("%s() - mFrontBuffer (line %d)", __FUNCTION__, __LINE__));
+   &GFXRenderTargetProfile, avar("%s() - mFrontBuffer (line %d)", __FUNCTION__, __LINE__));
    if (!mFrontBuffer.isValid())
    if (!mFrontBuffer.isValid())
    {
    {
       Con::errorf("VolumetricFogRTManager::Resize() Fatal Error: Unable to create front buffer");
       Con::errorf("VolumetricFogRTManager::Resize() Fatal Error: Unable to create front buffer");
@@ -249,7 +249,7 @@ bool VolumetricFogRTManager::Resize()
    mFrontTarget.setTexture(mFrontBuffer);
    mFrontTarget.setTexture(mFrontBuffer);
    
    
    mDepthBuffer = GFXTexHandle(mWidth, mHeight, GFXFormatR32F,
    mDepthBuffer = GFXTexHandle(mWidth, mHeight, GFXFormatR32F,
-   &GFXDefaultRenderTargetProfile, avar("%s() - mDepthBuffer (line %d)", __FUNCTION__, __LINE__));
+   &GFXRenderTargetProfile, avar("%s() - mDepthBuffer (line %d)", __FUNCTION__, __LINE__));
    if (!mDepthBuffer.isValid())
    if (!mDepthBuffer.isValid())
    {
    {
       Con::errorf("VolumetricFogRTManager::Resize() Fatal Error: Unable to create Depthbuffer");
       Con::errorf("VolumetricFogRTManager::Resize() Fatal Error: Unable to create Depthbuffer");

+ 2 - 2
Engine/source/environment/basicClouds.cpp

@@ -341,10 +341,10 @@ void BasicClouds::_initTexture()
       }
       }
 
 
       if ( mTexName[i].isNotEmpty() )
       if ( mTexName[i].isNotEmpty() )
-      mTexture[i].set( mTexName[i], &GFXDefaultStaticDiffuseProfile, "BasicClouds" );
+      mTexture[i].set( mTexName[i], &GFXStaticTextureSRGBProfile, "BasicClouds" );
 
 
       if ( mTexture[i].isNull() )
       if ( mTexture[i].isNull() )
-         mTexture[i].set( GFXTextureManager::getWarningTexturePath(), &GFXDefaultStaticDiffuseProfile, "BasicClouds" );
+         mTexture[i].set( GFXTextureManager::getWarningTexturePath(), &GFXStaticTextureSRGBProfile, "BasicClouds" );
    }
    }
 }
 }
 
 

+ 4 - 4
Engine/source/environment/cloudLayer.cpp

@@ -353,12 +353,12 @@ void CloudLayer::renderObject( ObjectRenderInst *ri, SceneRenderState *state, Ba
    mShaderConsts->setSafe( mEyePosWorldSC, camPos );
    mShaderConsts->setSafe( mEyePosWorldSC, camPos );
 
 
    LightInfo *lightinfo = LIGHTMGR->getSpecialLight(LightManager::slSunLightType);
    LightInfo *lightinfo = LIGHTMGR->getSpecialLight(LightManager::slSunLightType);
-   const ColorF &sunlight = state->getAmbientLightColor();
+   const LinearColorF &sunlight = state->getAmbientLightColor();
 
 
    Point3F ambientColor( sunlight.red, sunlight.green, sunlight.blue );
    Point3F ambientColor( sunlight.red, sunlight.green, sunlight.blue );
    mShaderConsts->setSafe( mAmbientColorSC, ambientColor );   
    mShaderConsts->setSafe( mAmbientColorSC, ambientColor );   
 
 
-   const ColorF &sunColor = lightinfo->getColor();
+   const LinearColorF &sunColor = lightinfo->getColor();
    Point3F data( sunColor.red, sunColor.green, sunColor.blue );
    Point3F data( sunColor.red, sunColor.green, sunColor.blue );
    mShaderConsts->setSafe( mSunColorSC, data );
    mShaderConsts->setSafe( mSunColorSC, data );
 
 
@@ -398,10 +398,10 @@ void CloudLayer::_initTexture()
    }
    }
 
 
    if ( mTextureName.isNotEmpty() )
    if ( mTextureName.isNotEmpty() )
-      mTexture.set( mTextureName, &GFXDefaultStaticDiffuseProfile, "CloudLayer" );
+      mTexture.set( mTextureName, &GFXStaticTextureSRGBProfile, "CloudLayer" );
 
 
    if ( mTexture.isNull() )
    if ( mTexture.isNull() )
-      mTexture.set( GFXTextureManager::getWarningTexturePath(), &GFXDefaultStaticDiffuseProfile, "CloudLayer" );
+      mTexture.set( GFXTextureManager::getWarningTexturePath(), &GFXStaticTextureSRGBProfile, "CloudLayer" );
 }
 }
 
 
 void CloudLayer::_initBuffers()
 void CloudLayer::_initBuffers()

+ 1 - 1
Engine/source/environment/cloudLayer.h

@@ -125,7 +125,7 @@ protected:
    Point2F mTexDirection[TEX_COUNT];
    Point2F mTexDirection[TEX_COUNT];
    F32 mTexSpeed[TEX_COUNT];   
    F32 mTexSpeed[TEX_COUNT];   
    
    
-   ColorF mBaseColor;
+   LinearColorF mBaseColor;
    F32 mExposure;
    F32 mExposure;
    F32 mCoverage;
    F32 mCoverage;
    F32 mWindSpeed;   
    F32 mWindSpeed;   

+ 1 - 1
Engine/source/environment/river.cpp

@@ -924,7 +924,7 @@ void River::setShaderParams( SceneRenderState *state, BaseMatInstance* mat, cons
    // set pixel shader constants
    // set pixel shader constants
    //-----------------------------------
    //-----------------------------------
 
 
-   ColorF c( mWaterFogData.color );
+   LinearColorF c( mWaterFogData.color );
    matParams->setSafe(paramHandles.mBaseColorSC, c);
    matParams->setSafe(paramHandles.mBaseColorSC, c);
 
 
    // By default we need to show a true reflection is fullReflect is enabled and
    // By default we need to show a true reflection is fullReflect is enabled and

+ 16 - 16
Engine/source/environment/scatterSky.cpp

@@ -122,10 +122,10 @@ ScatterSky::ScatterSky()
    mAmbientScale.set( 1.0f, 1.0f, 1.0f, 1.0f );
    mAmbientScale.set( 1.0f, 1.0f, 1.0f, 1.0f );
 
 
    mSunColor.set( 0, 0, 0, 1.0f );
    mSunColor.set( 0, 0, 0, 1.0f );
-   mSunScale = ColorF::WHITE;
+   mSunScale = LinearColorF::WHITE;
 
 
    mFogColor.set( 0, 0, 0, 1.0f );
    mFogColor.set( 0, 0, 0, 1.0f );
-   mFogScale = ColorF::WHITE;
+   mFogScale = LinearColorF::WHITE;
 
 
    mExposure = 1.0f;
    mExposure = 1.0f;
    mNightInterpolant = 0;
    mNightInterpolant = 0;
@@ -548,7 +548,7 @@ void ScatterSky::unpackUpdate(NetConnection *con, BitStream *stream)
 
 
       stream->read( &mScale );
       stream->read( &mScale );
 
 
-      ColorF tmpColor( 0, 0, 0 );
+      LinearColorF tmpColor( 0, 0, 0 );
 
 
       stream->read( &tmpColor );
       stream->read( &tmpColor );
 
 
@@ -1093,7 +1093,7 @@ void ScatterSky::_renderMoon( ObjectRenderInst *ri, SceneRenderState *state, Bas
    }
    }
 
 
    // Vertex color.
    // Vertex color.
-   ColorF moonVertColor( 1.0f, 1.0f, 1.0f, mNightInterpolant );
+   LinearColorF moonVertColor( 1.0f, 1.0f, 1.0f, mNightInterpolant );
 
 
    // Copy points to buffer.
    // Copy points to buffer.
 
 
@@ -1104,7 +1104,7 @@ void ScatterSky::_renderMoon( ObjectRenderInst *ri, SceneRenderState *state, Bas
 
 
    for ( S32 i = 0; i < 4; i++ )
    for ( S32 i = 0; i < 4; i++ )
    {
    {
-      pVert->color.set( moonVertColor );
+      pVert->color.set( moonVertColor.toColorI());
       pVert->point.set( points[i] );
       pVert->point.set( points[i] );
       pVert->texCoord.set( sCoords[i].x, sCoords[i].y );
       pVert->texCoord.set( sCoords[i].x, sCoords[i].y );
       pVert++;
       pVert++;
@@ -1182,8 +1182,8 @@ void ScatterSky::_interpolateColors()
 
 
    mMieScattering = (mCurves[1].getVal( mTimeOfDay) * mSunSize ); //Scale the size of the sun's disk
    mMieScattering = (mCurves[1].getVal( mTimeOfDay) * mSunSize ); //Scale the size of the sun's disk
 
 
-   ColorF moonTemp = mMoonTint;
-   ColorF nightTemp = mNightColor;
+   LinearColorF moonTemp = mMoonTint;
+   LinearColorF nightTemp = mNightColor;
 
 
    moonTemp.interpolate( mNightColor, mMoonTint, mCurves[4].getVal( mTimeOfDay ) );
    moonTemp.interpolate( mNightColor, mMoonTint, mCurves[4].getVal( mTimeOfDay ) );
    nightTemp.interpolate( mMoonTint, mNightColor, mCurves[4].getVal( mTimeOfDay ) );
    nightTemp.interpolate( mMoonTint, mNightColor, mCurves[4].getVal( mTimeOfDay ) );
@@ -1195,12 +1195,12 @@ void ScatterSky::_interpolateColors()
    mSunColor.interpolate( mSunColor, mMoonTint, mCurves[3].getVal( mTimeOfDay ) );//mNightInterpolant );
    mSunColor.interpolate( mSunColor, mMoonTint, mCurves[3].getVal( mTimeOfDay ) );//mNightInterpolant );
 }
 }
 
 
-void ScatterSky::_getSunColor( ColorF *outColor )
+void ScatterSky::_getSunColor( LinearColorF *outColor )
 {
 {
    PROFILE_SCOPE( ScatterSky_GetSunColor );
    PROFILE_SCOPE( ScatterSky_GetSunColor );
 
 
    U32 count = 0;
    U32 count = 0;
-   ColorF tmpColor( 0, 0, 0 );
+   LinearColorF tmpColor( 0, 0, 0 );
    VectorF tmpVec( 0, 0, 0 );
    VectorF tmpVec( 0, 0, 0 );
 
 
    tmpVec = mLightDir;
    tmpVec = mLightDir;
@@ -1221,11 +1221,11 @@ void ScatterSky::_getSunColor( ColorF *outColor )
       (*outColor) /= count;
       (*outColor) /= count;
 }
 }
 
 
-void ScatterSky::_getAmbientColor( ColorF *outColor )
+void ScatterSky::_getAmbientColor( LinearColorF *outColor )
 {
 {
    PROFILE_SCOPE( ScatterSky_GetAmbientColor );
    PROFILE_SCOPE( ScatterSky_GetAmbientColor );
 
 
-   ColorF tmpColor( 0, 0, 0, 0 );
+   LinearColorF tmpColor( 0, 0, 0, 0 );
    U32 count = 0;
    U32 count = 0;
 
 
    // Disable mieScattering for purposes of calculating the ambient color.
    // Disable mieScattering for purposes of calculating the ambient color.
@@ -1246,7 +1246,7 @@ void ScatterSky::_getAmbientColor( ColorF *outColor )
    mMieScattering = oldMieScattering;
    mMieScattering = oldMieScattering;
 }
 }
 
 
-void ScatterSky::_getFogColor( ColorF *outColor )
+void ScatterSky::_getFogColor( LinearColorF *outColor )
 {
 {
    PROFILE_SCOPE( ScatterSky_GetFogColor );
    PROFILE_SCOPE( ScatterSky_GetFogColor );
 
 
@@ -1261,7 +1261,7 @@ void ScatterSky::_getFogColor( ColorF *outColor )
    originalYaw = yaw;
    originalYaw = yaw;
    pitch = mDegToRad( 10.0f );
    pitch = mDegToRad( 10.0f );
 
 
-   ColorF tmpColor( 0, 0, 0 );
+   LinearColorF tmpColor( 0, 0, 0 );
 
 
    U32 i = 0;
    U32 i = 0;
    for ( i = 0; i < 10; i++ )
    for ( i = 0; i < 10; i++ )
@@ -1309,7 +1309,7 @@ F32 ScatterSky::_getRayleighPhase( F32 fCos2 )
    return 0.75 + 0.75 * fCos2;
    return 0.75 + 0.75 * fCos2;
 }
 }
 
 
-void ScatterSky::_getColor( const Point3F &pos, ColorF *outColor )
+void ScatterSky::_getColor( const Point3F &pos, LinearColorF *outColor )
 {
 {
    PROFILE_SCOPE( ScatterSky_GetColor );
    PROFILE_SCOPE( ScatterSky_GetColor );
 
 
@@ -1379,7 +1379,7 @@ void ScatterSky::_getColor( const Point3F &pos, ColorF *outColor )
    F32 miePhase = _getMiePhase( fCos, fCos2, g, g2 );
    F32 miePhase = _getMiePhase( fCos, fCos2, g, g2 );
 
 
    Point3F color = rayleighColor + (miePhase * mieColor);
    Point3F color = rayleighColor + (miePhase * mieColor);
-   ColorF tmp( color.x, color.y, color.z, color.y );
+   LinearColorF tmp( color.x, color.y, color.z, color.y );
 
 
    Point3F expColor( 0, 0, 0 );
    Point3F expColor( 0, 0, 0 );
    expColor.x = 1.0f - exp(-mExposure * color.x);
    expColor.x = 1.0f - exp(-mExposure * color.x);
@@ -1388,7 +1388,7 @@ void ScatterSky::_getColor( const Point3F &pos, ColorF *outColor )
 
 
    tmp.set( expColor.x, expColor.y, expColor.z, 1.0f );
    tmp.set( expColor.x, expColor.y, expColor.z, 1.0f );
 
 
-   if ( !tmp.isValidColor() )
+   if ( !tmp.isClamped() )
    {
    {
       F32 len = expColor.len();
       F32 len = expColor.len();
       if ( len > 0 )
       if ( len > 0 )

+ 15 - 15
Engine/source/environment/scatterSky.h

@@ -119,10 +119,10 @@ protected:
 
 
    void _generateSkyPoints();
    void _generateSkyPoints();
 
 
-   void _getColor( const Point3F &pos, ColorF *outColor );
-   void _getFogColor( ColorF *outColor );
-   void _getAmbientColor( ColorF *outColor );
-   void _getSunColor( ColorF *outColor );
+   void _getColor( const Point3F &pos, LinearColorF *outColor );
+   void _getFogColor( LinearColorF *outColor );
+   void _getAmbientColor( LinearColorF *outColor );
+   void _getSunColor( LinearColorF *outColor );
    void _interpolateColors();
    void _interpolateColors();
 
 
    void _conformLights();
    void _conformLights();
@@ -161,7 +161,7 @@ protected:
 
 
    F32 mOuterRadius;
    F32 mOuterRadius;
    F32 mScale;
    F32 mScale;
-   ColorF mWavelength;
+   LinearColorF mWavelength;
    F32 mWavelength4[3];
    F32 mWavelength4[3];
    F32 mRayleighScaleDepth;
    F32 mRayleighScaleDepth;
    F32 mMieScaleDepth;
    F32 mMieScaleDepth;
@@ -185,16 +185,16 @@ protected:
 
 
    F32 mBrightness;
    F32 mBrightness;
 
 
-   ColorF mNightColor;
-   ColorF mNightFogColor;
+   LinearColorF mNightColor;
+   LinearColorF mNightFogColor;
 
 
-   ColorF mAmbientColor;   ///< Not a field
-   ColorF mSunColor;       ///< Not a field
-   ColorF mFogColor;       ///< Not a field
+   LinearColorF mAmbientColor;   ///< Not a field
+   LinearColorF mSunColor;       ///< Not a field
+   LinearColorF mFogColor;       ///< Not a field
 
 
-   ColorF mAmbientScale;
-   ColorF mSunScale;
-   ColorF mFogScale;
+   LinearColorF mAmbientScale;
+   LinearColorF mSunScale;
+   LinearColorF mFogScale;
 
 
    LightInfo *mLight;
    LightInfo *mLight;
 
 
@@ -211,7 +211,7 @@ protected:
    String mMoonMatName;
    String mMoonMatName;
    BaseMatInstance *mMoonMatInst;
    BaseMatInstance *mMoonMatInst;
    F32 mMoonScale;
    F32 mMoonScale;
-   ColorF mMoonTint;
+   LinearColorF mMoonTint;
    VectorF mMoonLightDir;
    VectorF mMoonLightDir;
    CubemapData *mNightCubemap;
    CubemapData *mNightCubemap;
    String mNightCubemapName;
    String mNightCubemapName;
@@ -241,7 +241,7 @@ protected:
    GFXShaderConstHandle *mNightInterpolantAndExposureSC;
    GFXShaderConstHandle *mNightInterpolantAndExposureSC;
    GFXShaderConstHandle *mUseCubemapSC;
    GFXShaderConstHandle *mUseCubemapSC;
    F32 mColorizeAmt;
    F32 mColorizeAmt;
-   ColorF mColorize;
+   LinearColorF mColorize;
    GFXShaderConstHandle *mColorizeSC;
    GFXShaderConstHandle *mColorizeSC;
 
 
 };
 };

+ 1 - 1
Engine/source/environment/skyBox.cpp

@@ -198,7 +198,7 @@ void SkyBox::prepRenderImage( SceneRenderState *state )
 
 
 void SkyBox::_renderObject( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *mi )
 void SkyBox::_renderObject( ObjectRenderInst *ri, SceneRenderState *state, BaseMatInstance *mi )
 {
 {
-   GFXDEBUGEVENT_SCOPE( SkyBox_RenderObject, ColorF::WHITE );
+   GFXDEBUGEVENT_SCOPE( SkyBox_RenderObject, ColorI::WHITE );
 
 
    GFXTransformSaver saver;  
    GFXTransformSaver saver;  
    GFX->setVertexBuffer( mVB );         
    GFX->setVertexBuffer( mVB );         

+ 1 - 1
Engine/source/environment/skyBox.h

@@ -111,7 +111,7 @@ protected:
    Material *mFogBandMat;
    Material *mFogBandMat;
    BaseMatInstance *mFogBandMatInst;
    BaseMatInstance *mFogBandMatInst;
 
 
-   ColorF mLastFogColor;
+   LinearColorF mLastFogColor;
 
 
    bool mDrawBottom;
    bool mDrawBottom;
    bool mIsVBDirty;
    bool mIsVBDirty;

+ 3 - 3
Engine/source/environment/sun.cpp

@@ -394,7 +394,7 @@ void Sun::setElevation( F32 elevation )
    setMaskBits( UpdateMask ); // TODO: Break out the masks to save some space!
    setMaskBits( UpdateMask ); // TODO: Break out the masks to save some space!
 }
 }
 
 
-void Sun::setColor( const ColorF &color )
+void Sun::setColor( const LinearColorF &color )
 {
 {
    mLightColor = color;
    mLightColor = color;
    _conformLights();
    _conformLights();
@@ -490,7 +490,7 @@ void Sun::_renderCorona( ObjectRenderInst *ri, SceneRenderState *state, BaseMatI
       points[i] += mLightWorldPos;
       points[i] += mLightWorldPos;
    }
    }
 
 
-   ColorF vertColor;
+   LinearColorF vertColor;
    if ( mCoronaUseLightColor )
    if ( mCoronaUseLightColor )
       vertColor = mLightColor;
       vertColor = mLightColor;
    else
    else
@@ -503,7 +503,7 @@ void Sun::_renderCorona( ObjectRenderInst *ri, SceneRenderState *state, BaseMatI
 
 
    for ( S32 i = 0; i < 4; i++ )
    for ( S32 i = 0; i < 4; i++ )
    {
    {
-      pVert->color.set( vertColor );
+      pVert->color.set( vertColor.toColorI());
       pVert->point.set( points[i] );
       pVert->point.set( points[i] );
       pVert->texCoord.set( sCoords[i].x, sCoords[i].y );
       pVert->texCoord.set( sCoords[i].x, sCoords[i].y );
       pVert++;
       pVert++;

+ 4 - 4
Engine/source/environment/sun.h

@@ -50,9 +50,9 @@ protected:
    
    
    F32 mSunElevation;
    F32 mSunElevation;
 
 
-   ColorF mLightColor;
+   LinearColorF mLightColor;
 
 
-   ColorF mLightAmbient;
+   LinearColorF mLightAmbient;
 
 
    F32 mBrightness;
    F32 mBrightness;
 
 
@@ -79,7 +79,7 @@ protected:
    BaseMatInstance *mCoronaMatInst;
    BaseMatInstance *mCoronaMatInst;
    MatrixSet *mMatrixSet;   
    MatrixSet *mMatrixSet;   
    F32 mCoronaScale;
    F32 mCoronaScale;
-   ColorF mCoronaTint;
+   LinearColorF mCoronaTint;
    bool mCoronaUseLightColor;
    bool mCoronaUseLightColor;
 
 
    // These are not user specified.
    // These are not user specified.
@@ -136,7 +136,7 @@ public:
    void setElevation( F32 elevation );
    void setElevation( F32 elevation );
 
 
    ///
    ///
-   void setColor( const ColorF &color );
+   void setColor( const LinearColorF &color );
 
 
    ///
    ///
    void animate( F32 duration, F32 startAzimuth, F32 endAzimuth, F32 startElevation, F32 endElevation );
    void animate( F32 duration, F32 startAzimuth, F32 endAzimuth, F32 startElevation, F32 endElevation );

+ 4 - 4
Engine/source/environment/timeOfDay.cpp

@@ -378,7 +378,7 @@ F32 TimeOfDay::_calcAzimuth( F32 lat, F32 dec, F32 mer )
 	  return mAtan2( mSin(mer), mCos(mer) * mSin(lat) - mTan(dec) * mCos(lat) ) + M_PI_F;
 	  return mAtan2( mSin(mer), mCos(mer) * mSin(lat) - mTan(dec) * mCos(lat) ) + M_PI_F;
 }
 }
 
 
-void TimeOfDay::_getSunColor( ColorF *outColor ) const
+void TimeOfDay::_getSunColor( LinearColorF *outColor ) const
 {
 {
 	  const COLOR_TARGET *ct = NULL;
 	  const COLOR_TARGET *ct = NULL;
 
 
@@ -451,8 +451,8 @@ void TimeOfDay::_initColors()
    // NOTE: The elevation targets represent distances 
    // NOTE: The elevation targets represent distances 
    // from PI/2 radians (strait up).
    // from PI/2 radians (strait up).
 
 
-   ColorF c;
-   ColorF bc;
+   LinearColorF c;
+   LinearColorF bc;
 
 
    // e is for elevation
    // e is for elevation
    F32 e = M_PI_F / 13.0f; // (semicircle in radians)/(number of color target entries);
    F32 e = M_PI_F / 13.0f; // (semicircle in radians)/(number of color target entries);
@@ -495,7 +495,7 @@ void TimeOfDay::_initColors()
    _addColorTarget(M_PI_F, c, 1.0f, c); // Midnight at equanox.
    _addColorTarget(M_PI_F, c, 1.0f, c); // Midnight at equanox.
 }
 }
 
 
-void TimeOfDay::_addColorTarget( F32 ele, const ColorF &color, F32 bandMod, const ColorF &bandColor )
+void TimeOfDay::_addColorTarget( F32 ele, const LinearColorF &color, F32 bandMod, const LinearColorF &bandColor )
 {
 {
    COLOR_TARGET  newTarget;
    COLOR_TARGET  newTarget;
 
 

+ 7 - 7
Engine/source/environment/timeOfDay.h

@@ -34,9 +34,9 @@ class TimeOfDay;
 struct COLOR_TARGET
 struct COLOR_TARGET
 {
 {
 	F32		elevation; // maximum target elevation
 	F32		elevation; // maximum target elevation
-	ColorF	color; //normalized 0 = 1.0 ... 
+	LinearColorF	color; //normalized 0 = 1.0 ... 
 	F32		bandMod;  //6 is max
 	F32		bandMod;  //6 is max
-	ColorF	bandColor;
+	LinearColorF	bandColor;
 };
 };
 
 
 typedef Vector<COLOR_TARGET> COLOR_TARGETS;
 typedef Vector<COLOR_TARGET> COLOR_TARGETS;
@@ -108,7 +108,7 @@ public:
 	{ return (mCurrentColor.blue + mCurrentColor.green + mCurrentColor.red) / 3; }
 	{ return (mCurrentColor.blue + mCurrentColor.green + mCurrentColor.red) / 3; }
    */
    */
    static TimeOfDayUpdateSignal& getTimeOfDayUpdateSignal() { return smTimeOfDayUpdateSignal; } 
    static TimeOfDayUpdateSignal& getTimeOfDayUpdateSignal() { return smTimeOfDayUpdateSignal; } 
-   void getSunColor( ColorF *outColor ) const { _getSunColor( outColor ); }
+   void getSunColor( LinearColorF *outColor ) const { _getSunColor( outColor ); }
 
 
    void addTimeEvent( F32 triggerElevation, const UTF8 *identifier );
    void addTimeEvent( F32 triggerElevation, const UTF8 *identifier );
 
 
@@ -150,10 +150,10 @@ protected:
    /// @param color [in] target color.
    /// @param color [in] target color.
    /// @param bandMod [in]
    /// @param bandMod [in]
    /// @param bandColor [in]
    /// @param bandColor [in]
-   void _addColorTarget( F32 ele, const ColorF &color, F32 bandMod, const ColorF &bandColor );
+   void _addColorTarget( F32 ele, const LinearColorF &color, F32 bandMod, const LinearColorF &bandColor );
 
 
 	  // Grab our sun and sky colors based upon sun elevation.
 	  // Grab our sun and sky colors based upon sun elevation.
-   void _getSunColor( ColorF *outColor ) const;
+   void _getSunColor( LinearColorF *outColor ) const;
 
 
    static bool setTimeOfDay( void *object, const char *index, const char *data );
    static bool setTimeOfDay( void *object, const char *index, const char *data );
    static bool setPlay( void *object, const char *index, const char *data );
    static bool setPlay( void *object, const char *index, const char *data );
@@ -196,9 +196,9 @@ protected:
    bool mAnimate;
    bool mAnimate;
 
 
    /*
    /*
-	ColorF mCurrentColor;
+	LinearColorF mCurrentColor;
 	F32 mBandMod;
 	F32 mBandMod;
-	ColorF mCurrentBandColor;
+	LinearColorF mCurrentBandColor;
 
 
 	// PersistFields preparation
 	// PersistFields preparation
 	bool mConvertedToRads;	
 	bool mConvertedToRads;	

+ 1 - 1
Engine/source/environment/waterBlock.cpp

@@ -424,7 +424,7 @@ void WaterBlock::setShaderParams( SceneRenderState *state, BaseMatInstance *mat,
    // set pixel shader constants
    // set pixel shader constants
    //-----------------------------------
    //-----------------------------------
 
 
-   ColorF c( mWaterFogData.color );
+   LinearColorF c( mWaterFogData.color );
    matParams->setSafe( paramHandles.mBaseColorSC, c );
    matParams->setSafe( paramHandles.mBaseColorSC, c );
       
       
    // By default we need to show a true reflection is fullReflect is enabled and
    // By default we need to show a true reflection is fullReflect is enabled and

+ 8 - 8
Engine/source/environment/waterObject.cpp

@@ -1022,7 +1022,7 @@ void WaterObject::setShaderParams( SceneRenderState *state, BaseMatInstance *mat
    matParams->setSafe(paramHandles.mDistortionParamsSC, distortionParams );
    matParams->setSafe(paramHandles.mDistortionParamsSC, distortionParams );
 
 
    LightInfo *sun = LIGHTMGR->getSpecialLight(LightManager::slSunLightType);
    LightInfo *sun = LIGHTMGR->getSpecialLight(LightManager::slSunLightType);
-   const ColorF &sunlight = state->getAmbientLightColor();
+   const LinearColorF &sunlight = state->getAmbientLightColor();
    Point3F ambientColor = mEmissive ? Point3F::One : sunlight;
    Point3F ambientColor = mEmissive ? Point3F::One : sunlight;
    matParams->setSafe(paramHandles.mAmbientColorSC, ambientColor );
    matParams->setSafe(paramHandles.mAmbientColorSC, ambientColor );
    matParams->setSafe(paramHandles.mLightDirSC, sun->getDirection() );
    matParams->setSafe(paramHandles.mLightDirSC, sun->getDirection() );
@@ -1036,7 +1036,7 @@ void WaterObject::setShaderParams( SceneRenderState *state, BaseMatInstance *mat
    Point4F specularParams( mSpecularColor.red, mSpecularColor.green, mSpecularColor.blue, mSpecularPower );   
    Point4F specularParams( mSpecularColor.red, mSpecularColor.green, mSpecularColor.blue, mSpecularPower );   
    if ( !mEmissive )
    if ( !mEmissive )
    {
    {
-      const ColorF &sunColor = sun->getColor();
+      const LinearColorF &sunColor = sun->getColor();
       F32 brightness = sun->getBrightness();
       F32 brightness = sun->getBrightness();
       specularParams.x *= sunColor.red * brightness;
       specularParams.x *= sunColor.red * brightness;
       specularParams.y *= sunColor.green * brightness;
       specularParams.y *= sunColor.green * brightness;
@@ -1159,22 +1159,22 @@ bool WaterObject::initMaterial( S32 idx )
 void WaterObject::initTextures()
 void WaterObject::initTextures()
 {
 {
    if ( mRippleTexName.isNotEmpty() )
    if ( mRippleTexName.isNotEmpty() )
-      mRippleTex.set( mRippleTexName, &GFXDefaultStaticDiffuseProfile, "WaterObject::mRippleTex" );
+      mRippleTex.set( mRippleTexName, &GFXStaticTextureSRGBProfile, "WaterObject::mRippleTex" );
    if ( mRippleTex.isNull() )
    if ( mRippleTex.isNull() )
-      mRippleTex.set( GFXTextureManager::getWarningTexturePath(), &GFXDefaultStaticDiffuseProfile, "WaterObject::mRippleTex" );
+      mRippleTex.set( GFXTextureManager::getWarningTexturePath(), &GFXStaticTextureSRGBProfile, "WaterObject::mRippleTex" );
 
 
    if ( mDepthGradientTexName.isNotEmpty() )
    if ( mDepthGradientTexName.isNotEmpty() )
-      mDepthGradientTex.set( mDepthGradientTexName, &GFXDefaultStaticDiffuseProfile, "WaterObject::mDepthGradientTex" );
+      mDepthGradientTex.set( mDepthGradientTexName, &GFXStaticTextureSRGBProfile, "WaterObject::mDepthGradientTex" );
    if ( mDepthGradientTex.isNull() )
    if ( mDepthGradientTex.isNull() )
-      mDepthGradientTex.set( GFXTextureManager::getWarningTexturePath(), &GFXDefaultStaticDiffuseProfile, "WaterObject::mDepthGradientTex" );
+      mDepthGradientTex.set( GFXTextureManager::getWarningTexturePath(), &GFXStaticTextureSRGBProfile, "WaterObject::mDepthGradientTex" );
    
    
    if ( mNamedDepthGradTex.isRegistered() )
    if ( mNamedDepthGradTex.isRegistered() )
       mNamedDepthGradTex.setTexture( mDepthGradientTex );
       mNamedDepthGradTex.setTexture( mDepthGradientTex );
 
 
    if ( mFoamTexName.isNotEmpty() )
    if ( mFoamTexName.isNotEmpty() )
-      mFoamTex.set( mFoamTexName, &GFXDefaultStaticDiffuseProfile, "WaterObject::mFoamTex" );
+      mFoamTex.set( mFoamTexName, &GFXStaticTextureSRGBProfile, "WaterObject::mFoamTex" );
    if ( mFoamTex.isNull() )
    if ( mFoamTex.isNull() )
-      mFoamTex.set( GFXTextureManager::getWarningTexturePath(), &GFXDefaultStaticDiffuseProfile, "WaterObject::mFoamTex" );
+      mFoamTex.set( GFXTextureManager::getWarningTexturePath(), &GFXStaticTextureSRGBProfile, "WaterObject::mFoamTex" );
 
 
    if ( mCubemapName.isNotEmpty() )
    if ( mCubemapName.isNotEmpty() )
       Sim::findObject( mCubemapName, mCubemap );   
       Sim::findObject( mCubemapName, mCubemap );   

+ 1 - 1
Engine/source/environment/waterObject.h

@@ -212,7 +212,7 @@ protected:
    F32 mFresnelBias;
    F32 mFresnelBias;
    F32 mFresnelPower;
    F32 mFresnelPower;
    F32 mSpecularPower;
    F32 mSpecularPower;
-   ColorF mSpecularColor;
+   LinearColorF mSpecularColor;
    bool mEmissive;
    bool mEmissive;
 
 
    // Reflection
    // Reflection

+ 1 - 1
Engine/source/environment/waterPlane.cpp

@@ -664,7 +664,7 @@ void WaterPlane::setShaderParams( SceneRenderState *state, BaseMatInstance* mat,
    // set pixel shader constants
    // set pixel shader constants
    //-----------------------------------
    //-----------------------------------
 
 
-   ColorF c( mWaterFogData.color );
+   LinearColorF c( mWaterFogData.color );
    matParams->setSafe( paramHandles.mBaseColorSC, c );   
    matParams->setSafe( paramHandles.mBaseColorSC, c );   
    
    
    // By default we need to show a true reflection is fullReflect is enabled and
    // By default we need to show a true reflection is fullReflect is enabled and

+ 52 - 32
Engine/source/gfx/D3D11/gfxD3D11Cubemap.cpp

@@ -24,6 +24,7 @@
 #include "gfx/gfxCardProfile.h"
 #include "gfx/gfxCardProfile.h"
 #include "gfx/gfxTextureManager.h"
 #include "gfx/gfxTextureManager.h"
 #include "gfx/D3D11/gfxD3D11EnumTranslate.h"
 #include "gfx/D3D11/gfxD3D11EnumTranslate.h"
+#include "gfx/bitmap/imageUtils.h"
 
 
 GFXD3D11Cubemap::GFXD3D11Cubemap() : mTexture(NULL), mSRView(NULL), mDSView(NULL)
 GFXD3D11Cubemap::GFXD3D11Cubemap() : mTexture(NULL), mSRView(NULL), mDSView(NULL)
 {
 {
@@ -65,14 +66,6 @@ void GFXD3D11Cubemap::_onTextureEvent(GFXTexCallbackCode code)
       initDynamic(mTexSize);
       initDynamic(mTexSize);
 }
 }
 
 
-bool GFXD3D11Cubemap::isCompressed(GFXFormat format)
-{
-   if (format >= GFXFormatDXT1 && format <= GFXFormatDXT5)
-      return true;
-
-   return false;
-}
-
 void GFXD3D11Cubemap::initStatic(GFXTexHandle *faces)
 void GFXD3D11Cubemap::initStatic(GFXTexHandle *faces)
 {
 {
    AssertFatal( faces, "GFXD3D11Cubemap::initStatic - Got null GFXTexHandle!" );
    AssertFatal( faces, "GFXD3D11Cubemap::initStatic - Got null GFXTexHandle!" );
@@ -81,7 +74,7 @@ void GFXD3D11Cubemap::initStatic(GFXTexHandle *faces)
 	// NOTE - check tex sizes on all faces - they MUST be all same size
 	// NOTE - check tex sizes on all faces - they MUST be all same size
 	mTexSize = faces->getWidth();
 	mTexSize = faces->getWidth();
 	mFaceFormat = faces->getFormat();
 	mFaceFormat = faces->getFormat();
-   bool compressed = isCompressed(mFaceFormat);
+   bool compressed = ImageUtil::isCompressedFormat(mFaceFormat);
 
 
    UINT bindFlags = D3D11_BIND_SHADER_RESOURCE;
    UINT bindFlags = D3D11_BIND_SHADER_RESOURCE;
    UINT miscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
    UINT miscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
@@ -91,15 +84,15 @@ void GFXD3D11Cubemap::initStatic(GFXTexHandle *faces)
       miscFlags |= D3D11_RESOURCE_MISC_GENERATE_MIPS;
       miscFlags |= D3D11_RESOURCE_MISC_GENERATE_MIPS;
    }
    }
 
 
-   U32 mipLevels = faces->getPointer()->getMipLevels();
-   if (mipLevels > 1 && !compressed)
+   mMipMapLevels = faces->getPointer()->getMipLevels();
+   if (mMipMapLevels < 1 && !compressed)
       mAutoGenMips = true;
       mAutoGenMips = true;
 
 
 	D3D11_TEXTURE2D_DESC desc;
 	D3D11_TEXTURE2D_DESC desc;
 	ZeroMemory(&desc, sizeof(D3D11_TEXTURE2D_DESC));
 	ZeroMemory(&desc, sizeof(D3D11_TEXTURE2D_DESC));
 	desc.Width = mTexSize;
 	desc.Width = mTexSize;
 	desc.Height = mTexSize;
 	desc.Height = mTexSize;
-   desc.MipLevels = mAutoGenMips ? 0 : mipLevels;
+   desc.MipLevels = mAutoGenMips ? 0 : mMipMapLevels;
 	desc.ArraySize = 6;
 	desc.ArraySize = 6;
 	desc.Format = GFXD3D11TextureFormat[mFaceFormat];
 	desc.Format = GFXD3D11TextureFormat[mFaceFormat];
 	desc.SampleDesc.Count = 1;
 	desc.SampleDesc.Count = 1;
@@ -113,15 +106,15 @@ void GFXD3D11Cubemap::initStatic(GFXTexHandle *faces)
 
 
 	if (FAILED(hr))
 	if (FAILED(hr))
 	{
 	{
-		AssertFatal(false, "GFXD3D11Cubemap:initStatic(GFXTexhandle *faces) - failed to create texcube texture");
+		AssertFatal(false, "GFXD3D11Cubemap:initStatic(GFXTexhandle *faces) - CreateTexture2D failure");
 	}
 	}
    
    
    for (U32 i = 0; i < CubeFaces; i++)
    for (U32 i = 0; i < CubeFaces; i++)
    {
    {
       GFXD3D11TextureObject *texObj = static_cast<GFXD3D11TextureObject*>((GFXTextureObject*)faces[i]);
       GFXD3D11TextureObject *texObj = static_cast<GFXD3D11TextureObject*>((GFXTextureObject*)faces[i]);
-      for (U32 currentMip = 0; currentMip < mipLevels; currentMip++)
+      for (U32 currentMip = 0; currentMip < mMipMapLevels; currentMip++)
       {
       {
-         U32 subResource = D3D11CalcSubresource(currentMip, i, mipLevels);
+         U32 subResource = D3D11CalcSubresource(currentMip, i, mMipMapLevels);
          D3D11DEVICECONTEXT->CopySubresourceRegion(mTexture, subResource, 0, 0, 0, texObj->get2DTex(), currentMip, NULL);
          D3D11DEVICECONTEXT->CopySubresourceRegion(mTexture, subResource, 0, 0, 0, texObj->get2DTex(), currentMip, NULL);
       }
       }
    }
    }
@@ -129,7 +122,7 @@ void GFXD3D11Cubemap::initStatic(GFXTexHandle *faces)
 	D3D11_SHADER_RESOURCE_VIEW_DESC SMViewDesc;
 	D3D11_SHADER_RESOURCE_VIEW_DESC SMViewDesc;
 	SMViewDesc.Format = GFXD3D11TextureFormat[mFaceFormat];
 	SMViewDesc.Format = GFXD3D11TextureFormat[mFaceFormat];
 	SMViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
 	SMViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
-   SMViewDesc.TextureCube.MipLevels = mAutoGenMips ? -1 : mipLevels;
+   SMViewDesc.TextureCube.MipLevels = mAutoGenMips ? -1 : mMipMapLevels;
 	SMViewDesc.TextureCube.MostDetailedMip = 0;
 	SMViewDesc.TextureCube.MostDetailedMip = 0;
 
 
 	hr = D3D11DEVICE->CreateShaderResourceView(mTexture, &SMViewDesc, &mSRView);
 	hr = D3D11DEVICE->CreateShaderResourceView(mTexture, &SMViewDesc, &mSRView);
@@ -138,8 +131,16 @@ void GFXD3D11Cubemap::initStatic(GFXTexHandle *faces)
 		AssertFatal(false, "GFXD3D11Cubemap::initStatic(GFXTexHandle *faces) - texcube shader resource view  creation failure");
 		AssertFatal(false, "GFXD3D11Cubemap::initStatic(GFXTexHandle *faces) - texcube shader resource view  creation failure");
 	} 
 	} 
 
 
+   //Generate mips
    if (mAutoGenMips && !compressed)
    if (mAutoGenMips && !compressed)
+   {
       D3D11DEVICECONTEXT->GenerateMips(mSRView);
       D3D11DEVICECONTEXT->GenerateMips(mSRView);
+      //get mip level count
+      D3D11_SHADER_RESOURCE_VIEW_DESC viewDesc;
+      mSRView->GetDesc(&viewDesc);
+      mMipMapLevels = viewDesc.TextureCube.MipLevels;
+   }
+
 }
 }
 
 
 void GFXD3D11Cubemap::initStatic(DDSFile *dds)
 void GFXD3D11Cubemap::initStatic(DDSFile *dds)
@@ -151,45 +152,53 @@ void GFXD3D11Cubemap::initStatic(DDSFile *dds)
    // NOTE - check tex sizes on all faces - they MUST be all same size
    // NOTE - check tex sizes on all faces - they MUST be all same size
    mTexSize = dds->getWidth();
    mTexSize = dds->getWidth();
    mFaceFormat = dds->getFormat();
    mFaceFormat = dds->getFormat();
-   U32 levels = dds->getMipLevels();
+   mMipMapLevels = dds->getMipLevels();
 
 
 	D3D11_TEXTURE2D_DESC desc;
 	D3D11_TEXTURE2D_DESC desc;
 
 
 	desc.Width = mTexSize;
 	desc.Width = mTexSize;
 	desc.Height = mTexSize;
 	desc.Height = mTexSize;
-	desc.MipLevels = levels;
-	desc.ArraySize = 6;
+   desc.MipLevels = mMipMapLevels;
+	desc.ArraySize = CubeFaces;
 	desc.Format = GFXD3D11TextureFormat[mFaceFormat];
 	desc.Format = GFXD3D11TextureFormat[mFaceFormat];
 	desc.SampleDesc.Count = 1;
 	desc.SampleDesc.Count = 1;
 	desc.SampleDesc.Quality = 0;
 	desc.SampleDesc.Quality = 0;
 	desc.Usage = D3D11_USAGE_IMMUTABLE;
 	desc.Usage = D3D11_USAGE_IMMUTABLE;
 	desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
 	desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
-	desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
-	desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE | D3D11_RESOURCE_MISC_GENERATE_MIPS;
-
-	D3D11_SUBRESOURCE_DATA* pData = new D3D11_SUBRESOURCE_DATA[6 + levels];
+	desc.CPUAccessFlags = 0;
+	desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
 
 
-   for (U32 i = 0; i<CubeFaces; i++)
+	D3D11_SUBRESOURCE_DATA* pData = new D3D11_SUBRESOURCE_DATA[CubeFaces * mMipMapLevels];
+   for (U32 currentFace = 0; currentFace < CubeFaces; currentFace++)
 	{
 	{
-		if (!dds->mSurfaces[i])
+		if (!dds->mSurfaces[currentFace])
 			continue;
 			continue;
 
 
-		for(U32 j = 0; j < levels; j++)
+      // convert to Z up
+      const U32 faceIndex = _zUpFaceIndex(currentFace);
+
+		for(U32 currentMip = 0; currentMip < mMipMapLevels; currentMip++)
 		{
 		{
-			pData[i + j].pSysMem = dds->mSurfaces[i]->mMips[j];
-			pData[i + j].SysMemPitch = dds->getSurfacePitch(j);
-			pData[i + j].SysMemSlicePitch = dds->getSurfaceSize(j);
+         const U32 dataIndex = faceIndex * mMipMapLevels + currentMip;
+			pData[dataIndex].pSysMem = dds->mSurfaces[currentFace]->mMips[currentMip];
+			pData[dataIndex].SysMemPitch = dds->getSurfacePitch(currentMip);
+         pData[dataIndex].SysMemSlicePitch = 0;
 		}
 		}
+
 	}
 	}
 
 
-	HRESULT hr = D3D11DEVICE->CreateTexture2D(&desc, pData, &mTexture);
+   HRESULT hr = D3D11DEVICE->CreateTexture2D(&desc, pData, &mTexture);
+   if (FAILED(hr))
+   {
+      AssertFatal(false, "GFXD3D11Cubemap::initStatic(DDSFile *dds) - CreateTexture2D failure");
+   }
 
 
 	delete [] pData;
 	delete [] pData;
 
 
 	D3D11_SHADER_RESOURCE_VIEW_DESC SMViewDesc;
 	D3D11_SHADER_RESOURCE_VIEW_DESC SMViewDesc;
 	SMViewDesc.Format = GFXD3D11TextureFormat[mFaceFormat];
 	SMViewDesc.Format = GFXD3D11TextureFormat[mFaceFormat];
 	SMViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
 	SMViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
-	SMViewDesc.TextureCube.MipLevels =  levels;
+	SMViewDesc.TextureCube.MipLevels = mMipMapLevels;
 	SMViewDesc.TextureCube.MostDetailedMip = 0;
 	SMViewDesc.TextureCube.MostDetailedMip = 0;
 
 
 	hr = D3D11DEVICE->CreateShaderResourceView(mTexture, &SMViewDesc, &mSRView);
 	hr = D3D11DEVICE->CreateShaderResourceView(mTexture, &SMViewDesc, &mSRView);
@@ -209,7 +218,8 @@ void GFXD3D11Cubemap::initDynamic(U32 texSize, GFXFormat faceFormat)
    mAutoGenMips = true;
    mAutoGenMips = true;
 	mTexSize = texSize;
 	mTexSize = texSize;
 	mFaceFormat = faceFormat;
 	mFaceFormat = faceFormat;
-   bool compressed = isCompressed(mFaceFormat);
+   mMipMapLevels = 0;
+   bool compressed = ImageUtil::isCompressedFormat(mFaceFormat);
 
 
    UINT bindFlags = D3D11_BIND_SHADER_RESOURCE;
    UINT bindFlags = D3D11_BIND_SHADER_RESOURCE;
    UINT miscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
    UINT miscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
@@ -250,6 +260,16 @@ void GFXD3D11Cubemap::initDynamic(U32 texSize, GFXFormat faceFormat)
 		AssertFatal(false, "GFXD3D11Cubemap::initDynamic - CreateTexture2D call failure");
 		AssertFatal(false, "GFXD3D11Cubemap::initDynamic - CreateTexture2D call failure");
 	}
 	}
 
 
+   //Generate mips
+   if (mAutoGenMips && !compressed)
+   {
+      D3D11DEVICECONTEXT->GenerateMips(mSRView);
+      //get mip level count
+      D3D11_SHADER_RESOURCE_VIEW_DESC viewDesc;
+      mSRView->GetDesc(&viewDesc);
+      mMipMapLevels = viewDesc.TextureCube.MipLevels;
+   }
+
    D3D11_RENDER_TARGET_VIEW_DESC viewDesc;
    D3D11_RENDER_TARGET_VIEW_DESC viewDesc;
 	viewDesc.Format = desc.Format;
 	viewDesc.Format = desc.Format;
 	viewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
 	viewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;

+ 0 - 1
Engine/source/gfx/D3D11/gfxD3D11Cubemap.h

@@ -71,7 +71,6 @@ private:
    
    
    void releaseSurfaces();
    void releaseSurfaces();
 
 
-   bool isCompressed(GFXFormat format);
    /// The callback used to get texture events.
    /// The callback used to get texture events.
    /// @see GFXTextureManager::addEventDelegate
    /// @see GFXTextureManager::addEventDelegate
    void _onTextureEvent(GFXTexCallbackCode code);
    void _onTextureEvent(GFXTexCallbackCode code);

+ 257 - 109
Engine/source/gfx/D3D11/gfxD3D11Device.cpp

@@ -45,14 +45,6 @@
 #pragma comment(lib, "dxgi.lib")
 #pragma comment(lib, "dxgi.lib")
 #pragma comment(lib, "d3d11.lib")
 #pragma comment(lib, "d3d11.lib")
 
 
-GFXAdapter::CreateDeviceInstanceDelegate GFXD3D11Device::mCreateDeviceInstance(GFXD3D11Device::createInstance);
-
-GFXDevice *GFXD3D11Device::createInstance(U32 adapterIndex)
-{
-   GFXD3D11Device* dev = new GFXD3D11Device(adapterIndex);
-   return dev;
-}
-
 class GFXPCD3D11RegisterDevice
 class GFXPCD3D11RegisterDevice
 {
 {
 public:
 public:
@@ -79,6 +71,14 @@ static void sgPCD3D11DeviceHandleCommandLine(S32 argc, const char **argv)
 // Register the command line parsing hook
 // Register the command line parsing hook
 static ProcessRegisterCommandLine sgCommandLine(sgPCD3D11DeviceHandleCommandLine);
 static ProcessRegisterCommandLine sgCommandLine(sgPCD3D11DeviceHandleCommandLine);
 
 
+GFXAdapter::CreateDeviceInstanceDelegate GFXD3D11Device::mCreateDeviceInstance(GFXD3D11Device::createInstance);
+
+GFXDevice *GFXD3D11Device::createInstance(U32 adapterIndex)
+{
+   GFXD3D11Device* dev = new GFXD3D11Device(adapterIndex);
+   return dev;
+}
+
 GFXD3D11Device::GFXD3D11Device(U32 index)
 GFXD3D11Device::GFXD3D11Device(U32 index)
 {
 {
    mDeviceSwizzle32 = &Swizzles::bgra;
    mDeviceSwizzle32 = &Swizzles::bgra;
@@ -88,6 +88,9 @@ GFXD3D11Device::GFXD3D11Device(U32 index)
 
 
    mAdapterIndex = index;
    mAdapterIndex = index;
    mD3DDevice = NULL;
    mD3DDevice = NULL;
+   mD3DDeviceContext = NULL;
+   mD3DDevice1 = NULL;
+   mD3DDeviceContext1 = NULL;
    mUserAnnotation = NULL;
    mUserAnnotation = NULL;
    mVolatileVB = NULL;
    mVolatileVB = NULL;
 
 
@@ -122,6 +125,7 @@ GFXD3D11Device::GFXD3D11Device(U32 index)
    mCurrentConstBuffer = NULL;
    mCurrentConstBuffer = NULL;
 
 
    mOcclusionQuerySupported = false;
    mOcclusionQuerySupported = false;
+   mCbufferPartialSupported = false;
 
 
    mDebugLayers = false;
    mDebugLayers = false;
 
 
@@ -149,7 +153,7 @@ GFXD3D11Device::~GFXD3D11Device()
 
 
    // Free the vertex declarations.
    // Free the vertex declarations.
    VertexDeclMap::Iterator iter = mVertexDecls.begin();
    VertexDeclMap::Iterator iter = mVertexDecls.begin();
-   for (; iter != mVertexDecls.end(); iter++)
+   for (; iter != mVertexDecls.end(); ++iter)
       delete iter->value;
       delete iter->value;
 
 
    // Forcibly clean up the pools
    // Forcibly clean up the pools
@@ -162,6 +166,7 @@ GFXD3D11Device::~GFXD3D11Device()
    SAFE_RELEASE(mDeviceDepthStencil);
    SAFE_RELEASE(mDeviceDepthStencil);
    SAFE_RELEASE(mDeviceBackbuffer);
    SAFE_RELEASE(mDeviceBackbuffer);
    SAFE_RELEASE(mUserAnnotation);
    SAFE_RELEASE(mUserAnnotation);
+   SAFE_RELEASE(mD3DDeviceContext1);
    SAFE_RELEASE(mD3DDeviceContext);
    SAFE_RELEASE(mD3DDeviceContext);
 
 
    SAFE_DELETE(mCardProfiler);
    SAFE_DELETE(mCardProfiler);
@@ -179,6 +184,7 @@ GFXD3D11Device::~GFXD3D11Device()
 #endif
 #endif
 
 
    SAFE_RELEASE(mSwapChain);
    SAFE_RELEASE(mSwapChain);
+   SAFE_RELEASE(mD3DDevice1);
    SAFE_RELEASE(mD3DDevice);
    SAFE_RELEASE(mD3DDevice);
 }
 }
 
 
@@ -220,7 +226,7 @@ DXGI_SWAP_CHAIN_DESC GFXD3D11Device::setupPresentParams(const GFXVideoMode &mode
    d3dpp.BufferCount = !smDisableVSync ? 2 : 1; // triple buffering when vsync is on.
    d3dpp.BufferCount = !smDisableVSync ? 2 : 1; // triple buffering when vsync is on.
    d3dpp.BufferDesc.Width = mode.resolution.x;
    d3dpp.BufferDesc.Width = mode.resolution.x;
    d3dpp.BufferDesc.Height = mode.resolution.y;
    d3dpp.BufferDesc.Height = mode.resolution.y;
-   d3dpp.BufferDesc.Format = GFXD3D11TextureFormat[GFXFormatR8G8B8A8];
+   d3dpp.BufferDesc.Format = GFXD3D11TextureFormat[GFXFormatR8G8B8A8_SRGB];
    d3dpp.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    d3dpp.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    d3dpp.OutputWindow = hwnd;
    d3dpp.OutputWindow = hwnd;
    d3dpp.SampleDesc = sampleDesc;
    d3dpp.SampleDesc = sampleDesc;
@@ -287,7 +293,7 @@ void GFXD3D11Device::enumerateAdapters(Vector<GFXAdapter*> &adapterList)
 
 
       UINT numModes = 0;
       UINT numModes = 0;
       DXGI_MODE_DESC* displayModes = NULL;
       DXGI_MODE_DESC* displayModes = NULL;
-      DXGI_FORMAT format = DXGI_FORMAT_B8G8R8A8_UNORM;
+      DXGI_FORMAT format = GFXD3D11TextureFormat[GFXFormatR8G8B8A8_SRGB];
 
 
       // Get the number of elements
       // Get the number of elements
       hr = pOutput->GetDisplayModeList(format, 0, &numModes, NULL);
       hr = pOutput->GetDisplayModeList(format, 0, &numModes, NULL);
@@ -391,7 +397,7 @@ void GFXD3D11Device::enumerateVideoModes()
 
 
       UINT numModes = 0;
       UINT numModes = 0;
       DXGI_MODE_DESC* displayModes = NULL;
       DXGI_MODE_DESC* displayModes = NULL;
-      DXGI_FORMAT format = GFXD3D11TextureFormat[GFXFormatR8G8B8A8];
+      DXGI_FORMAT format = GFXD3D11TextureFormat[GFXFormatR8G8B8A8_SRGB];
 
 
       // Get the number of elements
       // Get the number of elements
       hr = pOutput->GetDisplayModeList(format, 0, &numModes, NULL);
       hr = pOutput->GetDisplayModeList(format, 0, &numModes, NULL);
@@ -430,8 +436,8 @@ void GFXD3D11Device::enumerateVideoModes()
 void GFXD3D11Device::init(const GFXVideoMode &mode, PlatformWindow *window)
 void GFXD3D11Device::init(const GFXVideoMode &mode, PlatformWindow *window)
 {
 {
    AssertFatal(window, "GFXD3D11Device::init - must specify a window!");
    AssertFatal(window, "GFXD3D11Device::init - must specify a window!");
-   HWND hwnd = (HWND)window->getSystemWindow(PlatformWindow::WindowSystem_Windows);
-   SetFocus(hwnd);//ensure window has focus
+
+   HWND winHwnd = (HWND)window->getSystemWindow( PlatformWindow::WindowSystem_Windows );
 
 
    UINT createDeviceFlags = D3D11_CREATE_DEVICE_SINGLETHREADED | D3D11_CREATE_DEVICE_BGRA_SUPPORT;
    UINT createDeviceFlags = D3D11_CREATE_DEVICE_SINGLETHREADED | D3D11_CREATE_DEVICE_BGRA_SUPPORT;
 #ifdef TORQUE_DEBUG
 #ifdef TORQUE_DEBUG
@@ -439,48 +445,78 @@ void GFXD3D11Device::init(const GFXVideoMode &mode, PlatformWindow *window)
    mDebugLayers = true;
    mDebugLayers = true;
 #endif
 #endif
 
 
+   DXGI_SWAP_CHAIN_DESC d3dpp = setupPresentParams(mode, winHwnd);
+
+   // TODO support at least feature level 10 to match GL
+   D3D_FEATURE_LEVEL pFeatureLevels[] = { D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0 };
+   U32 nFeatureCount = ARRAYSIZE(pFeatureLevels);
    D3D_DRIVER_TYPE driverType = D3D_DRIVER_TYPE_HARDWARE;// use D3D_DRIVER_TYPE_REFERENCE for reference device
    D3D_DRIVER_TYPE driverType = D3D_DRIVER_TYPE_HARDWARE;// use D3D_DRIVER_TYPE_REFERENCE for reference device
-   // create a device & device context
-   HRESULT hres = D3D11CreateDevice(NULL,
-                                    driverType,
-                                    NULL,
-                                    createDeviceFlags,
-                                    NULL,
-                                    0,
-                                    D3D11_SDK_VERSION,
-                                    &mD3DDevice,
-                                    &mFeatureLevel,
-                                    &mD3DDeviceContext);
+   // create a device, device context and swap chain using the information in the d3dpp struct
+   HRESULT hres = D3D11CreateDeviceAndSwapChain(NULL,
+                                 driverType,
+                                 NULL,
+                                 createDeviceFlags,
+											pFeatureLevels,
+                                 nFeatureCount,
+                                 D3D11_SDK_VERSION,
+                                 &d3dpp,
+                                 &mSwapChain,
+                                 &mD3DDevice,
+                                 &mFeatureLevel,
+                                 &mD3DDeviceContext);
 
 
    if(FAILED(hres))
    if(FAILED(hres))
    {
    {
       #ifdef TORQUE_DEBUG
       #ifdef TORQUE_DEBUG
-         //try again without debug device layer enabled
-         createDeviceFlags &= ~D3D11_CREATE_DEVICE_DEBUG;
-         hres = D3D11CreateDevice(NULL,
-                                  driverType,
-                                  NULL,
-                                  createDeviceFlags,
-                                  NULL,
-                                  0,
-                                  D3D11_SDK_VERSION,
-                                  &mD3DDevice,
-                                  &mFeatureLevel,
-                                  &mD3DDeviceContext);
-         //if we failed again than we definitely have a problem
-         if (FAILED(hres))
-            AssertFatal(false, "GFXD3D11Device::init - D3D11CreateDeviceAndSwapChain failed!");
-
-         Con::warnf("GFXD3D11Device::init - Debug layers not detected!");
-         mDebugLayers = false;
-      #else
+      //try again without debug device layer enabled
+      createDeviceFlags &= ~D3D11_CREATE_DEVICE_DEBUG;
+      hres = D3D11CreateDeviceAndSwapChain(NULL, driverType,NULL,createDeviceFlags,NULL, 0,
+         D3D11_SDK_VERSION,
+         &d3dpp,
+         &mSwapChain,
+         &mD3DDevice,
+         &mFeatureLevel,
+         &mD3DDeviceContext);
+      //if we failed again than we definitely have a problem
+      if (FAILED(hres))
          AssertFatal(false, "GFXD3D11Device::init - D3D11CreateDeviceAndSwapChain failed!");
          AssertFatal(false, "GFXD3D11Device::init - D3D11CreateDeviceAndSwapChain failed!");
+
+      Con::warnf("GFXD3D11Device::init - Debug layers not detected!");
+      mDebugLayers = false;
+      #else
+      AssertFatal(false, "GFXD3D11Device::init - D3D11CreateDeviceAndSwapChain failed!");
       #endif
       #endif
    }
    }
 
 
-#ifdef TORQUE_DEBUG
-   _suppressDebugMessages();
-#endif
+   // Grab DX 11.1 device and context if available and also ID3DUserDefinedAnnotation
+   hres = mD3DDevice->QueryInterface(__uuidof(ID3D11Device1), reinterpret_cast<void**>(&mD3DDevice1));
+   if (SUCCEEDED(hres))
+   {
+      //11.1 context
+      mD3DDeviceContext->QueryInterface(__uuidof(ID3D11DeviceContext1), reinterpret_cast<void**>(&mD3DDeviceContext1));
+      // ID3DUserDefinedAnnotation
+      mD3DDeviceContext->QueryInterface(IID_PPV_ARGS(&mUserAnnotation));
+      //Check what is supported, windows 7 supports very little from 11.1
+      D3D11_FEATURE_DATA_D3D11_OPTIONS options;
+      mD3DDevice1->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS, &options,
+         sizeof(D3D11_FEATURE_DATA_D3D11_OPTIONS));
+
+      //Cbuffer partial updates
+      if (options.ConstantBufferOffsetting && options.ConstantBufferPartialUpdate)
+         mCbufferPartialSupported = true;
+   }
+
+
+
+   //set the fullscreen state here if we need to
+   if(mode.fullScreen)
+   {
+      hres = mSwapChain->SetFullscreenState(TRUE, NULL);
+      if(FAILED(hres))
+      {
+         AssertFatal(false, "GFXD3D11Device::init- Failed to set fullscreen state!");
+      }
+   }
 
 
    mTextureManager = new GFXD3D11TextureManager();
    mTextureManager = new GFXD3D11TextureManager();
 
 
@@ -489,6 +525,7 @@ void GFXD3D11Device::init(const GFXVideoMode &mode, PlatformWindow *window)
    //set vert/pixel shader targets
    //set vert/pixel shader targets
    switch (mFeatureLevel)
    switch (mFeatureLevel)
    {
    {
+   case D3D_FEATURE_LEVEL_11_1:
    case D3D_FEATURE_LEVEL_11_0:
    case D3D_FEATURE_LEVEL_11_0:
       mVertexShaderTarget = "vs_5_0";
       mVertexShaderTarget = "vs_5_0";
       mPixelShaderTarget = "ps_5_0";
       mPixelShaderTarget = "ps_5_0";
@@ -527,6 +564,68 @@ void GFXD3D11Device::init(const GFXVideoMode &mode, PlatformWindow *window)
    mCardProfiler = new GFXD3D11CardProfiler();
    mCardProfiler = new GFXD3D11CardProfiler();
    mCardProfiler->init();
    mCardProfiler->init();
 
 
+   D3D11_TEXTURE2D_DESC desc;
+   desc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
+   desc.CPUAccessFlags = 0;
+   desc.Format = GFXD3D11TextureFormat[GFXFormatD24S8];
+   desc.MipLevels = 1;
+   desc.ArraySize = 1;
+   desc.Usage = D3D11_USAGE_DEFAULT;
+   desc.Width = mode.resolution.x;
+   desc.Height = mode.resolution.y;
+   desc.SampleDesc.Count =1;
+   desc.SampleDesc.Quality =0;
+   desc.MiscFlags = 0;
+
+   HRESULT hr = mD3DDevice->CreateTexture2D(&desc, NULL, &mDeviceDepthStencil);
+   if(FAILED(hr)) 
+   {
+      AssertFatal(false, "GFXD3D11Device::init - couldn't create device's depth-stencil surface.");
+   }
+
+   D3D11_DEPTH_STENCIL_VIEW_DESC depthDesc;
+   depthDesc.Format = GFXD3D11TextureFormat[GFXFormatD24S8];
+   depthDesc.Flags =0 ;
+   depthDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
+   depthDesc.Texture2D.MipSlice = 0;
+
+   hr = mD3DDevice->CreateDepthStencilView(mDeviceDepthStencil, &depthDesc, &mDeviceDepthStencilView);
+
+   if(FAILED(hr))
+   {
+      AssertFatal(false, "GFXD3D11Device::init - couldn't create depth stencil view");
+   }
+
+   hr = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&mDeviceBackbuffer);
+   if(FAILED(hr))
+     AssertFatal(false, "GFXD3D11Device::init - coudln't retrieve backbuffer ref");
+
+   //create back buffer view
+   D3D11_RENDER_TARGET_VIEW_DESC RTDesc;
+
+   RTDesc.Format = GFXD3D11TextureFormat[GFXFormatR8G8B8A8_SRGB];
+   RTDesc.Texture2D.MipSlice = 0;
+   RTDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
+
+   hr = mD3DDevice->CreateRenderTargetView(mDeviceBackbuffer, &RTDesc, &mDeviceBackBufferView);
+
+   if(FAILED(hr))
+       AssertFatal(false, "GFXD3D11Device::init - couldn't create back buffer target view");
+
+#ifdef TORQUE_DEBUG
+   String backBufferName = "MainBackBuffer";
+   String depthSteniclName = "MainDepthStencil";
+   String backBuffViewName = "MainBackBuffView";
+   String depthStencViewName = "MainDepthView";
+   mDeviceBackbuffer->SetPrivateData(WKPDID_D3DDebugObjectName, backBufferName.size(), backBufferName.c_str());
+   mDeviceDepthStencil->SetPrivateData(WKPDID_D3DDebugObjectName, depthSteniclName.size(), depthSteniclName.c_str());
+   mDeviceDepthStencilView->SetPrivateData(WKPDID_D3DDebugObjectName, depthStencViewName.size(), depthStencViewName.c_str());
+   mDeviceBackBufferView->SetPrivateData(WKPDID_D3DDebugObjectName, backBuffViewName.size(), backBuffViewName.c_str());
+
+   _suppressDebugMessages();
+
+#endif
+
    gScreenShot = new ScreenShotD3D11;
    gScreenShot = new ScreenShotD3D11;
 
 
    mInitialized = true;
    mInitialized = true;
@@ -576,35 +675,14 @@ GFXWindowTarget * GFXD3D11Device::allocWindowTarget(PlatformWindow *window)
 {
 {
    AssertFatal(window,"GFXD3D11Device::allocWindowTarget - no window provided!");
    AssertFatal(window,"GFXD3D11Device::allocWindowTarget - no window provided!");
 
 
+   // Allocate the device.
+   init(window->getVideoMode(), window);
+
    // Set up a new window target...
    // Set up a new window target...
    GFXD3D11WindowTarget *gdwt = new GFXD3D11WindowTarget();
    GFXD3D11WindowTarget *gdwt = new GFXD3D11WindowTarget();
    gdwt->mWindow = window;
    gdwt->mWindow = window;
    gdwt->mSize = window->getClientExtent();
    gdwt->mSize = window->getClientExtent();
-   
-   if (!mInitialized)
-   {
-      gdwt->mSecondaryWindow = false;
-      // Allocate the device.
-      init(window->getVideoMode(), window);
-      gdwt->initPresentationParams();
-      gdwt->createSwapChain();
-      gdwt->createBuffersAndViews();
-
-      mSwapChain = gdwt->getSwapChain();
-      mDeviceBackbuffer = gdwt->getBackBuffer();
-      mDeviceDepthStencil = gdwt->getDepthStencil();
-      mDeviceBackBufferView = gdwt->getBackBufferView();
-      mDeviceDepthStencilView = gdwt->getDepthStencilView();
-
-   }
-   else //additional window/s
-   {
-      gdwt->mSecondaryWindow = true;
-      gdwt->initPresentationParams();
-      gdwt->createSwapChain();
-      gdwt->createBuffersAndViews();
-   }
-   
+   gdwt->initPresentationParams();
    gdwt->registerResourceWithDevice(this);
    gdwt->registerResourceWithDevice(this);
 
 
    return gdwt;
    return gdwt;
@@ -618,15 +696,13 @@ GFXTextureTarget* GFXD3D11Device::allocRenderToTextureTarget()
    return targ;
    return targ;
 }
 }
 
 
-void GFXD3D11Device::beginReset()
+void GFXD3D11Device::reset(DXGI_SWAP_CHAIN_DESC &d3dpp)
 {
 {
    if (!mD3DDevice)
    if (!mD3DDevice)
       return;
       return;
 
 
    mInitialized = false;
    mInitialized = false;
 
 
-   releaseDefaultPoolResources();
-
    // Clean up some commonly dangling state. This helps prevents issues with
    // Clean up some commonly dangling state. This helps prevents issues with
    // items that are destroyed by the texture manager callbacks and recreated
    // items that are destroyed by the texture manager callbacks and recreated
    // later, but still left bound.
    // later, but still left bound.
@@ -637,26 +713,117 @@ void GFXD3D11Device::beginReset()
 
 
    mD3DDeviceContext->ClearState();
    mD3DDeviceContext->ClearState();
 
 
-   //release old buffers and views
-   SAFE_RELEASE(mDeviceDepthStencilView);
+   DXGI_MODE_DESC displayModes;
+   displayModes.Format = d3dpp.BufferDesc.Format;
+   displayModes.Height = d3dpp.BufferDesc.Height;
+   displayModes.Width = d3dpp.BufferDesc.Width;
+   displayModes.RefreshRate = d3dpp.BufferDesc.RefreshRate;
+   displayModes.Scaling = d3dpp.BufferDesc.Scaling;
+   displayModes.ScanlineOrdering = d3dpp.BufferDesc.ScanlineOrdering;
+
+   HRESULT hr;
+   if (!d3dpp.Windowed)
+   {
+      hr = mSwapChain->ResizeTarget(&displayModes);
+
+      if (FAILED(hr))
+      {
+         AssertFatal(false, "D3D11Device::reset - failed to resize target!");
+      }
+   }
+
+   // First release all the stuff we allocated from D3DPOOL_DEFAULT
+   releaseDefaultPoolResources();
+
+   //release the backbuffer, depthstencil, and their views
    SAFE_RELEASE(mDeviceBackBufferView);
    SAFE_RELEASE(mDeviceBackBufferView);
-   SAFE_RELEASE(mDeviceDepthStencil);
    SAFE_RELEASE(mDeviceBackbuffer);
    SAFE_RELEASE(mDeviceBackbuffer);
-}
+   SAFE_RELEASE(mDeviceDepthStencilView);
+   SAFE_RELEASE(mDeviceDepthStencil);
 
 
-void GFXD3D11Device::endReset(GFXD3D11WindowTarget *windowTarget)
-{
-   //grab new references
-   mDeviceBackbuffer = windowTarget->getBackBuffer();
-   mDeviceDepthStencil = windowTarget->getDepthStencil();
-   mDeviceBackBufferView = windowTarget->getBackBufferView();
-   mDeviceDepthStencilView = windowTarget->getDepthStencilView();
+   hr = mSwapChain->ResizeBuffers(d3dpp.BufferCount, d3dpp.BufferDesc.Width, d3dpp.BufferDesc.Height, d3dpp.BufferDesc.Format, d3dpp.Windowed ? 0 : DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH);
+
+   if (FAILED(hr))
+   {
+      AssertFatal(false, "D3D11Device::reset - failed to resize back buffer!");
+   }
+
+   //recreate backbuffer view. depth stencil view and texture
+   D3D11_TEXTURE2D_DESC desc;
+   desc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
+   desc.CPUAccessFlags = 0;
+   desc.Format = GFXD3D11TextureFormat[GFXFormatD24S8];
+   desc.MipLevels = 1;
+   desc.ArraySize = 1;
+   desc.Usage = D3D11_USAGE_DEFAULT;
+   desc.Width = d3dpp.BufferDesc.Width;
+   desc.Height = d3dpp.BufferDesc.Height;
+   desc.SampleDesc.Count = 1;
+   desc.SampleDesc.Quality = 0;
+   desc.MiscFlags = 0;
+
+   hr = mD3DDevice->CreateTexture2D(&desc, NULL, &mDeviceDepthStencil);
+   if (FAILED(hr))
+   {
+      AssertFatal(false, "GFXD3D11Device::reset - couldn't create device's depth-stencil surface.");
+   }
+
+   D3D11_DEPTH_STENCIL_VIEW_DESC depthDesc;
+   depthDesc.Format = GFXD3D11TextureFormat[GFXFormatD24S8];
+   depthDesc.Flags = 0;
+   depthDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
+   depthDesc.Texture2D.MipSlice = 0;
+
+   hr = mD3DDevice->CreateDepthStencilView(mDeviceDepthStencil, &depthDesc, &mDeviceDepthStencilView);
+
+   if (FAILED(hr))
+   {
+      AssertFatal(false, "GFXD3D11Device::reset - couldn't create depth stencil view");
+   }
+
+   hr = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&mDeviceBackbuffer);
+   if (FAILED(hr))
+      AssertFatal(false, "GFXD3D11Device::reset - coudln't retrieve backbuffer ref");
+
+   //create back buffer view
+   D3D11_RENDER_TARGET_VIEW_DESC RTDesc;
+
+   RTDesc.Format = GFXD3D11TextureFormat[GFXFormatR8G8B8A8_SRGB];
+   RTDesc.Texture2D.MipSlice = 0;
+   RTDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
+
+   hr = mD3DDevice->CreateRenderTargetView(mDeviceBackbuffer, &RTDesc, &mDeviceBackBufferView);
+
+   if (FAILED(hr))
+      AssertFatal(false, "GFXD3D11Device::reset - couldn't create back buffer target view");
 
 
    mD3DDeviceContext->OMSetRenderTargets(1, &mDeviceBackBufferView, mDeviceDepthStencilView);
    mD3DDeviceContext->OMSetRenderTargets(1, &mDeviceBackBufferView, mDeviceDepthStencilView);
 
 
-   // Now reacquire all the resources we trashed earlier
-   reacquireDefaultPoolResources();
+   hr = mSwapChain->SetFullscreenState(!d3dpp.Windowed, NULL);
+
+   if (FAILED(hr))
+   {
+      AssertFatal(false, "D3D11Device::reset - failed to change screen states!");
+   }
+
+   //Microsoft recommend this, see DXGI documentation
+   if (!d3dpp.Windowed)
+   {
+      displayModes.RefreshRate.Numerator = 0;
+      displayModes.RefreshRate.Denominator = 0;
+      hr = mSwapChain->ResizeTarget(&displayModes);
+
+      if (FAILED(hr))
+      {
+         AssertFatal(false, "D3D11Device::reset - failed to resize target!");
+      }
+   }
+
    mInitialized = true;
    mInitialized = true;
+
+   // Now re aquire all the resources we trashed earlier
+   reacquireDefaultPoolResources();
+
    // Mark everything dirty and flush to card, for sanity.
    // Mark everything dirty and flush to card, for sanity.
    updateStates(true);
    updateStates(true);
 }
 }
@@ -763,7 +930,7 @@ void GFXD3D11Device::setShaderConstBufferInternal(GFXShaderConstBuffer* buffer)
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 
 
-void GFXD3D11Device::clear(U32 flags, ColorI color, F32 z, U32 stencil)
+void GFXD3D11Device::clear(U32 flags, const LinearColorF& color, F32 z, U32 stencil)
 {
 {
    // Make sure we have flushed our render target state.
    // Make sure we have flushed our render target state.
    _updateRenderTargets();
    _updateRenderTargets();
@@ -775,12 +942,7 @@ void GFXD3D11Device::clear(U32 flags, ColorI color, F32 z, U32 stencil)
 
 
    mD3DDeviceContext->OMGetRenderTargets(1, &rtView, &dsView);
    mD3DDeviceContext->OMGetRenderTargets(1, &rtView, &dsView);
 
 
-   const FLOAT clearColor[4] = {
-      static_cast<F32>(color.red) * (1.0f / 255.0f),
-      static_cast<F32>(color.green) * (1.0f / 255.0f),
-      static_cast<F32>(color.blue) * (1.0f / 255.0f),
-      static_cast<F32>(color.alpha) * (1.0f / 255.0f)
-   };
+   const FLOAT clearColor[4] = { color.red, color.green, color.blue, color.alpha };
 
 
    if (flags & GFXClearTarget && rtView)
    if (flags & GFXClearTarget && rtView)
       mD3DDeviceContext->ClearRenderTargetView(rtView, clearColor);
       mD3DDeviceContext->ClearRenderTargetView(rtView, clearColor);
@@ -1355,7 +1517,6 @@ String GFXD3D11Device::_createTempShaderInternal(const GFXVertexFormat *vertexFo
    //make shader
    //make shader
    mainBodyData.append("VertOut main(VertIn IN){VertOut OUT;");
    mainBodyData.append("VertOut main(VertIn IN){VertOut OUT;");
 
 
-   bool addedPadding = false;
    for (U32 i = 0; i < elemCount; i++)
    for (U32 i = 0; i < elemCount; i++)
    {
    {
       const GFXVertexElement &element = vertexFormat->getElement(i);
       const GFXVertexElement &element = vertexFormat->getElement(i);
@@ -1363,8 +1524,6 @@ String GFXD3D11Device::_createTempShaderInternal(const GFXVertexFormat *vertexFo
       String semanticOut = semantic;
       String semanticOut = semantic;
       String type;
       String type;
 
 
-      AssertFatal(!(addedPadding && !element.isSemantic(GFXSemantic::PADDING)), "Padding added before data");
-
       if (element.isSemantic(GFXSemantic::POSITION))
       if (element.isSemantic(GFXSemantic::POSITION))
       {
       {
          semantic = "POSITION";
          semantic = "POSITION";
@@ -1400,11 +1559,6 @@ String GFXD3D11Device::_createTempShaderInternal(const GFXVertexFormat *vertexFo
          semantic = String::ToString("BLENDWEIGHT%d", element.getSemanticIndex());
          semantic = String::ToString("BLENDWEIGHT%d", element.getSemanticIndex());
          semanticOut = semantic;
          semanticOut = semantic;
       }
       }
-      else if (element.isSemantic(GFXSemantic::PADDING))
-      {
-         addedPadding = true;
-         continue;
-      }
       else
       else
       {
       {
          //Anything that falls thru to here will be a texture coord.
          //Anything that falls thru to here will be a texture coord.
@@ -1566,12 +1720,6 @@ GFXVertexDecl* GFXD3D11Device::allocVertexDecl( const GFXVertexFormat *vertexFor
          vd[i].SemanticName = "BLENDINDICES";
          vd[i].SemanticName = "BLENDINDICES";
          vd[i].SemanticIndex = element.getSemanticIndex();
          vd[i].SemanticIndex = element.getSemanticIndex();
       }
       }
-      else if (element.isSemantic(GFXSemantic::PADDING))
-      {
-         i--;
-         elemCount--;
-         continue;
-      }
       else
       else
       {
       {
           //Anything that falls thru to here will be a texture coord.
           //Anything that falls thru to here will be a texture coord.

+ 14 - 5
Engine/source/gfx/D3D11/gfxD3D11Device.h

@@ -39,6 +39,9 @@
 #define D3D11 static_cast<GFXD3D11Device*>(GFX)
 #define D3D11 static_cast<GFXD3D11Device*>(GFX)
 #define D3D11DEVICE D3D11->getDevice()
 #define D3D11DEVICE D3D11->getDevice()
 #define D3D11DEVICECONTEXT D3D11->getDeviceContext()
 #define D3D11DEVICECONTEXT D3D11->getDeviceContext()
+// DX 11.1 - always check these are not NULL, dodgy support with win 7
+#define D3D11DEVICE1 D3D11->getDevice1()
+#define D3D11DEVICECONTEXT1 D3D11->getDeviceContext1()
 
 
 class PlatformWindow;
 class PlatformWindow;
 class GFXD3D11ShaderConstBuffer;
 class GFXD3D11ShaderConstBuffer;
@@ -126,6 +129,9 @@ protected:
    IDXGISwapChain *mSwapChain;
    IDXGISwapChain *mSwapChain;
    ID3D11Device* mD3DDevice;
    ID3D11Device* mD3DDevice;
    ID3D11DeviceContext* mD3DDeviceContext;
    ID3D11DeviceContext* mD3DDeviceContext;
+   // DX 11.1
+   ID3D11Device1* mD3DDevice1;
+   ID3D11DeviceContext1* mD3DDeviceContext1;
    ID3DUserDefinedAnnotation* mUserAnnotation;
    ID3DUserDefinedAnnotation* mUserAnnotation;
 
 
    GFXShader* mCurrentShader;
    GFXShader* mCurrentShader;
@@ -143,12 +149,12 @@ protected:
    String mPixelShaderTarget;
    String mPixelShaderTarget;
    // String for use with shader macros in the form of shader model version * 10
    // String for use with shader macros in the form of shader model version * 10
    String mShaderModel;
    String mShaderModel;
-
    bool mDebugLayers;
    bool mDebugLayers;
 
 
    DXGI_SAMPLE_DESC mMultisampleDesc;
    DXGI_SAMPLE_DESC mMultisampleDesc;
 
 
    bool mOcclusionQuerySupported;
    bool mOcclusionQuerySupported;
+   bool mCbufferPartialSupported;
 
 
    U32 mDrawInstancesCount;   
    U32 mDrawInstancesCount;   
 
 
@@ -181,7 +187,7 @@ protected:
    virtual void setMatrix( GFXMatrixType /*mtype*/, const MatrixF &/*mat*/ ) { };
    virtual void setMatrix( GFXMatrixType /*mtype*/, const MatrixF &/*mat*/ ) { };
    virtual void setLightInternal(U32 /*lightStage*/, const GFXLightInfo /*light*/, bool /*lightEnable*/) { };
    virtual void setLightInternal(U32 /*lightStage*/, const GFXLightInfo /*light*/, bool /*lightEnable*/) { };
    virtual void setLightMaterialInternal(const GFXLightMaterial /*mat*/) { };
    virtual void setLightMaterialInternal(const GFXLightMaterial /*mat*/) { };
-   virtual void setGlobalAmbientInternal(ColorF /*color*/) { };
+   virtual void setGlobalAmbientInternal(LinearColorF /*color*/) { };
 
 
    // }
    // }
 
 
@@ -243,7 +249,7 @@ public:
 
 
    // Misc rendering control
    // Misc rendering control
    // {
    // {
-   virtual void clear( U32 flags, ColorI color, F32 z, U32 stencil );
+   virtual void clear( U32 flags, const LinearColorF& color, F32 z, U32 stencil );
    virtual bool beginSceneInternal();
    virtual bool beginSceneInternal();
    virtual void endSceneInternal();
    virtual void endSceneInternal();
 
 
@@ -291,10 +297,13 @@ public:
 
 
    ID3D11DeviceContext* getDeviceContext(){ return mD3DDeviceContext; }
    ID3D11DeviceContext* getDeviceContext(){ return mD3DDeviceContext; }
    ID3D11Device* getDevice(){ return mD3DDevice; }
    ID3D11Device* getDevice(){ return mD3DDevice; }
+   IDXGISwapChain* getSwapChain() { return mSwapChain; }
+   //DX 11.1
+   ID3D11DeviceContext1* getDeviceContext1() { return mD3DDeviceContext1; }
+   ID3D11Device1* getDevice1() { return mD3DDevice1; }
 
 
    /// Reset
    /// Reset
-   void beginReset();
-   void endReset(GFXD3D11WindowTarget *windowTarget);
+   void reset( DXGI_SWAP_CHAIN_DESC &d3dpp );
 
 
    virtual void setupGenericShaders( GenericShaderType type  = GSColor );
    virtual void setupGenericShaders( GenericShaderType type  = GSColor );
 
 

+ 12 - 6
Engine/source/gfx/D3D11/gfxD3D11EnumTranslate.cpp

@@ -54,11 +54,11 @@ void GFXD3D11EnumTranslate::init()
    GFXD3D11TextureFormat[GFXFormatA8L8] = DXGI_FORMAT_R8G8_UNORM;
    GFXD3D11TextureFormat[GFXFormatA8L8] = DXGI_FORMAT_R8G8_UNORM;
    GFXD3D11TextureFormat[GFXFormatA8] = DXGI_FORMAT_A8_UNORM;
    GFXD3D11TextureFormat[GFXFormatA8] = DXGI_FORMAT_A8_UNORM;
    GFXD3D11TextureFormat[GFXFormatL8] = DXGI_FORMAT_R8_UNORM;
    GFXD3D11TextureFormat[GFXFormatL8] = DXGI_FORMAT_R8_UNORM;
-   GFXD3D11TextureFormat[GFXFormatDXT1] = DXGI_FORMAT_BC1_UNORM;
-   GFXD3D11TextureFormat[GFXFormatDXT2] = DXGI_FORMAT_BC1_UNORM;
-   GFXD3D11TextureFormat[GFXFormatDXT3] = DXGI_FORMAT_BC2_UNORM;
-   GFXD3D11TextureFormat[GFXFormatDXT4] = DXGI_FORMAT_BC2_UNORM;
-   GFXD3D11TextureFormat[GFXFormatDXT5] = DXGI_FORMAT_BC3_UNORM;
+   GFXD3D11TextureFormat[GFXFormatBC1] = DXGI_FORMAT_BC1_UNORM;
+   GFXD3D11TextureFormat[GFXFormatBC2] = DXGI_FORMAT_BC2_UNORM;
+   GFXD3D11TextureFormat[GFXFormatBC3] = DXGI_FORMAT_BC3_UNORM;
+   GFXD3D11TextureFormat[GFXFormatBC4] = DXGI_FORMAT_BC4_UNORM;
+   GFXD3D11TextureFormat[GFXFormatBC5] = DXGI_FORMAT_BC5_UNORM;
    GFXD3D11TextureFormat[GFXFormatR32G32B32A32F] = DXGI_FORMAT_R32G32B32A32_FLOAT;
    GFXD3D11TextureFormat[GFXFormatR32G32B32A32F] = DXGI_FORMAT_R32G32B32A32_FLOAT;
    GFXD3D11TextureFormat[GFXFormatR16G16B16A16F] = DXGI_FORMAT_R16G16B16A16_FLOAT;
    GFXD3D11TextureFormat[GFXFormatR16G16B16A16F] = DXGI_FORMAT_R16G16B16A16_FLOAT;
    GFXD3D11TextureFormat[GFXFormatL16] = DXGI_FORMAT_R16_UNORM;
    GFXD3D11TextureFormat[GFXFormatL16] = DXGI_FORMAT_R16_UNORM;
@@ -72,8 +72,14 @@ void GFXD3D11EnumTranslate::init()
    GFXD3D11TextureFormat[GFXFormatD24S8] = DXGI_FORMAT_D24_UNORM_S8_UINT;
    GFXD3D11TextureFormat[GFXFormatD24S8] = DXGI_FORMAT_D24_UNORM_S8_UINT;
    GFXD3D11TextureFormat[GFXFormatD24FS8] = DXGI_FORMAT_UNKNOWN;
    GFXD3D11TextureFormat[GFXFormatD24FS8] = DXGI_FORMAT_UNKNOWN;
    GFXD3D11TextureFormat[GFXFormatD16] = DXGI_FORMAT_D16_UNORM;
    GFXD3D11TextureFormat[GFXFormatD16] = DXGI_FORMAT_D16_UNORM;
+   //sRGB
    GFXD3D11TextureFormat[GFXFormatR8G8B8A8_SRGB] = DXGI_FORMAT_B8G8R8A8_UNORM_SRGB;
    GFXD3D11TextureFormat[GFXFormatR8G8B8A8_SRGB] = DXGI_FORMAT_B8G8R8A8_UNORM_SRGB;
-   GFXD3D11TextureFormat[GFXFormatR8G8B8A8_LINEAR_FORCE] = DXGI_FORMAT_R8G8B8A8_UNORM;
+   GFXD3D11TextureFormat[GFXFormatR8G8B8_SRGB] = DXGI_FORMAT_B8G8R8X8_UNORM_SRGB;
+   GFXD3D11TextureFormat[GFXFormatBC1_SRGB] = DXGI_FORMAT_BC1_UNORM_SRGB;
+   GFXD3D11TextureFormat[GFXFormatBC2_SRGB] = DXGI_FORMAT_BC2_UNORM_SRGB;
+   GFXD3D11TextureFormat[GFXFormatBC3_SRGB] = DXGI_FORMAT_BC3_UNORM_SRGB;
+
+
 //------------------------------------------------------------------------------
 //------------------------------------------------------------------------------
 //------------------------------------------------------------------------------
 //------------------------------------------------------------------------------
    GFXD3D11TextureFilter[GFXTextureFilterNone] = D3D11_FILTER_MIN_MAG_MIP_POINT;
    GFXD3D11TextureFilter[GFXTextureFilterNone] = D3D11_FILTER_MIN_MAG_MIP_POINT;

+ 25 - 51
Engine/source/gfx/D3D11/gfxD3D11Shader.cpp

@@ -204,39 +204,6 @@ bool GFXD3D11ConstBufferLayout::setMatrix(const ParamDesc& pd, const GFXShaderCo
 
 
       return false;
       return false;
    }
    }
-   else if (pd.constType == GFXSCT_Float4x3)
-   {
-      const U32 csize = 48;
-
-      // Loop through and copy 
-      bool ret = false;
-      U8* currDestPointer = basePointer + pd.offset;
-      const U8* currSourcePointer = static_cast<const U8*>(data);
-      const U8* endData = currSourcePointer + size;
-      while (currSourcePointer < endData)
-      {
-#ifdef TORQUE_DOUBLE_CHECK_43MATS
-         Point4F col;
-         ((MatrixF*)currSourcePointer)->getRow(3, &col);
-         AssertFatal(col.x == 0.0f && col.y == 0.0f && col.z == 0.0f && col.w == 1.0f, "3rd row used");
-#endif
-
-         if (dMemcmp(currDestPointer, currSourcePointer, csize) != 0)
-         {
-            dMemcpy(currDestPointer, currSourcePointer, csize);
-            ret = true;
-         }
-         else if (pd.constType == GFXSCT_Float4x3)
-         {
-            ret = true;
-         }
-
-         currDestPointer += csize;
-         currSourcePointer += sizeof(MatrixF);
-      }
-
-      return ret;
-   }
    else
    else
    {
    {
       PROFILE_SCOPE(GFXD3D11ConstBufferLayout_setMatrix_not4x4);
       PROFILE_SCOPE(GFXD3D11ConstBufferLayout_setMatrix_not4x4);
@@ -251,6 +218,9 @@ bool GFXD3D11ConstBufferLayout::setMatrix(const ParamDesc& pd, const GFXShaderCo
       case GFXSCT_Float3x3 : 
       case GFXSCT_Float3x3 : 
          csize = 44; //This takes up 16+16+12
          csize = 44; //This takes up 16+16+12
          break;
          break;
+      case GFXSCT_Float4x3:
+         csize = 48;
+         break;
       default:
       default:
          AssertFatal(false, "Unhandled case!");
          AssertFatal(false, "Unhandled case!");
          return false;
          return false;
@@ -269,6 +239,10 @@ bool GFXD3D11ConstBufferLayout::setMatrix(const ParamDesc& pd, const GFXShaderCo
             dMemcpy(currDestPointer, currSourcePointer, csize);            
             dMemcpy(currDestPointer, currSourcePointer, csize);            
             ret = true;
             ret = true;
          }
          }
+         else if (pd.constType == GFXSCT_Float4x3)
+         {
+            ret = true;
+         }
 
 
          currDestPointer += csize;
          currDestPointer += csize;
          currSourcePointer += sizeof(MatrixF);
          currSourcePointer += sizeof(MatrixF);
@@ -303,6 +277,8 @@ GFXD3D11ShaderConstBuffer::GFXD3D11ShaderConstBuffer( GFXD3D11Shader* shader,
     mPixelConstBufferLayout = pixelLayout;
     mPixelConstBufferLayout = pixelLayout;
     mPixelConstBuffer = new GenericConstBuffer(pixelLayout);
     mPixelConstBuffer = new GenericConstBuffer(pixelLayout);
 
 
+    mDeviceContext = D3D11DEVICECONTEXT;
+
     _createBuffers();
     _createBuffers();
 	
 	
 }
 }
@@ -431,7 +407,7 @@ void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const PlaneF&
    SET_CONSTANT(handle, fv, mVertexConstBuffer, mPixelConstBuffer);
    SET_CONSTANT(handle, fv, mVertexConstBuffer, mPixelConstBuffer);
 }
 }
 
 
-void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const ColorF& fv)
+void GFXD3D11ShaderConstBuffer::set(GFXShaderConstHandle* handle, const LinearColorF& fv)
 { 
 { 
    SET_CONSTANT(handle, fv, mVertexConstBuffer, mPixelConstBuffer);
    SET_CONSTANT(handle, fv, mVertexConstBuffer, mPixelConstBuffer);
 }
 }
@@ -654,8 +630,6 @@ void GFXD3D11ShaderConstBuffer::activate( GFXD3D11ShaderConstBuffer *prevShaderB
       }      
       }      
    }
    }
 
 
-   ID3D11DeviceContext* devCtx = D3D11DEVICECONTEXT;
-
    D3D11_MAPPED_SUBRESOURCE pConstData;
    D3D11_MAPPED_SUBRESOURCE pConstData;
    ZeroMemory(&pConstData, sizeof(D3D11_MAPPED_SUBRESOURCE));
    ZeroMemory(&pConstData, sizeof(D3D11_MAPPED_SUBRESOURCE));
    
    
@@ -670,11 +644,11 @@ void GFXD3D11ShaderConstBuffer::activate( GFXD3D11ShaderConstBuffer *prevShaderB
       for (U32 i = 0; i < subBuffers.size(); ++i)
       for (U32 i = 0; i < subBuffers.size(); ++i)
       {
       {
          const ConstSubBufferDesc &desc = subBuffers[i];
          const ConstSubBufferDesc &desc = subBuffers[i];
-         devCtx->UpdateSubresource(mConstantBuffersV[i], 0, NULL, buf + desc.start, desc.size, 0);
+         mDeviceContext->UpdateSubresource(mConstantBuffersV[i], 0, NULL, buf + desc.start, desc.size, 0);
          nbBuffers++;
          nbBuffers++;
       }
       }
 
 
-      devCtx->VSSetConstantBuffers(0, nbBuffers, mConstantBuffersV);
+      mDeviceContext->VSSetConstantBuffers(0, nbBuffers, mConstantBuffersV);
    }
    }
 
 
    nbBuffers = 0;
    nbBuffers = 0;
@@ -688,11 +662,11 @@ void GFXD3D11ShaderConstBuffer::activate( GFXD3D11ShaderConstBuffer *prevShaderB
       for (U32 i = 0; i < subBuffers.size(); ++i)
       for (U32 i = 0; i < subBuffers.size(); ++i)
       {
       {
          const ConstSubBufferDesc &desc = subBuffers[i];
          const ConstSubBufferDesc &desc = subBuffers[i];
-         devCtx->UpdateSubresource(mConstantBuffersP[i], 0, NULL, buf + desc.start, desc.size, 0);
+         mDeviceContext->UpdateSubresource(mConstantBuffersP[i], 0, NULL, buf + desc.start, desc.size, 0);
          nbBuffers++;
          nbBuffers++;
       }
       }
 
 
-      devCtx->PSSetConstantBuffers(0, nbBuffers, mConstantBuffersP);
+      mDeviceContext->PSSetConstantBuffers(0, nbBuffers, mConstantBuffersP);
    }
    }
 
 
    #ifdef TORQUE_DEBUG
    #ifdef TORQUE_DEBUG
@@ -877,12 +851,12 @@ bool GFXD3D11Shader::_compileShader( const Torque::Path &filePath,
    ID3DBlob* errorBuff = NULL;
    ID3DBlob* errorBuff = NULL;
    ID3D11ShaderReflection* reflectionTable = NULL;
    ID3D11ShaderReflection* reflectionTable = NULL;
 
 
-#ifdef TORQUE_DEBUG
-	U32 flags = D3DCOMPILE_DEBUG | D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_WARNINGS_ARE_ERRORS;
-#else
-   U32 flags = D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_OPTIMIZATION_LEVEL3; //TODO double check load times with D3DCOMPILE_OPTIMIZATION_LEVEL3
-   //recommended flags for NSight, uncomment to use. NSight should be used in release mode only. *Still works with above flags however
-   //flags = D3DCOMPILE_DEBUG | D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_PREFER_FLOW_CONTROL | D3DCOMPILE_SKIP_OPTIMIZATION;
+#ifdef TORQUE_GFX_VISUAL_DEBUG //for use with NSight, GPU Perf studio, VS graphics debugger
+	U32 flags = D3DCOMPILE_DEBUG | D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_PREFER_FLOW_CONTROL | D3DCOMPILE_SKIP_OPTIMIZATION;
+#elif defined(TORQUE_DEBUG) //debug build
+   U32 flags = D3DCOMPILE_DEBUG | D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_WARNINGS_ARE_ERRORS;
+#else //release build
+   U32 flags = D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_OPTIMIZATION_LEVEL3;
 #endif
 #endif
 
 
 #ifdef D3D11_DEBUG_SPEW
 #ifdef D3D11_DEBUG_SPEW
@@ -1054,20 +1028,20 @@ bool GFXD3D11Shader::_compileShader( const Torque::Path &filePath,
 
 
    return result;
    return result;
 }
 }
-void GFXD3D11Shader::_getShaderConstants( ID3D11ShaderReflection *pTable, 
+void GFXD3D11Shader::_getShaderConstants( ID3D11ShaderReflection *refTable,
                                          GenericConstBufferLayout *bufferLayoutIn,
                                          GenericConstBufferLayout *bufferLayoutIn,
                                          Vector<GFXShaderConstDesc> &samplerDescriptions )
                                          Vector<GFXShaderConstDesc> &samplerDescriptions )
 {
 {
    PROFILE_SCOPE( GFXD3D11Shader_GetShaderConstants );
    PROFILE_SCOPE( GFXD3D11Shader_GetShaderConstants );
 
 
-   AssertFatal(pTable, "NULL constant table not allowed, is this an assembly shader?");
+   AssertFatal(refTable, "NULL constant table not allowed, is this an assembly shader?");
 
 
    GFXD3D11ConstBufferLayout *bufferLayout = (GFXD3D11ConstBufferLayout*)bufferLayoutIn;
    GFXD3D11ConstBufferLayout *bufferLayout = (GFXD3D11ConstBufferLayout*)bufferLayoutIn;
    Vector<ConstSubBufferDesc> &subBuffers = bufferLayout->getSubBufferDesc();
    Vector<ConstSubBufferDesc> &subBuffers = bufferLayout->getSubBufferDesc();
    subBuffers.clear();
    subBuffers.clear();
 
 
    D3D11_SHADER_DESC tableDesc;
    D3D11_SHADER_DESC tableDesc;
-   HRESULT hr = pTable->GetDesc(&tableDesc);
+   HRESULT hr = refTable->GetDesc(&tableDesc);
    if (FAILED(hr))
    if (FAILED(hr))
    {
    {
 	   AssertFatal(false, "Shader Reflection table unable to be created");
 	   AssertFatal(false, "Shader Reflection table unable to be created");
@@ -1077,7 +1051,7 @@ void GFXD3D11Shader::_getShaderConstants( ID3D11ShaderReflection *pTable,
    U32 bufferOffset = 0;
    U32 bufferOffset = 0;
    for (U32 i = 0; i < tableDesc.ConstantBuffers; i++)
    for (U32 i = 0; i < tableDesc.ConstantBuffers; i++)
    {
    {
-	   ID3D11ShaderReflectionConstantBuffer* constantBuffer = pTable->GetConstantBufferByIndex(i);
+	   ID3D11ShaderReflectionConstantBuffer* constantBuffer = refTable->GetConstantBufferByIndex(i);
 	   D3D11_SHADER_BUFFER_DESC constantBufferDesc;
 	   D3D11_SHADER_BUFFER_DESC constantBufferDesc;
 
 
       if (constantBuffer->GetDesc(&constantBufferDesc) == S_OK)
       if (constantBuffer->GetDesc(&constantBufferDesc) == S_OK)
@@ -1162,7 +1136,7 @@ void GFXD3D11Shader::_getShaderConstants( ID3D11ShaderReflection *pTable,
    {
    {
       GFXShaderConstDesc desc;
       GFXShaderConstDesc desc;
       D3D11_SHADER_INPUT_BIND_DESC bindDesc;
       D3D11_SHADER_INPUT_BIND_DESC bindDesc;
-      pTable->GetResourceBindingDesc(i, &bindDesc);
+      refTable->GetResourceBindingDesc(i, &bindDesc);
 
 
       switch (bindDesc.Type)
       switch (bindDesc.Type)
       {
       {

+ 4 - 2
Engine/source/gfx/D3D11/gfxD3D11Shader.h

@@ -297,6 +297,8 @@ public:
 class GFXD3D11ShaderConstBuffer : public GFXShaderConstBuffer
 class GFXD3D11ShaderConstBuffer : public GFXShaderConstBuffer
 {
 {
    friend class GFXD3D11Shader;
    friend class GFXD3D11Shader;
+   // Cache device context
+   ID3D11DeviceContext* mDeviceContext;
 
 
 public:
 public:
 
 
@@ -324,7 +326,7 @@ public:
    virtual void set(GFXShaderConstHandle* handle, const Point3F& fv);
    virtual void set(GFXShaderConstHandle* handle, const Point3F& fv);
    virtual void set(GFXShaderConstHandle* handle, const Point4F& fv);
    virtual void set(GFXShaderConstHandle* handle, const Point4F& fv);
    virtual void set(GFXShaderConstHandle* handle, const PlaneF& fv);
    virtual void set(GFXShaderConstHandle* handle, const PlaneF& fv);
-   virtual void set(GFXShaderConstHandle* handle, const ColorF& fv);
+   virtual void set(GFXShaderConstHandle* handle, const LinearColorF& fv);
    virtual void set(GFXShaderConstHandle* handle, const S32 f);
    virtual void set(GFXShaderConstHandle* handle, const S32 f);
    virtual void set(GFXShaderConstHandle* handle, const Point2I& fv);
    virtual void set(GFXShaderConstHandle* handle, const Point2I& fv);
    virtual void set(GFXShaderConstHandle* handle, const Point3I& fv);
    virtual void set(GFXShaderConstHandle* handle, const Point3I& fv);
@@ -434,7 +436,7 @@ protected:
                                 GenericConstBufferLayout *bufferLayout, 
                                 GenericConstBufferLayout *bufferLayout, 
                                 Vector<GFXShaderConstDesc> &samplerDescriptions );
                                 Vector<GFXShaderConstDesc> &samplerDescriptions );
 
 
-   void _getShaderConstants( ID3D11ShaderReflection* pTable, 
+   void _getShaderConstants( ID3D11ShaderReflection* refTable, 
 	                         GenericConstBufferLayout *bufferLayout,
 	                         GenericConstBufferLayout *bufferLayout,
                              Vector<GFXShaderConstDesc> &samplerDescriptions );
                              Vector<GFXShaderConstDesc> &samplerDescriptions );
 
 

+ 12 - 9
Engine/source/gfx/D3D11/gfxD3D11StateBlock.cpp

@@ -151,29 +151,32 @@ GFXD3D11StateBlock::GFXD3D11StateBlock(const GFXStateBlockDesc& desc)
          mSamplerDesc[i].MinLOD = 0;
          mSamplerDesc[i].MinLOD = 0;
          mSamplerDesc[i].MaxLOD = FLT_MAX;
          mSamplerDesc[i].MaxLOD = FLT_MAX;
 
 
+         const bool comparison = gfxSamplerState.samplerFunc != GFXCmpNever;
+
          if (gfxSamplerState.magFilter == GFXTextureFilterPoint && gfxSamplerState.minFilter == GFXTextureFilterPoint && gfxSamplerState.mipFilter == GFXTextureFilterPoint)
          if (gfxSamplerState.magFilter == GFXTextureFilterPoint && gfxSamplerState.minFilter == GFXTextureFilterPoint && gfxSamplerState.mipFilter == GFXTextureFilterPoint)
-            mSamplerDesc[i].Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
+            mSamplerDesc[i].Filter = comparison ? D3D11_FILTER_COMPARISON_MIN_MAG_MIP_POINT : D3D11_FILTER_MIN_MAG_MIP_POINT;
          else if (gfxSamplerState.magFilter == GFXTextureFilterPoint && gfxSamplerState.minFilter == GFXTextureFilterPoint && gfxSamplerState.mipFilter == GFXTextureFilterLinear)
          else if (gfxSamplerState.magFilter == GFXTextureFilterPoint && gfxSamplerState.minFilter == GFXTextureFilterPoint && gfxSamplerState.mipFilter == GFXTextureFilterLinear)
-            mSamplerDesc[i].Filter = D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR;
+            mSamplerDesc[i].Filter = comparison ? D3D11_FILTER_COMPARISON_MIN_MAG_POINT_MIP_LINEAR : D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR;
          else if (gfxSamplerState.magFilter == GFXTextureFilterLinear && gfxSamplerState.minFilter == GFXTextureFilterPoint && gfxSamplerState.mipFilter == GFXTextureFilterPoint)
          else if (gfxSamplerState.magFilter == GFXTextureFilterLinear && gfxSamplerState.minFilter == GFXTextureFilterPoint && gfxSamplerState.mipFilter == GFXTextureFilterPoint)
-            mSamplerDesc[i].Filter = D3D11_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT;
+            mSamplerDesc[i].Filter = comparison ? D3D11_FILTER_COMPARISON_MIN_POINT_MAG_LINEAR_MIP_POINT : D3D11_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT;
          else if (gfxSamplerState.magFilter == GFXTextureFilterLinear && gfxSamplerState.minFilter == GFXTextureFilterPoint && gfxSamplerState.mipFilter == GFXTextureFilterLinear)
          else if (gfxSamplerState.magFilter == GFXTextureFilterLinear && gfxSamplerState.minFilter == GFXTextureFilterPoint && gfxSamplerState.mipFilter == GFXTextureFilterLinear)
-            mSamplerDesc[i].Filter = D3D11_FILTER_MIN_POINT_MAG_MIP_LINEAR;
+            mSamplerDesc[i].Filter = comparison ? D3D11_FILTER_COMPARISON_MIN_POINT_MAG_MIP_LINEAR : D3D11_FILTER_MIN_POINT_MAG_MIP_LINEAR;
          else if (gfxSamplerState.magFilter == GFXTextureFilterPoint && gfxSamplerState.minFilter == GFXTextureFilterLinear && gfxSamplerState.mipFilter == GFXTextureFilterPoint)
          else if (gfxSamplerState.magFilter == GFXTextureFilterPoint && gfxSamplerState.minFilter == GFXTextureFilterLinear && gfxSamplerState.mipFilter == GFXTextureFilterPoint)
-            mSamplerDesc[i].Filter = D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT;
+            mSamplerDesc[i].Filter = comparison ? D3D11_FILTER_COMPARISON_MIN_LINEAR_MAG_MIP_POINT : D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT;
          else if (gfxSamplerState.magFilter == GFXTextureFilterPoint && gfxSamplerState.minFilter == GFXTextureFilterLinear && gfxSamplerState.mipFilter == GFXTextureFilterLinear)
          else if (gfxSamplerState.magFilter == GFXTextureFilterPoint && gfxSamplerState.minFilter == GFXTextureFilterLinear && gfxSamplerState.mipFilter == GFXTextureFilterLinear)
-            mSamplerDesc[i].Filter = D3D11_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR;
+            mSamplerDesc[i].Filter = comparison ? D3D11_FILTER_COMPARISON_MIN_LINEAR_MAG_POINT_MIP_LINEAR : D3D11_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR;
          else if (gfxSamplerState.magFilter == GFXTextureFilterLinear && gfxSamplerState.minFilter == GFXTextureFilterLinear && gfxSamplerState.mipFilter == GFXTextureFilterPoint)
          else if (gfxSamplerState.magFilter == GFXTextureFilterLinear && gfxSamplerState.minFilter == GFXTextureFilterLinear && gfxSamplerState.mipFilter == GFXTextureFilterPoint)
-            mSamplerDesc[i].Filter = D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT;
+            mSamplerDesc[i].Filter = comparison ? D3D11_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT : D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT;
          else if (gfxSamplerState.magFilter == GFXTextureFilterLinear && gfxSamplerState.minFilter == GFXTextureFilterLinear && mDesc.samplers[i].mipFilter == GFXTextureFilterLinear)
          else if (gfxSamplerState.magFilter == GFXTextureFilterLinear && gfxSamplerState.minFilter == GFXTextureFilterLinear && mDesc.samplers[i].mipFilter == GFXTextureFilterLinear)
-            mSamplerDesc[i].Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
+            mSamplerDesc[i].Filter = comparison ? D3D11_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR : D3D11_FILTER_MIN_MAG_MIP_LINEAR;
          else
          else
-            mSamplerDesc[i].Filter = D3D11_FILTER_ANISOTROPIC;
+            mSamplerDesc[i].Filter = comparison ? D3D11_FILTER_COMPARISON_ANISOTROPIC : D3D11_FILTER_ANISOTROPIC;
 
 
          mSamplerDesc[i].BorderColor[0] = 1.0f;
          mSamplerDesc[i].BorderColor[0] = 1.0f;
          mSamplerDesc[i].BorderColor[1] = 1.0f;
          mSamplerDesc[i].BorderColor[1] = 1.0f;
          mSamplerDesc[i].BorderColor[2] = 1.0f;
          mSamplerDesc[i].BorderColor[2] = 1.0f;
          mSamplerDesc[i].BorderColor[3] = 1.0f;
          mSamplerDesc[i].BorderColor[3] = 1.0f;
+         mSamplerDesc[i].ComparisonFunc = GFXD3D11CmpFunc[gfxSamplerState.samplerFunc];
 
 
          hr = D3D11DEVICE->CreateSamplerState(&mSamplerDesc[i], &mSamplerStates[i]);
          hr = D3D11DEVICE->CreateSamplerState(&mSamplerDesc[i], &mSamplerStates[i]);
          if (FAILED(hr))
          if (FAILED(hr))

+ 21 - 202
Engine/source/gfx/D3D11/gfxD3D11Target.cpp

@@ -248,10 +248,10 @@ void GFXD3D11TextureTarget::activate()
    stateApplied();
    stateApplied();
    
    
    // Now set all the new surfaces into the appropriate slots.
    // Now set all the new surfaces into the appropriate slots.
-   ID3D11RenderTargetView* rtViews[MaxRenderSlotId] = { NULL, NULL, NULL, NULL, NULL, NULL};
+   ID3D11RenderTargetView* rtViews[MaxRenderSlotId] = { NULL, NULL, NULL, NULL, NULL, NULL };
 
 
    ID3D11DepthStencilView* dsView = (ID3D11DepthStencilView*)(mTargetViews[GFXTextureTarget::DepthStencil]);
    ID3D11DepthStencilView* dsView = (ID3D11DepthStencilView*)(mTargetViews[GFXTextureTarget::DepthStencil]);
-   for (U32 i = 0; i < 4; i++)
+   for (U32 i = 0; i < 6; i++)
    {
    {
       rtViews[i] = (ID3D11RenderTargetView*)mTargetViews[GFXTextureTarget::Color0 + i];
       rtViews[i] = (ID3D11RenderTargetView*)mTargetViews[GFXTextureTarget::Color0 + i];
    }
    }
@@ -263,7 +263,7 @@ void GFXD3D11TextureTarget::activate()
 void GFXD3D11TextureTarget::deactivate()
 void GFXD3D11TextureTarget::deactivate()
 {
 {
    //re-gen mip maps
    //re-gen mip maps
-   for (U32 i = 0; i < 4; i++)
+   for (U32 i = 0; i < 6; i++)
    {
    {
       ID3D11ShaderResourceView* pSRView = mTargetSRViews[GFXTextureTarget::Color0 + i];
       ID3D11ShaderResourceView* pSRView = mTargetSRViews[GFXTextureTarget::Color0 + i];
       if (pSRView)
       if (pSRView)
@@ -314,34 +314,21 @@ void GFXD3D11TextureTarget::resurrect()
 
 
 GFXD3D11WindowTarget::GFXD3D11WindowTarget()
 GFXD3D11WindowTarget::GFXD3D11WindowTarget()
 {
 {
-   mWindow = NULL;
-   mBackBuffer = NULL;
-   mDepthStencilView = NULL;
-   mDepthStencil = NULL;
-   mBackBufferView = NULL;
-   mSecondaryWindow = false;
+   mWindow       = NULL;
+   mBackbuffer   = NULL;
 }
 }
 
 
 GFXD3D11WindowTarget::~GFXD3D11WindowTarget()
 GFXD3D11WindowTarget::~GFXD3D11WindowTarget()
 {
 {
-   SAFE_RELEASE(mDepthStencilView)
-   SAFE_RELEASE(mDepthStencil);
-   SAFE_RELEASE(mBackBufferView);
-   SAFE_RELEASE(mBackBuffer);
-   SAFE_RELEASE(mSwapChain);
+   SAFE_RELEASE(mBackbuffer);
 }
 }
 
 
 void GFXD3D11WindowTarget::initPresentationParams()
 void GFXD3D11WindowTarget::initPresentationParams()
 {
 {
    // Get some video mode related info.
    // Get some video mode related info.
-   const GFXVideoMode &vm = mWindow->getVideoMode();
-   HWND hwnd = (HWND)mWindow->getSystemWindow(PlatformWindow::WindowSystem_Windows);
-
-   // Do some validation...
-   if (vm.fullScreen && mSecondaryWindow)
-   {
-      AssertFatal(false, "GFXD3D11WindowTarget::initPresentationParams - Cannot go fullscreen with secondary window!");
-   }
+   GFXVideoMode vm = mWindow->getVideoMode();
+   Win32Window* win = static_cast<Win32Window*>(mWindow);
+   HWND hwnd = win->getHWND();
 
 
    mPresentationParams = D3D11->setupPresentParams(vm, hwnd);
    mPresentationParams = D3D11->setupPresentParams(vm, hwnd);
 }
 }
@@ -360,178 +347,40 @@ GFXFormat GFXD3D11WindowTarget::getFormat()
 
 
 bool GFXD3D11WindowTarget::present()
 bool GFXD3D11WindowTarget::present()
 {
 {
-   return (mSwapChain->Present(!D3D11->smDisableVSync, 0) == S_OK);
-}
-
-void GFXD3D11WindowTarget::createSwapChain()
-{
-   //create dxgi factory & swapchain
-   IDXGIFactory1* DXGIFactory;
-   HRESULT hr = CreateDXGIFactory1(__uuidof(IDXGIFactory1), reinterpret_cast<void**>(&DXGIFactory));
-   if (FAILED(hr))
-      AssertFatal(false, "GFXD3D11WindowTarget::createSwapChain - couldn't create dxgi factory.");
-
-   hr = DXGIFactory->CreateSwapChain(D3D11DEVICE, &mPresentationParams, &mSwapChain);
-
-   if (FAILED(hr))
-      AssertFatal(false, "GFXD3D11WindowTarget::createSwapChain - couldn't create swap chain.");
-
-   SAFE_RELEASE(DXGIFactory);   
+   return (D3D11->getSwapChain()->Present(!D3D11->smDisableVSync, 0) == S_OK);
 }
 }
 
 
-void GFXD3D11WindowTarget::createBuffersAndViews()
+void GFXD3D11WindowTarget::setImplicitSwapChain()
 {
 {
-   //release old if they exist
-   SAFE_RELEASE(mDepthStencilView);
-   SAFE_RELEASE(mDepthStencil);
-   SAFE_RELEASE(mBackBufferView);
-   SAFE_RELEASE(mBackBuffer);
-
-   //grab video mode
-   const GFXVideoMode &vm = mWindow->getVideoMode();
-   //create depth/stencil
-   D3D11_TEXTURE2D_DESC desc;
-   desc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
-   desc.CPUAccessFlags = 0;
-   desc.Format = GFXD3D11TextureFormat[GFXFormatD24S8];
-   desc.MipLevels = 1;
-   desc.ArraySize = 1;
-   desc.Usage = D3D11_USAGE_DEFAULT;
-   desc.Width = vm.resolution.x;
-   desc.Height = vm.resolution.y;
-   desc.SampleDesc.Count = 1;
-   desc.SampleDesc.Quality = 0;
-   desc.MiscFlags = 0;
-
-   HRESULT hr = D3D11DEVICE->CreateTexture2D(&desc, NULL, &mDepthStencil);
-   if (FAILED(hr))
-      AssertFatal(false, "GFXD3D11WindowTarget::createBuffersAndViews - couldn't create device's depth-stencil surface.");
-
-   D3D11_DEPTH_STENCIL_VIEW_DESC depthDesc;
-   depthDesc.Format = GFXD3D11TextureFormat[GFXFormatD24S8];
-   depthDesc.Flags = 0;
-   depthDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
-   depthDesc.Texture2D.MipSlice = 0;
-
-   hr = D3D11DEVICE->CreateDepthStencilView(mDepthStencil, &depthDesc, &mDepthStencilView);
-   if (FAILED(hr))
-      AssertFatal(false, "GFXD3D11WindowTarget::createBuffersAndViews - couldn't create depth stencil view");
-
-   setBackBuffer();
-
-   //create back buffer view
-   D3D11_RENDER_TARGET_VIEW_DESC RTDesc;
-   RTDesc.Format = GFXD3D11TextureFormat[GFXFormatR8G8B8A8];
-   RTDesc.Texture2D.MipSlice = 0;
-   RTDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
-
-   hr = D3D11DEVICE->CreateRenderTargetView(mBackBuffer, &RTDesc, &mBackBufferView);
-
-   if (FAILED(hr))
-      AssertFatal(false, "GFXD3D11WindowTarget::createBuffersAndViews - couldn't create back buffer target view");
-
-   //debug names
-#ifdef TORQUE_DEBUG
-   if (!mSecondaryWindow)
-   {
-      String backBufferName = "MainBackBuffer";
-      String depthSteniclName = "MainDepthStencil";
-      String backBuffViewName = "MainBackBuffView";
-      String depthStencViewName = "MainDepthView";
-      mBackBuffer->SetPrivateData(WKPDID_D3DDebugObjectName, backBufferName.size(), backBufferName.c_str());
-      mDepthStencil->SetPrivateData(WKPDID_D3DDebugObjectName, depthSteniclName.size(), depthSteniclName.c_str());
-      mDepthStencilView->SetPrivateData(WKPDID_D3DDebugObjectName, depthStencViewName.size(), depthStencViewName.c_str());
-      mBackBufferView->SetPrivateData(WKPDID_D3DDebugObjectName, backBuffViewName.size(), backBuffViewName.c_str());
-   }
-#endif
+   if (!mBackbuffer)      
+      D3D11->mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&mBackbuffer);
 }
 }
 
 
 void GFXD3D11WindowTarget::resetMode()
 void GFXD3D11WindowTarget::resetMode()
 {
 {
-   HRESULT hr;
-   if (mSwapChain)
-   {
-      // The current video settings.
-      DXGI_SWAP_CHAIN_DESC desc;
-      hr = mSwapChain->GetDesc(&desc);
-      if (FAILED(hr))
-         AssertFatal(false, "GFXD3D11WindowTarget::resetMode - failed to get swap chain description!");
-
-      bool fullscreen = !desc.Windowed;
-      Point2I backbufferSize(desc.BufferDesc.Width, desc.BufferDesc.Height);
-
-      // The settings we are now applying.
-      const GFXVideoMode &vm = mWindow->getVideoMode();
-
-      // Early out if none of the settings which require a device reset
-      // have changed.      
-      if (backbufferSize == vm.resolution &&
-         fullscreen == vm.fullScreen)
-         return;
-   }
-
-   //release old buffers and views
-   SAFE_RELEASE(mDepthStencilView)
-   SAFE_RELEASE(mDepthStencil);
-   SAFE_RELEASE(mBackBufferView);
-   SAFE_RELEASE(mBackBuffer);
-
-   if(!mSecondaryWindow)
-      D3D11->beginReset();
-
    mWindow->setSuppressReset(true);
    mWindow->setSuppressReset(true);
 
 
    // Setup our presentation params.
    // Setup our presentation params.
    initPresentationParams();
    initPresentationParams();
 
 
-   if (!mPresentationParams.Windowed)
-   {
-      mPresentationParams.BufferDesc.RefreshRate.Numerator = 0;
-      mPresentationParams.BufferDesc.RefreshRate.Denominator = 0;
-      hr = mSwapChain->ResizeTarget(&mPresentationParams.BufferDesc);
-
-      if (FAILED(hr))
-         AssertFatal(false, "GFXD3D11WindowTarget::resetMode - failed to resize target!");
-
-   }
-
-   hr = mSwapChain->ResizeBuffers(mPresentationParams.BufferCount, mPresentationParams.BufferDesc.Width, mPresentationParams.BufferDesc.Height, 
-      mPresentationParams.BufferDesc.Format, mPresentationParams.Windowed ? 0 : DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH);
-
-   if (FAILED(hr))
-      AssertFatal(false, "GFXD3D11WindowTarget::resetMode - failed to resize back buffer!");
-
-   hr = mSwapChain->SetFullscreenState(!mPresentationParams.Windowed, NULL);
-
-   if (FAILED(hr))
-      AssertFatal(false, "GFXD3D11WindowTarget::resetMode - failed to change screen states!");
+   // Otherwise, we have to reset the device, if we're the implicit swapchain.
+   D3D11->reset(mPresentationParams);
 
 
    // Update our size, too.
    // Update our size, too.
    mSize = Point2I(mPresentationParams.BufferDesc.Width, mPresentationParams.BufferDesc.Height);
    mSize = Point2I(mPresentationParams.BufferDesc.Width, mPresentationParams.BufferDesc.Height);
 
 
    mWindow->setSuppressReset(false);
    mWindow->setSuppressReset(false);
-
-   //re-create buffers and views
-   createBuffersAndViews();
-
-   if (!mSecondaryWindow)
-      D3D11->endReset(this);
+   GFX->beginReset();
 }
 }
 
 
 void GFXD3D11WindowTarget::zombify()
 void GFXD3D11WindowTarget::zombify()
 {
 {
-   SAFE_RELEASE(mBackBuffer);
+   SAFE_RELEASE(mBackbuffer);
 }
 }
 
 
 void GFXD3D11WindowTarget::resurrect()
 void GFXD3D11WindowTarget::resurrect()
 {
 {
-   setBackBuffer();
-}
-
-void GFXD3D11WindowTarget::setBackBuffer()
-{
-   if (!mBackBuffer)
-      mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&mBackBuffer);
+   setImplicitSwapChain();
 }
 }
 
 
 void GFXD3D11WindowTarget::activate()
 void GFXD3D11WindowTarget::activate()
@@ -542,10 +391,10 @@ void GFXD3D11WindowTarget::activate()
    ID3D11RenderTargetView* rtViews[8] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
    ID3D11RenderTargetView* rtViews[8] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
 
 
    D3D11DEVICECONTEXT->OMSetRenderTargets(8, rtViews, NULL);
    D3D11DEVICECONTEXT->OMSetRenderTargets(8, rtViews, NULL);
-   D3D11DEVICECONTEXT->OMSetRenderTargets(1, &mBackBufferView, mDepthStencilView);
+   D3D11DEVICECONTEXT->OMSetRenderTargets(1, &D3D11->mDeviceBackBufferView, D3D11->mDeviceDepthStencilView);
 
 
    DXGI_SWAP_CHAIN_DESC pp;
    DXGI_SWAP_CHAIN_DESC pp;
-   mSwapChain->GetDesc(&pp);
+   D3D11->mSwapChain->GetDesc(&pp);
 
 
    // Update our video mode here, too.
    // Update our video mode here, too.
    GFXVideoMode vm;
    GFXVideoMode vm;
@@ -563,35 +412,5 @@ void GFXD3D11WindowTarget::resolveTo(GFXTextureObject *tex)
    D3D11_TEXTURE2D_DESC desc;
    D3D11_TEXTURE2D_DESC desc;
    ID3D11Texture2D* surf = ((GFXD3D11TextureObject*)(tex))->get2DTex();
    ID3D11Texture2D* surf = ((GFXD3D11TextureObject*)(tex))->get2DTex();
    surf->GetDesc(&desc);
    surf->GetDesc(&desc);
-   D3D11DEVICECONTEXT->ResolveSubresource(surf, 0, mBackBuffer, 0, desc.Format);
-}
-
-IDXGISwapChain *GFXD3D11WindowTarget::getSwapChain()
-{
-   mSwapChain->AddRef();
-   return mSwapChain;
-}
-
-ID3D11Texture2D *GFXD3D11WindowTarget::getBackBuffer()
-{
-   mBackBuffer->AddRef();
-   return mBackBuffer;
-}
-
-ID3D11Texture2D *GFXD3D11WindowTarget::getDepthStencil()
-{
-   mDepthStencil->AddRef();
-   return mDepthStencil;
-}
-
-ID3D11RenderTargetView* GFXD3D11WindowTarget::getBackBufferView()
-{
-   mBackBufferView->AddRef();
-   return mBackBufferView;
-}
-
-ID3D11DepthStencilView* GFXD3D11WindowTarget::getDepthStencilView()
-{
-   mDepthStencilView->AddRef();
-   return mDepthStencilView;
+   D3D11DEVICECONTEXT->ResolveSubresource(surf, 0, D3D11->mDeviceBackbuffer, 0, desc.Format);
 }
 }

+ 2 - 18
Engine/source/gfx/D3D11/gfxD3D11Target.h

@@ -76,11 +76,7 @@ class GFXD3D11WindowTarget : public GFXWindowTarget
    friend class GFXD3D11Device;
    friend class GFXD3D11Device;
 
 
    /// Our backbuffer
    /// Our backbuffer
-   ID3D11Texture2D *mBackBuffer;
-   ID3D11Texture2D *mDepthStencil;
-   ID3D11RenderTargetView* mBackBufferView;
-   ID3D11DepthStencilView* mDepthStencilView;
-   IDXGISwapChain *mSwapChain;
+   ID3D11Texture2D *mBackbuffer;
 
 
    /// Maximum size we can render to.
    /// Maximum size we can render to.
    Point2I mSize;
    Point2I mSize;
@@ -89,9 +85,6 @@ class GFXD3D11WindowTarget : public GFXWindowTarget
    /// Internal interface that notifies us we need to reset our video mode.
    /// Internal interface that notifies us we need to reset our video mode.
    void resetMode();
    void resetMode();
 
 
-   /// Is this a secondary window
-   bool mSecondaryWindow;
-
 public:
 public:
 
 
    GFXD3D11WindowTarget();
    GFXD3D11WindowTarget();
@@ -102,9 +95,7 @@ public:
    virtual bool present();
    virtual bool present();
 
 
    void initPresentationParams();
    void initPresentationParams();
-   void createSwapChain();
-   void createBuffersAndViews();
-   void setBackBuffer();
+   void setImplicitSwapChain();
 
 
    virtual void activate();   
    virtual void activate();   
 
 
@@ -112,13 +103,6 @@ public:
    void resurrect();
    void resurrect();
 
 
    virtual void resolveTo( GFXTextureObject *tex );
    virtual void resolveTo( GFXTextureObject *tex );
-
-   // These are all reference counted and must be released by whomever uses the get* function
-   IDXGISwapChain *getSwapChain();
-   ID3D11Texture2D *getBackBuffer();
-   ID3D11Texture2D *getDepthStencil();
-   ID3D11RenderTargetView* getBackBufferView();
-   ID3D11DepthStencilView* getDepthStencilView();
 };
 };
 
 
 #endif
 #endif

+ 12 - 8
Engine/source/gfx/D3D11/gfxD3D11TextureManager.cpp

@@ -23,6 +23,7 @@
 #include "gfx/D3D11/gfxD3D11Device.h"
 #include "gfx/D3D11/gfxD3D11Device.h"
 #include "gfx/D3D11/gfxD3D11EnumTranslate.h"
 #include "gfx/D3D11/gfxD3D11EnumTranslate.h"
 #include "gfx/bitmap/bitmapUtils.h"
 #include "gfx/bitmap/bitmapUtils.h"
+#include "gfx/bitmap/imageUtils.h"
 #include "gfx/gfxCardProfile.h"
 #include "gfx/gfxCardProfile.h"
 #include "gfx/gfxStringEnumTranslate.h"
 #include "gfx/gfxStringEnumTranslate.h"
 #include "core/strings/unicode.h"
 #include "core/strings/unicode.h"
@@ -139,7 +140,7 @@ void GFXD3D11TextureManager::_innerCreateTexture( GFXD3D11TextureObject *retTex,
    }
    }
    else
    else
    {
    {
-		UINT numQualityLevels = 0;
+		U32 numQualityLevels = 0;
 
 
 		switch (antialiasLevel)
 		switch (antialiasLevel)
 		{
 		{
@@ -151,7 +152,6 @@ void GFXD3D11TextureManager::_innerCreateTexture( GFXD3D11TextureObject *retTex,
 			default:
 			default:
 			{
 			{
 				antialiasLevel = 0;
 				antialiasLevel = 0;
-				UINT numQualityLevels;
 				D3D11DEVICE->CheckMultisampleQualityLevels(d3dTextureFormat, antialiasLevel, &numQualityLevels);
 				D3D11DEVICE->CheckMultisampleQualityLevels(d3dTextureFormat, antialiasLevel, &numQualityLevels);
 				AssertFatal(numQualityLevels, "Invalid AA level!");
 				AssertFatal(numQualityLevels, "Invalid AA level!");
 				break;
 				break;
@@ -287,7 +287,7 @@ bool GFXD3D11TextureManager::_loadTexture(GFXTextureObject *aTexture, GBitmap *p
    const bool supportsAutoMips = GFX->getCardProfiler()->queryProfile("autoMipMapLevel", true);
    const bool supportsAutoMips = GFX->getCardProfiler()->queryProfile("autoMipMapLevel", true);
 
 
    // Helper bool
    // Helper bool
-   const bool isCompressedTexFmt = aTexture->mFormat >= GFXFormatDXT1 && aTexture->mFormat <= GFXFormatDXT5;
+   const bool isCompressedTexFmt = ImageUtil::isCompressedFormat(aTexture->mFormat);
 
 
    // Settings for mipmap generation
    // Settings for mipmap generation
    U32 maxDownloadMip = pDL->getNumMipLevels();
    U32 maxDownloadMip = pDL->getNumMipLevels();
@@ -312,10 +312,10 @@ bool GFXD3D11TextureManager::_loadTexture(GFXTextureObject *aTexture, GBitmap *p
 
 
 		   switch(texture->mFormat)
 		   switch(texture->mFormat)
 			{
 			{
-				case GFXFormatR8G8B8:
+            case GFXFormatR8G8B8:
+            case GFXFormatR8G8B8_SRGB:
 				{
 				{
 					PROFILE_SCOPE(Swizzle24_Upload);
 					PROFILE_SCOPE(Swizzle24_Upload);
-					AssertFatal(pDL->getFormat() == GFXFormatR8G8B8, "Assumption failed");
 
 
 					U8* Bits = new U8[pDL->getWidth(i) * pDL->getHeight(i) * 4];
 					U8* Bits = new U8[pDL->getWidth(i) * pDL->getHeight(i) * 4];
 					dMemcpy(Bits, pDL->getBits(i), pDL->getWidth(i) * pDL->getHeight(i) * 3);
 					dMemcpy(Bits, pDL->getBits(i), pDL->getWidth(i) * pDL->getHeight(i) * 3);
@@ -330,6 +330,7 @@ bool GFXD3D11TextureManager::_loadTexture(GFXTextureObject *aTexture, GBitmap *p
 
 
 				case GFXFormatR8G8B8A8:
 				case GFXFormatR8G8B8A8:
 				case GFXFormatR8G8B8X8:
 				case GFXFormatR8G8B8X8:
+            case GFXFormatR8G8B8A8_SRGB:
 				{
 				{
                PROFILE_SCOPE(Swizzle32_Upload);
                PROFILE_SCOPE(Swizzle32_Upload);
                copyBuffer = new U8[pDL->getWidth(i) * pDL->getHeight(i) * pDL->getBytesPerPixel()];
                copyBuffer = new U8[pDL->getWidth(i) * pDL->getHeight(i) * pDL->getBytesPerPixel()];
@@ -360,9 +361,9 @@ bool GFXD3D11TextureManager::_loadTexture(GFXTextureObject *aTexture, GBitmap *p
 			switch( texture->mFormat )
 			switch( texture->mFormat )
 			{
 			{
 				case GFXFormatR8G8B8:
 				case GFXFormatR8G8B8:
+            case GFXFormatR8G8B8_SRGB:
 				{
 				{
 					PROFILE_SCOPE(Swizzle24_Upload);
 					PROFILE_SCOPE(Swizzle24_Upload);
-					AssertFatal(pDL->getFormat() == GFXFormatR8G8B8, "Assumption failed");
 
 
 					U8* Bits = new U8[pDL->getWidth(i) * pDL->getHeight(i) * 4];
 					U8* Bits = new U8[pDL->getWidth(i) * pDL->getHeight(i) * 4];
 					dMemcpy(Bits, pDL->getBits(i), pDL->getWidth(i) * pDL->getHeight(i) * 3);
 					dMemcpy(Bits, pDL->getBits(i), pDL->getWidth(i) * pDL->getHeight(i) * 3);
@@ -375,6 +376,7 @@ bool GFXD3D11TextureManager::_loadTexture(GFXTextureObject *aTexture, GBitmap *p
 
 
             case GFXFormatR8G8B8A8:
             case GFXFormatR8G8B8A8:
             case GFXFormatR8G8B8X8:
             case GFXFormatR8G8B8X8:
+            case GFXFormatR8G8B8A8_SRGB:
             {
             {
                PROFILE_SCOPE(Swizzle32_Upload);
                PROFILE_SCOPE(Swizzle32_Upload);
                dev->getDeviceSwizzle32()->ToBuffer(mapping.pData, pDL->getBits(i), pDL->getWidth(i) * pDL->getHeight(i) * pDL->getBytesPerPixel());
                dev->getDeviceSwizzle32()->ToBuffer(mapping.pData, pDL->getBits(i), pDL->getWidth(i) * pDL->getHeight(i) * pDL->getBytesPerPixel());
@@ -417,7 +419,7 @@ bool GFXD3D11TextureManager::_loadTexture(GFXTextureObject *inTex, void *raw)
 
 
    U8* Bits = NULL;
    U8* Bits = NULL;
   
   
-   if(texture->mFormat == GFXFormatR8G8B8)
+   if(texture->mFormat == GFXFormatR8G8B8 || texture->mFormat == GFXFormatR8G8B8_SRGB)
    {
    {
 	   // convert 24 bit to 32 bit
 	   // convert 24 bit to 32 bit
 	   Bits = new U8[texture->getWidth() * texture->getHeight() * texture->getDepth() * 4];
 	   Bits = new U8[texture->getWidth() * texture->getHeight() * texture->getDepth() * 4];
@@ -430,8 +432,10 @@ bool GFXD3D11TextureManager::_loadTexture(GFXTextureObject *inTex, void *raw)
    switch(texture->mFormat)
    switch(texture->mFormat)
    {
    {
       case GFXFormatR8G8B8:
       case GFXFormatR8G8B8:
+      case GFXFormatR8G8B8_SRGB:
       case GFXFormatR8G8B8A8:
       case GFXFormatR8G8B8A8:
       case GFXFormatR8G8B8X8:
       case GFXFormatR8G8B8X8:
+      case GFXFormatR8G8B8A8_SRGB:
          bytesPerPix = 4;
          bytesPerPix = 4;
          break;
          break;
    }
    }
@@ -444,7 +448,7 @@ bool GFXD3D11TextureManager::_loadTexture(GFXTextureObject *inTex, void *raw)
    box.top     = 0;
    box.top     = 0;
    box.bottom  = texture->getHeight();
    box.bottom  = texture->getHeight();
 
 
-   if(texture->mFormat == GFXFormatR8G8B8) // converted format also for volume textures
+   if(texture->mFormat == GFXFormatR8G8B8 || texture->mFormat == GFXFormatR8G8B8_SRGB) // converted format also for volume textures
 		dev->getDeviceContext()->UpdateSubresource(texture->get3DTex(), 0, &box, Bits, texture->getWidth() * bytesPerPix, texture->getHeight() * bytesPerPix);
 		dev->getDeviceContext()->UpdateSubresource(texture->get3DTex(), 0, &box, Bits, texture->getWidth() * bytesPerPix, texture->getHeight() * bytesPerPix);
    else
    else
 		dev->getDeviceContext()->UpdateSubresource(texture->get3DTex(), 0, &box, raw, texture->getWidth() * bytesPerPix, texture->getHeight() * bytesPerPix);
 		dev->getDeviceContext()->UpdateSubresource(texture->get3DTex(), 0, &box, raw, texture->getWidth() * bytesPerPix, texture->getHeight() * bytesPerPix);

+ 5 - 4
Engine/source/gfx/D3D11/gfxD3D11TextureObject.cpp

@@ -74,7 +74,7 @@ GFXLockedRect *GFXD3D11TextureObject::lock(U32 mipLevel /*= 0*/, RectI *inRect /
           mLockTex->getWidth() != getWidth() ||
           mLockTex->getWidth() != getWidth() ||
           mLockTex->getHeight() != getHeight() )
           mLockTex->getHeight() != getHeight() )
       {
       {
-         mLockTex.set( getWidth(), getHeight(), mFormat, &GFXSystemMemProfile, avar("%s() - mLockTex (line %d)", __FUNCTION__, __LINE__) );
+         mLockTex.set( getWidth(), getHeight(), mFormat, &GFXSystemMemTextureProfile, avar("%s() - mLockTex (line %d)", __FUNCTION__, __LINE__) );
       }
       }
 
 
       PROFILE_START(GFXD3D11TextureObject_lockRT);
       PROFILE_START(GFXD3D11TextureObject_lockRT);
@@ -180,8 +180,8 @@ bool GFXD3D11TextureObject::copyToBmp(GBitmap* bmp)
    // check format limitations
    // check format limitations
    // at the moment we only support RGBA for the source (other 4 byte formats should
    // at the moment we only support RGBA for the source (other 4 byte formats should
    // be easy to add though)
    // be easy to add though)
-   AssertFatal(mFormat == GFXFormatR8G8B8A8 || mFormat == GFXFormatR8G8B8A8_LINEAR_FORCE, "copyToBmp: invalid format");
-   if (mFormat != GFXFormatR8G8B8A8 && mFormat != GFXFormatR8G8B8A8_LINEAR_FORCE)
+   AssertFatal(mFormat == GFXFormatR8G8B8A8 || mFormat == GFXFormatR8G8B8A8_LINEAR_FORCE || mFormat == GFXFormatR8G8B8A8_SRGB, "copyToBmp: invalid format");
+   if (mFormat != GFXFormatR8G8B8A8 && mFormat != GFXFormatR8G8B8A8_LINEAR_FORCE && mFormat != GFXFormatR8G8B8A8_SRGB)
       return false;
       return false;
 
 
    PROFILE_START(GFXD3D11TextureObject_copyToBmp);
    PROFILE_START(GFXD3D11TextureObject_copyToBmp);
@@ -197,7 +197,8 @@ bool GFXD3D11TextureObject::copyToBmp(GBitmap* bmp)
    const U32 sourceBytesPerPixel = 4;
    const U32 sourceBytesPerPixel = 4;
    U32 destBytesPerPixel = 0;
    U32 destBytesPerPixel = 0;
 
 
-   if (bmp->getFormat() == GFXFormatR8G8B8A8 || bmp->getFormat() == GFXFormatR8G8B8A8_LINEAR_FORCE)
+   const GFXFormat fmt = bmp->getFormat();
+   if (fmt == GFXFormatR8G8B8A8 || fmt == GFXFormatR8G8B8A8_LINEAR_FORCE || fmt == GFXFormatR8G8B8A8_SRGB)
       destBytesPerPixel = 4;
       destBytesPerPixel = 4;
    else if(bmp->getFormat() == GFXFormatR8G8B8)
    else if(bmp->getFormat() == GFXFormatR8G8B8)
       destBytesPerPixel = 3;
       destBytesPerPixel = 3;

+ 2 - 2
Engine/source/gfx/Null/gfxNullDevice.h

@@ -101,7 +101,7 @@ protected:
 
 
    virtual void setLightInternal(U32 lightStage, const GFXLightInfo light, bool lightEnable);
    virtual void setLightInternal(U32 lightStage, const GFXLightInfo light, bool lightEnable);
    virtual void setLightMaterialInternal(const GFXLightMaterial mat) { };
    virtual void setLightMaterialInternal(const GFXLightMaterial mat) { };
-   virtual void setGlobalAmbientInternal(ColorF color) { };
+   virtual void setGlobalAmbientInternal(LinearColorF color) { };
 
 
    /// @name State Initalization.
    /// @name State Initalization.
    /// @{
    /// @{
@@ -150,7 +150,7 @@ public:
    virtual GFXShader* createShader() { return NULL; };
    virtual GFXShader* createShader() { return NULL; };
 
 
 
 
-   virtual void clear( U32 flags, ColorI color, F32 z, U32 stencil ) { };
+   virtual void clear( U32 flags, const LinearColorF& color, F32 z, U32 stencil ) { };
    virtual bool beginSceneInternal() { return true; };
    virtual bool beginSceneInternal() { return true; };
    virtual void endSceneInternal() { };
    virtual void endSceneInternal() { };
 
 

+ 779 - 0
Engine/source/gfx/bitmap/ddsData.h

@@ -0,0 +1,779 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2016 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.
+//-----------------------------------------------------------------------------
+
+////////////////////////////////////////////////////////////////////////////////
+// Portions Copyright (c) Microsoft Corporation. All rights reserved.
+// https://github.com/Microsoft/DirectXTex
+////////////////////////////////////////////////////////////////////////////////
+
+#ifndef _DDSDATA_H_
+#define _DDSDATA_H_
+
+#ifndef _TORQUE_TYPES_H_
+#include "platform/types.h"
+#endif
+
+#include "core/util/fourcc.h"
+
+#ifdef TORQUE_OS_WIN
+#include <dxgiformat.h>
+#endif
+
+namespace dds
+{
+   ///////////////////////////////////////////////////////////////////////////////////
+   //                           DXGI Formats                                        //
+   ///////////////////////////////////////////////////////////////////////////////////
+#ifndef TORQUE_OS_WIN
+   //From directx SDK
+   typedef enum DXGI_FORMAT
+   {
+      DXGI_FORMAT_UNKNOWN = 0,
+      DXGI_FORMAT_R32G32B32A32_TYPELESS = 1,
+      DXGI_FORMAT_R32G32B32A32_FLOAT = 2,
+      DXGI_FORMAT_R32G32B32A32_UINT = 3,
+      DXGI_FORMAT_R32G32B32A32_SINT = 4,
+      DXGI_FORMAT_R32G32B32_TYPELESS = 5,
+      DXGI_FORMAT_R32G32B32_FLOAT = 6,
+      DXGI_FORMAT_R32G32B32_UINT = 7,
+      DXGI_FORMAT_R32G32B32_SINT = 8,
+      DXGI_FORMAT_R16G16B16A16_TYPELESS = 9,
+      DXGI_FORMAT_R16G16B16A16_FLOAT = 10,
+      DXGI_FORMAT_R16G16B16A16_UNORM = 11,
+      DXGI_FORMAT_R16G16B16A16_UINT = 12,
+      DXGI_FORMAT_R16G16B16A16_SNORM = 13,
+      DXGI_FORMAT_R16G16B16A16_SINT = 14,
+      DXGI_FORMAT_R32G32_TYPELESS = 15,
+      DXGI_FORMAT_R32G32_FLOAT = 16,
+      DXGI_FORMAT_R32G32_UINT = 17,
+      DXGI_FORMAT_R32G32_SINT = 18,
+      DXGI_FORMAT_R32G8X24_TYPELESS = 19,
+      DXGI_FORMAT_D32_FLOAT_S8X24_UINT = 20,
+      DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS = 21,
+      DXGI_FORMAT_X32_TYPELESS_G8X24_UINT = 22,
+      DXGI_FORMAT_R10G10B10A2_TYPELESS = 23,
+      DXGI_FORMAT_R10G10B10A2_UNORM = 24,
+      DXGI_FORMAT_R10G10B10A2_UINT = 25,
+      DXGI_FORMAT_R11G11B10_FLOAT = 26,
+      DXGI_FORMAT_R8G8B8A8_TYPELESS = 27,
+      DXGI_FORMAT_R8G8B8A8_UNORM = 28,
+      DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = 29,
+      DXGI_FORMAT_R8G8B8A8_UINT = 30,
+      DXGI_FORMAT_R8G8B8A8_SNORM = 31,
+      DXGI_FORMAT_R8G8B8A8_SINT = 32,
+      DXGI_FORMAT_R16G16_TYPELESS = 33,
+      DXGI_FORMAT_R16G16_FLOAT = 34,
+      DXGI_FORMAT_R16G16_UNORM = 35,
+      DXGI_FORMAT_R16G16_UINT = 36,
+      DXGI_FORMAT_R16G16_SNORM = 37,
+      DXGI_FORMAT_R16G16_SINT = 38,
+      DXGI_FORMAT_R32_TYPELESS = 39,
+      DXGI_FORMAT_D32_FLOAT = 40,
+      DXGI_FORMAT_R32_FLOAT = 41,
+      DXGI_FORMAT_R32_UINT = 42,
+      DXGI_FORMAT_R32_SINT = 43,
+      DXGI_FORMAT_R24G8_TYPELESS = 44,
+      DXGI_FORMAT_D24_UNORM_S8_UINT = 45,
+      DXGI_FORMAT_R24_UNORM_X8_TYPELESS = 46,
+      DXGI_FORMAT_X24_TYPELESS_G8_UINT = 47,
+      DXGI_FORMAT_R8G8_TYPELESS = 48,
+      DXGI_FORMAT_R8G8_UNORM = 49,
+      DXGI_FORMAT_R8G8_UINT = 50,
+      DXGI_FORMAT_R8G8_SNORM = 51,
+      DXGI_FORMAT_R8G8_SINT = 52,
+      DXGI_FORMAT_R16_TYPELESS = 53,
+      DXGI_FORMAT_R16_FLOAT = 54,
+      DXGI_FORMAT_D16_UNORM = 55,
+      DXGI_FORMAT_R16_UNORM = 56,
+      DXGI_FORMAT_R16_UINT = 57,
+      DXGI_FORMAT_R16_SNORM = 58,
+      DXGI_FORMAT_R16_SINT = 59,
+      DXGI_FORMAT_R8_TYPELESS = 60,
+      DXGI_FORMAT_R8_UNORM = 61,
+      DXGI_FORMAT_R8_UINT = 62,
+      DXGI_FORMAT_R8_SNORM = 63,
+      DXGI_FORMAT_R8_SINT = 64,
+      DXGI_FORMAT_A8_UNORM = 65,
+      DXGI_FORMAT_R1_UNORM = 66,
+      DXGI_FORMAT_R9G9B9E5_SHAREDEXP = 67,
+      DXGI_FORMAT_R8G8_B8G8_UNORM = 68,
+      DXGI_FORMAT_G8R8_G8B8_UNORM = 69,
+      DXGI_FORMAT_BC1_TYPELESS = 70,
+      DXGI_FORMAT_BC1_UNORM = 71,
+      DXGI_FORMAT_BC1_UNORM_SRGB = 72,
+      DXGI_FORMAT_BC2_TYPELESS = 73,
+      DXGI_FORMAT_BC2_UNORM = 74,
+      DXGI_FORMAT_BC2_UNORM_SRGB = 75,
+      DXGI_FORMAT_BC3_TYPELESS = 76,
+      DXGI_FORMAT_BC3_UNORM = 77,
+      DXGI_FORMAT_BC3_UNORM_SRGB = 78,
+      DXGI_FORMAT_BC4_TYPELESS = 79,
+      DXGI_FORMAT_BC4_UNORM = 80,
+      DXGI_FORMAT_BC4_SNORM = 81,
+      DXGI_FORMAT_BC5_TYPELESS = 82,
+      DXGI_FORMAT_BC5_UNORM = 83,
+      DXGI_FORMAT_BC5_SNORM = 84,
+      DXGI_FORMAT_B5G6R5_UNORM = 85,
+      DXGI_FORMAT_B5G5R5A1_UNORM = 86,
+      DXGI_FORMAT_B8G8R8A8_UNORM = 87,
+      DXGI_FORMAT_B8G8R8X8_UNORM = 88,
+      DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM = 89,
+      DXGI_FORMAT_B8G8R8A8_TYPELESS = 90,
+      DXGI_FORMAT_B8G8R8A8_UNORM_SRGB = 91,
+      DXGI_FORMAT_B8G8R8X8_TYPELESS = 92,
+      DXGI_FORMAT_B8G8R8X8_UNORM_SRGB = 93,
+      DXGI_FORMAT_BC6H_TYPELESS = 94,
+      DXGI_FORMAT_BC6H_UF16 = 95,
+      DXGI_FORMAT_BC6H_SF16 = 96,
+      DXGI_FORMAT_BC7_TYPELESS = 97,
+      DXGI_FORMAT_BC7_UNORM = 98,
+      DXGI_FORMAT_BC7_UNORM_SRGB = 99,
+      DXGI_FORMAT_AYUV = 100,
+      DXGI_FORMAT_Y410 = 101,
+      DXGI_FORMAT_Y416 = 102,
+      DXGI_FORMAT_NV12 = 103,
+      DXGI_FORMAT_P010 = 104,
+      DXGI_FORMAT_P016 = 105,
+      DXGI_FORMAT_420_OPAQUE = 106,
+      DXGI_FORMAT_YUY2 = 107,
+      DXGI_FORMAT_Y210 = 108,
+      DXGI_FORMAT_Y216 = 109,
+      DXGI_FORMAT_NV11 = 110,
+      DXGI_FORMAT_AI44 = 111,
+      DXGI_FORMAT_IA44 = 112,
+      DXGI_FORMAT_P8 = 113,
+      DXGI_FORMAT_A8P8 = 114,
+      DXGI_FORMAT_B4G4R4A4_UNORM = 115,
+      DXGI_FORMAT_FORCE_UINT = 0xffffffff
+   } DXGI_FORMAT;
+#endif
+
+   ///////////////////////////////////////////////////////////////////////////////////
+   //                           D3DFMT Formats                                      //
+   ///////////////////////////////////////////////////////////////////////////////////
+   enum D3DFMT
+   {
+      D3DFMT_UNKNOWN = 0,
+
+      D3DFMT_R8G8B8 = 20,
+      D3DFMT_A8R8G8B8 = 21,
+      D3DFMT_X8R8G8B8 = 22,
+      D3DFMT_R5G6B5 = 23,
+      D3DFMT_X1R5G5B5 = 24,
+      D3DFMT_A1R5G5B5 = 25,
+      D3DFMT_A4R4G4B4 = 26,
+      D3DFMT_R3G3B2 = 27,
+      D3DFMT_A8 = 28,
+      D3DFMT_A8R3G3B2 = 29,
+      D3DFMT_X4R4G4B4 = 30,
+      D3DFMT_A2B10G10R10 = 31,
+      D3DFMT_A8B8G8R8 = 32,
+      D3DFMT_X8B8G8R8 = 33,
+      D3DFMT_G16R16 = 34,
+      D3DFMT_A2R10G10B10 = 35,
+      D3DFMT_A16B16G16R16 = 36,
+
+      D3DFMT_A8P8 = 40,
+      D3DFMT_P8 = 41,
+
+      D3DFMT_L8 = 50,
+      D3DFMT_A8L8 = 51,
+      D3DFMT_A4L4 = 52,
+
+      D3DFMT_V8U8 = 60,
+      D3DFMT_L6V5U5 = 61,
+      D3DFMT_X8L8V8U8 = 62,
+      D3DFMT_Q8W8V8U8 = 63,
+      D3DFMT_V16U16 = 64,
+      D3DFMT_A2W10V10U10 = 67,
+
+      D3DFMT_UYVY = MakeFourCC('U', 'Y', 'V', 'Y'),
+      D3DFMT_R8G8_B8G8 = MakeFourCC('R', 'G', 'B', 'G'),
+      D3DFMT_YUY2 = MakeFourCC('Y', 'U', 'Y', '2'),
+      D3DFMT_G8R8_G8B8 = MakeFourCC('G', 'R', 'G', 'B'),
+      D3DFMT_DXT1 = MakeFourCC('D', 'X', 'T', '1'),
+      D3DFMT_DXT2 = MakeFourCC('D', 'X', 'T', '2'),
+      D3DFMT_DXT3 = MakeFourCC('D', 'X', 'T', '3'),
+      D3DFMT_DXT4 = MakeFourCC('D', 'X', 'T', '4'),
+      D3DFMT_DXT5 = MakeFourCC('D', 'X', 'T', '5'),
+
+      D3DFMT_ATI1 = MakeFourCC('A', 'T', 'I', '1'),
+      D3DFMT_AT1N = MakeFourCC('A', 'T', '1', 'N'),
+      D3DFMT_ATI2 = MakeFourCC('A', 'T', 'I', '2'),
+      D3DFMT_AT2N = MakeFourCC('A', 'T', '2', 'N'),
+
+      D3DFMT_BC4U = MakeFourCC('B', 'C', '4', 'U'),
+      D3DFMT_BC4S = MakeFourCC('B', 'C', '4', 'S'),
+      D3DFMT_BC5U = MakeFourCC('B', 'C', '5', 'U'),
+      D3DFMT_BC5S = MakeFourCC('B', 'C', '5', 'S'),
+
+      D3DFMT_ETC = MakeFourCC('E', 'T', 'C', ' '),
+      D3DFMT_ETC1 = MakeFourCC('E', 'T', 'C', '1'),
+      D3DFMT_ATC = MakeFourCC('A', 'T', 'C', ' '),
+      D3DFMT_ATCA = MakeFourCC('A', 'T', 'C', 'A'),
+      D3DFMT_ATCI = MakeFourCC('A', 'T', 'C', 'I'),
+
+      D3DFMT_POWERVR_2BPP = MakeFourCC('P', 'T', 'C', '2'),
+      D3DFMT_POWERVR_4BPP = MakeFourCC('P', 'T', 'C', '4'),
+
+      D3DFMT_D16_LOCKABLE = 70,
+      D3DFMT_D32 = 71,
+      D3DFMT_D15S1 = 73,
+      D3DFMT_D24S8 = 75,
+      D3DFMT_D24X8 = 77,
+      D3DFMT_D24X4S4 = 79,
+      D3DFMT_D16 = 80,
+
+      D3DFMT_D32F_LOCKABLE = 82,
+      D3DFMT_D24FS8 = 83,
+
+      D3DFMT_L16 = 81,
+
+      D3DFMT_VERTEXDATA = 100,
+      D3DFMT_INDEX16 = 101,
+      D3DFMT_INDEX32 = 102,
+
+      D3DFMT_Q16W16V16U16 = 110,
+
+      D3DFMT_MULTI2_ARGB8 = MakeFourCC('M', 'E', 'T', '1'),
+
+      D3DFMT_R16F = 111,
+      D3DFMT_G16R16F = 112,
+      D3DFMT_A16B16G16R16F = 113,
+
+      D3DFMT_R32F = 114,
+      D3DFMT_G32R32F = 115,
+      D3DFMT_A32B32G32R32F = 116,
+
+      D3DFMT_CxV8U8 = 117,
+
+      D3DFMT_DX10 = MakeFourCC('D', 'X', '1', '0'),
+
+      D3DFMT_FORCE_DWORD = 0x7fffffff
+   };
+
+   ///////////////////////////////////////////////////////////////////////////////////
+   //                               Defines                                         //
+   ///////////////////////////////////////////////////////////////////////////////////
+   #pragma pack(push,1)
+
+   #define DDS_HEADER_SIZE       124
+   #define DDS_HEADER_DX10_SIZE  20
+   #define DDS_MAGIC       0x20534444  // "DDS "
+   #define DDS_FOURCC      0x00000004  // DDPF_FOURCC
+   #define DDS_RGB         0x00000040  // DDPF_RGB
+   #define DDS_RGBA        0x00000041  // DDPF_RGB | DDPF_ALPHAPIXELS
+   #define DDS_LUMINANCE   0x00020000  // DDPF_LUMINANCE
+   #define DDS_LUMINANCEA  0x00020001  // DDPF_LUMINANCE | DDPF_ALPHAPIXELS
+   #define DDS_ALPHAPIXELS 0x00000001  // DDPF_ALPHAPIXELS
+   #define DDS_ALPHA       0x00000002  // DDPF_ALPHA
+   #define DDS_PAL8        0x00000020  // DDPF_PALETTEINDEXED8
+   #define DDS_BUMPDUDV    0x00080000  // DDPF_BUMPDUDV
+   #define DDS_YUV         0x00000200  //DDPF_YUV
+
+   #define DDS_HEADER_FLAGS_TEXTURE        0x00001007  // DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT 
+   #define DDS_HEADER_FLAGS_MIPMAP         0x00020000  // DDSD_MIPMAPCOUNT
+   #define DDS_HEADER_FLAGS_VOLUME         0x00800000  // DDSD_DEPTH
+   #define DDS_HEADER_FLAGS_PITCH          0x00000008  // DDSD_PITCH
+   #define DDS_HEADER_FLAGS_LINEARSIZE     0x00080000  // DDSD_LINEARSIZE
+
+   #define DDS_HEIGHT 0x00000002 // DDSD_HEIGHT
+   #define DDS_WIDTH  0x00000004 // DDSD_WIDTH
+
+   #define DDS_SURFACE_FLAGS_TEXTURE 0x00001000 // DDSCAPS_TEXTURE
+   #define DDS_SURFACE_FLAGS_MIPMAP  0x00400008 // DDSCAPS_COMPLEX | DDSCAPS_MIPMAP
+   #define DDS_SURFACE_FLAGS_CUBEMAP 0x00000008 // DDSCAPS_COMPLEX
+
+   #define DDS_CUBEMAP 0x00000200 // DDSCAPS2_CUBEMAP
+   #define DDS_CUBEMAP_POSITIVEX 0x00000400 //  DDSCAPS2_CUBEMAP_POSITIVEX
+   #define DDS_CUBEMAP_NEGATIVEX 0x00000800 //  DDSCAPS2_CUBEMAP_NEGATIVEX
+   #define DDS_CUBEMAP_POSITIVEY 0x00001000 //  DDSCAPS2_CUBEMAP_POSITIVEY
+   #define DDS_CUBEMAP_NEGATIVEY 0x00002000 //  DDSCAPS2_CUBEMAP_NEGATIVEY
+   #define DDS_CUBEMAP_POSITIVEZ 0x00004000 //  DDSCAPS2_CUBEMAP_POSITIVEZ
+   #define DDS_CUBEMAP_NEGATIVEZ 0x00008000 //  DDSCAPS2_CUBEMAP_NEGATIVEZ
+
+   #define DDS_CUBEMAP_ALLFACES ( DDS_CUBEMAP | DDS_CUBEMAP_POSITIVEX | DDS_CUBEMAP_NEGATIVEX |\
+                                  DDS_CUBEMAP_POSITIVEY | DDS_CUBEMAP_NEGATIVEY |\
+                                  DDS_CUBEMAP_POSITIVEZ | DDS_CUBEMAP_NEGATIVEZ )
+
+   #define DDS_FLAGS_VOLUME 0x00200000 // DDSCAPS2_VOLUME
+
+   ///////////////////////////////////////////////////////////////////////////////////
+   //                                Enums                                          //
+   ///////////////////////////////////////////////////////////////////////////////////
+   // Subset here matches D3D10_RESOURCE_DIMENSION and D3D11_RESOURCE_DIMENSION
+   enum DDS_RESOURCE_DIMENSION
+   {
+      DDS_DIMENSION_TEXTURE1D = 2,
+      DDS_DIMENSION_TEXTURE2D = 3,
+      DDS_DIMENSION_TEXTURE3D = 4,
+   };
+
+   // Subset here matches D3D10_RESOURCE_MISC_FLAG and D3D11_RESOURCE_MISC_FLAG
+   enum DDS_RESOURCE_MISC_FLAG
+   {
+      DDS_RESOURCE_MISC_TEXTURECUBE = 0x4L,
+   };
+
+   enum DDS_MISC_FLAGS2
+   {
+      DDS_MISC_FLAGS2_ALPHA_MODE_MASK = 0x7L,
+   };
+
+   enum DDS_ALPHA_MODE
+   {
+      DDS_ALPHA_MODE_UNKNOWN = 0,
+      DDS_ALPHA_MODE_STRAIGHT = 1,
+      DDS_ALPHA_MODE_PREMULTIPLIED = 2,
+      DDS_ALPHA_MODE_OPAQUE = 3,
+      DDS_ALPHA_MODE_CUSTOM = 4,
+   };
+
+   enum D3D10_RESOURCE_DIMENSION
+   {
+      D3D10_RESOURCE_DIMENSION_UNKNOWN = 0,
+      D3D10_RESOURCE_DIMENSION_BUFFER = 1,
+      D3D10_RESOURCE_DIMENSION_TEXTURE1D = 2,
+      D3D10_RESOURCE_DIMENSION_TEXTURE2D = 3,
+      D3D10_RESOURCE_DIMENSION_TEXTURE3D = 4
+   };
+
+   enum D3D10_RESOURCE_MISC_FLAG
+   {
+      D3D10_RESOURCE_MISC_GENERATE_MIPS = 0x1L,
+      D3D10_RESOURCE_MISC_SHARED = 0x2L,
+      D3D10_RESOURCE_MISC_TEXTURECUBE = 0x4L,
+      D3D10_RESOURCE_MISC_SHARED_KEYEDMUTEX = 0x10L,
+      D3D10_RESOURCE_MISC_GDI_COMPATIBLE = 0x20L,
+   };
+
+   ///////////////////////////////////////////////////////////////////////////////////
+   //                                Structs                                        //
+   ///////////////////////////////////////////////////////////////////////////////////
+
+   struct DDS_PIXELFORMAT
+   {
+      U32   size;
+      U32   flags;
+      U32   fourCC;
+      U32   bpp;
+      U32   RBitMask;
+      U32   GBitMask;
+      U32   BBitMask;
+      U32   ABitMask;
+
+      bool operator==(const DDS_PIXELFORMAT& _test) const
+      {
+         return ( size == _test.size &&
+                  flags == _test.flags &&
+                  fourCC == _test.fourCC &&
+                  bpp == _test.bpp &&
+                  RBitMask == _test.RBitMask &&
+                  GBitMask == _test.GBitMask &&
+                  BBitMask == _test.BBitMask &&
+                  ABitMask == _test.ABitMask);
+      }
+   };
+
+   struct DDS_HEADER
+   {
+      U32   size;
+      U32   flags;
+      U32   height;
+      U32   width;
+      U32   pitchOrLinearSize;
+      U32   depth; // only if DDS_HEADER_FLAGS_VOLUME is set in dwFlags
+      U32   mipMapCount;
+      U32   reserved1[11];
+      DDS_PIXELFORMAT ddspf;
+      U32   surfaceFlags;
+      U32   cubemapFlags;
+      U32   reserved2[3];
+   };
+
+   struct DDS_HEADER_DXT10
+   {
+      DXGI_FORMAT dxgiFormat;
+      U32    resourceDimension;
+      U32    miscFlag; // see DDS_RESOURCE_MISC_FLAG
+      U32    arraySize;
+      U32    miscFlags2; // see DDS_MISC_FLAGS2
+   };
+
+   ///////////////////////////////////////////////////////////////////////////////////
+   //                            Pixel Formats                                      //
+   ///////////////////////////////////////////////////////////////////////////////////
+
+   const DDS_PIXELFORMAT DDSPF_DXT1 =
+   { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, D3DFMT_DXT1, 0, 0, 0, 0, 0 };
+
+   const DDS_PIXELFORMAT DDSPF_DXT2 =
+   { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, D3DFMT_DXT2, 0, 0, 0, 0, 0 };
+
+   const DDS_PIXELFORMAT DDSPF_DXT3 =
+   { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, D3DFMT_DXT3, 0, 0, 0, 0, 0 };
+
+   const DDS_PIXELFORMAT DDSPF_DXT4 =
+   { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, D3DFMT_DXT4, 0, 0, 0, 0, 0 };
+
+   const DDS_PIXELFORMAT DDSPF_DXT5 =
+   { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, D3DFMT_DXT5, 0, 0, 0, 0, 0 };
+
+   const DDS_PIXELFORMAT DDSPF_BC4_UNORM =
+   { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, D3DFMT_BC4U, 0, 0, 0, 0, 0 };
+
+   const DDS_PIXELFORMAT DDSPF_BC4_SNORM =
+   { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, D3DFMT_BC4S, 0, 0, 0, 0, 0 };
+
+   //todo check diff between this and ('B','C','5','U')
+   const DDS_PIXELFORMAT DDSPF_ATI2 =
+   { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, D3DFMT_ATI2, 0, 0, 0, 0, 0 };
+
+   const DDS_PIXELFORMAT DDSPF_ATI1 =
+   { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, D3DFMT_ATI1, 0, 0, 0, 0, 0 };
+
+   const DDS_PIXELFORMAT DDSPF_BC5_UNORM =
+   { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, D3DFMT_BC5U, 0, 0, 0, 0, 0 };
+
+   const DDS_PIXELFORMAT DDSPF_BC5_SNORM =
+   { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, D3DFMT_BC5S, 0, 0, 0, 0, 0 };
+
+   const DDS_PIXELFORMAT DDSPF_R8G8_B8G8 =
+   { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, D3DFMT_R8G8_B8G8, 0, 0, 0, 0, 0 };
+
+   const DDS_PIXELFORMAT DDSPF_G8R8_G8B8 =
+   { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, D3DFMT_G8R8_G8B8, 0, 0, 0, 0, 0 };
+
+   const DDS_PIXELFORMAT DDSPF_YUY2 =
+   { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, D3DFMT_YUY2, 0, 0, 0, 0, 0 };
+
+   const DDS_PIXELFORMAT DDSPF_A8R8G8B8 =
+   { sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 };
+
+   const DDS_PIXELFORMAT DDSPF_X8R8G8B8 =
+   { sizeof(DDS_PIXELFORMAT), DDS_RGB,  0, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000 };
+
+   const DDS_PIXELFORMAT DDSPF_A8B8G8R8 =
+   { sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 };
+
+   const DDS_PIXELFORMAT DDSPF_X8B8G8R8 =
+   { sizeof(DDS_PIXELFORMAT), DDS_RGB,  0, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000 };
+
+   const DDS_PIXELFORMAT DDSPF_G16R16 =
+   { sizeof(DDS_PIXELFORMAT), DDS_RGB,  0, 32, 0x0000ffff, 0xffff0000, 0x00000000, 0x00000000 };
+
+   const DDS_PIXELFORMAT DDSPF_R5G6B5 =
+   { sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 16, 0x0000f800, 0x000007e0, 0x0000001f, 0x00000000 };
+
+   const DDS_PIXELFORMAT DDSPF_A1R5G5B5 =
+   { sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 16, 0x00007c00, 0x000003e0, 0x0000001f, 0x00008000 };
+
+   const DDS_PIXELFORMAT DDSPF_A4R4G4B4 =
+   { sizeof(DDS_PIXELFORMAT), DDS_RGBA, 0, 16, 0x00000f00, 0x000000f0, 0x0000000f, 0x0000f000 };
+
+   const DDS_PIXELFORMAT DDSPF_R8G8B8 =
+   { sizeof(DDS_PIXELFORMAT), DDS_RGB, 0, 24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000 };
+
+   const DDS_PIXELFORMAT DDSPF_L8 =
+   { sizeof(DDS_PIXELFORMAT), DDS_LUMINANCE, 0,  8, 0xff, 0x00, 0x00, 0x00 };
+
+   const DDS_PIXELFORMAT DDSPF_L16 =
+   { sizeof(DDS_PIXELFORMAT), DDS_LUMINANCE, 0, 16, 0xffff, 0x0000, 0x0000, 0x0000 };
+
+   const DDS_PIXELFORMAT DDSPF_A8L8 =
+   { sizeof(DDS_PIXELFORMAT), DDS_LUMINANCEA, 0, 16, 0x00ff, 0x0000, 0x0000, 0xff00 };
+
+   const DDS_PIXELFORMAT DDSPF_A4L4 =
+   { sizeof(DDS_PIXELFORMAT), DDS_LUMINANCEA, 0, 8, 0x0000000f, 0x0000, 0x0000, 0x000000f0 };
+
+   const DDS_PIXELFORMAT DDSPF_A8 =
+   { sizeof(DDS_PIXELFORMAT), DDS_ALPHA, 0, 8, 0x00, 0x00, 0x00, 0xff };
+
+   const DDS_PIXELFORMAT DDSPF_V8U8 =
+   { sizeof(DDS_PIXELFORMAT), DDS_BUMPDUDV, 0, 16, 0x00ff, 0xff00, 0x0000, 0x0000 };
+
+   const DDS_PIXELFORMAT DDSPF_Q8W8V8U8 =
+   { sizeof(DDS_PIXELFORMAT), DDS_BUMPDUDV, 0, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 };
+
+   const DDS_PIXELFORMAT DDSPF_V16U16 =
+   { sizeof(DDS_PIXELFORMAT), DDS_BUMPDUDV, 0, 32, 0x0000ffff, 0xffff0000, 0x00000000, 0x00000000 };
+
+   // D3DFMT_A2R10G10B10/D3DFMT_A2B10G10R10 should be written using DX10 extension to avoid D3DX 10:10:10:2 reversal issue
+
+   // This indicates the DDS_HEADER_DXT10 extension is present (the format is in dxgiFormat)
+   const DDS_PIXELFORMAT DDSPF_DX10 =
+   { sizeof(DDS_PIXELFORMAT), DDS_FOURCC, D3DFMT_DX10, 0, 0, 0, 0, 0 };
+
+   #pragma pack(pop)
+
+   ///////////////////////////////////////////////////////////////////////////////////
+   //                               Functions                                       //
+   ///////////////////////////////////////////////////////////////////////////////////
+
+   //get DDS_PIXELFORMAT struct from GFXFormat - todo more formats
+   const DDS_PIXELFORMAT getDDSFormat(const GFXFormat format)
+   {
+      switch (format)
+      {
+         case GFXFormatA4L4:     return DDSPF_A4L4;
+         case GFXFormatL8:       return DDSPF_L8;
+         case GFXFormatA8:       return DDSPF_A8;
+         case GFXFormatA8L8:     return DDSPF_A8L8;
+         case GFXFormatL16:      return DDSPF_L16;
+         case GFXFormatR5G6B5:   return DDSPF_R5G6B5;
+         case GFXFormatR5G5B5A1: return DDSPF_A1R5G5B5;
+         case GFXFormatR8G8B8:   return DDSPF_R8G8B8;
+         case GFXFormatR8G8B8A8: return DDSPF_A8R8G8B8;
+         case GFXFormatR8G8B8X8: return DDSPF_X8R8G8B8;
+         case GFXFormatB8G8R8A8: return DDSPF_A8B8G8R8;
+         case GFXFormatR16G16B16A16F:
+         case GFXFormatR32G32B32A32F: return DDSPF_DX10;
+         //compressed
+         case GFXFormatBC1:      return DDSPF_DXT1;
+         case GFXFormatBC2:      return DDSPF_DXT3;
+         case GFXFormatBC3:      return DDSPF_DXT5;
+         case GFXFormatBC4:      return DDSPF_ATI1;
+         case GFXFormatBC5:      return DDSPF_ATI2;
+         default:
+         {
+            Con::errorf("dds::getDDSFormat: unknown format");
+            return DDSPF_A8R8G8B8;
+         }
+      }
+   }
+
+   //get DXGI_FORMAT from GFXFormat - todo more formats
+   const DXGI_FORMAT getDXGIFormat(const GFXFormat format)
+   {
+      switch (format)
+      {
+         //byte
+         case GFXFormatR5G6B5:         return DXGI_FORMAT_B5G6R5_UNORM;
+         case GFXFormatR5G5B5A1:       return DXGI_FORMAT_B5G5R5A1_UNORM;
+         case GFXFormatB8G8R8A8:       return DXGI_FORMAT_R8G8B8A8_UNORM;
+         case GFXFormatR8G8B8A8:       return DXGI_FORMAT_B8G8R8A8_UNORM;
+         case GFXFormatR8G8B8X8:       return DXGI_FORMAT_B8G8R8X8_UNORM;
+         case GFXFormatR10G10B10A2:    return DXGI_FORMAT_R10G10B10A2_UNORM;
+         //uint
+         case GFXFormatR16G16:         return DXGI_FORMAT_R16G16_UINT;
+         case GFXFormatR16G16B16A16:   return DXGI_FORMAT_R16G16B16A16_UINT;
+         //float
+         case GFXFormatR16F:           return DXGI_FORMAT_R16_FLOAT;
+         case GFXFormatR32F:           return DXGI_FORMAT_R32_FLOAT;
+         case GFXFormatR16G16B16A16F:  return DXGI_FORMAT_R16G16B16A16_FLOAT;
+         case GFXFormatR32G32B32A32F:  return DXGI_FORMAT_R32G32B32A32_FLOAT;
+         //compressed
+         case GFXFormatBC1:            return DXGI_FORMAT_BC1_UNORM;
+         case GFXFormatBC2:            return DXGI_FORMAT_BC2_UNORM;
+         case GFXFormatBC3:            return DXGI_FORMAT_BC3_UNORM;
+         case GFXFormatBC4:            return DXGI_FORMAT_BC4_UNORM;
+         case GFXFormatBC5:            return DXGI_FORMAT_BC5_UNORM;
+         default:
+         {
+            Con::errorf("dds::getDXGIFormat: unknown format");
+            return DXGI_FORMAT_UNKNOWN;
+         }
+      }
+   }
+
+   //get GFXFormat from D3DFMT - todo more formats
+   const GFXFormat getGFXFormat(const D3DFMT format)
+   {
+      switch (format)
+      {
+         //byte        
+         case D3DFMT_A4L4:          return GFXFormatA4L4;
+         case D3DFMT_L8:            return GFXFormatL8;
+         case D3DFMT_A8:            return GFXFormatA8;
+         case D3DFMT_A8L8:          return GFXFormatA8L8;
+         case D3DFMT_L16:           return GFXFormatL16;
+         case D3DFMT_R5G6B5:        return GFXFormatR5G6B5;
+         case D3DFMT_A1R5G5B5:      return GFXFormatR5G5B5A1;
+         case D3DFMT_R8G8B8:        return GFXFormatR8G8B8;
+         case D3DFMT_A8R8G8B8:      return GFXFormatR8G8B8A8;
+         case D3DFMT_X8R8G8B8:      return GFXFormatR8G8B8A8;
+         case D3DFMT_A8B8G8R8:      return GFXFormatB8G8R8A8;
+         case D3DFMT_X8B8G8R8:      return GFXFormatB8G8R8A8;
+         //uint
+         case D3DFMT_G16R16:        return GFXFormatR16G16;
+         case D3DFMT_A16B16G16R16:  return GFXFormatR16G16B16A16;
+         //float
+         case D3DFMT_R16F:          return GFXFormatR16F;
+         case D3DFMT_R32F:          return GFXFormatR32F;
+         case D3DFMT_A16B16G16R16F: return GFXFormatR16G16B16A16F;
+         case D3DFMT_A32B32G32R32F: return GFXFormatR32G32B32A32F;
+         //compressed
+         case D3DFMT_DXT1:          return GFXFormatBC1;
+         case D3DFMT_DXT2:          
+         case D3DFMT_DXT3:          return GFXFormatBC2;
+         case D3DFMT_DXT4:
+         case D3DFMT_DXT5:          return GFXFormatBC3;
+         case D3DFMT_ATI1:          return GFXFormatBC4;
+         case D3DFMT_ATI2:          return GFXFormatBC5;
+         default:
+         {
+            Con::errorf("dds::getGFXFormat: unknown format");
+            return GFXFormat_FIRST;
+         }
+      }
+   }
+
+   //get GFXFormat from DXGI_FORMAT - todo more formats
+   const GFXFormat getGFXFormat(const DXGI_FORMAT format)
+   {
+      switch (format)
+      {
+         //byte
+         case DXGI_FORMAT_B5G6R5_UNORM:         return GFXFormatR5G6B5;
+         case DXGI_FORMAT_B5G5R5A1_UNORM:       return GFXFormatR5G5B5A1;
+         case DXGI_FORMAT_R8G8B8A8_UNORM:       return GFXFormatB8G8R8A8;
+         case DXGI_FORMAT_B8G8R8A8_UNORM:       return GFXFormatR8G8B8A8;
+         case DXGI_FORMAT_B8G8R8X8_UNORM:       return GFXFormatR8G8B8X8;
+         case DXGI_FORMAT_R10G10B10A2_UNORM:    return GFXFormatR10G10B10A2;
+         //uint
+         case DXGI_FORMAT_R16G16_UINT:          return GFXFormatR16G16;
+         case DXGI_FORMAT_R16G16B16A16_UINT:    return GFXFormatR16G16B16A16;
+         //float
+         case DXGI_FORMAT_R16_FLOAT:            return GFXFormatR16F;
+         case DXGI_FORMAT_R32_FLOAT:            return GFXFormatR32F;
+         case DXGI_FORMAT_R16G16B16A16_FLOAT:   return GFXFormatR16G16B16A16F;
+         case DXGI_FORMAT_R32G32B32A32_FLOAT:   return GFXFormatR32G32B32A32F;
+         //compressed
+         case DXGI_FORMAT_BC1_UNORM:            return GFXFormatBC1;
+         case DXGI_FORMAT_BC2_UNORM:            return GFXFormatBC2;
+         case DXGI_FORMAT_BC3_UNORM:            return GFXFormatBC3;
+         case DXGI_FORMAT_BC4_UNORM:            return GFXFormatBC4;
+         case DXGI_FORMAT_BC5_UNORM:            return GFXFormatBC5;
+         default:
+         {
+            Con::errorf("dds::getGFXFormatDxgi: unknown format");
+            return GFXFormat_FIRST;
+         }
+      }
+   }
+
+   //get GFXFormat from DDS_PIXELFORMAT struct - todo more formats
+   const GFXFormat getGFXFormat(const DDS_PIXELFORMAT &format)
+   {
+      if (format == DDSPF_DXT1)
+         return GFXFormatBC1;
+      else if (format == DDSPF_DXT2)
+         return GFXFormatBC2;
+      else if (format == DDSPF_DXT3)
+         return GFXFormatBC2;
+      else if (format == DDSPF_DXT4)
+         return GFXFormatBC3;
+      else if (format == DDSPF_DXT5)
+         return GFXFormatBC3;
+      else if (format == DDSPF_ATI1)
+         return GFXFormatBC4;
+      else if (format == DDSPF_ATI2)
+         return GFXFormatBC5;
+      else if (format == DDSPF_A8R8G8B8)
+         return GFXFormatR8G8B8A8;
+      else if (format == DDSPF_X8R8G8B8)
+         return GFXFormatR8G8B8A8;
+      else if (format == DDSPF_A8B8G8R8)
+         return GFXFormatB8G8R8A8;
+      else if (format == DDSPF_X8B8G8R8)
+         return GFXFormatB8G8R8A8;
+      else if (format == DDSPF_R8G8B8)
+         return GFXFormatR8G8B8;
+      else if (format == DDSPF_A8L8)
+         return GFXFormatA8L8;
+      else if (format == DDSPF_A4L4)
+         return GFXFormatA4L4;
+      else if (format == DDSPF_A8)
+         return GFXFormatA8;
+      else if (format == DDSPF_L8)
+         return GFXFormatL8;
+      else if (format == DDSPF_R5G6B5)
+         return GFXFormatR5G6B5;
+      else if (format == DDSPF_A1R5G5B5)
+         return GFXFormatR5G5B5A1;
+      else
+      {
+         Con::errorf("dds::getGFXFormat: unknown format");
+         return GFXFormat_FIRST;
+      }
+   }
+
+   //get GFXFormat from fourcc value - todo more formats
+   const GFXFormat getGFXFormat(const U32 fourcc)
+   {
+      switch (fourcc)
+      {
+         case D3DFMT_DXT1: return GFXFormatBC1;
+         case D3DFMT_DXT2:
+         case D3DFMT_DXT3: return GFXFormatBC2;
+         case D3DFMT_DXT4:
+         case D3DFMT_DXT5: return GFXFormatBC3;
+         case D3DFMT_ATI1: return GFXFormatBC4;
+         case D3DFMT_ATI2: return GFXFormatBC5;
+         case D3DFMT_A16B16G16R16F: return GFXFormatR16G16B16A16F;
+         case D3DFMT_A32B32G32R32F: return GFXFormatR32G32B32A32F;
+         default:
+         {
+            Con::errorf("dds::getGFXFormatFourcc: unknown format");
+            return GFXFormat_FIRST;
+         }
+      }
+   }
+
+   const bool validateHeader(const DDS_HEADER &header)
+   {
+      if (header.size != DDS_HEADER_SIZE)
+      {
+         Con::errorf("DDS_HEADER - incorrect header size. Expected 124 bytes.");
+         return false;
+      }
+
+      if (!(header.flags & DDS_HEADER_FLAGS_TEXTURE))
+      {
+         Con::errorf("DDS_HEADER - incorrect surface description flags.");
+         return false;
+      }
+
+      if ((header.flags & (DDS_HEADER_FLAGS_LINEARSIZE | DDS_HEADER_FLAGS_PITCH)) == (DDS_HEADER_FLAGS_LINEARSIZE | DDS_HEADER_FLAGS_PITCH))
+      {
+         // Both are invalid!
+         Con::errorf("DDS_HEADER - encountered both DDSD_LINEARSIZE and DDSD_PITCH!");
+         return false;
+      }
+
+      return true;
+   }
+
+   const bool validateHeaderDx10(const DDS_HEADER_DXT10 &header)
+   {
+      if (sizeof(DDS_HEADER_DXT10) != DDS_HEADER_DX10_SIZE)
+      {
+         Con::errorf("DDS_HEADER_DXT10 - incorrect header size. Expected 20 bytes.");
+         return false;
+      }
+
+      return true;
+   }
+
+}
+
+#endif

+ 265 - 405
Engine/source/gfx/bitmap/ddsLoader.cpp → Engine/source/gfx/bitmap/ddsFile.cpp

@@ -22,7 +22,9 @@
 
 
 #include "platform/platform.h"
 #include "platform/platform.h"
 #include "gfx/bitmap/ddsFile.h"
 #include "gfx/bitmap/ddsFile.h"
-
+#include "gfx/bitmap/ddsData.h"
+#include "gfx/bitmap/bitmapUtils.h"
+#include "gfx/bitmap/imageUtils.h"
 #include "gfx/gfxDevice.h"
 #include "gfx/gfxDevice.h"
 #include "core/util/fourcc.h"
 #include "core/util/fourcc.h"
 #include "console/console.h"
 #include "console/console.h"
@@ -31,56 +33,11 @@
 #include "gfx/bitmap/gBitmap.h"
 #include "gfx/bitmap/gBitmap.h"
 #include "console/engineAPI.h"
 #include "console/engineAPI.h"
 
 
-
+#include <squish.h>
 
 
 S32 DDSFile::smActiveCopies = 0;
 S32 DDSFile::smActiveCopies = 0;
 U32 DDSFile::smDropMipCount = 0;
 U32 DDSFile::smDropMipCount = 0;
 
 
-// These were copied from the DX9 docs. The names are changed
-// from the "real" defines since not all platforms have them.
-enum DDSSurfaceDescFlags
-{
-   DDSDCaps         = 0x00000001l,
-   DDSDHeight       = 0x00000002l,
-   DDSDWidth        = 0x00000004l,
-   DDSDPitch        = 0x00000008l,
-   DDSDPixelFormat  = 0x00001000l,
-   DDSDMipMapCount  = 0x00020000l,
-   DDSDLinearSize   = 0x00080000l,
-   DDSDDepth        = 0x00800000l,
-};
-
-enum DDSPixelFormatFlags
-{
-   DDPFAlphaPixels   = 0x00000001,
-   DDPFFourCC        = 0x00000004,
-   DDPFRGB           = 0x00000040,
-   DDPFLUMINANCE     = 0x00020000
-};
-
-
-enum DDSCapFlags
-{
-   DDSCAPSComplex = 0x00000008,
-   DDSCAPSTexture = 0x00001000,
-   DDSCAPSMipMap  = 0x00400000,
-
-   DDSCAPS2Cubemap = 0x00000200,
-   DDSCAPS2Cubemap_POSITIVEX = 0x00000400,
-   DDSCAPS2Cubemap_NEGATIVEX = 0x00000800,
-   DDSCAPS2Cubemap_POSITIVEY = 0x00001000,
-   DDSCAPS2Cubemap_NEGATIVEY = 0x00002000,
-   DDSCAPS2Cubemap_POSITIVEZ = 0x00004000,
-   DDSCAPS2Cubemap_NEGATIVEZ = 0x00008000,
-   DDSCAPS2Volume = 0x00200000,
-};
-
-#define FOURCC_DXT1  (MakeFourCC('D','X','T','1'))
-#define FOURCC_DXT2  (MakeFourCC('D','X','T','2'))
-#define FOURCC_DXT3  (MakeFourCC('D','X','T','3'))
-#define FOURCC_DXT4  (MakeFourCC('D','X','T','4'))
-#define FOURCC_DXT5  (MakeFourCC('D','X','T','5'))
-
 DDSFile::DDSFile( const DDSFile &dds )
 DDSFile::DDSFile( const DDSFile &dds )
    :  mFlags( dds.mFlags ),
    :  mFlags( dds.mFlags ),
       mHeight( dds.mHeight ),
       mHeight( dds.mHeight ),
@@ -133,13 +90,13 @@ U32 DDSFile::getSurfacePitch( U32 mipLevel ) const
 
 
       switch(mFormat)
       switch(mFormat)
       {
       {
-      case GFXFormatDXT1:
+      case GFXFormatBC1:
+      case GFXFormatBC4:
          sizeMultiple = 8;
          sizeMultiple = 8;
          break;
          break;
-      case GFXFormatDXT2:
-      case GFXFormatDXT3:
-      case GFXFormatDXT4:
-      case GFXFormatDXT5:
+      case GFXFormatBC2:
+      case GFXFormatBC3:      
+      case GFXFormatBC5:
          sizeMultiple = 16;
          sizeMultiple = 16;
          break;
          break;
       default:
       default:
@@ -172,13 +129,13 @@ U32 DDSFile::getSurfaceSize( U32 height, U32 width, U32 mipLevel ) const
 
 
       switch(mFormat)
       switch(mFormat)
       {
       {
-      case GFXFormatDXT1:
+      case GFXFormatBC1:
+      case GFXFormatBC4:
          sizeMultiple = 8;
          sizeMultiple = 8;
          break;
          break;
-      case GFXFormatDXT2:
-      case GFXFormatDXT3:
-      case GFXFormatDXT4:
-      case GFXFormatDXT5:
+      case GFXFormatBC2:
+      case GFXFormatBC3:      
+      case GFXFormatBC5:
          sizeMultiple = 16;
          sizeMultiple = 16;
          break;
          break;
       default:
       default:
@@ -197,25 +154,34 @@ U32 DDSFile::getSurfaceSize( U32 height, U32 width, U32 mipLevel ) const
 U32 DDSFile::getSizeInBytes() const
 U32 DDSFile::getSizeInBytes() const
 {
 {
    // TODO: This doesn't take mDepth into account, so
    // TODO: This doesn't take mDepth into account, so
-   // it doesn't work right for volume or cubemap textures!
+   // it doesn't work right for volume textures!
 
 
    U32 bytes = 0;
    U32 bytes = 0;
-   for ( U32 i=0; i < mMipMapCount; i++ )
-      bytes += getSurfaceSize( mHeight, mWidth, i );
+   if (mFlags.test(CubeMapFlag))
+   {
+      for(U32 cubeFace=0;cubeFace < Cubemap_Surface_Count;cubeFace++)
+         for (U32 i = 0; i < mMipMapCount; i++)
+            bytes += getSurfaceSize(mHeight, mWidth, i);
+   }
+   else
+   {
+      for (U32 i = 0; i < mMipMapCount; i++)
+         bytes += getSurfaceSize(mHeight, mWidth, i);
+   }
 
 
    return bytes;
    return bytes;
 }
 }
 
 
 U32 DDSFile::getSizeInBytes( GFXFormat format, U32 height, U32 width, U32 mipLevels )
 U32 DDSFile::getSizeInBytes( GFXFormat format, U32 height, U32 width, U32 mipLevels )
 {
 {
-   AssertFatal( format >= GFXFormatDXT1 && format <= GFXFormatDXT5, 
-      "DDSFile::getSizeInBytes - Must be a DXT format!" );
+   AssertFatal( ImageUtil::isCompressedFormat(format), 
+      "DDSFile::getSizeInBytes - Must be a Block Compression format!" );
 
 
    // From the directX docs:
    // From the directX docs:
    // max(1, width ÷ 4) x max(1, height ÷ 4) x 8(DXT1) or 16(DXT2-5)
    // max(1, width ÷ 4) x max(1, height ÷ 4) x 8(DXT1) or 16(DXT2-5)
 
 
    U32 sizeMultiple = 0;
    U32 sizeMultiple = 0;
-   if ( format == GFXFormatDXT1 )
+   if ( format == GFXFormatBC1 || format == GFXFormatBC1_SRGB || format == GFXFormatBC4)
       sizeMultiple = 8;
       sizeMultiple = 8;
    else
    else
       sizeMultiple = 16;
       sizeMultiple = 16;
@@ -236,317 +202,146 @@ U32 DDSFile::getSizeInBytes( GFXFormat format, U32 height, U32 width, U32 mipLev
 
 
 bool DDSFile::readHeader(Stream &s)
 bool DDSFile::readHeader(Stream &s)
 {
 {
-   U32 tmp;
-
+   U32 fourcc;
    // Read the FOURCC
    // Read the FOURCC
-   s.read(&tmp);
+   s.read(&fourcc);
 
 
-   if(tmp != MakeFourCC('D', 'D', 'S', ' '))
+   if(fourcc != DDS_MAGIC)
    {
    {
       Con::errorf("DDSFile::readHeader - unexpected magic number, wanted 'DDS '!");
       Con::errorf("DDSFile::readHeader - unexpected magic number, wanted 'DDS '!");
       return false;
       return false;
    }
    }
 
 
-   // Read the size of the header.
-   s.read(&tmp);
+   //dds headers
+   dds::DDS_HEADER header = {};
+   dds::DDS_HEADER_DXT10 dx10header = {};
+   //todo DX10 formats
+   bool hasDx10Header = false;
 
 
-   if(tmp != 124)
+   //read in header
+   s.read(DDS_HEADER_SIZE, &header);
+   //check for dx10 header support
+   if ((header.ddspf.flags & DDS_FOURCC) && (header.ddspf.fourCC == dds::D3DFMT_DX10))
    {
    {
-      Con::errorf("DDSFile::readHeader - incorrect header size. Expected 124 bytes.");
-      return false;
-   }
-
-   // Read some flags...
-   U32 ddsdFlags;
-   s.read(&ddsdFlags);
+      //read in dx10 header
+      s.read(DDS_HEADER_DX10_SIZE, &dx10header);
+      if (!dds::validateHeaderDx10(dx10header))
+         return false;
 
 
-   // "Always include DDSD_CAPS, DDSD_PIXELFORMAT, DDSD_WIDTH, DDSD_HEIGHT."
-   if(!(ddsdFlags & (DDSDCaps | DDSDPixelFormat | DDSDWidth | DDSDHeight)))
-   {
-      Con::errorf("DDSFile::readHeader - incorrect surface description flags.");
-      return false;
+      hasDx10Header = true;
    }
    }
 
 
-   // Read height and width (always present)
-   s.read(&mHeight);
-   s.read(&mWidth);
-
-   // Read pitch or linear size.
-
-   // First make sure we have valid flags (either linear size or pitch).
-   if((ddsdFlags & (DDSDLinearSize | DDSDPitch)) == (DDSDLinearSize | DDSDPitch))
-   {
-      // Both are invalid!
-      Con::errorf("DDSFile::readHeader - encountered both DDSD_LINEARSIZE and DDSD_PITCH!");
+   //make sure our dds header is valid
+   if (!dds::validateHeader(header))
       return false;
       return false;
-   }
 
 
-   // Ok, some flags are set, so let's do some reading.
-   s.read(&mPitchOrLinearSize);
+   // store details
+   mPitchOrLinearSize = header.pitchOrLinearSize;
+   mMipMapCount = header.mipMapCount ? header.mipMapCount : 1;
+   mHeight = header.height;
+   mWidth = header.width;
+   mDepth = header.depth;
+   mFourCC = header.ddspf.fourCC;
 
 
-   if(ddsdFlags & DDSDLinearSize)
-   {
-      mFlags.set(LinearSizeFlag); // ( mHeight / 4 ) * ( mWidth / 4 ) * DDSSIZE
-   }
-   else if (ddsdFlags & DDSDPitch)
-   {
-      mFlags.set(PitchSizeFlag); // ( mWidth / 4 ) * DDSSIZE ???
-   }
-   else
+   //process dx10 header
+   if (hasDx10Header)
    {
    {
-      // Neither set! This appears to be depressingly common.
-      // Con::warnf("DDSFile::readHeader - encountered neither DDSD_LINEARSIZE nor DDSD_PITCH!");
-   }
-
-   // Do we need to read depth? If so, we are a volume texture!
-   s.read(&mDepth);
-
-   if(ddsdFlags & DDSDDepth)
-   {
-      mFlags.set(VolumeFlag);
-   }
-   else
-   {
-      // Wipe it if the flag wasn't set!
-      mDepth = 0;
-   }
-
-   // Deal with mips!
-   s.read(&mMipMapCount);
-
-   if(ddsdFlags & DDSDMipMapCount)
-   {
-      mFlags.set(MipMapsFlag);
-   }
-   else
-   {
-      // Wipe it if the flag wasn't set!
-      mMipMapCount = 1;
-   }
-
-   // Deal with 11 DWORDS of reserved space (this reserved space brought to
-   // you by DirectDraw and the letters F and U).
-   for(U32 i=0; i<11; i++)
-      s.read(&tmp);
-
-   // Now we're onto the pixel format!
-   s.read(&tmp);
-
-   if(tmp != 32)
-   {
-      Con::errorf("DDSFile::readHeader - pixel format chunk has unexpected size!");
-      return false;
-   }
-
-   U32 ddpfFlags;
-
-   s.read(&ddpfFlags);
-
-   // Read the next few values so we can deal with them all in one go.
-   U32 pfFourCC, pfBitCount, pfRMask, pfGMask, pfBMask, pfAlphaMask;
-
-   s.read(&pfFourCC);
-   s.read(&pfBitCount);
-   s.read(&pfRMask);
-   s.read(&pfGMask);
-   s.read(&pfBMask);
-   s.read(&pfAlphaMask);
-
-   // Sanity check flags...
-   if(!(ddpfFlags & (DDPFRGB | DDPFFourCC | DDPFLUMINANCE)))
-   {
-      Con::errorf("DDSFile::readHeader - incoherent pixel flags, neither RGB, FourCC, or Luminance!");
-      return false;
-   }
-
-   // For now let's just dump the header info.
-   if(ddpfFlags & DDPFLUMINANCE)
-   {
-      mFlags.set(RGBData);
-
-      mBytesPerPixel = pfBitCount / 8;      
-
-      bool hasAlpha = ddpfFlags & DDPFAlphaPixels;
-
-      mHasTransparency = hasAlpha;
-
-      // Try to match a format.
-      if(hasAlpha)
+      if (dx10header.arraySize > 1)
       {
       {
-         // If it has alpha it is one of...
-         // GFXFormatA8L8
-         // GFXFormatA4L4
-
-         if(pfBitCount == 16)
-            mFormat = GFXFormatA8L8;
-         else if(pfBitCount == 8)
-            mFormat = GFXFormatA4L4;
-         else
-         {
-            Con::errorf("DDSFile::readHeader - unable to match alpha Luminance format!");
-            return false;
-         }
+         Con::errorf("DDSFile::readHeader - DX10 arrays not supported");
+         return false;
       }
       }
-      else
+
+      mFormat = dds::getGFXFormat(dx10header.dxgiFormat);
+      //make sure getGFXFormat gave us a valid format
+      if (mFormat == GFXFormat_FIRST)
+         return false;
+      //cubemap
+      if (dx10header.miscFlag & dds::D3D10_RESOURCE_MISC_TEXTURECUBE)
       {
       {
-         // Otherwise it is one of...
-         // GFXFormatL16
-         // GFXFormatL8
-
-         if(pfBitCount == 16)
-            mFormat = GFXFormatL16;
-         else if(pfBitCount == 8)
-            mFormat = GFXFormatL8;
-         else
-         {
-            Con::errorf("DDSFile::readHeader - unable to match non-alpha Luminance format!");
-            return false;
-         }
+         mFlags.set(CubeMap_All_Flags | ComplexFlag);
       }
       }
-   }
-   else if(ddpfFlags & DDPFRGB)
-   {
-      mFlags.set(RGBData);
 
 
-      //Con::printf("RGB Pixel format of DDS:");
-      //Con::printf("   bitcount = %d (16, 24, 32)", pfBitCount);
-      mBytesPerPixel = pfBitCount / 8;
-      //Con::printf("   red   mask = %x", pfRMask);
-      //Con::printf("   green mask = %x", pfGMask);
-      //Con::printf("   blue  mask = %x", pfBMask);
+      mHasTransparency = ImageUtil::isAlphaFormat(mFormat);
 
 
-      bool hasAlpha = false;
+      //mip map flag
+      if (mMipMapCount > 1)
+         mFlags.set(MipMapsFlag | ComplexFlag);
 
 
-      if(ddpfFlags & DDPFAlphaPixels)
-      {
-         hasAlpha = true;
-         //Con::printf("   alpha mask = %x", pfAlphaMask);
-      }
+      if (ImageUtil::isCompressedFormat(mFormat))
+         mFlags.set(CompressedData);
       else
       else
       {
       {
-         //Con::printf("   no alpha.");
+         mBytesPerPixel = header.ddspf.bpp / 8;
+         mFlags.set(RGBData);
       }
       }
 
 
-      mHasTransparency = hasAlpha;
-
-      // Try to match a format.
-      if(hasAlpha)
-      {
-         // If it has alpha it is one of...
-         // GFXFormatR8G8B8A8
-         // GFXFormatR5G5B5A1
-         // GFXFormatA8
-
-         if(pfBitCount == 32)
-            mFormat = GFXFormatR8G8B8A8;
-         else if(pfBitCount == 16)
-            mFormat = GFXFormatR5G5B5A1;
-         else if(pfBitCount == 8)
-            mFormat = GFXFormatA8;
-         else
-         {
-            Con::errorf("DDSFile::readHeader - unable to match alpha RGB format!");
-            return false;
-         }
-      }
-      else
-      {
-         // Otherwise it is one of...
-         // GFXFormatR8G8B8
-         // GFXFormatR8G8B8X8
-         // GFXFormatR5G6B5
-         // GFXFormatL8
-
-         if(pfBitCount == 24)
-            mFormat = GFXFormatR8G8B8;
-         else if(pfBitCount == 32)
-            mFormat = GFXFormatR8G8B8X8;
-         else if(pfBitCount == 16)
-            mFormat = GFXFormatR5G6B5;
-         else if(pfBitCount == 8)
-         {
-            // luminance
-            mFormat = GFXFormatL8;
-         }
-         else
-         {
-            Con::errorf("DDSFile::readHeader - unable to match non-alpha RGB format!");
-            return false;
-         }
-      }
+      // we finished now
+      return true;
+   }
 
 
+   //process regular header
 
 
-      // Sweet, all done.
-   }
-   else if (ddpfFlags & DDPFFourCC)
+   //D3DFMT_DX10 is caught above, no need to check now
+   if (header.ddspf.flags & DDS_FOURCC)
    {
    {
-      mHasTransparency = (ddpfFlags & DDPFAlphaPixels);
-      mFlags.set(CompressedData);
-
-/*      Con::printf("FourCC Pixel format of DDS:");
-      Con::printf("   fourcc = '%c%c%c%c'", ((U8*)&pfFourCC)[0], ((U8*)&pfFourCC)[1], ((U8*)&pfFourCC)[2], ((U8*)&pfFourCC)[3]); */
+      mFormat = dds::getGFXFormat(mFourCC);
+      //make sure getGFXFormat gave us a valid format
+      if (mFormat == GFXFormat_FIRST)
+         return false;
 
 
-      // Ok, make a format determination.
-      switch(pfFourCC)
+      if (ImageUtil::isCompressedFormat(mFormat))
+         mFlags.set(CompressedData);
+      else
       {
       {
-      case FOURCC_DXT1:
-         mFormat = GFXFormatDXT1;
-         break;
-      case FOURCC_DXT2:
-         mFormat = GFXFormatDXT2;
-         break;
-      case FOURCC_DXT3:
-         mFormat = GFXFormatDXT3;
-         break;
-      case FOURCC_DXT4:
-         mFormat = GFXFormatDXT4;
-         break;
-      case FOURCC_DXT5:
-         mFormat = GFXFormatDXT5;
-         break;
-      default:
-         Con::errorf("DDSFile::readHeader - unknown fourcc = '%c%c%c%c'", ((U8*)&pfFourCC)[0], ((U8*)&pfFourCC)[1], ((U8*)&pfFourCC)[2], ((U8*)&pfFourCC)[3]);
-         break;
+         mBytesPerPixel = header.ddspf.bpp / 8;
+         mFlags.set(RGBData);
       }
       }
+   }
+   else
+   {
+      mFormat = dds::getGFXFormat(header.ddspf);
+      //make sure getGFXFormat gave us a valid format
+      if (mFormat == GFXFormat_FIRST)
+         return false;
 
 
+      mBytesPerPixel = header.ddspf.bpp / 8;
+      mFlags.set(RGBData);
    }
    }
 
 
-   // Deal with final caps bits... Is this really necessary?
+   //mip map flag
+   if (mMipMapCount > 1)
+      mFlags.set(MipMapsFlag | ComplexFlag);
 
 
-   U32 caps1, caps2;
-   s.read(&caps1);
-   s.read(&caps2);
-   s.read(&tmp);
-   s.read(&tmp); // More icky reserved space.
+   //set transparency flag
+   mHasTransparency = (header.ddspf.flags & DDS_ALPHAPIXELS);
 
 
-   // Screw caps1.
-   // if(!(caps1 & DDSCAPS_TEXTURE)))
-   // {
-   // }
+   if (header.flags & DDS_HEADER_FLAGS_LINEARSIZE)
+      mFlags.set(LinearSizeFlag);
+   else if (header.flags & DDS_HEADER_FLAGS_PITCH)
+      mFlags.set(PitchSizeFlag);
 
 
-   // Caps2 has cubemap/volume info. Care about that.
-   if(caps2 & DDSCAPS2Cubemap)
+   //set cubemap flags
+   if (header.cubemapFlags & DDS_CUBEMAP)
    {
    {
-      mFlags.set(CubeMapFlag);
-
+      mFlags.set(CubeMapFlag | ComplexFlag);
       // Store the face flags too.
       // Store the face flags too.
-      if ( caps2 & DDSCAPS2Cubemap_POSITIVEX ) mFlags.set( CubeMap_PosX_Flag );
-      if ( caps2 & DDSCAPS2Cubemap_NEGATIVEX ) mFlags.set( CubeMap_NegX_Flag );
-      if ( caps2 & DDSCAPS2Cubemap_POSITIVEY ) mFlags.set( CubeMap_PosY_Flag );
-      if ( caps2 & DDSCAPS2Cubemap_NEGATIVEY ) mFlags.set( CubeMap_NegY_Flag );
-      if ( caps2 & DDSCAPS2Cubemap_POSITIVEZ ) mFlags.set( CubeMap_PosZ_Flag );
-      if ( caps2 & DDSCAPS2Cubemap_NEGATIVEZ ) mFlags.set( CubeMap_NegZ_Flag );
+      if (header.cubemapFlags & DDS_CUBEMAP_POSITIVEX) mFlags.set(CubeMap_PosX_Flag);
+      if (header.cubemapFlags & DDS_CUBEMAP_NEGATIVEX) mFlags.set(CubeMap_NegX_Flag);
+      if (header.cubemapFlags & DDS_CUBEMAP_POSITIVEY) mFlags.set(CubeMap_PosY_Flag);
+      if (header.cubemapFlags & DDS_CUBEMAP_NEGATIVEY) mFlags.set(CubeMap_NegY_Flag);
+      if (header.cubemapFlags & DDS_CUBEMAP_POSITIVEZ) mFlags.set(CubeMap_PosZ_Flag);
+      if (header.cubemapFlags & DDS_CUBEMAP_NEGATIVEZ) mFlags.set(CubeMap_NegZ_Flag);
    }
    }
 
 
-   // MS has ANOTHER reserved word here. This one particularly sucks.
-   s.read(&tmp);
+
 
 
    return true;
    return true;
 }
 }
 
 
 bool DDSFile::read(Stream &s, U32 dropMipCount)
 bool DDSFile::read(Stream &s, U32 dropMipCount)
 {
 {
-   if( !readHeader(s) || mMipMapCount == 0 )
+   if( !readHeader(s) )
    {
    {
       Con::errorf("DDSFile::read - error reading header!");
       Con::errorf("DDSFile::read - error reading header!");
       return false;
       return false;
@@ -618,96 +413,82 @@ bool DDSFile::read(Stream &s, U32 dropMipCount)
 
 
 bool DDSFile::writeHeader( Stream &s )
 bool DDSFile::writeHeader( Stream &s )
 {
 {
-   // Read the FOURCC
-   s.write( 4, "DDS " );
-
-   U32 tmp = 0;
-
-   // Read the size of the header.
-   s.write( 124 );
-
-   // Read some flags...
-   U32 ddsdFlags = DDSDCaps | DDSDPixelFormat | DDSDWidth | DDSDHeight;
-   
-   if ( mFlags.test( CompressedData ) )
-      ddsdFlags |= DDSDLinearSize;
-   else
-      ddsdFlags |= DDSDPitch;
-
-   if ( mMipMapCount > 0 )
-      ddsdFlags |= DDSDMipMapCount;
-
-   s.write( ddsdFlags );
-
-   // Read height and width (always present)
-   s.write( mHeight );
-   s.write( mWidth );
-
-   // Ok, some flags are set, so let's do some reading.
-   s.write( mPitchOrLinearSize );
+   // write DDS magic
+   U32 magic = DDS_MAGIC;
+   s.write(magic);
 
 
-   // Do we need to read depth? If so, we are a volume texture!
-   s.write( mDepth );
+   dds::DDS_HEADER header = {};
+   dds::DDS_HEADER_DXT10 dx10header = {};
 
 
-   // Deal with mips!
-   s.write( mMipMapCount );
+   bool hasDx10Header = false;
+   //flags
+   U32 surfaceFlags = DDS_SURFACE_FLAGS_TEXTURE;
+   U32 cubemapFlags = 0;
+   U32 headerFlags = DDS_HEADER_FLAGS_TEXTURE;
 
 
-   // Deal with 11 DWORDS of reserved space (this reserved space brought to
-   // you by DirectDraw and the letters F and U).
-   for(U32 i=0; i<11; i++)
-      s.write( tmp ); // is this right?
+   //pixel format
+   const dds::DDS_PIXELFORMAT &format = dds::getDDSFormat(mFormat);
 
 
-   // Now we're onto the pixel format!
-
-   // This is the size, in bits,
-   // of the pixel format data.
-   tmp = 32;
-   s.write( tmp );
-
-   U32 ddpfFlags;
-
-   U32 fourCC = 0;
-
-   if ( mFlags.test( CompressedData ) )
+   // todo better dx10 support
+   if (format.fourCC == dds::D3DFMT_DX10)
    {
    {
-      ddpfFlags = DDPFFourCC;
-      if (mFormat == GFXFormatDXT1)
-         fourCC = FOURCC_DXT1;
-      if (mFormat == GFXFormatDXT3)
-         fourCC = FOURCC_DXT3;
-      if (mFormat == GFXFormatDXT5)
-         fourCC = FOURCC_DXT5;
+      dx10header.dxgiFormat = dds::getDXGIFormat(mFormat);
+      dx10header.arraySize = 1;
+      dx10header.resourceDimension = dds::D3D10_RESOURCE_DIMENSION_TEXTURE2D;
+      dx10header.miscFlag = 0;
+      dx10header.miscFlags2 = 0;
+      hasDx10Header = true;
    }
    }
-   else
-      ddpfFlags = mBytesPerPixel == 4 ? DDPFRGB | DDPFAlphaPixels : DDPFRGB;
 
 
-   s.write( ddpfFlags );
+   if (mFlags.test(CompressedData))
+      headerFlags |= DDS_HEADER_FLAGS_LINEARSIZE;
+   else
+      headerFlags |= DDS_HEADER_FLAGS_PITCH;
 
 
-   // Read the next few values so we can deal with them all in one go.
-   //U32 pfFourCC, pfBitCount, pfRMask, pfGMask, pfBMask, pfAlphaMask;
+   if (mMipMapCount > 1)
+   {
+      surfaceFlags |= DDS_SURFACE_FLAGS_MIPMAP;
+      headerFlags |= DDS_HEADER_FLAGS_MIPMAP;
+   }   
 
 
-   s.write( fourCC );
-   s.write( mBytesPerPixel * 8 );
-   s.write( 0x000000FF );
-   s.write( 0x00FF0000 );
-   s.write( 0x0000FF00 );
-   s.write( 0xFF000000 );
+   //cubemap flags
+   if (mFlags.test(CubeMapFlag))
+   {
+      surfaceFlags |= DDS_SURFACE_FLAGS_CUBEMAP;
+      cubemapFlags |= DDS_CUBEMAP_ALLFACES;
+   }
 
 
-   // Deal with final caps bits... Is this really necessary?
- 
-   U32 caps1 = DDSCAPSTexture;
-   if ( mMipMapCount > 0 )
-      caps1 |= DDSCAPSComplex | DDSCAPSMipMap;
+   //volume texture
+   if (mDepth > 0)
+   {
+      headerFlags |= DDS_HEADER_FLAGS_VOLUME;
+      dx10header.resourceDimension = dds::D3D10_RESOURCE_DIMENSION_TEXTURE3D;
+   }
 
 
-   tmp = 0;
+   //main dds header
+   header.size = sizeof(dds::DDS_HEADER);
+   header.flags = headerFlags;
+   header.height = mHeight;
+   header.width = mWidth;
+   header.pitchOrLinearSize = mPitchOrLinearSize;
+   header.depth = mDepth;
+   header.ddspf = format;
+   header.mipMapCount = mMipMapCount;
+   header.surfaceFlags = surfaceFlags;   
+   header.cubemapFlags = cubemapFlags;   
+   memset(header.reserved1, 0, sizeof(header.reserved1));
+   memset(header.reserved2, 0, sizeof(header.reserved2));
 
 
-   s.write( caps1 );
-   s.write( tmp );
-   s.write( tmp );
-   s.write( tmp );// More icky reserved space.
+   //check our header is ok
+   if (!dds::validateHeader(header))
+      return false;
 
 
-   // MS has ANOTHER reserved word here. This one particularly sucks.
-   s.write( tmp );
+   //Write out the header
+   s.write(DDS_HEADER_SIZE, &header);
+   
+   //Write out dx10 header
+   if (hasDx10Header)
+      s.write(DDS_HEADER_DX10_SIZE, &dx10header);
 
 
    return true;
    return true;
 }
 }
@@ -720,13 +501,16 @@ bool DDSFile::write( Stream &s )
       return false;
       return false;
    }
    }
 
 
-   // At this point we know what sort of image we contain. So we should
-   // allocate some buffers, and read it in.
-
    // How many surfaces are we talking about?
    // How many surfaces are we talking about?
    if(mFlags.test(CubeMapFlag))
    if(mFlags.test(CubeMapFlag))
    {
    {
       // Do something with cubemaps.
       // Do something with cubemaps.
+      for (U32 cubeFace = 0; cubeFace < Cubemap_Surface_Count; cubeFace++)
+      {
+         // write the mips
+         for (S32 i = 0; i < mMipMapCount; i++)
+            mSurfaces[cubeFace]->writeNextMip(this, s, mHeight, mWidth, i);
+      }
    }
    }
    else if (mFlags.test(VolumeFlag))
    else if (mFlags.test(VolumeFlag))
    {
    {
@@ -912,6 +696,82 @@ DDSFile *DDSFile::createDDSFileFromGBitmap( const GBitmap *gbmp )
    return ret;
    return ret;
 }
 }
 
 
+DDSFile *DDSFile::createDDSCubemapFileFromGBitmaps(GBitmap **gbmps)
+{
+   if (gbmps == NULL)
+      return NULL;
+
+   AssertFatal(gbmps[0], "createDDSCubemapFileFromGBitmaps bitmap 0 is null");
+   AssertFatal(gbmps[1], "createDDSCubemapFileFromGBitmaps bitmap 1 is null");
+   AssertFatal(gbmps[2], "createDDSCubemapFileFromGBitmaps bitmap 2 is null");
+   AssertFatal(gbmps[3], "createDDSCubemapFileFromGBitmaps bitmap 3 is null");
+   AssertFatal(gbmps[4], "createDDSCubemapFileFromGBitmaps bitmap 4 is null");
+   AssertFatal(gbmps[5], "createDDSCubemapFileFromGBitmaps bitmap 5 is null");
+
+   DDSFile *ret = new DDSFile;
+   //all cubemaps have the same dimensions and formats
+   GBitmap *pBitmap = gbmps[0];
+
+   if (pBitmap->getFormat() != GFXFormatR8G8B8A8)
+   {
+      Con::errorf("createDDSCubemapFileFromGBitmaps: Only GFXFormatR8G8B8A8 supported for now");
+      return NULL;
+   }
+
+   // Set up the DDSFile properties that matter. Since this is a GBitmap, there
+   // are assumptions that can be made
+   ret->mHeight = pBitmap->getHeight();
+   ret->mWidth = pBitmap->getWidth();
+   ret->mDepth = 0;
+   ret->mFormat = pBitmap->getFormat();
+   ret->mFlags.set( RGBData | CubeMapFlag | CubeMap_PosX_Flag | CubeMap_NegX_Flag | CubeMap_PosY_Flag |
+      CubeMap_NegY_Flag | CubeMap_PosZ_Flag | CubeMap_NegZ_Flag);
+   ret->mBytesPerPixel = pBitmap->getBytesPerPixel();
+   //todo implement mip mapping
+   ret->mMipMapCount = pBitmap->getNumMipLevels();
+   ret->mHasTransparency = pBitmap->getHasTransparency();
+
+   for (U32 cubeFace = 0; cubeFace < Cubemap_Surface_Count; cubeFace++)
+   {
+      ret->mSurfaces.push_back(new SurfaceData());
+      // Load the mips
+      for (S32 i = 0; i < ret->mMipMapCount; i++)
+      {
+         const U32 mipSz = ret->getSurfaceSize(i);
+         ret->mSurfaces.last()->mMips.push_back(new U8[mipSz]);
+
+         U8 *mipMem = ret->mSurfaces.last()->mMips.last();
+         //straight copy
+         dMemcpy(mipMem, gbmps[cubeFace]->getBits(i), mipSz);
+      }
+   }
+
+   return ret;
+}
+
+bool DDSFile::decompressToGBitmap(GBitmap *dest)
+{
+   // TBD: do we support other formats?
+   if (mFormat != GFXFormatBC1 && mFormat != GFXFormatBC2 && mFormat != GFXFormatBC3)
+      return false;
+
+   dest->allocateBitmapWithMips(getWidth(), getHeight(), getMipLevels(), GFXFormatR8G8B8A8);
+
+   // Decompress and copy mips...
+
+   U32 numMips = getMipLevels();
+
+   for (U32 i = 0; i < numMips; i++)
+   {
+      U8 *addr = dest->getAddress(0, 0, i);
+      const U8 *mipBuffer = mSurfaces[0]->mMips[i];
+      ImageUtil::decompress(mipBuffer, addr, getWidth(i), getHeight(i), mFormat);
+
+   }
+
+   return true;
+}
+
 DefineEngineFunction( getActiveDDSFiles, S32, (),,
 DefineEngineFunction( getActiveDDSFiles, S32, (),,
    "Returns the count of active DDSs files in memory.\n"
    "Returns the count of active DDSs files in memory.\n"
    "@ingroup Rendering\n" )
    "@ingroup Rendering\n" )

+ 4 - 3
Engine/source/gfx/bitmap/ddsFile.h

@@ -65,6 +65,7 @@ struct DDSFile
       CubeMap_NegY_Flag = BIT(11),
       CubeMap_NegY_Flag = BIT(11),
       CubeMap_PosZ_Flag = BIT(12),
       CubeMap_PosZ_Flag = BIT(12),
       CubeMap_NegZ_Flag = BIT(13),
       CubeMap_NegZ_Flag = BIT(13),
+      CubeMap_All_Flags = CubeMapFlag|CubeMap_PosX_Flag | CubeMap_NegX_Flag | CubeMap_PosY_Flag | CubeMap_NegY_Flag | CubeMap_PosZ_Flag | CubeMap_NegZ_Flag,
    };
    };
 
 
    /// The index into mSurfaces for each 
    /// The index into mSurfaces for each 
@@ -115,9 +116,6 @@ struct DDSFile
 
 
       Vector<U8*> mMips;
       Vector<U8*> mMips;
 
 
-      // Helper function to read in a mipchain.
-      bool readMipChain();
-
       void dumpImage(DDSFile *dds, U32 mip, const char *file);
       void dumpImage(DDSFile *dds, U32 mip, const char *file);
       
       
       /// Helper for reading a mip level.
       /// Helper for reading a mip level.
@@ -200,6 +198,9 @@ struct DDSFile
    }
    }
 
 
    static DDSFile *createDDSFileFromGBitmap( const GBitmap *gbmp );
    static DDSFile *createDDSFileFromGBitmap( const GBitmap *gbmp );
+   //Create a single cubemap texture from 6 GBitmap
+   static DDSFile *createDDSCubemapFileFromGBitmaps(GBitmap **gbmps);
+   bool decompressToGBitmap(GBitmap *dest);
 };
 };
 
 
 #endif // _DDSFILE_H_
 #endif // _DDSFILE_H_

+ 0 - 113
Engine/source/gfx/bitmap/ddsUtils.cpp

@@ -1,113 +0,0 @@
-//-----------------------------------------------------------------------------
-// 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 "squish/squish.h"
-#include "gfx/bitmap/ddsFile.h"
-#include "gfx/bitmap/ddsUtils.h"
-
-//------------------------------------------------------------------------------
-
-// If false is returned, from this method, the source DDS is not modified
-bool DDSUtil::squishDDS( DDSFile *srcDDS, const GFXFormat dxtFormat )
-{
-   // Sanity check
-   if( srcDDS->mBytesPerPixel != 4 )
-   {
-      AssertFatal( false, "Squish wants 32-bit source data" );
-      return false;
-   }
-
-   // Build flags, start with fast compress
-   U32 squishFlags = squish::kColourRangeFit;
-
-   // Flag which format we are using
-   switch( dxtFormat )
-   {
-      case GFXFormatDXT1:
-         squishFlags |= squish::kDxt1;
-         break;
-
-      case GFXFormatDXT2:
-      case GFXFormatDXT3:
-         squishFlags |= squish::kDxt3;
-         break;
-
-      case GFXFormatDXT4:
-      case GFXFormatDXT5:
-         squishFlags |= squish::kDxt5;
-         break;
-
-      default:
-         AssertFatal( false, "Assumption failed" );
-         return false;
-         break;
-   }
-
-   // We got this far, so assume we can finish (gosh I hope so)
-   srcDDS->mFormat = dxtFormat;
-   srcDDS->mFlags.set( DDSFile::CompressedData );
-
-   // If this has alpha, set the flag
-   if( srcDDS->mFormat == GFXFormatR8G8B8A8 )
-      squishFlags |= squish::kWeightColourByAlpha;
-
-   // The source surface is the original surface of the file
-   DDSFile::SurfaceData *srcSurface = srcDDS->mSurfaces.last();
-
-   // Create a new surface, this will be the DXT compressed surface. Once we
-   // are done, we can discard the old surface, and replace it with this one.
-   DDSFile::SurfaceData *newSurface = new DDSFile::SurfaceData();
-
-   for( S32 i = 0; i < srcDDS->mMipMapCount; i++ )
-   {
-      const U8 *srcBits = srcSurface->mMips[i];
-
-      const U32 mipSz = srcDDS->getSurfaceSize(i);
-      U8 *dstBits = new U8[mipSz];
-      newSurface->mMips.push_back( dstBits );
-
-      PROFILE_START(SQUISH_DXT_COMPRESS);
-
-      // Compress with Squish
-      squish::CompressImage( srcBits, srcDDS->getWidth(i), srcDDS->getHeight(i), 
-         dstBits, squishFlags );
-
-      PROFILE_END();
-   }
-
-   // Now delete the source surface, and return.
-   srcDDS->mSurfaces.pop_back();
-   delete srcSurface;
-   srcDDS->mSurfaces.push_back( newSurface );
-
-   return true;
-}
-
-//------------------------------------------------------------------------------
-
-void DDSUtil::swizzleDDS( DDSFile *srcDDS, const Swizzle<U8, 4> &swizzle )
-{
-   for( S32 i = 0; i < srcDDS->mMipMapCount; i++ )
-   {
-      swizzle.InPlace( srcDDS->mSurfaces.last()->mMips[i], srcDDS->getSurfaceSize( i ) );
-   }
-}

+ 0 - 34
Engine/source/gfx/bitmap/ddsUtils.h

@@ -1,34 +0,0 @@
-//-----------------------------------------------------------------------------
-// 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 _DDS_UTILS_H_
-#define _DDS_UTILS_H_
-
-struct DDSFile;
-
-namespace DDSUtil
-{
-   bool squishDDS( DDSFile *srcDDS, const GFXFormat dxtFormat );
-   void swizzleDDS( DDSFile *srcDDS, const Swizzle<U8, 4> &swizzle );
-};
-
-#endif

+ 154 - 2
Engine/source/gfx/bitmap/gBitmap.cpp

@@ -347,6 +347,77 @@ void GBitmap::allocateBitmap(const U32 in_width, const U32 in_height, const bool
    }
    }
 }
 }
 
 
+//--------------------------------------------------------------------------
+void GBitmap::allocateBitmapWithMips(const U32 in_width, const U32 in_height, const U32 in_numMips, const GFXFormat in_format)
+{
+   //-------------------------------------- Some debug checks...
+   U32 svByteSize = mByteSize;
+   U8 *svBits = mBits;
+
+   AssertFatal(in_width != 0 && in_height != 0, "GBitmap::allocateBitmap: width or height is 0");
+
+   mInternalFormat = in_format;
+   mWidth = in_width;
+   mHeight = in_height;
+
+   mBytesPerPixel = 1;
+   switch (mInternalFormat)
+   {
+   case GFXFormatA8:
+   case GFXFormatL8:           mBytesPerPixel = 1;
+      break;
+   case GFXFormatR8G8B8:       mBytesPerPixel = 3;
+      break;
+   case GFXFormatR8G8B8X8:
+   case GFXFormatR8G8B8A8:     mBytesPerPixel = 4;
+      break;
+   case GFXFormatR5G6B5:
+   case GFXFormatR5G5B5A1:     mBytesPerPixel = 2;
+      break;
+   default:
+      AssertFatal(false, "GBitmap::GBitmap: misunderstood format specifier");
+      break;
+   }
+
+   // Set up the mip levels, if necessary...
+   mNumMipLevels = 1;
+   U32 allocPixels = in_width * in_height * mBytesPerPixel;
+   mMipLevelOffsets[0] = 0;
+
+
+   if (in_numMips != 0)
+   {
+      U32 currWidth = in_width;
+      U32 currHeight = in_height;
+
+      do
+      {
+         mMipLevelOffsets[mNumMipLevels] = mMipLevelOffsets[mNumMipLevels - 1] +
+            (currWidth * currHeight * mBytesPerPixel);
+         currWidth >>= 1;
+         currHeight >>= 1;
+         if (currWidth == 0) currWidth = 1;
+         if (currHeight == 0) currHeight = 1;
+
+         mNumMipLevels++;
+         allocPixels += currWidth * currHeight * mBytesPerPixel;
+      } while (currWidth != 1 || currHeight != 1 && mNumMipLevels != in_numMips);
+   }
+   AssertFatal(mNumMipLevels <= c_maxMipLevels, "GBitmap::allocateBitmap: too many miplevels");
+
+   // Set up the memory...
+   mByteSize = allocPixels;
+   mBits = new U8[mByteSize];
+
+   dMemset(mBits, 0xFF, mByteSize);
+
+   if (svBits != NULL)
+   {
+      dMemcpy(mBits, svBits, getMin(mByteSize, svByteSize));
+      delete[] svBits;
+   }
+}
+
 //--------------------------------------------------------------------------
 //--------------------------------------------------------------------------
 void GBitmap::extrudeMipLevels(bool clearBorders)
 void GBitmap::extrudeMipLevels(bool clearBorders)
 {
 {
@@ -410,6 +481,38 @@ void GBitmap::extrudeMipLevels(bool clearBorders)
    }
    }
 }
 }
 
 
+//--------------------------------------------------------------------------
+void GBitmap::chopTopMips(U32 mipsToChop)
+{
+   U32 scalePower = getMin(mipsToChop, getNumMipLevels() - 1);
+   U32 newMipCount = getNumMipLevels() - scalePower;
+
+   U32 realWidth = getMax((U32)1, getWidth() >> scalePower);
+   U32 realHeight = getMax((U32)1, getHeight() >> scalePower);
+
+   U8 *destBits = mBits;
+
+   U32 destOffsets[c_maxMipLevels];
+
+   for (U32 i = scalePower; i<mNumMipLevels; i++)
+   {
+      // Copy to the new bitmap...
+      dMemcpy(destBits,
+         getWritableBits(i),
+         getSurfaceSize(i));
+
+      destOffsets[i - scalePower] = destBits - mBits;
+      destBits += getSurfaceSize(i);
+   }
+
+   dMemcpy(mMipLevelOffsets, destOffsets, sizeof(destOffsets));
+
+   mWidth = realWidth;
+   mHeight = realHeight;
+   mByteSize = destBits - mBits;
+   mNumMipLevels = newMipCount;
+}
+
 //--------------------------------------------------------------------------
 //--------------------------------------------------------------------------
 void GBitmap::extrudeMipLevelsDetail()
 void GBitmap::extrudeMipLevelsDetail()
 {
 {
@@ -609,9 +712,9 @@ bool GBitmap::checkForTransparency()
 }
 }
 
 
 //------------------------------------------------------------------------------
 //------------------------------------------------------------------------------
-ColorF GBitmap::sampleTexel(F32 u, F32 v) const
+LinearColorF GBitmap::sampleTexel(F32 u, F32 v) const
 {
 {
-   ColorF col(0.5f, 0.5f, 0.5f);
+   LinearColorF col(0.5f, 0.5f, 0.5f);
    // normally sampling wraps all the way around at 1.0,
    // normally sampling wraps all the way around at 1.0,
    // but locking doesn't support this, and we seem to calc
    // but locking doesn't support this, and we seem to calc
    // the uv based on a clamped 0 - 1...
    // the uv based on a clamped 0 - 1...
@@ -733,6 +836,20 @@ bool GBitmap::setColor(const U32 x, const U32 y, const ColorI& rColor)
    return true;
    return true;
 }
 }
 
 
+//--------------------------------------------------------------------------
+U8 GBitmap::getChanelValueAt(U32 x, U32 y, U32 chan)
+{
+   ColorI pixelColor = ColorI(255,255,255,255);
+   getColor(x, y, pixelColor);
+
+   switch (chan) {
+   case 0: return pixelColor.red;
+   case 1: return pixelColor.green;
+   case 2: return pixelColor.blue;
+   default: return pixelColor.alpha;
+   }
+}
+
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 
 
 bool GBitmap::combine( const GBitmap *bitmapA, const GBitmap *bitmapB, const GFXTextureOp combineOp )
 bool GBitmap::combine( const GBitmap *bitmapA, const GBitmap *bitmapB, const GFXTextureOp combineOp )
@@ -1175,6 +1292,41 @@ Resource<GBitmap> GBitmap::_search(const Torque::Path &path)
    return Resource< GBitmap >( NULL );
    return Resource< GBitmap >( NULL );
 }
 }
 
 
+U32 GBitmap::getSurfaceSize(const U32 mipLevel) const
+{
+   // Bump by the mip level.
+   U32 height = getMax(U32(1), mHeight >> mipLevel);
+   U32 width = getMax(U32(1), mWidth >> mipLevel);
+
+   if (mInternalFormat >= GFXFormatBC1 && mInternalFormat <= GFXFormatBC3)
+   {
+      // From the directX docs:
+      // max(1, width ÷ 4) x max(1, height ÷ 4) x 8(DXT1) or 16(DXT2-5)
+
+      U32 sizeMultiple = 0;
+
+      switch (mInternalFormat)
+      {
+      case GFXFormatBC1:
+         sizeMultiple = 8;
+         break;
+      case GFXFormatBC2:
+      case GFXFormatBC3:
+         sizeMultiple = 16;
+         break;
+      default:
+         AssertISV(false, "DDSFile::getSurfaceSize - invalid compressed texture format, we only support DXT1-5 right now.");
+         break;
+      }
+
+      return getMax(U32(1), width / 4) * getMax(U32(1), height / 4) * sizeMultiple;
+   }
+   else
+   {
+      return height * width* mBytesPerPixel;
+   }
+}
+
 DefineEngineFunction( getBitmapInfo, String, ( const char *filename ),,
 DefineEngineFunction( getBitmapInfo, String, ( const char *filename ),,
    "Returns image info in the following format: width TAB height TAB bytesPerPixel. "
    "Returns image info in the following format: width TAB height TAB bytesPerPixel. "
    "It will return an empty string if the file is not found.\n"
    "It will return an empty string if the file is not found.\n"

部分文件因为文件数量过多而无法显示