Implementation of sRGB image support. Overhauls the linearization setup to utilize the sRGB image types, as well as refactors the use of ColorF and ColorI to be properly internally consistent. ColorIs are used only for front-facing/editing/UI settings, and ColorFs, now renamed to LinearColorF to reduce confusion of purpose, are used for color info in the engine itself. This avoids confusing and expensive conversions back and forth between types and avoids botches with linearity. Majority work done by @rextimmy

This commit is contained in:
Areloch 2017-06-23 11:36:20 -05:00
parent 8780f83262
commit 25686ed4be
294 changed files with 3894 additions and 2813 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;
@ -104,10 +107,6 @@ GFXD3D11Device::GFXD3D11Device(U32 index)
mPixVersion = 0.0; mPixVersion = 0.0;
mVertexShaderTarget = String::EmptyString;
mPixelShaderTarget = String::EmptyString;
mShaderModel = String::EmptyString;
mDrawInstancesCount = 0; mDrawInstancesCount = 0;
mCardProfiler = NULL; mCardProfiler = NULL;
@ -122,6 +121,7 @@ GFXD3D11Device::GFXD3D11Device(U32 index)
mCurrentConstBuffer = NULL; mCurrentConstBuffer = NULL;
mOcclusionQuerySupported = false; mOcclusionQuerySupported = false;
mCbufferPartialSupported = false;
mDebugLayers = false; mDebugLayers = false;
@ -149,7 +149,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 +162,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 +180,7 @@ GFXD3D11Device::~GFXD3D11Device()
#endif #endif
SAFE_RELEASE(mSwapChain); SAFE_RELEASE(mSwapChain);
SAFE_RELEASE(mD3DDevice1);
SAFE_RELEASE(mD3DDevice); SAFE_RELEASE(mD3DDevice);
} }
@ -220,7 +222,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 +289,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);
@ -315,47 +317,10 @@ void GFXD3D11Device::enumerateAdapters(Vector<GFXAdapter*> &adapterList)
toAdd->mAvailableModes.push_back(vmAdd); toAdd->mAvailableModes.push_back(vmAdd);
} }
//Check adapater can handle feature level 10
D3D_FEATURE_LEVEL deviceFeature;
ID3D11Device *pTmpDevice = nullptr;
// Create temp Direct3D11 device.
bool suitable = true;
UINT createDeviceFlags = D3D11_CREATE_DEVICE_SINGLETHREADED | D3D11_CREATE_DEVICE_BGRA_SUPPORT;
hr = D3D11CreateDevice(EnumAdapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, createDeviceFlags, NULL, 0, D3D11_SDK_VERSION, &pTmpDevice, &deviceFeature, NULL);
if (FAILED(hr))
suitable = false;
if (deviceFeature < D3D_FEATURE_LEVEL_10_0)
suitable = false;
//double check we support required bgra format for LEVEL_10_0 & LEVEL_10_1
if (deviceFeature == D3D_FEATURE_LEVEL_10_0 || deviceFeature == D3D_FEATURE_LEVEL_10_1)
{
U32 formatSupported = 0;
pTmpDevice->CheckFormatSupport(DXGI_FORMAT_B8G8R8A8_UNORM, &formatSupported);
U32 flagsRequired = D3D11_FORMAT_SUPPORT_RENDER_TARGET | D3D11_FORMAT_SUPPORT_DISPLAY;
if (!(formatSupported && flagsRequired))
{
Con::printf("DXGI adapter: %s does not support BGRA", Description.c_str());
suitable = false;
}
}
delete[] displayModes; delete[] displayModes;
SAFE_RELEASE(pTmpDevice);
SAFE_RELEASE(pOutput); SAFE_RELEASE(pOutput);
SAFE_RELEASE(EnumAdapter); SAFE_RELEASE(EnumAdapter);
adapterList.push_back(toAdd);
if (suitable)
{
adapterList.push_back(toAdd);
}
else
{
Con::printf("DXGI adapter: %s does not support D3D11 feature level 10 or better", Description.c_str());
delete toAdd;
}
} }
SAFE_RELEASE(DXGIFactory); SAFE_RELEASE(DXGIFactory);
@ -391,7 +356,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 +395,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,77 +404,88 @@ void GFXD3D11Device::init(const GFXVideoMode &mode, PlatformWindow *window)
mDebugLayers = true; mDebugLayers = true;
#endif #endif
DXGI_SWAP_CHAIN_DESC d3dpp = setupPresentParams(mode, winHwnd);
D3D_FEATURE_LEVEL deviceFeature;
// TODO support at least feature level 10 to match GL
D3D_FEATURE_LEVEL pFeatureLevels[] = { D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_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,
&deviceFeature,
&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, &deviceFeature,
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();
// Now reacquire all the resources we trashed earlier // Now reacquire all the resources we trashed earlier
reacquireDefaultPoolResources(); reacquireDefaultPoolResources();
//set vert/pixel shader targets if (deviceFeature >= D3D_FEATURE_LEVEL_11_0)
switch (mFeatureLevel)
{
case D3D_FEATURE_LEVEL_11_0:
mVertexShaderTarget = "vs_5_0";
mPixelShaderTarget = "ps_5_0";
mPixVersion = 5.0f; mPixVersion = 5.0f;
mShaderModel = "50"; else
break; AssertFatal(false, "GFXD3D11Device::init - We don't support anything below feature level 11.");
case D3D_FEATURE_LEVEL_10_1:
mVertexShaderTarget = "vs_4_1";
mPixelShaderTarget = "ps_4_1";
mPixVersion = 4.1f;
mShaderModel = "41";
break;
case D3D_FEATURE_LEVEL_10_0:
mVertexShaderTarget = "vs_4_0";
mPixelShaderTarget = "ps_4_0";
mPixVersion = 4.0f;
mShaderModel = "40";
break;
default:
AssertFatal(false, "GFXD3D11Device::init - We don't support this feature level");
}
D3D11_QUERY_DESC queryDesc; D3D11_QUERY_DESC queryDesc;
queryDesc.Query = D3D11_QUERY_OCCLUSION; queryDesc.Query = D3D11_QUERY_OCCLUSION;
@ -527,6 +503,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 +614,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 +635,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 +652,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);
} }
@ -668,12 +774,11 @@ void GFXD3D11Device::setupGenericShaders(GenericShaderType type)
if(mGenericShader[GSColor] == NULL) if(mGenericShader[GSColor] == NULL)
{ {
ShaderData *shaderData; ShaderData *shaderData;
//shader model 4.0 is enough for the generic shaders
const char* shaderModel = "4.0";
shaderData = new ShaderData(); shaderData = new ShaderData();
shaderData->setField("DXVertexShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/colorV.hlsl")); shaderData->setField("DXVertexShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/colorV.hlsl"));
shaderData->setField("DXPixelShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/colorP.hlsl")); shaderData->setField("DXPixelShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/colorP.hlsl"));
shaderData->setField("pixVersion", shaderModel); shaderData->setField("pixVersion", "5.0");
shaderData->registerObject(); shaderData->registerObject();
mGenericShader[GSColor] = shaderData->getShader(); mGenericShader[GSColor] = shaderData->getShader();
mGenericShaderBuffer[GSColor] = mGenericShader[GSColor]->allocConstBuffer(); mGenericShaderBuffer[GSColor] = mGenericShader[GSColor]->allocConstBuffer();
@ -683,7 +788,7 @@ void GFXD3D11Device::setupGenericShaders(GenericShaderType type)
shaderData = new ShaderData(); shaderData = new ShaderData();
shaderData->setField("DXVertexShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/modColorTextureV.hlsl")); shaderData->setField("DXVertexShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/modColorTextureV.hlsl"));
shaderData->setField("DXPixelShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/modColorTextureP.hlsl")); shaderData->setField("DXPixelShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/modColorTextureP.hlsl"));
shaderData->setField("pixVersion", shaderModel); shaderData->setField("pixVersion", "5.0");
shaderData->registerObject(); shaderData->registerObject();
mGenericShader[GSModColorTexture] = shaderData->getShader(); mGenericShader[GSModColorTexture] = shaderData->getShader();
mGenericShaderBuffer[GSModColorTexture] = mGenericShader[GSModColorTexture]->allocConstBuffer(); mGenericShaderBuffer[GSModColorTexture] = mGenericShader[GSModColorTexture]->allocConstBuffer();
@ -693,7 +798,7 @@ void GFXD3D11Device::setupGenericShaders(GenericShaderType type)
shaderData = new ShaderData(); shaderData = new ShaderData();
shaderData->setField("DXVertexShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/addColorTextureV.hlsl")); shaderData->setField("DXVertexShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/addColorTextureV.hlsl"));
shaderData->setField("DXPixelShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/addColorTextureP.hlsl")); shaderData->setField("DXPixelShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/addColorTextureP.hlsl"));
shaderData->setField("pixVersion", shaderModel); shaderData->setField("pixVersion", "5.0");
shaderData->registerObject(); shaderData->registerObject();
mGenericShader[GSAddColorTexture] = shaderData->getShader(); mGenericShader[GSAddColorTexture] = shaderData->getShader();
mGenericShaderBuffer[GSAddColorTexture] = mGenericShader[GSAddColorTexture]->allocConstBuffer(); mGenericShaderBuffer[GSAddColorTexture] = mGenericShader[GSAddColorTexture]->allocConstBuffer();
@ -703,7 +808,7 @@ void GFXD3D11Device::setupGenericShaders(GenericShaderType type)
shaderData = new ShaderData(); shaderData = new ShaderData();
shaderData->setField("DXVertexShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/textureV.hlsl")); shaderData->setField("DXVertexShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/textureV.hlsl"));
shaderData->setField("DXPixelShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/textureP.hlsl")); shaderData->setField("DXPixelShaderFile", String(Con::getVariable("$Core::CommonShaderPath")) + String("/fixedFunction/textureP.hlsl"));
shaderData->setField("pixVersion", shaderModel); shaderData->setField("pixVersion", "5.0");
shaderData->registerObject(); shaderData->registerObject();
mGenericShader[GSTexture] = shaderData->getShader(); mGenericShader[GSTexture] = shaderData->getShader();
mGenericShaderBuffer[GSTexture] = mGenericShader[GSTexture]->allocConstBuffer(); mGenericShaderBuffer[GSTexture] = mGenericShader[GSTexture]->allocConstBuffer();
@ -763,7 +868,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 +880,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 +1455,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 +1462,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 +1497,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 +1658,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;
@ -137,18 +143,12 @@ protected:
F32 mPixVersion; F32 mPixVersion;
D3D_FEATURE_LEVEL mFeatureLevel;
// Shader Model targers
String mVertexShaderTarget;
String mPixelShaderTarget;
// String for use with shader macros in the form of shader model version * 10
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 +181,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 +243,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 +291,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 );
@ -308,13 +311,6 @@ public:
// Default multisample parameters // Default multisample parameters
DXGI_SAMPLE_DESC getMultisampleType() const { return mMultisampleDesc; } DXGI_SAMPLE_DESC getMultisampleType() const { return mMultisampleDesc; }
// Get feature level this gfx device supports
D3D_FEATURE_LEVEL getFeatureLevel() const { return mFeatureLevel; }
// Shader Model targers
const String &getVertexShaderTarget() const { return mVertexShaderTarget; }
const String &getPixelShaderTarget() const { return mPixelShaderTarget; }
const String &getShaderModel() const { return mShaderModel; }
// grab the sampler map // grab the sampler map
const SamplerMap &getSamplersMap() const { return mSamplersMap; } const SamplerMap &getSamplersMap() const { return mSamplersMap; }
SamplerMap &getSamplersMap() { return mSamplersMap; } SamplerMap &getSamplersMap() { return mSamplersMap; }

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
@ -790,8 +764,9 @@ bool GFXD3D11Shader::_init()
d3dMacros[i+smGlobalMacros.size()].Definition = mMacros[i].value.c_str(); d3dMacros[i+smGlobalMacros.size()].Definition = mMacros[i].value.c_str();
} }
//TODO support D3D_FEATURE_LEVEL properly with shaders instead of hard coding at hlsl 5
d3dMacros[macroCount - 2].Name = "TORQUE_SM"; d3dMacros[macroCount - 2].Name = "TORQUE_SM";
d3dMacros[macroCount - 2].Definition = D3D11->getShaderModel().c_str(); d3dMacros[macroCount - 2].Definition = "50";
memset(&d3dMacros[macroCount - 1], 0, sizeof(D3D_SHADER_MACRO)); memset(&d3dMacros[macroCount - 1], 0, sizeof(D3D_SHADER_MACRO));
@ -809,21 +784,18 @@ bool GFXD3D11Shader::_init()
mSamplerDescriptions.clear(); mSamplerDescriptions.clear();
mShaderConsts.clear(); mShaderConsts.clear();
String vertTarget = D3D11->getVertexShaderTarget();
String pixTarget = D3D11->getPixelShaderTarget();
if ( !Con::getBoolVariable( "$shaders::forceLoadCSF", false ) ) if ( !Con::getBoolVariable( "$shaders::forceLoadCSF", false ) )
{ {
if (!mVertexFile.isEmpty() && !_compileShader( mVertexFile, vertTarget, d3dMacros, mVertexConstBufferLayout, mSamplerDescriptions ) ) if (!mVertexFile.isEmpty() && !_compileShader( mVertexFile, "vs_5_0", d3dMacros, mVertexConstBufferLayout, mSamplerDescriptions ) )
return false; return false;
if (!mPixelFile.isEmpty() && !_compileShader( mPixelFile, pixTarget, d3dMacros, mPixelConstBufferLayout, mSamplerDescriptions ) ) if (!mPixelFile.isEmpty() && !_compileShader( mPixelFile, "ps_5_0", d3dMacros, mPixelConstBufferLayout, mSamplerDescriptions ) )
return false; return false;
} }
else else
{ {
if ( !_loadCompiledOutput( mVertexFile, vertTarget, mVertexConstBufferLayout, mSamplerDescriptions ) ) if ( !_loadCompiledOutput( mVertexFile, "vs_5_0", mVertexConstBufferLayout, mSamplerDescriptions ) )
{ {
if ( smLogErrors ) if ( smLogErrors )
Con::errorf( "GFXD3D11Shader::init - Unable to load precompiled vertex shader for '%s'.", mVertexFile.getFullPath().c_str() ); Con::errorf( "GFXD3D11Shader::init - Unable to load precompiled vertex shader for '%s'.", mVertexFile.getFullPath().c_str() );
@ -831,7 +803,7 @@ bool GFXD3D11Shader::_init()
return false; return false;
} }
if ( !_loadCompiledOutput( mPixelFile, pixTarget, mPixelConstBufferLayout, mSamplerDescriptions ) ) if ( !_loadCompiledOutput( mPixelFile, "ps_5_0", mPixelConstBufferLayout, mSamplerDescriptions ) )
{ {
if ( smLogErrors ) if ( smLogErrors )
Con::errorf( "GFXD3D11Shader::init - Unable to load precompiled pixel shader for '%s'.", mPixelFile.getFullPath().c_str() ); Con::errorf( "GFXD3D11Shader::init - Unable to load precompiled pixel shader for '%s'.", mPixelFile.getFullPath().c_str() );
@ -877,12 +849,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 +1026,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 +1049,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 +1134,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