#ifndef _dx11ShaderNode_h_
#define _dx11ShaderNode_h_
#include <maya/MPxHardwareShader.h>
#include <maya/MStringArray.h>
#include <maya/MVaryingParameterList.h>
#include <maya/MUniformParameterList.h>
#include <maya/MHWGeometry.h>
#include <maya/MPlugArray.h>
#include <maya/MMessage.h>
#define WIN32_LEAN_AND_MEAN
#include <d3d11.h>
#if _MSC_VER >= 1700
#include <dxgi.h>
#else
#include <d3dx11.h>
#endif
#define HAVE_D3DX11EFFECT_LIBRARY_BUILT
#if defined(HAVE_D3DX11EFFECT_LIBRARY_BUILT)
#if defined(JAMBUILD)
#include <DX11/d3dx11effect.h>
#else
#include <../Samples/C++/Effects11/Inc/d3dx11effect.h>
#ifndef USE_BOOL
#define USE_BOOL // use BOOL instead of bool
#endif
#endif
#define dx11ShaderDX11Device ID3D11Device
#define dx11ShaderDX11DeviceContext ID3D11DeviceContext
#define dx11ShaderDX11Effect ID3DX11Effect
#define dx11ShaderDX11EffectTechnique ID3DX11EffectTechnique
#define dx11ShaderDX11Pass ID3DX11EffectPass
#define dx11ShaderDX11InputLayout ID3D11InputLayout
#define dx11ShaderDX11InputElementDesc D3D11_INPUT_ELEMENT_DESC
#define dx11ShaderDX11EffectVariable ID3DX11EffectVariable
#define dx11ShaderDX11EffectShaderResourceVariable ID3DX11EffectShaderResourceVariable
#define dx11ShaderDX11RasterizerState ID3D11RasterizerState
#define dx11ShaderDX11DepthStencilState ID3D11DepthStencilState
#define dx11ShaderDX11BlendState ID3D11BlendState
#else
#define dx11ShaderDX11Device void
#define dx11ShaderDX11DeviceContext void
#define dx11ShaderDX11Effect void
#define dx11ShaderDX11EffectTechnique void
#define dx11ShaderDX11Pass void
#define dx11ShaderDX11InputLayout void
#define dx11ShaderDX11InputElementDesc void
#define dx11ShaderDX11EffectVariable void
#define dx11ShaderDX11EffectShaderResourceVariable void
#define dx11ShaderDX11RasterizerState void
#define dx11ShaderDX11DepthStencilState void
#define dx11ShaderDX11BlendState void
#endif
#include <map>
#include <set>
#include <vector>
class CUniformParameterBuilder;
#define USE_GL_TEXTURE_CACHING
{
private:
enum ERenderType
{
RENDER_SCENE,
RENDER_SCENE_NON_MATERIAL,
RENDER_SWATCH,
RENDER_SWATCH_PROXY,
RENDER_UVTEXTURE
};
inline bool isRenderScene(ERenderType renderType) const { return (renderType == RENDER_SCENE || renderType == RENDER_SCENE_NON_MATERIAL); }
inline bool isRenderSwatch(ERenderType renderType) const { return (renderType == RENDER_SWATCH); }
inline bool isRenderNonMaterialItem(ERenderType renderType) const { return (renderType == RENDER_SCENE_NON_MATERIAL); }
inline bool needUpdateImplicitLightConnections(ERenderType renderType) const { return (renderType == RENDER_SCENE || renderType == RENDER_SWATCH); }
inline bool needUpdateExplicitLightConnections(ERenderType renderType) const { return (renderType == RENDER_SCENE); }
inline bool overrideRasterizerState(ERenderType renderType) const { return !isRenderScene(renderType); }
inline bool needUpdateMayaSwatchRenderVar(ERenderType renderType) const { return (renderType == RENDER_SWATCH || renderType == RENDER_SWATCH_PROXY); }
struct RenderItemDesc
{
bool isFatLine;
bool isFatPoint;
};
public:
enum ELightType
{
eInvalidLight,
eUndefinedLight,
eSpotLight,
ePointLight,
eDirectionalLight,
eAmbientLight,
eVolumeLight,
eAreaLight,
eDefaultLight,
eLightCount
};
enum ETransparencyState
{
eOpaque,
eTransparent,
eTestOpacitySemantics,
eScriptedTest
};
struct ContextStates
{
ContextStates() : rasterizerState(NULL), depthStencilState(NULL), blendState(NULL) {}
dx11ShaderDX11RasterizerState* rasterizerState;
dx11ShaderDX11DepthStencilState* depthStencilState;
UINT stencilRef;
dx11ShaderDX11BlendState* blendState;
float blendFactor[4];
UINT sampleMask;
};
class LightParameterInfo
{
typedef dx11ShaderNode::ELightType ELightType;
public:
LightParameterInfo(ELightType lightType = dx11ShaderNode::eInvalidLight, bool hasLightTypeSemantics = false);
ELightType lightType() const;
public:
ELightType fLightType;
bool fHasLightTypeSemantics;
bool fIsDirty;
typedef std::map<int, int> TConnectableParameters;
TConnectableParameters fConnectableParameters;
};
public:
dx11ShaderNode();
virtual ~dx11ShaderNode();
static void* creator();
static void initializeNodeAttrs();
public:
static void postDuplicateCB( void *data );
public:
bool rebuildAlways(size_t baseVersionId) const;
bool isDirty(size_t baseVersionId) const;
size_t geometryVersionId() const;
private:
bool hasUpdatedVaryingInput() const;
void setTopoDirty();
public:
static bool reloadAll(
const MString& effectName);
bool reload();
dx11ShaderDX11Effect* effect() const;
double boundingBoxExtraScale() const;
private:
bool loadEffect(
const MString& effectName );
bool loadFromFile(
const MString& fileName, dx11ShaderDX11Device* dxDevice);
bool loadFromBuffer(
const MString& identifier,
const void* pData,
unsigned int dataSize, dx11ShaderDX11Device* dxDevice);
bool initializeEffect();
void resetData(bool clearEffect = true);
public:
inline int techniqueCount() const;
bool techniqueIsTransparent() const;
bool techniqueSupportsAdvancedTransparency() const;
bool techniqueOverridesDrawState() const;
bool techniqueOverridesNonMaterialItems() const;
bool techniqueHandlesConsolidatedGeometry() const;
bool techniqueIsSelectable() const;
bool passHandlesContext(
const MStringArray& passSemantics,
unsigned int passIndex, ERenderType renderType,
const RenderItemDesc* renderItemDesc = NULL)
const;
int activeTechnique() const;
dx11ShaderDX11EffectTechnique* technique() const;
const MString& activeTechniqueName()
const;
const MString& techniqueIndexBufferType()
const;
private:
bool initializeTechniques();
bool setTechnique(
const MString& techniqueName );
bool setTechnique( int techniqueNumber );
void initTechniqueParameters();
void storeDefaultTextureNames();
void restoreDefaultTextureNames();
public:
int techniquePassCount() const;
private:
dx11ShaderDX11Pass* activatePass( dx11ShaderDX11Device *dxDevice, dx11ShaderDX11DeviceContext *dxContext, dx11ShaderDX11EffectTechnique* dxTechnique, unsigned int passId, ERenderType renderType ) const;
dx11ShaderDX11Pass* activatePass( dx11ShaderDX11Device *dxDevice, dx11ShaderDX11DeviceContext *dxContext, dx11ShaderDX11EffectTechnique* dxTechnique,
unsigned int passId,
const MStringArray& passSem, ERenderType renderType,
const RenderItemDesc* renderItemDesc = NULL )
const;
bool passHasHullShader(dx11ShaderDX11Pass* dxPass) const;
dx11ShaderDX11InputLayout* getInputLayout(dx11ShaderDX11Device* dxDevice, dx11ShaderDX11Pass* dxPass, unsigned int numLayouts, const dx11ShaderDX11InputElementDesc* layoutDesc) const;
public:
private:
typedef std::vector<const MHWRender::MRenderItem*> RenderItemList;
bool renderTechnique(dx11ShaderDX11Device *dxDevice, dx11ShaderDX11DeviceContext *dxContext, dx11ShaderDX11EffectTechnique* dxTechnique,
const RenderItemList& renderItemList,
bool renderPass(dx11ShaderDX11Device *dxDevice, dx11ShaderDX11DeviceContext *dxContext, dx11ShaderDX11Pass* dxPass,
const RenderItemList& renderItemList,
bool renderTechnique(dx11ShaderDX11Device *dxDevice, dx11ShaderDX11DeviceContext *dxContext, dx11ShaderDX11EffectTechnique* dxTechnique, unsigned int numPasses,
bool renderPass(dx11ShaderDX11Device *dxDevice, dx11ShaderDX11DeviceContext *dxContext, dx11ShaderDX11Pass* dxPass,
bool renderTechnique(dx11ShaderDX11Device *dxDevice, dx11ShaderDX11EffectTechnique* dxTechnique, unsigned int numPasses,
public:
void backupStates(dx11ShaderDX11DeviceContext *dxContext, ContextStates &states) const;
void restoreStates(dx11ShaderDX11DeviceContext *dxContext, ContextStates &states) const;
private:
typedef std::map< dx11ShaderDX11EffectShaderResourceVariable*, MHWRender::MTexture* > ResourceTextureMap;
void updateOverrideNonMaterialItemParameters(
const MHWRender::MRenderItem* item, RenderItemDesc& renderItemDesc )
const;
public:
void updateShaderBasedGeoChanges();
void updateLightsInformation();
private:
typedef std::map<int, bool> TshadowFlagBackupState;
void initShadowFlagBackupState(TshadowFlagBackupState& stateBackup ) const;
void setPerGeometryShadowOnFlag(bool receivesShadows, TshadowFlagBackupState& stateBackup ) const;
public:
void clearParameters();
private:
void preBuildUniformParameterList();
bool buildUniformParameterList();
bool buildVaryingParameterList();
bool buildVertexDescriptorFromVaryingParameters();
void initMayaParameters();
public:
int getIndexForUIGroupName(
const MString& uiGroupName,
bool appendGroup =
false);
MString getLightConnectionInfo(
int lightIndex);
MStringArray getLightableParameters(
int lightIndex,
bool showSemantics);
int getIndexForLightName(
const MString& lightName,
bool appendLight =
false);
bool getVariableNameAsAttributeName(){ return fVariableNameAsAttributeName; }
private:
bool appendParameterNameIfVisible(
int paramIndex,
MStringArray& paramArray)
const;
public:
void refreshLightConnectionAttributes(bool inSceneUpdateNotification=false);
void connectLight(
int lightIndex,
MDagPath light);
void disconnectLight(int lightIndex);
private:
void refreshView() const;
void setLightRequiresShadows(
const MObject& lightObject,
bool requiresShadow)
const;
private:
void updateImplicitLightParameterCache(std::vector<CUniformParameterBuilder*>& builders);
void clearLightConnectionData();
private:
void getLightParametersToUpdate(std::set<int>& parametersToUpdate, ERenderType renderType) const;
bool connectExplicitAmbientLight(
const LightParameterInfo& lightInfo,
const MObject& sourceLight)
const;
void turnOffLight(const LightParameterInfo& lightInfo) const;
void setLightParameterLocking(const LightParameterInfo& lightInfo, bool locked) const;
private:
void assignTexture(dx11ShaderDX11EffectShaderResourceVariable* resourceVariable,
const MString& textureName,
const MString& layerName,
int alphaChannelIdx, ResourceTextureMap& resourceTexture,
MObject node =
MObject())
const;
void releaseAllTextures(ResourceTextureMap& resourceTexture) const;
void releaseAllTextures();
MString &textureName,
MString& layerName,
int &alphaChannelIdx,
int &mipmapLevels);
public:
bool getTextureFile(
const MString& uniformName,
MString& textureFile)
const;
private:
void setParameterAsVector(int paramIndex, float* data) const;
void setParameterAsScalar(int paramIndex, float data) const;
void setParameterAsScalar(int paramIndex, bool data) const;
void setParameterAsScalar(int paramIndex, int data) const;
void setParameterAsMatrix(
int paramIndex,
MMatrix& data)
const;
void setParameterAsResource(int paramIndex, ID3D11ShaderResourceView* inResource) const;
void setParameterFromUniformAsVector(
int paramIndex,
const MHWRender::MDrawContext& context,
const float *data = NULL)
const;
public:
private:
void displayErrorAndWarnings() const;
void reportInternalError( const char* function, size_t errcode ) const;
private:
private:
struct PassSpec
{
bool forFatLine;
bool forFatPoint;
};
unsigned int findMatchingPass(const PassSpec& passSpecTest) const;
private:
size_t fGeometryVersionId;
bool fShaderChangesGeo;
double fLastTime;
bool fIgnoreLightLimits;
bool fVariableNameAsAttributeName;
mutable MUint64 fLastFrameStamp;
dx11ShaderNode* fDuplicateNodeSource;
MCallbackId fPostDuplicateCallBackId;
dx11ShaderDX11Effect* fEffect;
int fTechniqueIdx;
dx11ShaderDX11EffectTechnique* fTechnique;
int fTechniqueTextureMipMapLevels;
bool fTechniqueIsSelectable;
ETransparencyState fTechniqueIsTransparent;
bool fTechniqueSupportsAdvancedTransparency;
bool fTechniqueOverridesNonMaterialItems;
bool fTechniqueHandlesConsolidatedGeometry;
bool fTechniqueOverridesDrawState;
unsigned int fTechniquePassCount;
typedef std::map<unsigned int, PassSpec> PassSpecMap;
PassSpecMap fTechniquePassSpecs;
size_t fVaryingParametersGeometryVersionId;
size_t fVaryingParametersUpdateId;
typedef std::vector<LightParameterInfo> LightParameterInfoVec;
LightParameterInfoVec fLightParameters;
mutable int fImplicitAmbientLight;
std::vector<std::vector<int> > fUIGroupParameters;
ResourceTextureMap fResourceTextureMap;
mutable bool fForceUpdateTexture;
int fFixedTextureMipMapLevels;
#ifdef USE_GL_TEXTURE_CACHING
int fUVEditorLastAlphaChannel;
float fUVEditorBaseColor[4];
bool fUVEditorShowAlphaMask;
unsigned int fUVEditorGLTextureId;
float fUVEditorGLTextureScaleU;
float fUVEditorGLTextureScaleV;
#endif //USE_GL_TEXTURE_CACHING
double fBBoxExtraScaleValue;
dx11ShaderDX11EffectVariable* fMayaSwatchRenderVar;
dx11ShaderDX11EffectVariable* fMayaGammaCorrectVar;
dx11ShaderDX11EffectVariable* fMayaHwFogEnabled;
dx11ShaderDX11EffectVariable* fMayaHwFogMode;
dx11ShaderDX11EffectVariable* fMayaHwFogStart;
dx11ShaderDX11EffectVariable* fMayaHwFogEnd;
dx11ShaderDX11EffectVariable* fMayaHwFogDensity;
dx11ShaderDX11EffectVariable* fMayaHwFogColor;
dx11ShaderDX11EffectVariable* fDepthRange;
typedef std::map< dx11ShaderDX11Pass*, bool > PassHasHullShaderMap;
mutable PassHasHullShaderMap fPassHasHullShaderMap;
struct CachedInputElementDesc
{
unsigned int SemanticIndex;
int Format;
unsigned int InputSlot;
unsigned int AlignedByteOffset;
int InputSlotClass;
unsigned int InstanceDataStepRate;
};
struct InputLayoutData
{
dx11ShaderDX11InputLayout* inputLayout;
unsigned int numLayouts;
CachedInputElementDesc* layoutDesc;
};
typedef std::map< dx11ShaderDX11Pass*, InputLayoutData > PassInputLayoutMap;
mutable PassInputLayoutMap fPassInputLayoutMap;
mutable unsigned int fErrorCount;
};
inline bool dx11ShaderNode::rebuildAlways(size_t baseVersionId) const
{
return hasUpdatedVaryingInput() || isDirty(baseVersionId);
}
inline bool dx11ShaderNode::isDirty(size_t baseVersionId) const
{
return (fGeometryVersionId != baseVersionId);
}
inline size_t dx11ShaderNode::geometryVersionId() const
{
return fGeometryVersionId;
}
inline const MString& dx11ShaderNode::effectName()
const
{
return fEffectName;
}
inline dx11ShaderDX11Effect* dx11ShaderNode::effect() const
{
return fEffect;
}
inline double dx11ShaderNode::boundingBoxExtraScale() const
{
return (fBBoxExtraScaleValue > 1.0f ? fBBoxExtraScaleValue : 1.0f);
}
inline const MStringArray& dx11ShaderNode::techniques()
const
{
return fTechniqueNames;
}
inline int dx11ShaderNode::techniqueCount() const
{
return (
int)fTechniqueNames.
length();
}
inline int dx11ShaderNode::activeTechnique() const
{
return fTechniqueIdx;
}
inline dx11ShaderDX11EffectTechnique* dx11ShaderNode::technique() const
{
return fTechnique;
}
inline const MString& dx11ShaderNode::activeTechniqueName()
const
{
return fTechniqueName;
}
inline const MString& dx11ShaderNode::techniqueIndexBufferType()
const
{
return fTechniqueIndexBufferType;
}
inline bool dx11ShaderNode::techniqueOverridesDrawState() const
{
return fTechniqueOverridesDrawState;
}
inline bool dx11ShaderNode::techniqueSupportsAdvancedTransparency() const
{
return fTechniqueSupportsAdvancedTransparency;
}
inline bool dx11ShaderNode::techniqueOverridesNonMaterialItems() const
{
return fTechniqueOverridesNonMaterialItems;
}
inline bool dx11ShaderNode::techniqueHandlesConsolidatedGeometry() const
{
return fTechniqueHandlesConsolidatedGeometry;
}
inline bool dx11ShaderNode::techniqueIsSelectable() const
{
return fTechniqueIsSelectable;
}
inline int dx11ShaderNode::techniquePassCount() const
{
return fTechniquePassCount;
}
inline const MStringArray& dx11ShaderNode::getUIGroups()
const
{
return fUIGroupNames;
}
inline const MStringArray& dx11ShaderNode::lightInfoDescription()
const
{
return fLightDescriptions;
}
#endif