#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)
#include <maya/d3dx11effect.h>
#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;
namespace MHWRender {
class MLightParameterInformation;
class MTexture;
class MDrawContext;
}
#define USE_GL_TEXTURE_CACHING
{
public:
enum ERenderType
{
RENDER_SCENE,
RENDER_SWATCH,
RENDER_SWATCH_PROXY,
RENDER_UVTEXTURE,
RENDER_SCENE_DEFAULT_LIGHT
};
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 techniqueHandlesContext(
const MString& requestedContext)
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 passCount() 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;
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;
public:
void updateShaderBasedGeoChanges();
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)
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:
#if defined(MAYA_WANT_EXTERNALCONTENTTABLE)
#endif
private:
size_t fGeometryVersionId;
bool fShaderChangesGeo;
double fLastTime;
bool fVariableNameAsAttributeName;
mutable MUint64 fLastFrameStamp;
dx11ShaderNode* fDuplicateNodeSource;
MCallbackId fPostDuplicateCallBackId;
dx11ShaderDX11Effect* fEffect;
int fTechniqueIdx;
dx11ShaderDX11EffectTechnique* fTechnique;
int fTechniqueTextureMipMapLevels;
ETransparencyState fTechniqueIsTransparent;
bool fTechniqueSupportsAdvancedTransparency;
bool fTechniqueOverridesDrawState;
unsigned int fPassCount;
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;
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 int dx11ShaderNode::passCount() const
{
return fPassCount;
}
inline const MStringArray& dx11ShaderNode::getUIGroups()
const
{
return fUIGroupNames;
}
inline const MStringArray& dx11ShaderNode::lightInfoDescription()
const
{
return fLightDescriptions;
}
#endif