Merge pull request #2023 from Areloch/sRGB_Implementation

Implementation of sRGB image support
This commit is contained in:
Areloch 2017-07-05 22:28:35 -05:00 committed by GitHub
commit 597abec447
294 changed files with 3879 additions and 2721 deletions

View file

@ -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() );
} }

View file

@ -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,10 +1260,12 @@ 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; tCol /= div;
color.alpha = 255; tCol.alpha = 1;
color = tCol.toColorI();
Point3F pnt; Point3F pnt;
objToWorld.mulP( faceList[i].centroid, &pnt ); objToWorld.mulP( faceList[i].centroid, &pnt );
@ -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 ]; ColorI color = faceColorsx[j % 4];
S32 div = ( j / 4 ) * 4; LinearColorF tCol = LinearColorF(color);
if ( div > 0 ) S32 div = (j / 4) * 4;
color /= div; if (div > 0)
color.alpha = 255; tCol /= div;
tCol.alpha = 1;
color = tCol.toColorI();
PrimBuild::color( color ); PrimBuild::color( color );
PrimBuild::vertex3fv( p0 ); PrimBuild::vertex3fv( p0 );

View file

@ -42,9 +42,9 @@ class GuiClockHud : public GuiControl
bool mShowFill; bool mShowFill;
bool mTimeReversed; bool mTimeReversed;
ColorF mFillColor; LinearColorF mFillColor;
ColorF mFrameColor; LinearColorF mFrameColor;
ColorF mTextColor; 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());
} }

View file

@ -42,8 +42,8 @@ class GuiCrossHairHud : public GuiBitmapCtrl
{ {
typedef GuiBitmapCtrl Parent; typedef GuiBitmapCtrl Parent;
ColorF mDamageFillColor; LinearColorF mDamageFillColor;
ColorF mDamageFrameColor; 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());
} }

View file

@ -45,9 +45,9 @@ class GuiHealthBarHud : public GuiControl
bool mDisplayEnergy; bool mDisplayEnergy;
bool mFlip; bool mFlip;
ColorF mFillColor; LinearColorF mFillColor;
ColorF mFrameColor; LinearColorF mFrameColor;
ColorF mDamageFillColor; 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());
} }

View file

@ -41,10 +41,10 @@ class GuiHealthTextHud : public GuiControl
bool mShowEnergy; bool mShowEnergy;
bool mShowTrueHealth; bool mShowTrueHealth;
ColorF mFillColor; LinearColorF mFillColor;
ColorF mFrameColor; LinearColorF mFrameColor;
ColorF mTextColor; LinearColorF mTextColor;
ColorF mWarnColor; 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());
} }

View file

@ -47,11 +47,11 @@ class GuiShapeNameHud : public GuiControl {
typedef GuiControl Parent; typedef GuiControl Parent;
// field data // field data
ColorF mFillColor; LinearColorF mFillColor;
ColorF mFrameColor; LinearColorF mFrameColor;
ColorF mTextColor; LinearColorF mTextColor;
ColorF mLabelFillColor; LinearColorF mLabelFillColor;
ColorF mLabelFrameColor; 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());
} }

View file

@ -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; LinearColorF lightStartColor;
ColorF lightEndColor; LinearColorF lightEndColor;
F32 lightStartBrightness; F32 lightStartBrightness;
F32 lightEndBrightness; F32 lightEndBrightness;
F32 lightNormalOffset; F32 lightNormalOffset;

View file

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

View file

@ -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()
{ {

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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)
{ {
@ -1780,54 +1780,54 @@ void ParticleEmitter::setupOriented( 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 + crossDir; lVerts->point = start + crossDir;
lVerts->color = partCol; lVerts->color = color;
// Here and below, we copy UVs from particle datablock's current frame's UVs (oriented) // Here and below, we copy UVs from particle datablock's current frame's UVs (oriented)
lVerts->texCoord = part->dataBlock->animTexUVs[uv[0]]; lVerts->texCoord = part->dataBlock->animTexUVs[uv[0]];
++lVerts; ++lVerts;
lVerts->point = start - crossDir; lVerts->point = start - crossDir;
lVerts->color = partCol; lVerts->color = color;
lVerts->texCoord = part->dataBlock->animTexUVs[uv[1]]; lVerts->texCoord = part->dataBlock->animTexUVs[uv[1]];
++lVerts; ++lVerts;
lVerts->point = end - crossDir; lVerts->point = end - crossDir;
lVerts->color = partCol; lVerts->color = color;
lVerts->texCoord = part->dataBlock->animTexUVs[uv[2]]; lVerts->texCoord = part->dataBlock->animTexUVs[uv[2]];
++lVerts; ++lVerts;
lVerts->point = end + crossDir; lVerts->point = end + crossDir;
lVerts->color = partCol; lVerts->color = color;
lVerts->texCoord = part->dataBlock->animTexUVs[uv[3]]; lVerts->texCoord = part->dataBlock->animTexUVs[uv[3]];
++lVerts; ++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->point = start + cross;
lVerts->color = partCol; lVerts->color = color;
lVerts->texCoord = part->dataBlock->animTexUVs[uv[0]]; lVerts->texCoord = part->dataBlock->animTexUVs[uv[0]];
++lVerts; ++lVerts;
lVerts->point = start - cross; lVerts->point = start - cross;
lVerts->color = partCol; lVerts->color = color;
lVerts->texCoord = part->dataBlock->animTexUVs[uv[1]]; lVerts->texCoord = part->dataBlock->animTexUVs[uv[1]];
++lVerts; ++lVerts;
lVerts->point = end - cross; lVerts->point = end - cross;
lVerts->color = partCol; lVerts->color = color;
lVerts->texCoord = part->dataBlock->animTexUVs[uv[2]]; lVerts->texCoord = part->dataBlock->animTexUVs[uv[2]];
++lVerts; ++lVerts;
lVerts->point = end + cross; lVerts->point = end + cross;
lVerts->color = partCol; lVerts->color = color;
lVerts->texCoord = part->dataBlock->animTexUVs[uv[3]]; lVerts->texCoord = part->dataBlock->animTexUVs[uv[3]];
++lVerts; ++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;
} }

View file

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

View file

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

View file

@ -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

View file

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

View file

@ -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.

View file

@ -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__) );
} }
} }
} }

View file

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

View file

@ -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->setColor( LinearColorF( 1.0f, 1.0f, 1.0f ) );
mFakeSun->setAmbient( ColorF( 0.5f, 0.5f, 0.5f ) ); 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->setColor( LinearColorF( 1.0f, 1.0f, 1.0f ) );
GuiMaterialPreview::mFakeSun->setAmbient( ColorF( 0.5f, 0.5f, 0.5f ) ); 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 );

View file

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

View file

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

View file

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

View file

@ -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

View file

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

View file

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

View file

@ -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 ),

View file

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

View file

@ -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 ),

View file

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

View file

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

View file

@ -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];

View file

@ -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 );
} }
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------

View file

@ -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,

View file

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

View file

@ -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.

View file

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

View file

@ -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 ];

View file

@ -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 ).

View file

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

View file

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

View file

@ -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 ];

View file

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

View file

@ -567,13 +567,13 @@ ConsoleSetType( TypeFlag )
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// TypeColorF // TypeColorF
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
ConsoleType(ColorF, TypeColorF, ColorF, "") ConsoleType(LinearColorF, TypeColorF, LinearColorF, "")
ImplementConsoleTypeCasters( TypeColorF, ColorF ) 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?

View file

@ -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 * )

View file

@ -63,8 +63,8 @@ IMPLEMENT_STRUCT( ColorI,
END_IMPLEMENT_STRUCT; END_IMPLEMENT_STRUCT;
IMPLEMENT_STRUCT( ColorF, IMPLEMENT_STRUCT( LinearColorF,
ColorF,, 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." )

View file

@ -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_

View file

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

View file

@ -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_scan(const String &data, LinearColorF & result);
bool default_print(String & result, const ColorF & data); 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);

View file

@ -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 LinearColorF LinearColorF::ZERO( 0, 0, 0, 0 );
const ColorF ColorF::ONE( 1, 1, 1, 1 ); const LinearColorF LinearColorF::ONE( 1, 1, 1, 1 );
const ColorF ColorF::WHITE( 1, 1, 1 ); const LinearColorF LinearColorF::WHITE( 1, 1, 1 );
const ColorF ColorF::BLACK( 0, 0, 0 ); const LinearColorF LinearColorF::BLACK( 0, 0, 0 );
const ColorF ColorF::RED( 1, 0, 0 ); const LinearColorF LinearColorF::RED( 1, 0, 0 );
const ColorF ColorF::GREEN( 0, 1, 0 ); const LinearColorF LinearColorF::GREEN( 0, 1, 0 );
const ColorF ColorF::BLUE( 0, 0, 1 ); 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);

View file

@ -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;
//32bit color in linear space
class ColorF class LinearColorF
{ {
public: public:
F32 red; F32 red;
F32 green; F32 green;
F32 blue; F32 blue;
F32 alpha; F32 alpha;
public: public:
ColorF() { } LinearColorF() : red(0), green(0), blue(0), alpha(0) {}
ColorF(const ColorF& in_rCopy); LinearColorF(const LinearColorF& in_rCopy);
ColorF(const F32 in_r, LinearColorF(const F32 in_r, const F32 in_g, const F32 in_b, const F32 in_a = 1.0f);
const F32 in_g, LinearColorF(const ColorI &color);
const F32 in_b, LinearColorF(const char* pStockColorName);
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);
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 LinearColorF& operator*=(const LinearColorF& in_mul); // Can be useful for lighting
ColorF operator*(const ColorF& in_mul) const; LinearColorF operator*(const LinearColorF& in_mul) const;
ColorF& operator+=(const ColorF& in_rAdd); LinearColorF& operator+=(const LinearColorF& in_rAdd);
ColorF operator+(const ColorF& in_rAdd) const; LinearColorF operator+(const LinearColorF& in_rAdd) const;
ColorF& operator-=(const ColorF& in_rSub); LinearColorF& operator-=(const LinearColorF& in_rSub);
ColorF operator-(const ColorF& in_rSub) const; LinearColorF operator-(const LinearColorF& in_rSub) const;
ColorF& operator*=(const F32 in_mul); LinearColorF& operator*=(const F32 in_mul);
ColorF operator*(const F32 in_mul) const; LinearColorF operator*(const F32 in_mul) const;
ColorF& operator/=(const F32 in_div); LinearColorF& operator/=(const F32 in_div);
ColorF operator/(const F32 in_div) const; LinearColorF operator/(const F32 in_div) const;
ColorF operator-() const; LinearColorF operator-() const;
bool operator==(const ColorF&) const; bool operator==(const LinearColorF&) const;
bool operator!=(const ColorF&) 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 LinearColorF& in_rC1,
const LinearColorF& in_rC2,
void interpolate(const ColorF& in_rC1,
const ColorF& in_rC2,
const F32 in_factor); const F32 in_factor);
bool isValidColor() const { return (red >= 0.0f && red <= 1.0f) && bool isClamped() const { return (red >= 0.0f && red <= 1.0f) &&
(green >= 0.0f && green <= 1.0f) && (green >= 0.0f && green <= 1.0f) &&
(blue >= 0.0f && blue <= 1.0f) && (blue >= 0.0f && blue <= 1.0f) &&
(alpha >= 0.0f && alpha <= 1.0f); } (alpha >= 0.0f && alpha <= 1.0f); }
void clamp(); void clamp();
ColorF toLinear(); //calculate luminance
ColorF toGamma();
//calculate luminance, make sure color is linear first
F32 luminance(); F32 luminance();
static const ColorF ZERO; //convert to ColorI - slow operation, avoid when possible
static const ColorF ONE; ColorI toColorI(const bool keepAsLinear = false);
static const ColorF WHITE;
static const ColorF BLACK; static const LinearColorF ZERO;
static const ColorF RED; static const LinearColorF ONE;
static const ColorF GREEN; static const LinearColorF WHITE;
static const ColorF BLUE; 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 //8bit color in srgb space
// present in ColorF since they cannot recover
// properly from over/underflow.
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: public:
ColorI() { } 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, ColorI(const U8 in_r, const U8 in_g, const U8 in_b, const U8 in_a = U8(255));
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);
@ -174,24 +163,9 @@ 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,12 +184,10 @@ 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(); //convert linear color to srgb - slow operation, avoid when possible
ColorI toGamma(); ColorI fromLinear();
static const ColorI ZERO; static const ColorI ZERO;
static const ColorI ONE; static const ColorI ONE;
@ -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, inline void LinearColorF::set(const F32 in_r, const F32 in_g, const F32 in_b, const F32 in_a)
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, inline LinearColorF::LinearColorF(const F32 in_r, const F32 in_g, const F32 in_b, const F32 in_a)
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, LinearColorF tmp(*this);
green * in_mul.green, tmp *= in_mul;
blue * in_mul.blue, return tmp;
alpha * in_mul.alpha);
} }
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, LinearColorF temp(*this);
green + in_rAdd.green, temp += in_rAdd;
blue + in_rAdd.blue, return temp;
alpha + in_rAdd.alpha);
} }
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, LinearColorF tmp(*this);
green - in_rSub.green, tmp -= in_rSub;
blue - in_rSub.blue, return tmp;
alpha - in_rSub.alpha);
} }
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, LinearColorF tmp(*this);
green * in_mul, tmp *= in_mul;
blue * in_mul, return tmp;
alpha * in_mul);
} }
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;
LinearColorF tmp(*this);
return ColorF(red * inv, tmp /= inv;
green * inv, return tmp;
blue * inv,
alpha * inv);
} }
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, inline void LinearColorF::interpolate(const LinearColorF& in_rC1,
const ColorF& in_rC2, 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 = mClampF(red, 0.0f, 1.0f);
red = 1.0f; green = mClampF(green, 0.0f, 1.0f);
else if (red < 0.0f) blue = mClampF(blue, 0.0f, 1.0f);
red = 0.0f; alpha = mClampF(alpha, 0.0f, 1.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;
} }
inline ColorF ColorF::toGamma() inline F32 LinearColorF::luminance()
{
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()
{ {
// 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() inline LinearColorF::LinearColorF( const ColorI &color)
{ {
ColorF color = (ColorF)*this; red = sSrgbToLinear[color.red],
return (ColorI)color.toGamma(); green = sSrgbToLinear[color.green],
blue = sSrgbToLinear[color.blue],
alpha = F32(color.alpha * gOneOver255);
} }
inline ColorI ColorI::toLinear() inline ColorI LinearColorF::toColorI(const bool keepAsLinear)
{ {
ColorF color = (ColorF)*this; if (isClamped())
return (ColorI)color.toLinear(); {
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 CONVERSION OPERATORS inline ColorI ColorI::fromLinear()
inline ColorF::operator ColorI() const
{ {
return ColorI(U8(red * 255.0f + 0.5), //manually create LinearColorF, otherwise it will try and convert to linear first
U8(green * 255.0f + 0.5), LinearColorF linearColor = LinearColorF(F32(red) * 255.0f + 0.5f,
U8(blue * 255.0f + 0.5), F32(red) * 255.0f + 0.5f,
U8(alpha * 255.0f + 0.5)); F32(red) * 255.0f + 0.5f,
} F32(alpha) * 255.0f + 0.5f);
//convert back to srgb
inline ColorI::operator ColorF() const return linearColor.toColorI();
{
const F32 inv255 = 1.0f / 255.0f;
return ColorF(F32(red) * inv255,
F32(green) * inv255,
F32(blue) * inv255,
F32(alpha) * inv255);
} }
#endif //_COLOR_H_ #endif //_COLOR_H_

View file

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

View file

@ -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 &);

View file

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

View file

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

View file

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

View file

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

View file

@ -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.")
{ {

View file

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

View file

@ -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");

View file

@ -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" );
} }
} }

View file

@ -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()

View file

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

View file

@ -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

View file

@ -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; LinearColorF moonTemp = mMoonTint;
ColorF nightTemp = mNightColor; 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 )

View file

@ -119,10 +119,10 @@ protected:
void _generateSkyPoints(); void _generateSkyPoints();
void _getColor( const Point3F &pos, ColorF *outColor ); void _getColor( const Point3F &pos, LinearColorF *outColor );
void _getFogColor( ColorF *outColor ); void _getFogColor( LinearColorF *outColor );
void _getAmbientColor( ColorF *outColor ); void _getAmbientColor( LinearColorF *outColor );
void _getSunColor( ColorF *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; LinearColorF mNightColor;
ColorF mNightFogColor; LinearColorF mNightFogColor;
ColorF mAmbientColor; ///< Not a field LinearColorF mAmbientColor; ///< Not a field
ColorF mSunColor; ///< Not a field LinearColorF mSunColor; ///< Not a field
ColorF mFogColor; ///< Not a field LinearColorF mFogColor; ///< Not a field
ColorF mAmbientScale; LinearColorF mAmbientScale;
ColorF mSunScale; LinearColorF mSunScale;
ColorF mFogScale; 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;
}; };

View file

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

View file

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

View file

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

View file

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

View file

@ -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; LinearColorF c;
ColorF bc; 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;

View file

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

View file

@ -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

View file

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

View file

@ -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

View file

@ -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

View file

@ -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(); mMipMapLevels = faces->getPointer()->getMipLevels();
if (mipLevels > 1 && !compressed) 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.MipLevels = mMipMapLevels;
desc.ArraySize = 6; 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.CPUAccessFlags = 0;
desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE | D3D11_RESOURCE_MISC_GENERATE_MIPS; desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
D3D11_SUBRESOURCE_DATA* pData = new D3D11_SUBRESOURCE_DATA[6 + levels]; D3D11_SUBRESOURCE_DATA* pData = new D3D11_SUBRESOURCE_DATA[CubeFaces * mMipMapLevels];
for (U32 currentFace = 0; currentFace < CubeFaces; currentFace++)
for (U32 i = 0; i<CubeFaces; i++)
{ {
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]; const U32 dataIndex = faceIndex * mMipMapLevels + currentMip;
pData[i + j].SysMemPitch = dds->getSurfacePitch(j); pData[dataIndex].pSysMem = dds->mSurfaces[currentFace]->mMips[currentMip];
pData[i + j].SysMemSlicePitch = dds->getSurfaceSize(j); 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;

View file

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

View file

@ -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 // create a device, device context and swap chain using the information in the d3dpp struct
HRESULT hres = D3D11CreateDevice(NULL, HRESULT hres = D3D11CreateDeviceAndSwapChain(NULL,
driverType, driverType,
NULL, NULL,
createDeviceFlags, createDeviceFlags,
NULL, pFeatureLevels,
0, nFeatureCount,
D3D11_SDK_VERSION, D3D11_SDK_VERSION,
&mD3DDevice, &d3dpp,
&mFeatureLevel, &mSwapChain,
&mD3DDeviceContext); &mD3DDevice,
&mFeatureLevel,
&mD3DDeviceContext);
if(FAILED(hres)) if(FAILED(hres))
{ {
#ifdef TORQUE_DEBUG #ifdef TORQUE_DEBUG
//try again without debug device layer enabled //try again without debug device layer enabled
createDeviceFlags &= ~D3D11_CREATE_DEVICE_DEBUG; createDeviceFlags &= ~D3D11_CREATE_DEVICE_DEBUG;
hres = D3D11CreateDevice(NULL, hres = D3D11CreateDeviceAndSwapChain(NULL, driverType,NULL,createDeviceFlags,NULL, 0,
driverType, D3D11_SDK_VERSION,
NULL, &d3dpp,
createDeviceFlags, &mSwapChain,
NULL, &mD3DDevice,
0, &mFeatureLevel,
D3D11_SDK_VERSION, &mD3DDeviceContext);
&mD3DDevice, //if we failed again than we definitely have a problem
&mFeatureLevel, if (FAILED(hres))
&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
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 // Grab DX 11.1 device and context if available and also ID3DUserDefinedAnnotation
_suppressDebugMessages(); hres = mD3DDevice->QueryInterface(__uuidof(ID3D11Device1), reinterpret_cast<void**>(&mD3DDevice1));
#endif 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();
gdwt->initPresentationParams();
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->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 DXGI_MODE_DESC displayModes;
SAFE_RELEASE(mDeviceDepthStencilView); displayModes.Format = d3dpp.BufferDesc.Format;
SAFE_RELEASE(mDeviceBackBufferView); displayModes.Height = d3dpp.BufferDesc.Height;
SAFE_RELEASE(mDeviceDepthStencil); displayModes.Width = d3dpp.BufferDesc.Width;
SAFE_RELEASE(mDeviceBackbuffer); displayModes.RefreshRate = d3dpp.BufferDesc.RefreshRate;
} displayModes.Scaling = d3dpp.BufferDesc.Scaling;
displayModes.ScanlineOrdering = d3dpp.BufferDesc.ScanlineOrdering;
void GFXD3D11Device::endReset(GFXD3D11WindowTarget *windowTarget) HRESULT hr;
{ if (!d3dpp.Windowed)
//grab new references {
mDeviceBackbuffer = windowTarget->getBackBuffer(); hr = mSwapChain->ResizeTarget(&displayModes);
mDeviceDepthStencil = windowTarget->getDepthStencil();
mDeviceBackBufferView = windowTarget->getBackBufferView(); if (FAILED(hr))
mDeviceDepthStencilView = windowTarget->getDepthStencilView(); {
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(mDeviceBackbuffer);
SAFE_RELEASE(mDeviceDepthStencilView);
SAFE_RELEASE(mDeviceDepthStencil);
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 hr = mSwapChain->SetFullscreenState(!d3dpp.Windowed, NULL);
reacquireDefaultPoolResources();
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] = { const FLOAT clearColor[4] = { color.red, color.green, color.blue, color.alpha };
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)
};
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.

View file

@ -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 reset( DXGI_SWAP_CHAIN_DESC &d3dpp );
void endReset(GFXD3D11WindowTarget *windowTarget);
virtual void setupGenericShaders( GenericShaderType type = GSColor ); virtual void setupGenericShaders( GenericShaderType type = GSColor );

View file

@ -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[GFXFormatBC1] = DXGI_FORMAT_BC1_UNORM;
GFXD3D11TextureFormat[GFXFormatDXT2] = DXGI_FORMAT_BC1_UNORM; GFXD3D11TextureFormat[GFXFormatBC2] = DXGI_FORMAT_BC2_UNORM;
GFXD3D11TextureFormat[GFXFormatDXT3] = DXGI_FORMAT_BC2_UNORM; GFXD3D11TextureFormat[GFXFormatBC3] = DXGI_FORMAT_BC3_UNORM;
GFXD3D11TextureFormat[GFXFormatDXT4] = DXGI_FORMAT_BC2_UNORM; GFXD3D11TextureFormat[GFXFormatBC4] = DXGI_FORMAT_BC4_UNORM;
GFXD3D11TextureFormat[GFXFormatDXT5] = DXGI_FORMAT_BC3_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;

View file

@ -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 #ifdef TORQUE_GFX_VISUAL_DEBUG //for use with NSight, GPU Perf studio, VS graphics debugger
U32 flags = D3DCOMPILE_DEBUG | D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_WARNINGS_ARE_ERRORS; U32 flags = D3DCOMPILE_DEBUG | D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_PREFER_FLOW_CONTROL | D3DCOMPILE_SKIP_OPTIMIZATION;
#else #elif defined(TORQUE_DEBUG) //debug build
U32 flags = D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_OPTIMIZATION_LEVEL3; //TODO double check load times with D3DCOMPILE_OPTIMIZATION_LEVEL3 U32 flags = D3DCOMPILE_DEBUG | D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_WARNINGS_ARE_ERRORS;
//recommended flags for NSight, uncomment to use. NSight should be used in release mode only. *Still works with above flags however #else //release build
//flags = D3DCOMPILE_DEBUG | D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_PREFER_FLOW_CONTROL | D3DCOMPILE_SKIP_OPTIMIZATION; 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)
{ {

View file

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

View file

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

View file

@ -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; mWindow = NULL;
mBackBuffer = NULL; mBackbuffer = NULL;
mDepthStencilView = NULL;
mDepthStencil = NULL;
mBackBufferView = NULL;
mSecondaryWindow = false;
} }
GFXD3D11WindowTarget::~GFXD3D11WindowTarget() GFXD3D11WindowTarget::~GFXD3D11WindowTarget()
{ {
SAFE_RELEASE(mDepthStencilView) SAFE_RELEASE(mBackbuffer);
SAFE_RELEASE(mDepthStencil);
SAFE_RELEASE(mBackBufferView);
SAFE_RELEASE(mBackBuffer);
SAFE_RELEASE(mSwapChain);
} }
void GFXD3D11WindowTarget::initPresentationParams() void GFXD3D11WindowTarget::initPresentationParams()
{ {
// Get some video mode related info. // Get some video mode related info.
const GFXVideoMode &vm = mWindow->getVideoMode(); GFXVideoMode vm = mWindow->getVideoMode();
HWND hwnd = (HWND)mWindow->getSystemWindow(PlatformWindow::WindowSystem_Windows); Win32Window* win = static_cast<Win32Window*>(mWindow);
HWND hwnd = win->getHWND();
// Do some validation...
if (vm.fullScreen && mSecondaryWindow)
{
AssertFatal(false, "GFXD3D11WindowTarget::initPresentationParams - Cannot go fullscreen with secondary window!");
}
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); return (D3D11->getSwapChain()->Present(!D3D11->smDisableVSync, 0) == S_OK);
} }
void GFXD3D11WindowTarget::createSwapChain() void GFXD3D11WindowTarget::setImplicitSwapChain()
{ {
//create dxgi factory & swapchain if (!mBackbuffer)
IDXGIFactory1* DXGIFactory; D3D11->mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&mBackbuffer);
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);
}
void GFXD3D11WindowTarget::createBuffersAndViews()
{
//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
} }
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) // Otherwise, we have to reset the device, if we're the implicit swapchain.
{ D3D11->reset(mPresentationParams);
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!");
// 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);
GFX->beginReset();
//re-create buffers and views
createBuffersAndViews();
if (!mSecondaryWindow)
D3D11->endReset(this);
} }
void GFXD3D11WindowTarget::zombify() void GFXD3D11WindowTarget::zombify()
{ {
SAFE_RELEASE(mBackBuffer); SAFE_RELEASE(mBackbuffer);
} }
void GFXD3D11WindowTarget::resurrect() void GFXD3D11WindowTarget::resurrect()
{ {
setBackBuffer(); setImplicitSwapChain();
}
void GFXD3D11WindowTarget::setBackBuffer()
{
if (!mBackBuffer)
mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&mBackBuffer);
} }
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); D3D11DEVICECONTEXT->ResolveSubresource(surf, 0, D3D11->mDeviceBackbuffer, 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;
} }

View file

@ -76,11 +76,7 @@ class GFXD3D11WindowTarget : public GFXWindowTarget
friend class GFXD3D11Device; friend class GFXD3D11Device;
/// Our backbuffer /// Our backbuffer
ID3D11Texture2D *mBackBuffer; ID3D11Texture2D *mBackbuffer;
ID3D11Texture2D *mDepthStencil;
ID3D11RenderTargetView* mBackBufferView;
ID3D11DepthStencilView* mDepthStencilView;
IDXGISwapChain *mSwapChain;
/// 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 setImplicitSwapChain();
void createBuffersAndViews();
void setBackBuffer();
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

View file

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

View file

@ -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"); AssertFatal(mFormat == GFXFormatR8G8B8A8 || mFormat == GFXFormatR8G8B8A8_LINEAR_FORCE || mFormat == GFXFormatR8G8B8A8_SRGB, "copyToBmp: invalid format");
if (mFormat != GFXFormatR8G8B8A8 && mFormat != GFXFormatR8G8B8A8_LINEAR_FORCE) 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;

View file

@ -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() { };

View file

@ -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

View file

@ -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 GFXFormatBC2:
case GFXFormatDXT3: case GFXFormatBC3:
case GFXFormatDXT4: case GFXFormatBC5:
case GFXFormatDXT5:
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 GFXFormatBC2:
case GFXFormatDXT3: case GFXFormatBC3:
case GFXFormatDXT4: case GFXFormatBC5:
case GFXFormatDXT5:
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++ ) if (mFlags.test(CubeMapFlag))
bytes += getSurfaceSize( mHeight, mWidth, i ); {
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, AssertFatal( ImageUtil::isCompressedFormat(format),
"DDSFile::getSizeInBytes - Must be a DXT 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. //dds headers
s.read(&tmp); 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."); //read in dx10 header
s.read(DDS_HEADER_DX10_SIZE, &dx10header);
if (!dds::validateHeaderDx10(dx10header))
return false;
hasDx10Header = true;
}
//make sure our dds header is valid
if (!dds::validateHeader(header))
return false; return false;
// store details
mPitchOrLinearSize = header.pitchOrLinearSize;
mMipMapCount = header.mipMapCount ? header.mipMapCount : 1;
mHeight = header.height;
mWidth = header.width;
mDepth = header.depth;
mFourCC = header.ddspf.fourCC;
//process dx10 header
if (hasDx10Header)
{
if (dx10header.arraySize > 1)
{
Con::errorf("DDSFile::readHeader - DX10 arrays not supported");
return false;
}
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)
{
mFlags.set(CubeMap_All_Flags | ComplexFlag);
}
mHasTransparency = ImageUtil::isAlphaFormat(mFormat);
//mip map flag
if (mMipMapCount > 1)
mFlags.set(MipMapsFlag | ComplexFlag);
if (ImageUtil::isCompressedFormat(mFormat))
mFlags.set(CompressedData);
else
{
mBytesPerPixel = header.ddspf.bpp / 8;
mFlags.set(RGBData);
}
// we finished now
return true;
} }
// Read some flags... //process regular header
U32 ddsdFlags;
s.read(&ddsdFlags);
// "Always include DDSD_CAPS, DDSD_PIXELFORMAT, DDSD_WIDTH, DDSD_HEIGHT." //D3DFMT_DX10 is caught above, no need to check now
if(!(ddsdFlags & (DDSDCaps | DDSDPixelFormat | DDSDWidth | DDSDHeight))) if (header.ddspf.flags & DDS_FOURCC)
{ {
Con::errorf("DDSFile::readHeader - incorrect surface description flags."); mFormat = dds::getGFXFormat(mFourCC);
return false; //make sure getGFXFormat gave us a valid format
} if (mFormat == GFXFormat_FIRST)
return false;
// Read height and width (always present) if (ImageUtil::isCompressedFormat(mFormat))
s.read(&mHeight); mFlags.set(CompressedData);
s.read(&mWidth); else
{
// Read pitch or linear size. mBytesPerPixel = header.ddspf.bpp / 8;
mFlags.set(RGBData);
// 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!");
return false;
}
// Ok, some flags are set, so let's do some reading.
s.read(&mPitchOrLinearSize);
if(ddsdFlags & DDSDLinearSize)
{
mFlags.set(LinearSizeFlag); // ( mHeight / 4 ) * ( mWidth / 4 ) * DDSSIZE
}
else if (ddsdFlags & DDSDPitch)
{
mFlags.set(PitchSizeFlag); // ( mWidth / 4 ) * DDSSIZE ???
} }
else else
{ {
// Neither set! This appears to be depressingly common. mFormat = dds::getGFXFormat(header.ddspf);
// Con::warnf("DDSFile::readHeader - encountered neither DDSD_LINEARSIZE nor DDSD_PITCH!"); //make sure getGFXFormat gave us a valid format
} if (mFormat == GFXFormat_FIRST)
return false;
// Do we need to read depth? If so, we are a volume texture! mBytesPerPixel = header.ddspf.bpp / 8;
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); mFlags.set(RGBData);
mBytesPerPixel = pfBitCount / 8;
bool hasAlpha = ddpfFlags & DDPFAlphaPixels;
mHasTransparency = hasAlpha;
// Try to match a format.
if(hasAlpha)
{
// 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;
}
}
else
{
// 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;
}
}
}
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);
bool hasAlpha = false;
if(ddpfFlags & DDPFAlphaPixels)
{
hasAlpha = true;
//Con::printf(" alpha mask = %x", pfAlphaMask);
}
else
{
//Con::printf(" no alpha.");
}
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;
}
}
// Sweet, all done.
}
else if (ddpfFlags & DDPFFourCC)
{
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]); */
// Ok, make a format determination.
switch(pfFourCC)
{
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;
}
} }
// Deal with final caps bits... Is this really necessary? //mip map flag
if (mMipMapCount > 1)
mFlags.set(MipMapsFlag | ComplexFlag);
U32 caps1, caps2; //set transparency flag
s.read(&caps1); mHasTransparency = (header.ddspf.flags & DDS_ALPHAPIXELS);
s.read(&caps2);
s.read(&tmp);
s.read(&tmp); // More icky reserved space.
// Screw caps1. if (header.flags & DDS_HEADER_FLAGS_LINEARSIZE)
// if(!(caps1 & DDSCAPS_TEXTURE))) mFlags.set(LinearSizeFlag);
// { else if (header.flags & DDS_HEADER_FLAGS_PITCH)
// } mFlags.set(PitchSizeFlag);
// Caps2 has cubemap/volume info. Care about that. //set cubemap flags
if(caps2 & DDSCAPS2Cubemap) 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 (header.cubemapFlags & DDS_CUBEMAP_POSITIVEX) mFlags.set(CubeMap_PosX_Flag);
if ( caps2 & DDSCAPS2Cubemap_NEGATIVEX ) mFlags.set( CubeMap_NegX_Flag ); if (header.cubemapFlags & DDS_CUBEMAP_NEGATIVEX) mFlags.set(CubeMap_NegX_Flag);
if ( caps2 & DDSCAPS2Cubemap_POSITIVEY ) mFlags.set( CubeMap_PosY_Flag ); if (header.cubemapFlags & DDS_CUBEMAP_POSITIVEY) mFlags.set(CubeMap_PosY_Flag);
if ( caps2 & DDSCAPS2Cubemap_NEGATIVEY ) mFlags.set( CubeMap_NegY_Flag ); if (header.cubemapFlags & DDS_CUBEMAP_NEGATIVEY) mFlags.set(CubeMap_NegY_Flag);
if ( caps2 & DDSCAPS2Cubemap_POSITIVEZ ) mFlags.set( CubeMap_PosZ_Flag ); if (header.cubemapFlags & DDS_CUBEMAP_POSITIVEZ) mFlags.set(CubeMap_PosZ_Flag);
if ( caps2 & DDSCAPS2Cubemap_NEGATIVEZ ) mFlags.set( CubeMap_NegZ_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 // write DDS magic
s.write( 4, "DDS " ); U32 magic = DDS_MAGIC;
s.write(magic);
U32 tmp = 0; dds::DDS_HEADER header = {};
dds::DDS_HEADER_DXT10 dx10header = {};
// Read the size of the header. bool hasDx10Header = false;
s.write( 124 ); //flags
U32 surfaceFlags = DDS_SURFACE_FLAGS_TEXTURE;
U32 cubemapFlags = 0;
U32 headerFlags = DDS_HEADER_FLAGS_TEXTURE;
// Read some flags... //pixel format
U32 ddsdFlags = DDSDCaps | DDSDPixelFormat | DDSDWidth | DDSDHeight; const dds::DDS_PIXELFORMAT &format = dds::getDDSFormat(mFormat);
if ( mFlags.test( CompressedData ) ) // todo better dx10 support
ddsdFlags |= DDSDLinearSize; if (format.fourCC == dds::D3DFMT_DX10)
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 );
// Do we need to read depth? If so, we are a volume texture!
s.write( mDepth );
// Deal with mips!
s.write( mMipMapCount );
// 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?
// 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 ) )
{ {
ddpfFlags = DDPFFourCC; dx10header.dxgiFormat = dds::getDXGIFormat(mFormat);
if (mFormat == GFXFormatDXT1) dx10header.arraySize = 1;
fourCC = FOURCC_DXT1; dx10header.resourceDimension = dds::D3D10_RESOURCE_DIMENSION_TEXTURE2D;
if (mFormat == GFXFormatDXT3) dx10header.miscFlag = 0;
fourCC = FOURCC_DXT3; dx10header.miscFlags2 = 0;
if (mFormat == GFXFormatDXT5) hasDx10Header = true;
fourCC = FOURCC_DXT5;
} }
if (mFlags.test(CompressedData))
headerFlags |= DDS_HEADER_FLAGS_LINEARSIZE;
else else
ddpfFlags = mBytesPerPixel == 4 ? DDPFRGB | DDPFAlphaPixels : DDPFRGB; headerFlags |= DDS_HEADER_FLAGS_PITCH;
s.write( ddpfFlags ); if (mMipMapCount > 1)
{
surfaceFlags |= DDS_SURFACE_FLAGS_MIPMAP;
headerFlags |= DDS_HEADER_FLAGS_MIPMAP;
}
// Read the next few values so we can deal with them all in one go. //cubemap flags
//U32 pfFourCC, pfBitCount, pfRMask, pfGMask, pfBMask, pfAlphaMask; if (mFlags.test(CubeMapFlag))
{
surfaceFlags |= DDS_SURFACE_FLAGS_CUBEMAP;
cubemapFlags |= DDS_CUBEMAP_ALLFACES;
}
s.write( fourCC ); //volume texture
s.write( mBytesPerPixel * 8 ); if (mDepth > 0)
s.write( 0x000000FF ); {
s.write( 0x00FF0000 ); headerFlags |= DDS_HEADER_FLAGS_VOLUME;
s.write( 0x0000FF00 ); dx10header.resourceDimension = dds::D3D10_RESOURCE_DIMENSION_TEXTURE3D;
s.write( 0xFF000000 ); }
// Deal with final caps bits... Is this really necessary? //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));
U32 caps1 = DDSCAPSTexture; //check our header is ok
if ( mMipMapCount > 0 ) if (!dds::validateHeader(header))
caps1 |= DDSCAPSComplex | DDSCAPSMipMap; return false;
tmp = 0; //Write out the header
s.write(DDS_HEADER_SIZE, &header);
s.write( caps1 ); //Write out dx10 header
s.write( tmp ); if (hasDx10Header)
s.write( tmp ); s.write(DDS_HEADER_DX10_SIZE, &dx10header);
s.write( tmp );// More icky reserved space.
// MS has ANOTHER reserved word here. This one particularly sucks.
s.write( tmp );
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" )

View file

@ -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_

View file

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

View file

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

View file

@ -47,7 +47,7 @@ class Stream;
class RectI; class RectI;
class Point2I; class Point2I;
class ColorI; class ColorI;
class ColorF; class LinearColorF;
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
//-------------------------------------- GBitmap //-------------------------------------- GBitmap
@ -151,7 +151,13 @@ public:
const bool in_extrudeMipLevels = false, const bool in_extrudeMipLevels = false,
const GFXFormat in_format = GFXFormatR8G8B8 ); const GFXFormat in_format = GFXFormatR8G8B8 );
void allocateBitmapWithMips(const U32 in_width,
const U32 in_height,
const U32 in_numMips,
const GFXFormat in_format = GFXFormatR8G8B8);
void extrudeMipLevels(bool clearBorders = false); void extrudeMipLevels(bool clearBorders = false);
void chopTopMips(U32 mipsToChop);
void extrudeMipLevelsDetail(); void extrudeMipLevelsDetail();
U32 getNumMipLevels() const { return mNumMipLevels; } U32 getNumMipLevels() const { return mNumMipLevels; }
@ -182,6 +188,8 @@ public:
U32 getByteSize() const { return mByteSize; } U32 getByteSize() const { return mByteSize; }
U32 getBytesPerPixel() const { return mBytesPerPixel; } U32 getBytesPerPixel() const { return mBytesPerPixel; }
U32 getSurfaceSize(const U32 mipLevel) const;
/// Use these functions to set and get the mHasTransparency value /// Use these functions to set and get the mHasTransparency value
/// This is used to indicate that this bitmap has pixels that have /// This is used to indicate that this bitmap has pixels that have
/// an alpha value less than 255 (used by the auto-Material mapper) /// an alpha value less than 255 (used by the auto-Material mapper)
@ -194,9 +202,10 @@ public:
/// the bitmap bits and to check for alpha values less than 255 /// the bitmap bits and to check for alpha values less than 255
bool checkForTransparency(); bool checkForTransparency();
ColorF sampleTexel(F32 u, F32 v) const; LinearColorF sampleTexel(F32 u, F32 v) const;
bool getColor(const U32 x, const U32 y, ColorI& rColor) const; bool getColor(const U32 x, const U32 y, ColorI& rColor) const;
bool setColor(const U32 x, const U32 y, const ColorI& rColor); bool setColor(const U32 x, const U32 y, const ColorI& rColor);
U8 getChanelValueAt(U32 x, U32 y, U32 chan);
/// This method will combine bitmapA and bitmapB using the operation specified /// This method will combine bitmapA and bitmapB using the operation specified
/// by combineOp. The result will be stored in the bitmap that this method is /// by combineOp. The result will be stored in the bitmap that this method is

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