tge/lib/maxsdk70/include/mentalray/imrShaderTranslation.h
2017-04-17 06:17:10 -06:00

346 lines
15 KiB
C++
Executable File

/*==============================================================================
file: imrShaderTranslation.h
author: Daniel Levesque
created: 10feb2003
description:
Defition of the mental ray shader translation interface.
modified:
[dl] 28 April 2004. Added advanced translation of parameters, incremented
interface IDs to distinguish between the old (MAX 6) interface and the new (MAX 7)
interface.
© 2004 Autodesk
==============================================================================*/
#ifndef _IMRSHADERTRANSLATION_H_
#define _IMRSHADERTRANSLATION_H_
#include <mentalray\imrAdvancedTranslation.h>
#include <max.h>
#include <BaseInterface.h>
class imrShader;
class imrShaderCreation;
class Texmap;
class imrMaterialCustAttrib;
#define IMRSHADERTRANSLATION_INTERFACE_ID Interface_ID(0x1c396abd, 0x5f964e0c)
#define IMRMTLPHENTRANSLATION_INTERFACE_ID Interface_ID(0x5f970a9c, 0x65e75de4)
#define IMRGEOMSHADERTRANSLATION_INTERFACE_ID Interface_ID(0x31882a12, 0x2102a73)
#define IMRSHADERTRANSLATION_CLASSINFO_INTERFACE_ID Interface_ID(0x17a76fd6, 0x5ab32bcd)
//==============================================================================
// class imrShaderTranslation
//
// Interface to be implemented by the MAX plugin which translates to a mental
// ray shader. Materials do not use this interface. Instead, they use the
// imrMaterialTranslation interface.
//
// For example:
// A 3rd party implements a MAX texmap pluggin for a brick effect. By default,
// the mental ray translator does not support this texture and will be unable to
// render it. If the 3rd party has also implemented a mental ray shader for this
// effect, then this interface may be used to tell the mental ray translator
// which shader is to be used.
//==============================================================================
class imrShaderTranslation : public BaseInterface {
public:
// List of requirements that may be queried on this translation interface
enum Requirement {
// This shader requires tangent basis vectors.
// The tangent basis vectors will be translated for the object on which
// this shader is used.
// Return true if the vectors are needed, false otherwise.
// The 't', and 'valid' parameters are not used.
// The 'arg' variable is a pointer to an 'int', to which to map channel
// to be used should be assigned.
kReq_TangentBasisVectors = 0,
};
struct AdditionalDependency {
AdditionalDependency(ReferenceTarget* rt, bool assign = true) : refTarg(rt), assignAsChild(assign) {}
// The reference target that is to be translated as a dependency
ReferenceTarget* refTarg;
// This should be true in all but exceptional cases where the translator
// could run into potential problems with reference looping.
bool assignAsChild;
};
typedef Tab<AdditionalDependency> AdditionalDependencyTable;
// Called by the mental ray translator to get the mental ray shader which
// is to be used. The method may return a shader which was already created,
// or create a new one via the imrShaderCreation interface.
// This method will never be called more than once per render.
virtual imrShader* GetMRShader(imrShaderCreation& shaderCreation) = 0;
// This may be called when rendering is finished to discard the mental ray shaders.
// If the derived class holds a reference to the shader created by the call to GetMRShader(),
// then it may release that reference in this call. This is not an obligation,
// but it can free memory and/or resolve issues such as the "Make Unique"
// button always being enabled in the material editor.
virtual void ReleaseMRShader() = 0;
// Should the translator automatically copy the parameters based on the param
// block 2 system?
// NOTE: The metnal ray translator will correctly handle automatic translation
// of the parameters IF the 3rd party plugin's parameters all use the ParamBlock2
// system AND if the names & types of the parameters match the shader definition
// (names are not case sensitive).
// If this returns 'true', then the automatic translation will take place
// after the call to TranslateParameters().
virtual bool NeedsAutomaticParamBlock2Translation() = 0;
// Translates the parameters of this plugin to the mental ray shader. Called
// for the first frame, and for each subsequent frame that is not in the
// validity interval. The method must store the validity interval of the
// translated parameters in 'valid'.
// **The parameters must be stored in the shader at time 0.
virtual void TranslateParameters(imrShader* shader, TimeValue t, Interval& valid) = 0;
// If this class needs any ReferenceTarget to be translated, but which are not
// sub-references or within a parameter block of the plugin class, then these
// ReferenceTarget's may be given here. The mental ray translator will automatically
// create a dependency between the plugin and the given ReferenceTarget's.
virtual void GetAdditionalReferenceDependencies(AdditionalDependencyTable& refTargets) = 0;
// This method is meant for advanced users for whom TranslateParameters() either is not
// sufficient or causes performance issues.
// Whereas TranslateParameters() translates parameters using the ParamBlock2 system,
// this method is used to send parameters directly to mental ray, bypassing the ParamBlock2 system.
// If TranslateParameters() is enough for you, or if you do not understand why you would need
// this advanced translation method, then do not implement this method.
// See the documentation of class imrAdvancedTranslation for more details.
virtual void TranslateParameters_Advanced(imrAdvancedTranslation& advancedTranslation, TimeValue t, Interval& valid);
// This method is meant to query specific requirements from the translation interface.
// Look at the documentation for each requirement flag for more information.
// Note that 'arg' may or may not be used, depending on the requirement.
virtual bool HasRequirement(Requirement requirement, TimeValue t, Interval& valid, void* arg = NULL);
// -- from BaseInterface
virtual Interface_ID GetID();
};
inline imrShaderTranslation* GetIMRShaderTranslation(InterfaceServer* iserver) {
return static_cast<imrShaderTranslation*>(iserver->GetInterface(IMRSHADERTRANSLATION_INTERFACE_ID));
}
//==============================================================================
// class imrMaterialPhenomenonTranslation
//
// A material plugin that wishes to have a custom translation to a material
// phenomenon must derive from this interface. The interface is identical to
// imrShaderTranslation, except that:
// - the interface ID is different
// - only material phenomenon may be created via the imrShaderCreation interface.
//
// SPECIAL CASE: Using the mental ray material directly.
// To translate a material to a mental ray material directly, without actually
// using a phenomenon of your own, create an instance of the phenomenon called
// "max_default_mtl_phen". Even though this is a phenomenon, it is not translated
// as one, but instead it is translated as a material. NOTE, however, that this
// particular phenomenon does NOT support the automatic ParamBlock2 translation,
// so NeedsAutomaticParamBlock2Translation() should return false.
//==============================================================================
class imrMaterialPhenomenonTranslation : public imrShaderTranslation {
public:
// Returns whether this material supports the 'mental ray connection' custom
// attributes rollup. This rollup allows users to override any of the 10 shaders
// on the material. Note that only materials that translate to the default
// material phenomenon ("max_default_mtl_phen") may return true here, since
// the translator needs that phenomenon to translate the shader overrides.
// If the material does not return the default material phenomenon but still
// wishes to support the overrides, then it will have to do so itself.
virtual bool SupportsMtlOverrides() = 0;
// Initializes the mtl overrides custom attribute, if necessary. Only called
// if SupportsMtlOverrides() returned true.
// All that this function should do is enable/disable the shader locks of the custom
// attribute.
// A material may simply do nothing here, or it may disable some of the shader locks
// that don't apply.
virtual void InitializeMtlOverrides(imrMaterialCustAttrib* mtlCustAttrib) = 0;
// -- from BaseInterface
virtual Interface_ID GetID();
};
inline imrMaterialPhenomenonTranslation* GetIMRMaterialPhenomenonTranslation(InterfaceServer* iserver) {
return static_cast<imrMaterialPhenomenonTranslation*>(iserver->GetInterface(IMRMTLPHENTRANSLATION_INTERFACE_ID));
}
//==============================================================================
// class imrGeomShaderTranslation
//
// A geometry object plugin that wishes to have a custom translation to a mental
// ray shader must derive from this interface. The interface is used to retrieve
// an instance of the geometry shader to be used.
// Derive your GeomObject or ShapeObject from this class to have it translated
// to a geometry shader.
//==============================================================================
class imrGeomShaderTranslation : public BaseInterface {
public:
// Returns the geometry shader to be used with this object. The ReferenceTarget
// returned by this method should be a Texmap plugin that translates to a mental
// ray geometry shader. You may need to implement your own Texmap plugin that
// uses the imrShaderTranslation interface to translate itself to a mental ray
// shader.
virtual ReferenceTarget* GetGeomShader() = 0;
// Returns a scale for the geometry shader, to be applied on the instance transform.
// This is useful in the case that a geometry shader produces objects of a fixed
// size (e.g. the mib_geo_* shaders), but you still want to be able to expose
// a size parameter in the UI.
// If you don't care about scaling, just return a scale of (1,1,1).
virtual void GetScale(Point3& scale) = 0;
// -- from BaseInterface
virtual Interface_ID GetID();
};
inline imrGeomShaderTranslation* GetIMRGeomShaderTranslation(InterfaceServer* iserver) {
return static_cast<imrGeomShaderTranslation*>(iserver->GetInterface(IMRGEOMSHADERTRANSLATION_INTERFACE_ID));
}
//==============================================================================
// class imrShaderCreation
//
// Interface used to create new shader instances.
//
// A reference to this interface is passed to the "GetMRShader()" method of the
// imrShaderTranslation interface. If one tries to create a shader which does
// nto exist, CreateShader() outputs an error in the mental ray message window
// and returns NULL.
//
// IMPORTANT: If the implementation of this interface holds a pointer to
// a shader, to avoid re-creating it every time, then it MUST make a reference
// to that shader. Otherwise, the shader will be deleted when the render ends.
//==============================================================================
class imrShaderCreation {
public:
// Creates an instance of a shader with the given name. The name must be as it
// appears in the .mi declaration.
// This method may return NULL if the shader is not found, and the caller
// should check for NULL values.
virtual imrShader* CreateShader(
const TCHAR* declarationName,
const TCHAR* mtlName // The material's name is used when reporting errors.
// (Tip: Pass the result of MtlBase::GetFullName())
// Passing NULL suppresses error messages.
) = 0;
};
//==============================================================================
// class imrShaderTranslation_ClassInfo
//
// IMPLEMENTATION INSTRUCTIONS:
//
// To be subclassed by a ClassDesc or ClassDesc2 of a Texmap plugin.
// The subclass HAS TO call Init(*this) from its constructor.
//
// DESCRIPTION:
//
// This class is used to provide additional 'ApplyType' information for texmaps
// that translate to a custom shaders.
//
// All mental ray shaders have an 'apply' type. This type classifies shaders into
// different categories (e.g. texture shader, light shader, environment shader, etc.).
// The apply type restricts where and how a shader may be used. By default, if
// this interface is not implemented, a Texmap plugin will have the
// imrShaderClassDesc::kApplyFlag_Default apply type. If this is incorrect, then
// this interface should be implemented - otherwise it may be impossible to use
// the shader and crashes could occur if the shader is not used correctly.
//==============================================================================
class imrShaderTranslation_ClassInfo : public FPStaticInterface {
public:
// Initialization method. MUST be called from the constructor of the subclass. i.e. "Init(*this);".
void Init(
ClassDesc& classDesc
);
// Get the types to which this shader may be applied (combination of
// imrShaderClassDesc::ApplyFlags values).
virtual unsigned int GetApplyTypes() = 0;
};
//==============================================================================
// class imrShaderTranslation_ClassInfo inlined methods
//==============================================================================
// Given the class descriptor of a Mtl/Texmap plugin, this returns its compatibility interface (if it exists).
inline imrShaderTranslation_ClassInfo* Get_imrShaderTranslation_ClassInfo(ClassDesc& mtlBaseClassDesc) {
return static_cast<imrShaderTranslation_ClassInfo*>(mtlBaseClassDesc.GetInterface(IMRSHADERTRANSLATION_CLASSINFO_INTERFACE_ID));
}
//==============================================================================
// class imrShaderTranslation inlined methods
//==============================================================================
inline Interface_ID imrShaderTranslation::GetID() {
return IMRSHADERTRANSLATION_INTERFACE_ID;
}
inline void imrShaderTranslation::TranslateParameters_Advanced(imrAdvancedTranslation& advancedTranslation, TimeValue t, Interval& valid) {
// Default implementation does nothing
}
inline bool imrShaderTranslation::HasRequirement(Requirement, TimeValue t, Interval& valid, void* arg) {
// Default implementation has no requirements
return 0;
}
//==============================================================================
// class imrMaterialPhenomenonTranslation inlined methods
//==============================================================================
inline Interface_ID imrMaterialPhenomenonTranslation::GetID() {
return IMRMTLPHENTRANSLATION_INTERFACE_ID;
}
//==============================================================================
// class imrGeomShaderTranslation inlined methods
//==============================================================================
inline Interface_ID imrGeomShaderTranslation::GetID() {
return IMRGEOMSHADERTRANSLATION_INTERFACE_ID;
}
//==============================================================================
// class imrShaderTranslation_ClassInfo inlined methods
//==============================================================================
inline void imrShaderTranslation_ClassInfo::Init(ClassDesc& classDesc) {
LoadDescriptor(IMRSHADERTRANSLATION_CLASSINFO_INTERFACE_ID, _T("imrShaderTranslation_ClassInfo"), 0, &classDesc, 0, end);
}
#endif