I believe I'm getting there, got it all working now, but probably not optimal yet.
The part where I go through the loops for checking each group of 'caps', just feels like it's possible to do it more efficient.
To be honest, code is not cleaner then when I filled the multimap with the references to the Caps var, but definitely this brings a lot more flexibility, also for future use.
What do you think?
Here are the 2 resulting functions:
/**************************************************************************************/
/*** SET REQUIRED DEVICE CAPS ***/
/*** ==> usage: during initalization, before creating d3d device and loading scene ***/
/*** ==> fill mReqCapsTable with all caps needed for existing functionality ***/
/**************************************************************************************/
void CD3d::SetRequiredDeviceCaps()
{
mReqCapsTable.insert(std::make_pair("DevCaps", D3DDEVCAPS_DRAWPRIMTLVERTEX));
mReqCapsTable.insert(std::make_pair("DevCaps", D3DDEVCAPS_HWRASTERIZATION));
mReqCapsTable.insert(std::make_pair("DevCaps", D3DDEVCAPS_TLVERTEXSYSTEMMEMORY));
mReqCapsTable.insert(std::make_pair("DevCaps", D3DDEVCAPS_TLVERTEXVIDEOMEMORY));
mReqCapsTable.insert(std::make_pair("DevCaps", D3DDEVCAPS_EXECUTESYSTEMMEMORY));
mReqCapsTable.insert(std::make_pair("DevCaps", D3DDEVCAPS_EXECUTEVIDEOMEMORY));
mReqCapsTable.insert(std::make_pair("DevCaps", D3DDEVCAPS_TEXTUREVIDEOMEMORY));
mReqCapsTable.insert(std::make_pair("RasterCaps", D3DPRASTERCAPS_ANISOTROPY));
mReqCapsTable.insert(std::make_pair("RasterCaps", D3DPRASTERCAPS_DITHER));
mReqCapsTable.insert(std::make_pair("RasterCaps", D3DPRASTERCAPS_ZTEST));
mReqCapsTable.insert(std::make_pair("PrimitiveMiscCaps", D3DPMISCCAPS_CULLNONE));
mReqCapsTable.insert(std::make_pair("PrimitiveMiscCaps", D3DPMISCCAPS_CULLCW));
mReqCapsTable.insert(std::make_pair("PrimitiveMiscCaps", D3DPMISCCAPS_CULLCCW));
mReqCapsTable.insert(std::make_pair("PrimitiveMiscCaps", D3DPMISCCAPS_BLENDOP));
mReqCapsTable.insert(std::make_pair("PresentationIntervals", D3DPRESENT_INTERVAL_ONE));
mReqCapsTable.insert(std::make_pair("PresentationIntervals", D3DPRESENT_INTERVAL_TWO));
mReqCapsTable.insert(std::make_pair("PresentationIntervals", D3DPRESENT_INTERVAL_IMMEDIATE));
mReqCapsTable.insert(std::make_pair("VertexTextureFilterCaps", D3DPTFILTERCAPS_MAGFLINEAR));
mReqCapsTable.insert(std::make_pair("VertexTextureFilterCaps", D3DPTFILTERCAPS_MINFLINEAR));
mReqCapsTable.insert(std::make_pair("VertexTextureFilterCaps", D3DPTFILTERCAPS_MIPFLINEAR));
mReqCapsTable.insert(std::make_pair("VertexTextureFilterCaps", D3DPTFILTERCAPS_MINFANISOTROPIC));
mReqCapsTable.insert(std::make_pair("TextureCaps", D3DPTEXTURECAPS_MIPMAP));
mReqCapsTable.insert(std::make_pair("TextureCaps", D3DPTEXTURECAPS_ALPHA));
mReqCapsTable.insert(std::make_pair("TextureAddressCaps", D3DPTADDRESSCAPS_BORDER));
mReqCapsTable.insert(std::make_pair("TextureAddressCaps", D3DPTADDRESSCAPS_CLAMP));
mReqCapsTable.insert(std::make_pair("TextureAddressCaps", D3DPTADDRESSCAPS_WRAP));
mReqCapsTable.insert(std::make_pair("TextureAddressCaps", D3DPTADDRESSCAPS_INDEPENDENTUV));
mReqCapsTable.insert(std::make_pair("TextureAddressCaps", D3DPTADDRESSCAPS_MIRROR));
mReqCapsTable.insert(std::make_pair("ShadeCaps", D3DPSHADECAPS_ALPHAGOURAUDBLEND));
mReqCapsTable.insert(std::make_pair("ShadeCaps", D3DPSHADECAPS_SPECULARGOURAUDRGB));
mReqCapsTable.insert(std::make_pair("ShadeCaps", D3DPSHADECAPS_COLORGOURAUDRGB));
}
/**************************************************************************************/
/*** CHECK DEVICE CAPS ***/
/*** ==> usage: during initalization, before creating d3d device and loading scene ***/
/*** ==> check if device meets required caps for current functionality ***/
/**************************************************************************************/
bool CD3d::CheckDeviceCaps()
{
if(mD3d != NULL)
{
if(D3D_OK != mD3d->GetDeviceCaps(D3DADAPTER_DEFAULT, mDevType, &mCaps)) return false;
std::pair<CapsTable::iterator, CapsTable::iterator> range;
range = mReqCapsTable.equal_range("DevCaps");
for(CapsTable::iterator it=range.first;it!=range.second;++it) if(!(mCaps.DevCaps & it->second)) return false;
range = mReqCapsTable.equal_range("RasterCaps");
for(CapsTable::iterator it=range.first;it!=range.second;++it) if(!(mCaps.RasterCaps & it->second)) return false;
range = mReqCapsTable.equal_range("PrimitiveeMiscCaps");
for(CapsTable::iterator it=range.first;it!=range.second;++it) if(!(mCaps.PrimitiveMiscCaps & it->second)) return false;
range = mReqCapsTable.equal_range("PresentationIntervals");
for(CapsTable::iterator it=range.first;it!=range.second;++it) if(!(mCaps.PresentationIntervals & it->second)) return false;
range = mReqCapsTable.equal_range("VertexTextureFilterCaps");
for(CapsTable::iterator it=range.first;it!=range.second;++it) if(!(mCaps.VertexTextureFilterCaps & it->second)) return false;
range = mReqCapsTable.equal_range("TextureCaps");
for(CapsTable::iterator it=range.first;it!=range.second;++it) if(!(mCaps.TextureCaps & it->second)) return false;
range = mReqCapsTable.equal_range("TextureAddressCaps");
for(CapsTable::iterator it=range.first;it!=range.second;++it) if(!(mCaps.TextureAddressCaps & it->second)) return false;
range = mReqCapsTable.equal_range("ShadeCaps");
for(CapsTable::iterator it=range.first;it!=range.second;++it) if(!(mCaps.ShadeCaps & it->second)) return false;
if(D3D_OK != mD3d->CheckDeviceFormat(D3DADAPTER_DEFAULT, mDevType, mAdapterFormat, D3DUSAGE_AUTOGENMIPMAP, D3DRTYPE_TEXTURE, D3DFMT_X8R8G8B8)) return false;
if(!(mCaps.Caps2 & D3DCAPS2_CANAUTOGENMIPMAP)) return false;
if(mCaps.VertexShaderVersion < D3DVS_VERSION(2,0)) return false;
if(mCaps.PixelShaderVersion < D3DPS_VERSION(2,0)) return false;
if(mCaps.MaxAnisotropy < 4) return false;
if(mCaps.MaxTextureWidth < 256) return false;
if(mCaps.MaxTextureHeight < 256) return false;
return true;
}
else return false;
}