346 lines
15 KiB
C++
Executable File
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 |