Merge pull request #2023 from Areloch/sRGB_Implementation

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

View file

@ -265,7 +265,7 @@ void AccumulationVolume::setTexture( const String& name )
mTextureName = name;
if ( isClientObject() && mTextureName.isNotEmpty() )
{
mAccuTexture.set(mTextureName, &GFXDefaultStaticDiffuseProfile, "AccumulationVolume::mAccuTexture");
mAccuTexture.set(mTextureName, &GFXStaticTextureSRGBProfile, "AccumulationVolume::mAccuTexture");
if ( mAccuTexture.isNull() )
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::color( ColorI::WHITE * 0.8f );
PrimBuild::color( LinearColorF(ColorI::WHITE) * 0.8f );
for ( S32 j = 0; j < edgeList.size(); j++ )
{
@ -1260,11 +1260,13 @@ void ConvexShape::_renderDebug( ObjectRenderInst *ri, SceneRenderState *state, B
for ( S32 i = 0; i < faceList.size(); i++ )
{
ColorI color = faceColorsx[ i % 4 ];
LinearColorF tCol = LinearColorF(color);
S32 div = ( i / 4 ) * 4;
if ( div > 0 )
color /= div;
color.alpha = 255;
tCol /= div;
tCol.alpha = 1;
color = tCol.toColorI();
Point3F pnt;
objToWorld.mulP( faceList[i].centroid, &pnt );
drawer->drawCube( desc, size, pnt, color, NULL );
@ -1295,11 +1297,13 @@ void ConvexShape::_renderDebug( ObjectRenderInst *ri, SceneRenderState *state, B
objToWorld.mulP( p0 );
objToWorld.mulP( p1 );
ColorI color = faceColorsx[ j % 4 ];
S32 div = ( j / 4 ) * 4;
if ( div > 0 )
color /= div;
color.alpha = 255;
ColorI color = faceColorsx[j % 4];
LinearColorF tCol = LinearColorF(color);
S32 div = (j / 4) * 4;
if (div > 0)
tCol /= div;
tCol.alpha = 1;
color = tCol.toColorI();
PrimBuild::color( color );
PrimBuild::vertex3fv( p0 );

View file

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

View file

@ -42,8 +42,8 @@ class GuiCrossHairHud : public GuiBitmapCtrl
{
typedef GuiBitmapCtrl Parent;
ColorF mDamageFillColor;
ColorF mDamageFrameColor;
LinearColorF mDamageFillColor;
LinearColorF mDamageFrameColor;
Point2I mDamageRectSize;
Point2I mDamageOffset;
@ -178,7 +178,7 @@ void GuiCrossHairHud::drawDamage(Point2I offset, F32 damage, F32 opacity)
rect.point.x -= mDamageRectSize.x / 2;
// Draw the border
GFX->getDrawUtil()->drawRect(rect, mDamageFrameColor);
GFX->getDrawUtil()->drawRect(rect, mDamageFrameColor.toColorI());
// Draw the damage % fill
rect.point += Point2I(1, 1);
@ -187,5 +187,5 @@ void GuiCrossHairHud::drawDamage(Point2I offset, F32 damage, F32 opacity)
if (rect.extent.x == 1)
rect.extent.x = 2;
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 mFlip;
ColorF mFillColor;
ColorF mFrameColor;
ColorF mDamageFillColor;
LinearColorF mFillColor;
LinearColorF mFrameColor;
LinearColorF mDamageFillColor;
S32 mPulseRate;
F32 mPulseThreshold;
@ -163,7 +163,7 @@ void GuiHealthBarHud::onRender(Point2I offset, const RectI &updateRect)
// Background first
if (mShowFill)
GFX->getDrawUtil()->drawRectFill(updateRect, mFillColor);
GFX->getDrawUtil()->drawRectFill(updateRect, mFillColor.toColorI());
// Pulse the damage fill if it's below the threshold
if (mPulseRate != 0)
@ -196,9 +196,9 @@ void GuiHealthBarHud::onRender(Point2I offset, const RectI &updateRect)
else
rect.point.y = bottomY - rect.extent.y;
}
GFX->getDrawUtil()->drawRectFill(rect, mDamageFillColor);
GFX->getDrawUtil()->drawRectFill(rect, mDamageFillColor.toColorI());
// Border last
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 mShowTrueHealth;
ColorF mFillColor;
ColorF mFrameColor;
ColorF mTextColor;
ColorF mWarnColor;
LinearColorF mFillColor;
LinearColorF mFrameColor;
LinearColorF mTextColor;
LinearColorF mWarnColor;
F32 mWarnLevel;
F32 mPulseThreshold;
@ -167,7 +167,7 @@ void GuiHealthTextHud::onRender(Point2I offset, const RectI &updateRect)
// If enabled draw background first
if (mShowFill)
drawUtil->drawRectFill(updateRect, mFillColor);
drawUtil->drawRectFill(updateRect, mFillColor.toColorI());
// Prepare text and center it
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.y += (getBounds().extent.y - mProfile->mFont->getHeight()) / 2;
ColorF tColor = mTextColor;
LinearColorF tColor = mTextColor;
// If warning level is exceeded switch to warning color
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->clearBitmapModulation();
// If enabled draw the border last
if (mShowFrame)
drawUtil->drawRect(updateRect, mFrameColor);
drawUtil->drawRect(updateRect, mFrameColor.toColorI());
}

View file

@ -47,11 +47,11 @@ class GuiShapeNameHud : public GuiControl {
typedef GuiControl Parent;
// field data
ColorF mFillColor;
ColorF mFrameColor;
ColorF mTextColor;
ColorF mLabelFillColor;
ColorF mLabelFrameColor;
LinearColorF mFillColor;
LinearColorF mFrameColor;
LinearColorF mTextColor;
LinearColorF mLabelFillColor;
LinearColorF mLabelFrameColor;
F32 mVerticalOffset;
F32 mDistanceFade;
@ -162,7 +162,7 @@ void GuiShapeNameHud::onRender( Point2I, const RectI &updateRect)
{
// Background fill first
if (mShowFill)
GFX->getDrawUtil()->drawRectFill(updateRect, mFillColor);
GFX->getDrawUtil()->drawRectFill(updateRect, mFillColor.toColorI());
// Must be in a TS Control
GuiTSCtrl *parent = dynamic_cast<GuiTSCtrl*>(getParent());
@ -274,7 +274,7 @@ void GuiShapeNameHud::onRender( Point2I, const RectI &updateRect)
// Border last
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
if (mShowLabelFill)
drawUtil->drawRectFill(RectI(offset, extent), mLabelFillColor);
drawUtil->drawRectFill(RectI(offset, extent), mLabelFillColor.toColorI());
// Deal with opacity and draw.
mTextColor.alpha = opacity;
drawUtil->setBitmapModulation(mTextColor);
drawUtil->setBitmapModulation(mTextColor.toColorI());
drawUtil->drawText(mProfile->mFont, offset + mLabelPadding, name);
drawUtil->clearBitmapModulation();
// Border last
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.
F32 lightStartRadius;
F32 lightEndRadius;
ColorF lightStartColor;
ColorF lightEndColor;
LinearColorF lightStartColor;
LinearColorF lightEndColor;
F32 lightStartBrightness;
F32 lightEndBrightness;
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.
static Point3F BoxPnts[] = {
@ -1260,7 +1260,7 @@ bool fxFoliageReplicator::onAdd()
{
// Yes, so load foliage texture.
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)
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);
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
@ -1619,7 +1619,7 @@ void fxFoliageReplicator::renderQuad(fxFoliageQuadrantNode* quadNode, const Matr
{
// Draw the Quad Box (Debug Only).
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) {
for (U32 i = 0; i < 4; i++)
renderQuad(quadNode->QuadrantChildNode[i], RenderTransform, UseDebug);
@ -1632,7 +1632,7 @@ void fxFoliageReplicator::renderQuad(fxFoliageQuadrantNode* quadNode, const Matr
} else {
// Use a different color to say "I think I'm not visible!"
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.
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)
Con::printf("fxFoliageReplicator: %s is an invalid or missing foliage texture file.", mFieldData.mFoliageFile);

View file

@ -126,7 +126,7 @@ public:
public:
bool IsQuadrantVisible(const Box3F VisBox, const MatrixF& RenderTransform);
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 mShowPlacementArea;
U32 mPlacementBandHeight;
ColorF mPlaceAreaColour;
LinearColorF mPlaceAreaColour;
tagFieldData()
{

View file

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

View file

@ -113,7 +113,7 @@ protected:
U32 type;
F32 windAmplitude;
Box3F worldBox;
ColorF lmColor;
LinearColorF lmColor;
};
/// This is the x,y index for this cell.
@ -239,7 +239,7 @@ void GroundCoverCell::_rebuildVB()
const S32 &type = (*iter).type;
const Point3F &size = (*iter).size;
const F32 &windAmplitude = (*iter).windAmplitude;
GFXVertexColor color = (ColorI)(*iter).lmColor;
color = LinearColorF((*iter).lmColor).toColorI();
U8 *col = (U8 *)const_cast<U32 *>( (const U32 *)color );
vertPtr->point = position;
@ -944,7 +944,7 @@ void GroundCover::_initialize( U32 cellCount, U32 cellPlacementCount )
Material* mat = dynamic_cast<Material*>(mMatInst->getMaterial());
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())
{
U32 w = tex.getWidth();

View file

@ -303,7 +303,7 @@ bool LightningData::preload(bool server, String &errorStr)
{
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++;
}
}

View file

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

View file

@ -200,7 +200,7 @@ void ParticleData::initPersistFields()
"Deprecated. Use textureName instead." );
// 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"
"The particle color will linearly interpolate between the color/time keys "
"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.
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)
{
errorStr = String::ToString("Missing particle texture: %s", textureName);
@ -613,7 +613,7 @@ bool ParticleData::reload(char errorBuffer[256])
bool error = false;
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)
{
dSprintf(errorBuffer, 256, "Missing particle texture: %s", textureName);

View file

@ -67,7 +67,7 @@ class ParticleData : public SimDataBlock
U32 numFrames;
U32 framesPerSec;
ColorF colors[ PDC_NUM_KEYS ];
LinearColorF colors[ PDC_NUM_KEYS ];
F32 sizes[ 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
ColorF color;
LinearColorF color;
F32 size;
F32 spinSpeed;

View file

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

View file

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

View file

@ -248,7 +248,7 @@ Precipitation::Precipitation()
mDropAnimateMS = 0;
mUseLighting = false;
mGlowIntensity = ColorF( 0,0,0,0 );
mGlowIntensity = LinearColorF( 0,0,0,0 );
mReflect = false;
@ -604,7 +604,7 @@ void Precipitation::initMaterials()
mDropShader = 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);
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);
if ( dStrlen(pd->mSplashShaderName) > 0 )
@ -1581,7 +1581,7 @@ void Precipitation::renderObject(ObjectRenderInst *ri, SceneRenderState *state,
// shader. Once the lighting and shadow systems
// are added into TSE we can expand this to include
// the N nearest lights to the camera + the ambient.
ColorF ambient( 1, 1, 1 );
LinearColorF ambient( 1, 1, 1 );
if ( mUseLighting )
{
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
///< 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.
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 rightvert = mSegmentPoints[i];
F32 tRadius = mDataBlock->mSizes[0];
ColorF tColor = mDataBlock->mColours[0];
LinearColorF tColor = mDataBlock->mColours[0];
for (U8 j = 0; j < RibbonData::NumFields-1; j++) {
F32 curPosition = mDataBlock->mTimes[j];
F32 curRadius = mDataBlock->mSizes[j];
ColorF curColor = mDataBlock->mColours[j];
LinearColorF curColor = mDataBlock->mColours[j];
F32 nextPosition = mDataBlock->mTimes[j+1];
F32 nextRadius = mDataBlock->mSizes[j+1];
ColorF nextColor = mDataBlock->mColours[j+1];
LinearColorF nextColor = mDataBlock->mColours[j+1];
if ( curPosition < 0
|| curPosition > interpol )
@ -603,7 +603,7 @@ void Ribbon::createBuffers(SceneRenderState *state, GFXVertexBufferHandle<GFXVer
perpendicular += mSegmentPoints[i];
verts[count].point.set(perpendicular);
ColorF color = tColor;
LinearColorF color = tColor;
if (mDataBlock->mUseFadeOut)
color.alpha *= mFadeOut;
@ -623,7 +623,7 @@ void Ribbon::createBuffers(SceneRenderState *state, GFXVertexBufferHandle<GFXVer
else
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[0] = Point2F(0.0f, texCoords);
verts[count].normal.set(diff);
@ -651,7 +651,7 @@ void Ribbon::createBuffers(SceneRenderState *state, GFXVertexBufferHandle<GFXVer
if (mDataBlock->mUseFadeOut)
color.alpha *= mFadeOut;
verts[count].color = color;
verts[count].color = color.toColorI();
verts[count].texCoord[1] = Point2F(interpol, 1);
verts[count].texCoord[0] = Point2F(1.0f, texCoords);
verts[count].normal.set(diff);

View file

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

View file

@ -77,8 +77,8 @@ bool GuiMaterialPreview::onWake()
if (!mFakeSun)
mFakeSun = LightManager::createLightInfo();
mFakeSun->setColor( ColorF( 1.0f, 1.0f, 1.0f ) );
mFakeSun->setAmbient( ColorF( 0.5f, 0.5f, 0.5f ) );
mFakeSun->setColor( LinearColorF( 1.0f, 1.0f, 1.0f ) );
mFakeSun->setAmbient( LinearColorF( 0.5f, 0.5f, 0.5f ) );
mFakeSun->setDirection( VectorF( 0.0f, 0.707f, -0.707f ) );
mFakeSun->setPosition( mFakeSun->getDirection() * -10000.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.
void GuiMaterialPreview::setAmbientLightColor( F32 r, F32 g, F32 b )
{
ColorF temp(r, g, b);
LinearColorF temp(r, g, b);
temp.clamp();
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.
void GuiMaterialPreview::setLightColor( F32 r, F32 g, F32 b )
{
ColorF temp(r, g, b);
LinearColorF temp(r, g, b);
temp.clamp();
GuiMaterialPreview::mFakeSun->setColor( temp );
}
@ -437,8 +437,8 @@ void GuiMaterialPreview::resetViewport()
mOrbitPos = mModel->getShape()->center;
// Reset the viewport's lighting.
GuiMaterialPreview::mFakeSun->setColor( ColorF( 1.0f, 1.0f, 1.0f ) );
GuiMaterialPreview::mFakeSun->setAmbient( ColorF( 0.5f, 0.5f, 0.5f ) );
GuiMaterialPreview::mFakeSun->setColor( LinearColorF( 1.0f, 1.0f, 1.0f ) );
GuiMaterialPreview::mFakeSun->setAmbient( LinearColorF( 0.5f, 0.5f, 0.5f ) );
GuiMaterialPreview::mFakeSun->setDirection( VectorF( 0.0f, 0.707f, -0.707f ) );
}
@ -482,14 +482,14 @@ DefineEngineMethod(GuiMaterialPreview, reset, void, (),,
}
// 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")
{
object->setLightColor( color.red, color.green, color.blue );
}
// 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")
{
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;
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;
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"
"@param color Color of sunlight.\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"
"@param color Ambient color of sunlight.\n"
"@tsexample\n"

View file

@ -145,10 +145,10 @@ class GuiObjectView : public GuiTSCtrl
LightInfo* mLight;
///
ColorF mLightColor;
LinearColorF mLightColor;
///
ColorF mLightAmbient;
LinearColorF mLightAmbient;
///
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 );

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -126,7 +126,7 @@ LightFlareData::LightFlareData()
{
dMemset( mElementRect, 0, sizeof( RectF ) * 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( 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.
// 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.
const U32 vertCount = 4 * mElementCount;
@ -544,7 +544,7 @@ void LightFlareData::prepRender(SceneRenderState *state, LightFlareState *flareS
Point3F *basePos = mElementRotate[i] ? rotatedBasePoints : sBasePoints;
ColorF color( baseColor * mElementTint[i] );
LinearColorF color( baseColor * mElementTint[i] );
if ( mElementUseLightColor[i] )
color *= lightInfo->getColor();
color.clamp();
@ -571,22 +571,23 @@ void LightFlareData::prepRender(SceneRenderState *state, LightFlareState *flareS
size.y = getMax( size.y, 1.0f );
size *= oneOverViewportExtent;
vert->color = color;
const ColorI colori = color.toColorI();
vert->color = colori;
vert->point = ( basePos[0] * size ) + pos;
vert->texCoord.set( texCoordMin.x, texCoordMax.y );
vert++;
vert->color = color;
vert->color = colori;
vert->point = ( basePos[1] * size ) + pos;
vert->texCoord.set( texCoordMax.x, texCoordMax.y );
vert++;
vert->color = color;
vert->color = colori;
vert->point = ( basePos[2] * size ) + pos;
vert->texCoord.set( texCoordMax.x, texCoordMin.y );
vert++;
vert->color = color;
vert->color = colori;
vert->point = ( basePos[3] * size ) + pos;
vert->texCoord.set( texCoordMin.x, texCoordMin.y );
vert++;
@ -633,7 +634,7 @@ bool LightFlareData::_preload( bool server, String &errorStr )
if ( !server )
{
if ( mFlareTextureName.isNotEmpty() )
mFlareTexture.set( mFlareTextureName, &GFXDefaultStaticDiffuseProfile, "FlareTexture" );
mFlareTexture.set( mFlareTextureName, &GFXStaticTextureSRGBProfile, "FlareTexture" );
}
return true;

View file

@ -123,7 +123,7 @@ protected:
RectF mElementRect[MAX_ELEMENTS];
F32 mElementDist[MAX_ELEMENTS];
F32 mElementScale[MAX_ELEMENTS];
ColorF mElementTint[MAX_ELEMENTS];
LinearColorF mElementTint[MAX_ELEMENTS];
bool mElementRotate[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 ) );
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;
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 )
colorList[ x ].set( material->mEffectColor[ x ].red,

View file

@ -167,7 +167,7 @@ void PointLight::_renderViz( SceneRenderState *state )
desc.setBlend( true );
// Base the sphere color on the light color.
ColorI color( mColor );
ColorI color = mColor.toColorI();
color.alpha = 16;
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 );
desc.setFillModeWireframe();
GFX->getDrawUtil()->drawPolygon( desc, mPortalPolygonWS.address(), mPortalPolygonWS.size(), ColorF::RED );
GFX->getDrawUtil()->drawPolygon( desc, mPortalPolygonWS.address(), mPortalPolygonWS.size(), ColorI::RED );
// Render rest.

View file

@ -653,7 +653,7 @@ void ProximityMine::renderObject( ObjectRenderInst* ri,
// Render the trigger area
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 )
{
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 );
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 )
colorList[ x ] = material->mEffectColor[ x ];

View file

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

View file

@ -202,7 +202,7 @@ void SpotLight::_renderViz( SceneRenderState *state )
desc.setBlend( true );
// Base the color on the light color.
ColorI color( mColor );
ColorI color = mColor.toColorI();
color.alpha = 16;
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 mMinAngle; ///< Min pos of needle
Point2F mCenter; ///< Center of needle rotation
ColorF mColor; ///< Needle Color
LinearColorF mColor; ///< Needle Color
F32 mNeedleLength;
F32 mNeedleWidth;
F32 mTailLength;

View file

@ -1235,7 +1235,7 @@ void WheeledVehicle::updateWheelParticles(F32 dt)
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 )
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"
"@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"
@ -1030,10 +1030,10 @@ DefineConsoleFunction(ColorFloatToInt, ColorI, (ColorF color), ,
"@endtsexample\n"
"@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"
"@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"
@ -1042,7 +1042,7 @@ DefineConsoleFunction(ColorIntToFloat, ColorF, (ColorI color), ,
"@endtsexample\n"
"@ingroup Strings")
{
return (ColorF)color;
return LinearColorF(color);
}
DefineConsoleFunction(ColorRGBToHEX, const char*, (ColorI color), ,
@ -1080,10 +1080,8 @@ DefineConsoleFunction(ColorHEXToRGB, ColorI, (const char* hex), ,
"@endtsexample\n"
"@ingroup Strings")
{
S32 rgb = dAtoui(hex, 16);
ColorI color;
color.set(rgb & 0x000000FF, (rgb & 0x0000FF00) >> 8, (rgb & 0x00FF0000) >> 16);
color.set(String(hex));
return color;
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -23,13 +23,13 @@
#include "platform/platform.h"
#include "core/color.h"
const ColorF ColorF::ZERO( 0, 0, 0, 0 );
const ColorF ColorF::ONE( 1, 1, 1, 1 );
const ColorF ColorF::WHITE( 1, 1, 1 );
const ColorF ColorF::BLACK( 0, 0, 0 );
const ColorF ColorF::RED( 1, 0, 0 );
const ColorF ColorF::GREEN( 0, 1, 0 );
const ColorF ColorF::BLUE( 0, 0, 1 );
const LinearColorF LinearColorF::ZERO( 0, 0, 0, 0 );
const LinearColorF LinearColorF::ONE( 1, 1, 1, 1 );
const LinearColorF LinearColorF::WHITE( 1, 1, 1 );
const LinearColorF LinearColorF::BLACK( 0, 0, 0 );
const LinearColorF LinearColorF::RED( 1, 0, 0 );
const LinearColorF LinearColorF::GREEN( 0, 1, 0 );
const LinearColorF LinearColorF::BLUE( 0, 0, 1 );
const ColorI ColorI::ZERO( 0, 0, 0, 0 );
const ColorI ColorI::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<ColorF, StringTableEntry> typeColorFToNameHash;
typedef HashTable<LinearColorF, StringTableEntry> typeColorFToNameHash;
typedef HashTable<ColorI, StringTableEntry> typeColorIToNameHash;
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!
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.
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.
*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.
*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 );
}
//-----------------------------------------------------------------------------
StringTableEntry ColorF::StockColor( void )
StringTableEntry LinearColorF::StockColor( void )
{
// Return stock color name.
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"
"@return A count of available stock colors." )
{
@ -513,7 +584,7 @@ ConsoleFunction( getStockColorF, const char*, 2, 2, "(stockColorName) - Gets a f
return StringTable->EmptyString();
// Fetch stock color.
const ColorF& color = StockColor::colorF( pStockColorName );
const LinearColorF& color = StockColor::colorF( pStockColorName );
// Format stock color.
char* returnBuffer = Con::getReturnBuffer(256);

View file

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

View file

@ -271,9 +271,9 @@ bool Stream::write(const ColorI& rColor)
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);
}
@ -287,7 +287,7 @@ bool Stream::read(ColorI* pColor)
return success;
}
bool Stream::read(ColorF* pColor)
bool Stream::read(LinearColorF* pColor)
{
ColorI temp;
bool success = read(&temp);

View file

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

View file

@ -31,12 +31,12 @@
namespace ConvertRGB
{
ColorF toLUV( const ColorF &rgbColor )
LinearColorF toLUV( const LinearColorF &rgbColor )
{
static const Point3F scXYZLUVDot( 1.0f, 15.0f, 3.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);
@ -44,12 +44,12 @@ ColorF toLUV( const ColorF &rgbColor )
uvColor.convolve( xyz_xy );
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.green /= 0.62f;
return luvColor;

View file

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

View file

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

View file

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

View file

@ -1074,7 +1074,7 @@ void VolumetricFog::render(ObjectRenderInst *ri, SceneRenderState *state, BaseMa
mPPShaderConsts->setSafe(mPPModelViewProjSC, xform);
const ColorF &sunlight = state->getAmbientLightColor();
const LinearColorF &sunlight = state->getAmbientLightColor();
Point3F ambientColor(sunlight.red, sunlight.green, sunlight.blue);
mShaderConsts->setSafe(mAmbientColorSC, ambientColor);
@ -1204,7 +1204,7 @@ void VolumetricFog::InitTexture()
mIsTextured = false;
if (mTextureName.isNotEmpty())
mTexture.set(mTextureName, &GFXDefaultStaticDiffuseProfile, "VolumetricFogMod");
mTexture.set(mTextureName, &GFXStaticTextureSRGBProfile, "VolumetricFogMod");
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);
setMaskBits(FogColorMask);
@ -1266,7 +1266,7 @@ bool VolumetricFog::isInsideFog()
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."
"@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
// Used in script
void setFogColor(ColorF color);
void setFogColor(LinearColorF color);
void setFogColor(ColorI color);
void setFogDensity(F32 density);
void setFogModulation(F32 strength, Point2F speed1, Point2F speed2);

View file

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

View file

@ -341,10 +341,10 @@ void BasicClouds::_initTexture()
}
if ( mTexName[i].isNotEmpty() )
mTexture[i].set( mTexName[i], &GFXDefaultStaticDiffuseProfile, "BasicClouds" );
mTexture[i].set( mTexName[i], &GFXStaticTextureSRGBProfile, "BasicClouds" );
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 );
LightInfo *lightinfo = LIGHTMGR->getSpecialLight(LightManager::slSunLightType);
const ColorF &sunlight = state->getAmbientLightColor();
const LinearColorF &sunlight = state->getAmbientLightColor();
Point3F ambientColor( sunlight.red, sunlight.green, sunlight.blue );
mShaderConsts->setSafe( mAmbientColorSC, ambientColor );
const ColorF &sunColor = lightinfo->getColor();
const LinearColorF &sunColor = lightinfo->getColor();
Point3F data( sunColor.red, sunColor.green, sunColor.blue );
mShaderConsts->setSafe( mSunColorSC, data );
@ -398,10 +398,10 @@ void CloudLayer::_initTexture()
}
if ( mTextureName.isNotEmpty() )
mTexture.set( mTextureName, &GFXDefaultStaticDiffuseProfile, "CloudLayer" );
mTexture.set( mTextureName, &GFXStaticTextureSRGBProfile, "CloudLayer" );
if ( mTexture.isNull() )
mTexture.set( GFXTextureManager::getWarningTexturePath(), &GFXDefaultStaticDiffuseProfile, "CloudLayer" );
mTexture.set( GFXTextureManager::getWarningTexturePath(), &GFXStaticTextureSRGBProfile, "CloudLayer" );
}
void CloudLayer::_initBuffers()

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -394,7 +394,7 @@ void Sun::setElevation( F32 elevation )
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;
_conformLights();
@ -490,7 +490,7 @@ void Sun::_renderCorona( ObjectRenderInst *ri, SceneRenderState *state, BaseMatI
points[i] += mLightWorldPos;
}
ColorF vertColor;
LinearColorF vertColor;
if ( mCoronaUseLightColor )
vertColor = mLightColor;
else
@ -503,7 +503,7 @@ void Sun::_renderCorona( ObjectRenderInst *ri, SceneRenderState *state, BaseMatI
for ( S32 i = 0; i < 4; i++ )
{
pVert->color.set( vertColor );
pVert->color.set( vertColor.toColorI());
pVert->point.set( points[i] );
pVert->texCoord.set( sCoords[i].x, sCoords[i].y );
pVert++;

View file

@ -50,9 +50,9 @@ protected:
F32 mSunElevation;
ColorF mLightColor;
LinearColorF mLightColor;
ColorF mLightAmbient;
LinearColorF mLightAmbient;
F32 mBrightness;
@ -79,7 +79,7 @@ protected:
BaseMatInstance *mCoronaMatInst;
MatrixSet *mMatrixSet;
F32 mCoronaScale;
ColorF mCoronaTint;
LinearColorF mCoronaTint;
bool mCoronaUseLightColor;
// These are not user specified.
@ -136,7 +136,7 @@ public:
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 );

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;
}
void TimeOfDay::_getSunColor( ColorF *outColor ) const
void TimeOfDay::_getSunColor( LinearColorF *outColor ) const
{
const COLOR_TARGET *ct = NULL;
@ -451,8 +451,8 @@ void TimeOfDay::_initColors()
// NOTE: The elevation targets represent distances
// from PI/2 radians (strait up).
ColorF c;
ColorF bc;
LinearColorF c;
LinearColorF bc;
// e is for elevation
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.
}
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;

View file

@ -34,9 +34,9 @@ class TimeOfDay;
struct COLOR_TARGET
{
F32 elevation; // maximum target elevation
ColorF color; //normalized 0 = 1.0 ...
LinearColorF color; //normalized 0 = 1.0 ...
F32 bandMod; //6 is max
ColorF bandColor;
LinearColorF bandColor;
};
typedef Vector<COLOR_TARGET> COLOR_TARGETS;
@ -108,7 +108,7 @@ public:
{ return (mCurrentColor.blue + mCurrentColor.green + mCurrentColor.red) / 3; }
*/
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 );
@ -150,10 +150,10 @@ protected:
/// @param color [in] target color.
/// @param bandMod [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.
void _getSunColor( ColorF *outColor ) const;
void _getSunColor( LinearColorF *outColor ) const;
static bool setTimeOfDay( 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;
/*
ColorF mCurrentColor;
LinearColorF mCurrentColor;
F32 mBandMod;
ColorF mCurrentBandColor;
LinearColorF mCurrentBandColor;
// PersistFields preparation
bool mConvertedToRads;

View file

@ -424,7 +424,7 @@ void WaterBlock::setShaderParams( SceneRenderState *state, BaseMatInstance *mat,
// set pixel shader constants
//-----------------------------------
ColorF c( mWaterFogData.color );
LinearColorF c( mWaterFogData.color );
matParams->setSafe( paramHandles.mBaseColorSC, c );
// 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 );
LightInfo *sun = LIGHTMGR->getSpecialLight(LightManager::slSunLightType);
const ColorF &sunlight = state->getAmbientLightColor();
const LinearColorF &sunlight = state->getAmbientLightColor();
Point3F ambientColor = mEmissive ? Point3F::One : sunlight;
matParams->setSafe(paramHandles.mAmbientColorSC, ambientColor );
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 );
if ( !mEmissive )
{
const ColorF &sunColor = sun->getColor();
const LinearColorF &sunColor = sun->getColor();
F32 brightness = sun->getBrightness();
specularParams.x *= sunColor.red * brightness;
specularParams.y *= sunColor.green * brightness;
@ -1159,22 +1159,22 @@ bool WaterObject::initMaterial( S32 idx )
void WaterObject::initTextures()
{
if ( mRippleTexName.isNotEmpty() )
mRippleTex.set( mRippleTexName, &GFXDefaultStaticDiffuseProfile, "WaterObject::mRippleTex" );
mRippleTex.set( mRippleTexName, &GFXStaticTextureSRGBProfile, "WaterObject::mRippleTex" );
if ( mRippleTex.isNull() )
mRippleTex.set( GFXTextureManager::getWarningTexturePath(), &GFXDefaultStaticDiffuseProfile, "WaterObject::mRippleTex" );
mRippleTex.set( GFXTextureManager::getWarningTexturePath(), &GFXStaticTextureSRGBProfile, "WaterObject::mRippleTex" );
if ( mDepthGradientTexName.isNotEmpty() )
mDepthGradientTex.set( mDepthGradientTexName, &GFXDefaultStaticDiffuseProfile, "WaterObject::mDepthGradientTex" );
mDepthGradientTex.set( mDepthGradientTexName, &GFXStaticTextureSRGBProfile, "WaterObject::mDepthGradientTex" );
if ( mDepthGradientTex.isNull() )
mDepthGradientTex.set( GFXTextureManager::getWarningTexturePath(), &GFXDefaultStaticDiffuseProfile, "WaterObject::mDepthGradientTex" );
mDepthGradientTex.set( GFXTextureManager::getWarningTexturePath(), &GFXStaticTextureSRGBProfile, "WaterObject::mDepthGradientTex" );
if ( mNamedDepthGradTex.isRegistered() )
mNamedDepthGradTex.setTexture( mDepthGradientTex );
if ( mFoamTexName.isNotEmpty() )
mFoamTex.set( mFoamTexName, &GFXDefaultStaticDiffuseProfile, "WaterObject::mFoamTex" );
mFoamTex.set( mFoamTexName, &GFXStaticTextureSRGBProfile, "WaterObject::mFoamTex" );
if ( mFoamTex.isNull() )
mFoamTex.set( GFXTextureManager::getWarningTexturePath(), &GFXDefaultStaticDiffuseProfile, "WaterObject::mFoamTex" );
mFoamTex.set( GFXTextureManager::getWarningTexturePath(), &GFXStaticTextureSRGBProfile, "WaterObject::mFoamTex" );
if ( mCubemapName.isNotEmpty() )
Sim::findObject( mCubemapName, mCubemap );

View file

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

View file

@ -664,7 +664,7 @@ void WaterPlane::setShaderParams( SceneRenderState *state, BaseMatInstance* mat,
// set pixel shader constants
//-----------------------------------
ColorF c( mWaterFogData.color );
LinearColorF c( mWaterFogData.color );
matParams->setSafe( paramHandles.mBaseColorSC, c );
// 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/gfxTextureManager.h"
#include "gfx/D3D11/gfxD3D11EnumTranslate.h"
#include "gfx/bitmap/imageUtils.h"
GFXD3D11Cubemap::GFXD3D11Cubemap() : mTexture(NULL), mSRView(NULL), mDSView(NULL)
{
@ -65,14 +66,6 @@ void GFXD3D11Cubemap::_onTextureEvent(GFXTexCallbackCode code)
initDynamic(mTexSize);
}
bool GFXD3D11Cubemap::isCompressed(GFXFormat format)
{
if (format >= GFXFormatDXT1 && format <= GFXFormatDXT5)
return true;
return false;
}
void GFXD3D11Cubemap::initStatic(GFXTexHandle *faces)
{
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
mTexSize = faces->getWidth();
mFaceFormat = faces->getFormat();
bool compressed = isCompressed(mFaceFormat);
bool compressed = ImageUtil::isCompressedFormat(mFaceFormat);
UINT bindFlags = D3D11_BIND_SHADER_RESOURCE;
UINT miscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
@ -91,15 +84,15 @@ void GFXD3D11Cubemap::initStatic(GFXTexHandle *faces)
miscFlags |= D3D11_RESOURCE_MISC_GENERATE_MIPS;
}
U32 mipLevels = faces->getPointer()->getMipLevels();
if (mipLevels > 1 && !compressed)
mMipMapLevels = faces->getPointer()->getMipLevels();
if (mMipMapLevels < 1 && !compressed)
mAutoGenMips = true;
D3D11_TEXTURE2D_DESC desc;
ZeroMemory(&desc, sizeof(D3D11_TEXTURE2D_DESC));
desc.Width = mTexSize;
desc.Height = mTexSize;
desc.MipLevels = mAutoGenMips ? 0 : mipLevels;
desc.MipLevels = mAutoGenMips ? 0 : mMipMapLevels;
desc.ArraySize = 6;
desc.Format = GFXD3D11TextureFormat[mFaceFormat];
desc.SampleDesc.Count = 1;
@ -113,15 +106,15 @@ void GFXD3D11Cubemap::initStatic(GFXTexHandle *faces)
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++)
{
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);
}
}
@ -129,7 +122,7 @@ void GFXD3D11Cubemap::initStatic(GFXTexHandle *faces)
D3D11_SHADER_RESOURCE_VIEW_DESC SMViewDesc;
SMViewDesc.Format = GFXD3D11TextureFormat[mFaceFormat];
SMViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
SMViewDesc.TextureCube.MipLevels = mAutoGenMips ? -1 : mipLevels;
SMViewDesc.TextureCube.MipLevels = mAutoGenMips ? -1 : mMipMapLevels;
SMViewDesc.TextureCube.MostDetailedMip = 0;
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");
}
//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;
}
}
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
mTexSize = dds->getWidth();
mFaceFormat = dds->getFormat();
U32 levels = dds->getMipLevels();
mMipMapLevels = dds->getMipLevels();
D3D11_TEXTURE2D_DESC desc;
desc.Width = mTexSize;
desc.Height = mTexSize;
desc.MipLevels = levels;
desc.ArraySize = 6;
desc.MipLevels = mMipMapLevels;
desc.ArraySize = CubeFaces;
desc.Format = GFXD3D11TextureFormat[mFaceFormat];
desc.SampleDesc.Count = 1;
desc.SampleDesc.Quality = 0;
desc.Usage = D3D11_USAGE_IMMUTABLE;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE | D3D11_RESOURCE_MISC_GENERATE_MIPS;
desc.CPUAccessFlags = 0;
desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
D3D11_SUBRESOURCE_DATA* pData = new D3D11_SUBRESOURCE_DATA[6 + levels];
for (U32 i = 0; i<CubeFaces; i++)
D3D11_SUBRESOURCE_DATA* pData = new D3D11_SUBRESOURCE_DATA[CubeFaces * mMipMapLevels];
for (U32 currentFace = 0; currentFace < CubeFaces; currentFace++)
{
if (!dds->mSurfaces[i])
if (!dds->mSurfaces[currentFace])
continue;
for(U32 j = 0; j < levels; j++)
// convert to Z up
const U32 faceIndex = _zUpFaceIndex(currentFace);
for(U32 currentMip = 0; currentMip < mMipMapLevels; currentMip++)
{
pData[i + j].pSysMem = dds->mSurfaces[i]->mMips[j];
pData[i + j].SysMemPitch = dds->getSurfacePitch(j);
pData[i + j].SysMemSlicePitch = dds->getSurfaceSize(j);
const U32 dataIndex = faceIndex * mMipMapLevels + currentMip;
pData[dataIndex].pSysMem = dds->mSurfaces[currentFace]->mMips[currentMip];
pData[dataIndex].SysMemPitch = dds->getSurfacePitch(currentMip);
pData[dataIndex].SysMemSlicePitch = 0;
}
}
HRESULT hr = D3D11DEVICE->CreateTexture2D(&desc, pData, &mTexture);
HRESULT hr = D3D11DEVICE->CreateTexture2D(&desc, pData, &mTexture);
if (FAILED(hr))
{
AssertFatal(false, "GFXD3D11Cubemap::initStatic(DDSFile *dds) - CreateTexture2D failure");
}
delete [] pData;
D3D11_SHADER_RESOURCE_VIEW_DESC SMViewDesc;
SMViewDesc.Format = GFXD3D11TextureFormat[mFaceFormat];
SMViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
SMViewDesc.TextureCube.MipLevels = levels;
SMViewDesc.TextureCube.MipLevels = mMipMapLevels;
SMViewDesc.TextureCube.MostDetailedMip = 0;
hr = D3D11DEVICE->CreateShaderResourceView(mTexture, &SMViewDesc, &mSRView);
@ -209,7 +218,8 @@ void GFXD3D11Cubemap::initDynamic(U32 texSize, GFXFormat faceFormat)
mAutoGenMips = true;
mTexSize = texSize;
mFaceFormat = faceFormat;
bool compressed = isCompressed(mFaceFormat);
mMipMapLevels = 0;
bool compressed = ImageUtil::isCompressedFormat(mFaceFormat);
UINT bindFlags = D3D11_BIND_SHADER_RESOURCE;
UINT miscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
@ -250,6 +260,16 @@ void GFXD3D11Cubemap::initDynamic(U32 texSize, GFXFormat faceFormat)
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;
viewDesc.Format = desc.Format;
viewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;

View file

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

View file

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

View file

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

View file

@ -54,11 +54,11 @@ void GFXD3D11EnumTranslate::init()
GFXD3D11TextureFormat[GFXFormatA8L8] = DXGI_FORMAT_R8G8_UNORM;
GFXD3D11TextureFormat[GFXFormatA8] = DXGI_FORMAT_A8_UNORM;
GFXD3D11TextureFormat[GFXFormatL8] = DXGI_FORMAT_R8_UNORM;
GFXD3D11TextureFormat[GFXFormatDXT1] = DXGI_FORMAT_BC1_UNORM;
GFXD3D11TextureFormat[GFXFormatDXT2] = DXGI_FORMAT_BC1_UNORM;
GFXD3D11TextureFormat[GFXFormatDXT3] = DXGI_FORMAT_BC2_UNORM;
GFXD3D11TextureFormat[GFXFormatDXT4] = DXGI_FORMAT_BC2_UNORM;
GFXD3D11TextureFormat[GFXFormatDXT5] = DXGI_FORMAT_BC3_UNORM;
GFXD3D11TextureFormat[GFXFormatBC1] = DXGI_FORMAT_BC1_UNORM;
GFXD3D11TextureFormat[GFXFormatBC2] = DXGI_FORMAT_BC2_UNORM;
GFXD3D11TextureFormat[GFXFormatBC3] = DXGI_FORMAT_BC3_UNORM;
GFXD3D11TextureFormat[GFXFormatBC4] = DXGI_FORMAT_BC4_UNORM;
GFXD3D11TextureFormat[GFXFormatBC5] = DXGI_FORMAT_BC5_UNORM;
GFXD3D11TextureFormat[GFXFormatR32G32B32A32F] = DXGI_FORMAT_R32G32B32A32_FLOAT;
GFXD3D11TextureFormat[GFXFormatR16G16B16A16F] = DXGI_FORMAT_R16G16B16A16_FLOAT;
GFXD3D11TextureFormat[GFXFormatL16] = DXGI_FORMAT_R16_UNORM;
@ -72,8 +72,14 @@ void GFXD3D11EnumTranslate::init()
GFXD3D11TextureFormat[GFXFormatD24S8] = DXGI_FORMAT_D24_UNORM_S8_UINT;
GFXD3D11TextureFormat[GFXFormatD24FS8] = DXGI_FORMAT_UNKNOWN;
GFXD3D11TextureFormat[GFXFormatD16] = DXGI_FORMAT_D16_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;

View file

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

View file

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

View file

@ -151,29 +151,32 @@ GFXD3D11StateBlock::GFXD3D11StateBlock(const GFXStateBlockDesc& desc)
mSamplerDesc[i].MinLOD = 0;
mSamplerDesc[i].MaxLOD = FLT_MAX;
const bool comparison = gfxSamplerState.samplerFunc != GFXCmpNever;
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)
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)
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)
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)
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)
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)
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)
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
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[1] = 1.0f;
mSamplerDesc[i].BorderColor[2] = 1.0f;
mSamplerDesc[i].BorderColor[3] = 1.0f;
mSamplerDesc[i].ComparisonFunc = GFXD3D11CmpFunc[gfxSamplerState.samplerFunc];
hr = D3D11DEVICE->CreateSamplerState(&mSamplerDesc[i], &mSamplerStates[i]);
if (FAILED(hr))

View file

@ -248,10 +248,10 @@ void GFXD3D11TextureTarget::activate()
stateApplied();
// 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]);
for (U32 i = 0; i < 4; i++)
for (U32 i = 0; i < 6; i++)
{
rtViews[i] = (ID3D11RenderTargetView*)mTargetViews[GFXTextureTarget::Color0 + i];
}
@ -263,7 +263,7 @@ void GFXD3D11TextureTarget::activate()
void GFXD3D11TextureTarget::deactivate()
{
//re-gen mip maps
for (U32 i = 0; i < 4; i++)
for (U32 i = 0; i < 6; i++)
{
ID3D11ShaderResourceView* pSRView = mTargetSRViews[GFXTextureTarget::Color0 + i];
if (pSRView)
@ -314,34 +314,21 @@ void GFXD3D11TextureTarget::resurrect()
GFXD3D11WindowTarget::GFXD3D11WindowTarget()
{
mWindow = NULL;
mBackBuffer = NULL;
mDepthStencilView = NULL;
mDepthStencil = NULL;
mBackBufferView = NULL;
mSecondaryWindow = false;
mWindow = NULL;
mBackbuffer = NULL;
}
GFXD3D11WindowTarget::~GFXD3D11WindowTarget()
{
SAFE_RELEASE(mDepthStencilView)
SAFE_RELEASE(mDepthStencil);
SAFE_RELEASE(mBackBufferView);
SAFE_RELEASE(mBackBuffer);
SAFE_RELEASE(mSwapChain);
SAFE_RELEASE(mBackbuffer);
}
void GFXD3D11WindowTarget::initPresentationParams()
{
// Get some video mode related info.
const GFXVideoMode &vm = mWindow->getVideoMode();
HWND hwnd = (HWND)mWindow->getSystemWindow(PlatformWindow::WindowSystem_Windows);
// Do some validation...
if (vm.fullScreen && mSecondaryWindow)
{
AssertFatal(false, "GFXD3D11WindowTarget::initPresentationParams - Cannot go fullscreen with secondary window!");
}
GFXVideoMode vm = mWindow->getVideoMode();
Win32Window* win = static_cast<Win32Window*>(mWindow);
HWND hwnd = win->getHWND();
mPresentationParams = D3D11->setupPresentParams(vm, hwnd);
}
@ -360,178 +347,40 @@ GFXFormat GFXD3D11WindowTarget::getFormat()
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
IDXGIFactory1* DXGIFactory;
HRESULT hr = CreateDXGIFactory1(__uuidof(IDXGIFactory1), reinterpret_cast<void**>(&DXGIFactory));
if (FAILED(hr))
AssertFatal(false, "GFXD3D11WindowTarget::createSwapChain - couldn't create dxgi factory.");
hr = DXGIFactory->CreateSwapChain(D3D11DEVICE, &mPresentationParams, &mSwapChain);
if (FAILED(hr))
AssertFatal(false, "GFXD3D11WindowTarget::createSwapChain - couldn't create swap chain.");
SAFE_RELEASE(DXGIFactory);
}
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
if (!mBackbuffer)
D3D11->mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&mBackbuffer);
}
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);
// Setup our presentation params.
initPresentationParams();
if (!mPresentationParams.Windowed)
{
mPresentationParams.BufferDesc.RefreshRate.Numerator = 0;
mPresentationParams.BufferDesc.RefreshRate.Denominator = 0;
hr = mSwapChain->ResizeTarget(&mPresentationParams.BufferDesc);
if (FAILED(hr))
AssertFatal(false, "GFXD3D11WindowTarget::resetMode - failed to resize target!");
}
hr = mSwapChain->ResizeBuffers(mPresentationParams.BufferCount, mPresentationParams.BufferDesc.Width, mPresentationParams.BufferDesc.Height,
mPresentationParams.BufferDesc.Format, mPresentationParams.Windowed ? 0 : DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH);
if (FAILED(hr))
AssertFatal(false, "GFXD3D11WindowTarget::resetMode - failed to resize back buffer!");
hr = mSwapChain->SetFullscreenState(!mPresentationParams.Windowed, NULL);
if (FAILED(hr))
AssertFatal(false, "GFXD3D11WindowTarget::resetMode - failed to change screen states!");
// Otherwise, we have to reset the device, if we're the implicit swapchain.
D3D11->reset(mPresentationParams);
// Update our size, too.
mSize = Point2I(mPresentationParams.BufferDesc.Width, mPresentationParams.BufferDesc.Height);
mWindow->setSuppressReset(false);
//re-create buffers and views
createBuffersAndViews();
if (!mSecondaryWindow)
D3D11->endReset(this);
GFX->beginReset();
}
void GFXD3D11WindowTarget::zombify()
{
SAFE_RELEASE(mBackBuffer);
SAFE_RELEASE(mBackbuffer);
}
void GFXD3D11WindowTarget::resurrect()
{
setBackBuffer();
}
void GFXD3D11WindowTarget::setBackBuffer()
{
if (!mBackBuffer)
mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&mBackBuffer);
setImplicitSwapChain();
}
void GFXD3D11WindowTarget::activate()
@ -542,10 +391,10 @@ void GFXD3D11WindowTarget::activate()
ID3D11RenderTargetView* rtViews[8] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
D3D11DEVICECONTEXT->OMSetRenderTargets(8, rtViews, NULL);
D3D11DEVICECONTEXT->OMSetRenderTargets(1, &mBackBufferView, mDepthStencilView);
D3D11DEVICECONTEXT->OMSetRenderTargets(1, &D3D11->mDeviceBackBufferView, D3D11->mDeviceDepthStencilView);
DXGI_SWAP_CHAIN_DESC pp;
mSwapChain->GetDesc(&pp);
D3D11->mSwapChain->GetDesc(&pp);
// Update our video mode here, too.
GFXVideoMode vm;
@ -563,35 +412,5 @@ void GFXD3D11WindowTarget::resolveTo(GFXTextureObject *tex)
D3D11_TEXTURE2D_DESC desc;
ID3D11Texture2D* surf = ((GFXD3D11TextureObject*)(tex))->get2DTex();
surf->GetDesc(&desc);
D3D11DEVICECONTEXT->ResolveSubresource(surf, 0, mBackBuffer, 0, desc.Format);
}
IDXGISwapChain *GFXD3D11WindowTarget::getSwapChain()
{
mSwapChain->AddRef();
return mSwapChain;
}
ID3D11Texture2D *GFXD3D11WindowTarget::getBackBuffer()
{
mBackBuffer->AddRef();
return mBackBuffer;
}
ID3D11Texture2D *GFXD3D11WindowTarget::getDepthStencil()
{
mDepthStencil->AddRef();
return mDepthStencil;
}
ID3D11RenderTargetView* GFXD3D11WindowTarget::getBackBufferView()
{
mBackBufferView->AddRef();
return mBackBufferView;
}
ID3D11DepthStencilView* GFXD3D11WindowTarget::getDepthStencilView()
{
mDepthStencilView->AddRef();
return mDepthStencilView;
D3D11DEVICECONTEXT->ResolveSubresource(surf, 0, D3D11->mDeviceBackbuffer, 0, desc.Format);
}

View file

@ -76,11 +76,7 @@ class GFXD3D11WindowTarget : public GFXWindowTarget
friend class GFXD3D11Device;
/// Our backbuffer
ID3D11Texture2D *mBackBuffer;
ID3D11Texture2D *mDepthStencil;
ID3D11RenderTargetView* mBackBufferView;
ID3D11DepthStencilView* mDepthStencilView;
IDXGISwapChain *mSwapChain;
ID3D11Texture2D *mBackbuffer;
/// Maximum size we can render to.
Point2I mSize;
@ -89,9 +85,6 @@ class GFXD3D11WindowTarget : public GFXWindowTarget
/// Internal interface that notifies us we need to reset our video mode.
void resetMode();
/// Is this a secondary window
bool mSecondaryWindow;
public:
GFXD3D11WindowTarget();
@ -102,9 +95,7 @@ public:
virtual bool present();
void initPresentationParams();
void createSwapChain();
void createBuffersAndViews();
void setBackBuffer();
void setImplicitSwapChain();
virtual void activate();
@ -112,13 +103,6 @@ public:
void resurrect();
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

View file

@ -23,6 +23,7 @@
#include "gfx/D3D11/gfxD3D11Device.h"
#include "gfx/D3D11/gfxD3D11EnumTranslate.h"
#include "gfx/bitmap/bitmapUtils.h"
#include "gfx/bitmap/imageUtils.h"
#include "gfx/gfxCardProfile.h"
#include "gfx/gfxStringEnumTranslate.h"
#include "core/strings/unicode.h"
@ -139,7 +140,7 @@ void GFXD3D11TextureManager::_innerCreateTexture( GFXD3D11TextureObject *retTex,
}
else
{
UINT numQualityLevels = 0;
U32 numQualityLevels = 0;
switch (antialiasLevel)
{
@ -151,7 +152,6 @@ void GFXD3D11TextureManager::_innerCreateTexture( GFXD3D11TextureObject *retTex,
default:
{
antialiasLevel = 0;
UINT numQualityLevels;
D3D11DEVICE->CheckMultisampleQualityLevels(d3dTextureFormat, antialiasLevel, &numQualityLevels);
AssertFatal(numQualityLevels, "Invalid AA level!");
break;
@ -287,7 +287,7 @@ bool GFXD3D11TextureManager::_loadTexture(GFXTextureObject *aTexture, GBitmap *p
const bool supportsAutoMips = GFX->getCardProfiler()->queryProfile("autoMipMapLevel", true);
// Helper bool
const bool isCompressedTexFmt = aTexture->mFormat >= GFXFormatDXT1 && aTexture->mFormat <= GFXFormatDXT5;
const bool isCompressedTexFmt = ImageUtil::isCompressedFormat(aTexture->mFormat);
// Settings for mipmap generation
U32 maxDownloadMip = pDL->getNumMipLevels();
@ -312,10 +312,10 @@ bool GFXD3D11TextureManager::_loadTexture(GFXTextureObject *aTexture, GBitmap *p
switch(texture->mFormat)
{
case GFXFormatR8G8B8:
case GFXFormatR8G8B8:
case GFXFormatR8G8B8_SRGB:
{
PROFILE_SCOPE(Swizzle24_Upload);
AssertFatal(pDL->getFormat() == GFXFormatR8G8B8, "Assumption failed");
U8* Bits = new U8[pDL->getWidth(i) * pDL->getHeight(i) * 4];
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 GFXFormatR8G8B8X8:
case GFXFormatR8G8B8A8_SRGB:
{
PROFILE_SCOPE(Swizzle32_Upload);
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 )
{
case GFXFormatR8G8B8:
case GFXFormatR8G8B8_SRGB:
{
PROFILE_SCOPE(Swizzle24_Upload);
AssertFatal(pDL->getFormat() == GFXFormatR8G8B8, "Assumption failed");
U8* Bits = new U8[pDL->getWidth(i) * pDL->getHeight(i) * 4];
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 GFXFormatR8G8B8X8:
case GFXFormatR8G8B8A8_SRGB:
{
PROFILE_SCOPE(Swizzle32_Upload);
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;
if(texture->mFormat == GFXFormatR8G8B8)
if(texture->mFormat == GFXFormatR8G8B8 || texture->mFormat == GFXFormatR8G8B8_SRGB)
{
// convert 24 bit to 32 bit
Bits = new U8[texture->getWidth() * texture->getHeight() * texture->getDepth() * 4];
@ -430,8 +432,10 @@ bool GFXD3D11TextureManager::_loadTexture(GFXTextureObject *inTex, void *raw)
switch(texture->mFormat)
{
case GFXFormatR8G8B8:
case GFXFormatR8G8B8_SRGB:
case GFXFormatR8G8B8A8:
case GFXFormatR8G8B8X8:
case GFXFormatR8G8B8A8_SRGB:
bytesPerPix = 4;
break;
}
@ -444,7 +448,7 @@ bool GFXD3D11TextureManager::_loadTexture(GFXTextureObject *inTex, void *raw)
box.top = 0;
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);
else
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->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);
@ -180,8 +180,8 @@ bool GFXD3D11TextureObject::copyToBmp(GBitmap* bmp)
// check format limitations
// at the moment we only support RGBA for the source (other 4 byte formats should
// be easy to add though)
AssertFatal(mFormat == GFXFormatR8G8B8A8 || mFormat == GFXFormatR8G8B8A8_LINEAR_FORCE, "copyToBmp: invalid format");
if (mFormat != GFXFormatR8G8B8A8 && mFormat != GFXFormatR8G8B8A8_LINEAR_FORCE)
AssertFatal(mFormat == GFXFormatR8G8B8A8 || mFormat == GFXFormatR8G8B8A8_LINEAR_FORCE || mFormat == GFXFormatR8G8B8A8_SRGB, "copyToBmp: invalid format");
if (mFormat != GFXFormatR8G8B8A8 && mFormat != GFXFormatR8G8B8A8_LINEAR_FORCE && mFormat != GFXFormatR8G8B8A8_SRGB)
return false;
PROFILE_START(GFXD3D11TextureObject_copyToBmp);
@ -197,7 +197,8 @@ bool GFXD3D11TextureObject::copyToBmp(GBitmap* bmp)
const U32 sourceBytesPerPixel = 4;
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;
else if(bmp->getFormat() == GFXFormatR8G8B8)
destBytesPerPixel = 3;

View file

@ -101,7 +101,7 @@ protected:
virtual void setLightInternal(U32 lightStage, const GFXLightInfo light, bool lightEnable);
virtual void setLightMaterialInternal(const GFXLightMaterial mat) { };
virtual void setGlobalAmbientInternal(ColorF color) { };
virtual void setGlobalAmbientInternal(LinearColorF color) { };
/// @name State Initalization.
/// @{
@ -150,7 +150,7 @@ public:
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 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 "gfx/bitmap/ddsFile.h"
#include "gfx/bitmap/ddsData.h"
#include "gfx/bitmap/bitmapUtils.h"
#include "gfx/bitmap/imageUtils.h"
#include "gfx/gfxDevice.h"
#include "core/util/fourcc.h"
#include "console/console.h"
@ -31,56 +33,11 @@
#include "gfx/bitmap/gBitmap.h"
#include "console/engineAPI.h"
#include <squish.h>
S32 DDSFile::smActiveCopies = 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 )
: mFlags( dds.mFlags ),
mHeight( dds.mHeight ),
@ -133,13 +90,13 @@ U32 DDSFile::getSurfacePitch( U32 mipLevel ) const
switch(mFormat)
{
case GFXFormatDXT1:
case GFXFormatBC1:
case GFXFormatBC4:
sizeMultiple = 8;
break;
case GFXFormatDXT2:
case GFXFormatDXT3:
case GFXFormatDXT4:
case GFXFormatDXT5:
case GFXFormatBC2:
case GFXFormatBC3:
case GFXFormatBC5:
sizeMultiple = 16;
break;
default:
@ -172,13 +129,13 @@ U32 DDSFile::getSurfaceSize( U32 height, U32 width, U32 mipLevel ) const
switch(mFormat)
{
case GFXFormatDXT1:
case GFXFormatBC1:
case GFXFormatBC4:
sizeMultiple = 8;
break;
case GFXFormatDXT2:
case GFXFormatDXT3:
case GFXFormatDXT4:
case GFXFormatDXT5:
case GFXFormatBC2:
case GFXFormatBC3:
case GFXFormatBC5:
sizeMultiple = 16;
break;
default:
@ -197,25 +154,34 @@ U32 DDSFile::getSurfaceSize( U32 height, U32 width, U32 mipLevel ) const
U32 DDSFile::getSizeInBytes() const
{
// 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;
for ( U32 i=0; i < mMipMapCount; i++ )
bytes += getSurfaceSize( mHeight, mWidth, i );
if (mFlags.test(CubeMapFlag))
{
for(U32 cubeFace=0;cubeFace < Cubemap_Surface_Count;cubeFace++)
for (U32 i = 0; i < mMipMapCount; i++)
bytes += getSurfaceSize(mHeight, mWidth, i);
}
else
{
for (U32 i = 0; i < mMipMapCount; i++)
bytes += getSurfaceSize(mHeight, mWidth, i);
}
return bytes;
}
U32 DDSFile::getSizeInBytes( GFXFormat format, U32 height, U32 width, U32 mipLevels )
{
AssertFatal( format >= GFXFormatDXT1 && format <= GFXFormatDXT5,
"DDSFile::getSizeInBytes - Must be a DXT format!" );
AssertFatal( ImageUtil::isCompressedFormat(format),
"DDSFile::getSizeInBytes - Must be a Block Compression format!" );
// From the directX docs:
// max(1, width ÷ 4) x max(1, height ÷ 4) x 8(DXT1) or 16(DXT2-5)
U32 sizeMultiple = 0;
if ( format == GFXFormatDXT1 )
if ( format == GFXFormatBC1 || format == GFXFormatBC1_SRGB || format == GFXFormatBC4)
sizeMultiple = 8;
else
sizeMultiple = 16;
@ -236,317 +202,146 @@ U32 DDSFile::getSizeInBytes( GFXFormat format, U32 height, U32 width, U32 mipLev
bool DDSFile::readHeader(Stream &s)
{
U32 tmp;
U32 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 '!");
return false;
}
// Read the size of the header.
s.read(&tmp);
//dds headers
dds::DDS_HEADER header = {};
dds::DDS_HEADER_DXT10 dx10header = {};
//todo DX10 formats
bool hasDx10Header = false;
if(tmp != 124)
//read in header
s.read(DDS_HEADER_SIZE, &header);
//check for dx10 header support
if ((header.ddspf.flags & DDS_FOURCC) && (header.ddspf.fourCC == dds::D3DFMT_DX10))
{
Con::errorf("DDSFile::readHeader - incorrect header size. Expected 124 bytes.");
//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;
// 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...
U32 ddsdFlags;
s.read(&ddsdFlags);
//process regular header
// "Always include DDSD_CAPS, DDSD_PIXELFORMAT, DDSD_WIDTH, DDSD_HEIGHT."
if(!(ddsdFlags & (DDSDCaps | DDSDPixelFormat | DDSDWidth | DDSDHeight)))
//D3DFMT_DX10 is caught above, no need to check now
if (header.ddspf.flags & DDS_FOURCC)
{
Con::errorf("DDSFile::readHeader - incorrect surface description flags.");
return false;
}
mFormat = dds::getGFXFormat(mFourCC);
//make sure getGFXFormat gave us a valid format
if (mFormat == GFXFormat_FIRST)
return false;
// Read height and width (always present)
s.read(&mHeight);
s.read(&mWidth);
// Read pitch or linear size.
// First make sure we have valid flags (either linear size or pitch).
if((ddsdFlags & (DDSDLinearSize | DDSDPitch)) == (DDSDLinearSize | DDSDPitch))
{
// Both are invalid!
Con::errorf("DDSFile::readHeader - encountered both DDSD_LINEARSIZE and DDSD_PITCH!");
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 ???
if (ImageUtil::isCompressedFormat(mFormat))
mFlags.set(CompressedData);
else
{
mBytesPerPixel = header.ddspf.bpp / 8;
mFlags.set(RGBData);
}
}
else
{
// Neither set! This appears to be depressingly common.
// Con::warnf("DDSFile::readHeader - encountered neither DDSD_LINEARSIZE nor DDSD_PITCH!");
}
mFormat = dds::getGFXFormat(header.ddspf);
//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!
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)
{
mBytesPerPixel = header.ddspf.bpp / 8;
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;
s.read(&caps1);
s.read(&caps2);
s.read(&tmp);
s.read(&tmp); // More icky reserved space.
//set transparency flag
mHasTransparency = (header.ddspf.flags & DDS_ALPHAPIXELS);
// Screw caps1.
// if(!(caps1 & DDSCAPS_TEXTURE)))
// {
// }
if (header.flags & DDS_HEADER_FLAGS_LINEARSIZE)
mFlags.set(LinearSizeFlag);
else if (header.flags & DDS_HEADER_FLAGS_PITCH)
mFlags.set(PitchSizeFlag);
// Caps2 has cubemap/volume info. Care about that.
if(caps2 & DDSCAPS2Cubemap)
//set cubemap flags
if (header.cubemapFlags & DDS_CUBEMAP)
{
mFlags.set(CubeMapFlag);
mFlags.set(CubeMapFlag | ComplexFlag);
// Store the face flags too.
if ( caps2 & DDSCAPS2Cubemap_POSITIVEX ) mFlags.set( CubeMap_PosX_Flag );
if ( caps2 & DDSCAPS2Cubemap_NEGATIVEX ) mFlags.set( CubeMap_NegX_Flag );
if ( caps2 & DDSCAPS2Cubemap_POSITIVEY ) mFlags.set( CubeMap_PosY_Flag );
if ( caps2 & DDSCAPS2Cubemap_NEGATIVEY ) mFlags.set( CubeMap_NegY_Flag );
if ( caps2 & DDSCAPS2Cubemap_POSITIVEZ ) mFlags.set( CubeMap_PosZ_Flag );
if ( caps2 & DDSCAPS2Cubemap_NEGATIVEZ ) mFlags.set( CubeMap_NegZ_Flag );
if (header.cubemapFlags & DDS_CUBEMAP_POSITIVEX) mFlags.set(CubeMap_PosX_Flag);
if (header.cubemapFlags & DDS_CUBEMAP_NEGATIVEX) mFlags.set(CubeMap_NegX_Flag);
if (header.cubemapFlags & DDS_CUBEMAP_POSITIVEY) mFlags.set(CubeMap_PosY_Flag);
if (header.cubemapFlags & DDS_CUBEMAP_NEGATIVEY) mFlags.set(CubeMap_NegY_Flag);
if (header.cubemapFlags & DDS_CUBEMAP_POSITIVEZ) mFlags.set(CubeMap_PosZ_Flag);
if (header.cubemapFlags & DDS_CUBEMAP_NEGATIVEZ) mFlags.set(CubeMap_NegZ_Flag);
}
// MS has ANOTHER reserved word here. This one particularly sucks.
s.read(&tmp);
return true;
}
bool DDSFile::read(Stream &s, U32 dropMipCount)
{
if( !readHeader(s) || mMipMapCount == 0 )
if( !readHeader(s) )
{
Con::errorf("DDSFile::read - error reading header!");
return false;
@ -618,96 +413,82 @@ bool DDSFile::read(Stream &s, U32 dropMipCount)
bool DDSFile::writeHeader( Stream &s )
{
// Read the FOURCC
s.write( 4, "DDS " );
// write DDS magic
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.
s.write( 124 );
bool hasDx10Header = false;
//flags
U32 surfaceFlags = DDS_SURFACE_FLAGS_TEXTURE;
U32 cubemapFlags = 0;
U32 headerFlags = DDS_HEADER_FLAGS_TEXTURE;
// Read some flags...
U32 ddsdFlags = DDSDCaps | DDSDPixelFormat | DDSDWidth | DDSDHeight;
if ( mFlags.test( CompressedData ) )
ddsdFlags |= DDSDLinearSize;
else
ddsdFlags |= DDSDPitch;
//pixel format
const dds::DDS_PIXELFORMAT &format = dds::getDDSFormat(mFormat);
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 ) )
// todo better dx10 support
if (format.fourCC == dds::D3DFMT_DX10)
{
ddpfFlags = DDPFFourCC;
if (mFormat == GFXFormatDXT1)
fourCC = FOURCC_DXT1;
if (mFormat == GFXFormatDXT3)
fourCC = FOURCC_DXT3;
if (mFormat == GFXFormatDXT5)
fourCC = FOURCC_DXT5;
dx10header.dxgiFormat = dds::getDXGIFormat(mFormat);
dx10header.arraySize = 1;
dx10header.resourceDimension = dds::D3D10_RESOURCE_DIMENSION_TEXTURE2D;
dx10header.miscFlag = 0;
dx10header.miscFlags2 = 0;
hasDx10Header = true;
}
if (mFlags.test(CompressedData))
headerFlags |= DDS_HEADER_FLAGS_LINEARSIZE;
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.
//U32 pfFourCC, pfBitCount, pfRMask, pfGMask, pfBMask, pfAlphaMask;
//cubemap flags
if (mFlags.test(CubeMapFlag))
{
surfaceFlags |= DDS_SURFACE_FLAGS_CUBEMAP;
cubemapFlags |= DDS_CUBEMAP_ALLFACES;
}
s.write( fourCC );
s.write( mBytesPerPixel * 8 );
s.write( 0x000000FF );
s.write( 0x00FF0000 );
s.write( 0x0000FF00 );
s.write( 0xFF000000 );
//volume texture
if (mDepth > 0)
{
headerFlags |= DDS_HEADER_FLAGS_VOLUME;
dx10header.resourceDimension = dds::D3D10_RESOURCE_DIMENSION_TEXTURE3D;
}
// Deal with final caps bits... Is this really necessary?
U32 caps1 = DDSCAPSTexture;
if ( mMipMapCount > 0 )
caps1 |= DDSCAPSComplex | DDSCAPSMipMap;
//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));
tmp = 0;
//check our header is ok
if (!dds::validateHeader(header))
return false;
s.write( caps1 );
s.write( tmp );
s.write( tmp );
s.write( tmp );// More icky reserved space.
// MS has ANOTHER reserved word here. This one particularly sucks.
s.write( tmp );
//Write out the header
s.write(DDS_HEADER_SIZE, &header);
//Write out dx10 header
if (hasDx10Header)
s.write(DDS_HEADER_DX10_SIZE, &dx10header);
return true;
}
@ -720,13 +501,16 @@ bool DDSFile::write( Stream &s )
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?
if(mFlags.test(CubeMapFlag))
{
// 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))
{
@ -912,6 +696,82 @@ DDSFile *DDSFile::createDDSFileFromGBitmap( const GBitmap *gbmp )
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, (),,
"Returns the count of active DDSs files in memory.\n"
"@ingroup Rendering\n" )

View file

@ -65,6 +65,7 @@ struct DDSFile
CubeMap_NegY_Flag = BIT(11),
CubeMap_PosZ_Flag = BIT(12),
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
@ -115,9 +116,6 @@ struct DDSFile
Vector<U8*> mMips;
// Helper function to read in a mipchain.
bool readMipChain();
void dumpImage(DDSFile *dds, U32 mip, const char *file);
/// Helper for reading a mip level.
@ -200,6 +198,9 @@ struct DDSFile
}
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_

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)
{
@ -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()
{
@ -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,
// but locking doesn't support this, and we seem to calc
// 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;
}
//--------------------------------------------------------------------------
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 )
@ -1175,6 +1292,41 @@ Resource<GBitmap> GBitmap::_search(const Torque::Path &path)
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 ),,
"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"

View file

@ -47,7 +47,7 @@ class Stream;
class RectI;
class Point2I;
class ColorI;
class ColorF;
class LinearColorF;
//------------------------------------------------------------------------------
//-------------------------------------- GBitmap
@ -151,7 +151,13 @@ public:
const bool in_extrudeMipLevels = false,
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 chopTopMips(U32 mipsToChop);
void extrudeMipLevelsDetail();
U32 getNumMipLevels() const { return mNumMipLevels; }
@ -182,6 +188,8 @@ public:
U32 getByteSize() const { return mByteSize; }
U32 getBytesPerPixel() const { return mBytesPerPixel; }
U32 getSurfaceSize(const U32 mipLevel) const;
/// Use these functions to set and get the mHasTransparency value
/// This is used to indicate that this bitmap has pixels that have
/// 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
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 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
/// 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