- Main Page
- Related Pages
- Modules
- Classes
- Examples

- Class List
- Class Hierarchy
- Class Members

Classes | Public Member Functions | Static Public Member Functions | Protected Member Functions

# MPxShaderOverride Class Reference

# OpenMayaRender - API module for rendering | Proxy classes

This reference page is linked to from the following overview topics: Scene Overrides, Framework Classes, Transition Guide, Devkit Samples.

Search for all occurrences

## Detailed Description

Base class for user defined shading effect draw overrides.

MPxShaderOverride allows the user to create a custom override for associating a "full shading effect" with a shading node (custom or standard) in Maya. Its primary use is for associating hardware effects with pre-existing plugin software shaders.

A "full shading effect" defines the complete shading and lighting involved to render a given object. Input resources for shading such as geometry, textures, and lights are defined and bound to the shading effect via the override as required. The override is fully responsible for these tasks.

As an example, for hardware shading, this can be thought of as implementing a CgFx or HLSL effect file renderer which can use the resources defined within a Maya scene.

There are three main phases that the override must implement:

1) Initialization Phase : This phase occurs when Maya determines that the hardware shader generated through this override needs to be rebuilt. This may be due to a new object using the shader, or because something has changed on the shader that requires a complete rebuild. During the initialization phase the geometric stream requirements can be specified using addGeometryRequirement(). The requirements will determine which geometric streams are required from objects to which the given shading effect is assigned. If no requirements are specified then a single position stream requirement will be used.

The initialize() method must return a string representing the shader key. It often happens that different instances of the MPxShaderOverride represent essentially the same shader, but with different shader parameters. The shader key is used to identify the MPxShaderOverride instances representing the same shader. To optimize rendering, the Viewport 2.0 will make an effort to regroup the rendering of objects with the same MPxShaderOverride shader key. This allows the plug-in to perform its setup only once for the entire sequence. It is up to each plug-in to decide what the meaning of representing the same shader is.

There are two possible versions of initialize() to implement (however it is only necessary to implement one, the default implementation of the second calls the first). The first simply recieves the shader node that is being initialized. The second recieves additional context (such as the DAG path for the object bound to the shader) and also allows the implementation to also send back custom user data to attach to the MRenderItem representing the DAG-object/shader association. The custom user data must be derived from MUserData. If the deleteAfterUse() method returns true for the MUserData instance then the data object will automatically be deleted when the render item is deleted. Otherwise the lifetime of the user data object is the responsibility of the caller. This user data may be accessed in the draw phase from the render item being drawn. Note that Maya objects which have render items that have custom user data can only be consolidated when the user data pointer on each item references the same user data instance. Draw performance will suffer without consolidation, however if the user data object is shared then memory management must be handled manually (ie. deleteAfterUse() should return false).

2) Data Update Phase : In this phase, updating of all data values required for shading is performed. The interface has an explicit split of when the dependency graph can be accessed (updateDG()), and when the draw API (e.g. OpenGL) can be accessed (updateDevice()). Any intermediate data can be cleaned up when endUpdate() is called.

As an example the override may require input from an attribute on a given node.

- updateDG() would evaluate the plug for the attribute and cache its value temporarily on the override.
- updateDevice() would take the temporarily cached value and bind it to a shader stored on the graphic device.
- endUpdate() would reset the temporary data on the override.

Note that the override can provide a draw hint as to whether shading will involve semi-transparency. This hint can be provided by overriding the isTransparent() method which gets called between updateDevice() and endUpdate().

3) Drawing Phase : The actual drawing using the shader is performed in the pure virtual draw() method. The callback method should return true if it was able to draw successfully. If false is returned then drawing will be done using the default shader used for unsupported materials.

Drawing is explicitly not intermixed with the data update on purpose. By the time draw is being called all evaluation should have been completed. If there is user data that needs to be passed between the update and drawing phases the override must cache that data itself. It is an error to access the Maya dependency graph during draw and attempts to do so may result in instability.

Although it is possible for implementations of the draw() method to handle all shader setup and geometry draw, the expected use of the draw() method is to do shader setup only. Then drawGeometry() can be called to allow Maya to handle the actual geometry drawing. If manual geometry binding is required however, it is possible to query the hardware resource handles through the geometry on each render item in the render item list passed into the draw() method.

The activateKey() and terminateKey() method will also be invoked in the draw phase each time a render item is drawn with a different shader key (see the discussion above about shader keys). The activateKey() and terminateKey() methods can be used to optimize rendering by configuring the rendering state only once for a batch of draw() calls that are sharing the same shader key.

The sequence of invocations will look like:

- shaderOverrideA->activateKey(...)
- shaderOverrideA->draw(...)
- shaderOverrideB->draw(...)
- shaderOverrideC->draw(...)
- ...
- shaderOverrideA->terminateKey(...)
- shaderOverrideX->activateKey(...) Note that the terminateKey() callback is always invoked on the same MPxShaderOverride instance as the one used to invoked the activateKey() callback.

Note if full draw control is desired, the proxy class MPxDrawOverride may be more appropriate.

Implementations of MPxShaderOverride must be registered with Maya through MDrawRegistry.

Examples:

  cgfxShaderNode.cpp, cgfxShaderNode.h, hwColorPerVertexShader.cpp, and hwPhongShader.cpp.

`#include <MPxShaderOverride.h>`

List of all members.

## Classes
struct | MInitContext
| Initialization context used by advanced initalization method. More...
struct | MInitFeedback
| Data to pass back to Maya after initialization. More...
## Public Member Functions
| MPxShaderOverride (const MObject &obj)
| Construct an MPxShaderOverride.
virtual | ~MPxShaderOverride ()
| Destructor.
virtual MString | initialize (MObject shader)
| Initialization occurs when Maya determines that the hardware shader needs to be rebuilt.
virtual MString | initialize (const MInitContext &initContext, MInitFeedback &initFeedback)
| Initialization occurs when Maya determines that the hardware shader needs to be rebuilt.
virtual void | updateDG (MObject object)
| This is the first part of the update phase.
virtual void | updateDevice ()
| This is the second part of the update phase.
virtual void | endUpdate ()
| This is the final part of the update phase.
virtual void | activateKey (MDrawContext &context, const MString &key)
| This is the activateKey callback.
virtual bool | draw (MDrawContext &context, const MRenderItemList &renderItemList) const =0
| This is the draw callback, the method is called during the draw phase.
virtual void | terminateKey (MDrawContext &context, const MString &key)
| This is the terminateKey callback.
virtual MHWRender::DrawAPI | supportedDrawAPIs () const
| Returns the draw API supported by this override.
virtual bool | isTransparent ()
| During the update phase the override will be called to return whether it will be drawing with semi-transparency.
virtual bool | overridesDrawState ()
| During the draw phase this method will be called to determine whether the override will override the draw state when drawing.
virtual bool | rebuildAlways ()
| If this method returns true, it will force shader and geometry data to be rebuilt on any change to the shader.
virtual void | activateKey (MDrawContext &context)
| This method is obsolete.
virtual void | terminateKey (MDrawContext &context)
| This method is obsolete.
## Static Public Member Functions
static const char * | className ()
| Returns the name of this class.
## Protected Member Functions
MStatus | addGeometryRequirement (const MVertexBufferDescriptor &desc)
| During the initialization phase the geometry requirements for the shading effect can be updated.
MStatus | addGeometryRequirements (const MVertexBufferDescriptorList &list)
| During the initialization phase the geometry requirements for the shading effect can be updated.
MStatus | addShaderSignature (void *signature, size_t signatureSize)
| During the initialization phase, the "signature" for the shader may be set.
MStatus | addIndexingRequirement (const MIndexBufferDescriptor &desc)
| During the initialization phase the indexing requirements for the shading effect can be updated.
void | drawGeometry (const MDrawContext &context) const
| This method may be called from draw() and will cause Maya to immediately draw the current geometry using the current state of the draw API.

## Constructor & Destructor Documentation

MPxShaderOverride | ( | const MObject & | obj | ) |

Construct an MPxShaderOverride.

Parameters:

  [in] | obj | The Maya shading node this override will be used for

## Member Function Documentation

MString initialize | ( | MObject | shader | ) | `[virtual]`

Search for all occurrences

Initialization occurs when Maya determines that the hardware shader needs to be rebuilt.

Any initialization work may be performed here. Also, this is the only time that calls to addGeometryRequirement() may occur.

Changes to parameter values on the Maya shading node will not trigger a call to this method by default. If parameter value changes may cause the shader to alter its geometry requirements, rebuildAlways() should be overridden to return true. This will cause initialize() to be called before every update.

The implementation of this method must return the shader key that is used to identify the MPxShaderOverride instances representing the same shader.

Note: There are two versions of the initialize method. Derived classes should override exactly one of them.

The default implementation returns a constant string.

Parameters:

  [in] | shader | The Maya shading node this override is used for

Returns:
  The shader key

MString initialize | ( | const MInitContext & | initContext,
|  | MInitFeedback & | initFeedback
| ) |  | `[virtual]`

Search for all occurrences

Initialization occurs when Maya determines that the hardware shader needs to be rebuilt.

Any initialization work may be performed here. Also, this is the only time that calls to addGeometryRequirement() may occur.

Changes to parameter values on the Maya shading node will not trigger a call to this method by default. If parameter value changes may cause the shader to alter its geometry requirements, rebuildAlways() should be overridden to return true. This will cause initialize() to be called before every update.

The implementation of this method must return the shader key that is used to identify the MPxShaderOverride instances representing the same shader.

Implementations of this method may also allocate and return custom user data derived from MUserData. This user data will be attached to the MRenderItem representing the association of the shader to the geometry instance specified by the initContext.dagPath parameter. If the deleteAfterUse() method returns true for the MUserData instance then the data object will automatically be deleted when the render item is deleted. Otherwise, the lifetime of the user data object is the responsibility of the caller. This user data may be accessed in the draw phase directly from the render item being drawn. Note that Maya objects which have render items that have custom user data can only be consolidated when the user data pointer on each item references the same user data instance. Draw performance will suffer without consolidation, however if the user data object is shared then memory management must be handled manually (ie. deleteAfterUse() should return false).

Note: There are two versions of the initialize method. Derived classes should override exactly one of them.

The default implementation simply returns the result of MPxShaderOverride::initialize(initContext.shader).

Parameters:

  [in] | initContext | Context information about the current initialization call, such as the path to the Maya object being bound to the shader.
  [out] | initFeedback | Data to return to Maya after initialization such as blind data to attach to the render item.

Returns:
  The shader key

void updateDG | ( | MObject | obj | ) | `[virtual]`

Search for all occurrences

This is the first part of the update phase.

Perform any work required to update the shading effect which is related to evaluating the dependency graph. This should be the only place that dependency graph evaluation occurs. Data retrieved from Maya may be cached on the override for use in later stages.

Parameters:

  [in] | obj | The Maya shading node this override is used for.

void updateDevice | ( |  | ) | `[virtual]`

Search for all occurrences

This is the second part of the update phase.

Perform any work required to update the shading effect which is related to accessing the underlying graphics device. This is the only place that the graphics device may be safely accessed other than at draw time.

void endUpdate | ( |  | ) | `[virtual]`

Search for all occurrences

This is the final part of the update phase.

This method is called by Maya to allow the plugin to clean up any data or state from the previous update stages. No dependency graph evaluation, nor graphics device access should be performed during this phase.

void activateKey | ( | MDrawContext & | context,
|  | const MString & | key
| ) |  | `[virtual]`

Search for all occurrences

This is the activateKey callback.

This method is called during the draw phase before invoking any draw() callback that are sharing a common shader key.

The default implementation is empty.

Parameters:

  [in,out] | context | The current draw context
  [in] | key | The shader key that is being activated

bool draw | ( | MDrawContext & | context,
|  | const MRenderItemList & | renderItemList
| ) |  | const `[pure virtual]`

Search for all occurrences

This is the draw callback, the method is called during the draw phase.

The expected implementation of this method is to do shader setup and then call drawGeometry() to allow Maya to handle the actual geometry drawing. It is however possible to do all shader setup and geometry draw here directly by accessing the hardware resource handles for geometry and index buffers through the geometry associated with each render item in the render item list.

No dependency graph evaluation should occur during this phase. If data from Maya is needed here it must be cached on this object (or elsewhere) during the update phase.

This method should return true on successful draw. If false is returned, Maya will attempt to draw using the default internal draw mechanism.

Information about the current GPU state may be accessed through the MDrawContext object passed to this method. The MRenderItemList object contains one render item for each object that is meant to be drawn by this method.

Parameters:

  [in,out] | context | The current draw context
  [in] | renderItemList | The list of renderable items to draw

Returns:
  True if draw was successful, false otherwise.

void terminateKey | ( | MDrawContext & | context,
|  | const MString & | key
| ) |  | `[virtual]`

Search for all occurrences

This is the terminateKey callback.

This method is called during the draw phase after invoking draw() callbacks that are sharing a common shader key.

The default implementation is empty.

Parameters:

  [in,out] | context | The current draw context
  [in] | key | The shader key that is being terminated

MHWRender::DrawAPI supportedDrawAPIs | ( |  | ) | const `[virtual]`

Search for all occurrences

Returns the draw API supported by this override.

The returned value may be formed as the bitwise 'or' of MHWRender::DrawAPI elements to indicate that the override supports multiple draw APIs. This method returns 'MHWRender::kOpenGL' by default.

Returns:
  The draw API supported by this override

bool isTransparent | ( |  | ) | `[virtual]`

Search for all occurrences

During the update phase the override will be called to return whether it will be drawing with semi-transparency.

This call occurs after updateDevice() which allows for any device evaluation to occur to determine the transparency state.

The default return value is false.

Returns:
  True if semi-transparent drawing should occur.

bool overridesDrawState | ( |  | ) | `[virtual]`

Search for all occurrences

During the draw phase this method will be called to determine whether the override will override the draw state when drawing.

This call occurs after updateDevice() which allows for any device evaluation to occur to determine if the override will override the draw state.

The Viewport 2.0 renderer will skip setting the draw state for plugins that will override the draw state when drawing. Note that the MPxShaderOverride::terminateKey() should still return the draw state to the value it had when activateKey was called.

The default return value is false.

Returns:
  True if the override overrides the draw state.

bool rebuildAlways | ( |  | ) | `[virtual]`

Search for all occurrences

If this method returns true, it will force shader and geometry data to be rebuilt on any change to the shader.

This may be necessary for shaders that request specific named data sets like UVs or CPVs. Any change to the required data set means that geometry needs to be rebuilt.

The default return value is false.

Returns:
  True if the shader and geometry should be rebuilt on every update.

const char * className | ( |  | ) | `[static]`

Search for all occurrences

Returns the name of this class.

Returns:
  Name of this class.

MStatus addGeometryRequirement | ( | const MVertexBufferDescriptor & | desc | ) | `[protected]`

Search for all occurrences

During the initialization phase the geometry requirements for the shading effect can be updated.

The update is accomplished by calling this method once for each new data stream that needs to be added to the list of requirements.

If the geometry has multiple fields of the same type associated with it (e.g. multiple UV sets) the 'name' attribute of the vertex descriptor can be used to select the desired one. If that member is empty or does not match any of the fields then the default field of that type will be used.

Not all combinations of the 'semantic', 'dataType' and 'dimension' attributes of the vertex descriptor are permitted. Currently position, normal, tangent and bitangent vectors are 3-float, tangent with sign vectors are 4-float, texture coordinates are 2-float, and colors are 4-float.

Parameters:

  [in] | desc | The description of the geometry requirement to add

Returns:
  Status code

Status Codes:
  - MS::kSuccess Requirement was added.
  - MS::kFailure Object error.
  - MS::kInvalidParameter An unsupported 'semantic' was specified; or the 'dataType'/'dimension' was not compatible with the 'semantic'.
  - MS::kNotImplemented Requirement could not be added because method was called from outside of initialization phase.

MStatus addGeometryRequirements | ( | const MVertexBufferDescriptorList & | list | ) | `[protected]`

Search for all occurrences

During the initialization phase the geometry requirements for the shading effect can be updated.

The update is accomplished by calling this method with a list containing descriptions of all data streams that are required by the shader.

If the geometry has multiple fields of the same type associated with it (e.g. multiple UV sets) the 'name' attribute of the vertex descriptor can be used to select the desired one. If that member is empty or does not match any of the fields then the default field of that type will be used.

Not all combinations of the 'semantic', 'dataType' and 'dimension' attributes of the vertex descriptor are permitted. Currently position, normal, tangent and bitangent vectors are 3-float, texture coordinates are 2-float, and colors are 4-float.

This method will attempt to add as many requirements as possible from the list, skipping invalid ones. If kInvalidParameter is returned it means at least one requirement failed to be added.

Parameters:

  [in] | list | The list of descriptions of the geometry requirements to add

Returns:
  Status code

Status Codes:
  - MS::kSuccess Requirements were added.
  - MS::kFailure Object error.
  - MS::kInvalidParameter An unsupported 'semantic' was specified; or the 'dataType'/'dimension' was not compatible with the 'semantic'.
  - MS::kNotImplemented Requirements could not be added because method was called from outside of initialization phase.

MStatus addShaderSignature | ( | void * | signature,
|  | size_t | signatureSize
| ) |  | `[protected]`

Search for all occurrences

During the initialization phase, the "signature" for the shader may be set.

Certain Draw APIs require a signature to allow a shading effect to be properly activated. The signature will be used if the override uses MPxShaderOverride::drawGeometry() in the draw phase in order to perform drawing. If drawing is done manually, adding a shader signature is not necessary.

Parameters:

  [in] | signature | The signature of the shader
  [in] | signatureSize | The size of the signature block

Returns:
  Status code

Status Codes:
  - MS::kSuccess Signature was set.
  - MS::kNotImplemented Signature could not be set because method was called from outside of initialization phase.

MStatus addIndexingRequirement | ( | const MIndexBufferDescriptor & | desc | ) | `[protected]`

Search for all occurrences

During the initialization phase the indexing requirements for the shading effect can be updated.

The update is accomplished by calling this method once for each new index stream required by the shader.

A shader override can specify the type of primitive it supports. If the shader relies on a special primitive type like kPatch it should use this method to indicate that requirement to the system. Not all fields on the MIndexBufferDescriptor need to be filled in when using this method. Only the name(), primitive(), and primitiveStride() values are important for a shader to report as requirements.

The primitive type must be specified if the shader requires a primitive type different then a standard point, line, or triangle list or strip. The primitiveStride must be specified if using the kPatch primitive type. Valid values range from 1 - 32. The name can be specified to trigger a custom MPxPrimitiveGenerator plugin to be used to produce the desired primitive tessellation. When requesting custom primitives you should register an MPxPrimitiveGenerator that knows how to produce the custom primitive needed by the shader.

Parameters:

  [in] | desc | The description of the indexing requirement to add

Returns:
  Status code

Status Codes:
  - MS::kSuccess Requirement was added.
  - MS::kFailure Object error.

void drawGeometry | ( | const MDrawContext & | context | ) | const `[protected]`

Search for all occurrences

This method may be called from draw() and will cause Maya to immediately draw the current geometry using the current state of the draw API.

Parameters:

  [in] | context | The current draw context

Examples:
  hwPhongShader.cpp.

void activateKey | ( | MDrawContext & | context | ) | `[virtual]`

Search for all occurrences

This method is obsolete.

Deprecated:
  Use the activateKey(MDrawContext&, const MString&) version instead.

Parameters:

  [in,out] | context |

void terminateKey | ( | MDrawContext & | context | ) | `[virtual]`

Search for all occurrences

This method is obsolete.

Deprecated:
  Use the terminateKey(MDrawContext&, const MString&) version instead.

Parameters:

  [in,out] | context |

MPxShaderOverride MPxShaderOverride MPxShaderOverride MPxShaderOverride MPxShaderOverride MPxShaderOverride MPxShaderOverride MPxShaderOverride MPxShaderOverride MPxShaderOverride
MPxShaderOverride MPxShaderOverride MPxShaderOverride MPxShaderOverride MPxShaderOverride MPxShaderOverride MPxShaderOverride MPxShaderOverride MPxShaderOverride MPxShaderOverride