The scene override classes allow plug-ins to override elements of the scene, including geometry, shaders, and other renderable elements. These classes provide new APIs to replace the old rendering code in MPxLocatorNode, MPxSurfaceShape, MPxComponentShape, MPxHwShaderNode, and MPxHardwareShader. You can also define hardware shader fragment code for plug-in software shading nodes derived from MPxNode. User plug-ins can continue to derive off these existing base classes; however, you must register one of the following overrides to define your custom rendering logic in Viewport 2.0. Therefore, you can leave your existing rendering code in place, allowing your plug-in to work simultaneously in the legacy viewports and Viewport 2.0 as you transition your pipeline across. Legacy viewport drawing continues to call into the old code, and Viewport 2.0 uses the overrides defined below.
While many of the old interfaces provided raw C++ interfaces at render time, this approach does not provide the best performance, particularly when you have large numbers of plugin elements in the scene. The new overrides use the geometry data objects above to support a cached, retained mode rendering interface that more clearly separates shaders and shapes, and also allows them both to benefit from many of the performance optimizations in the new viewport (such as geometry consolidation). Having said this, there are still times where you'll want total control over what is rendered, so we still provide an immediate mode interface to succeed the interfaces provided in MPxLocatorNode and MPxSurfaceShapeUI.
MPxDrawOverride formalizes the draw override functionality provided by the old MPxLocatorNode class. It provides a simple interface that allows users to make arbitrary OpenGL calls whenever a specific shape type needs to be drawn by Maya. When using this interface, your plugin assumes full control over all the geometry and material resources and setup required to draw. This also means your plugin will not benefit from the resource management and resource optimizations provided by the new viewport. However for light-UI or large proxy geometry, this can still be a good approach.
Implementations of MPxDrawOverride must be registered with the MDrawRegistry class against a specific type of Maya DAG object (either plugin or standard). Registration is by classification string. This class can be used to provide drawing for plugin shapes or to completely override the draw of standard shapes like meshes or NURBS surfaces. For a DAG object type to be recognized by Viewport 2.0, it must be registered with a classification string that begins with “drawdb/geometry/” and this is the same classification string that is used to register the implementation of MPxDrawOverride. For example, the standard Maya mesh type is registered as “drawdb/geometry/mesh” and so to override the standard draw with an implementation of MPxDrawOverride one would register that implementation with the classification string “drawdb/geometry/mesh”.
This class provides very low-level access to the draw. It is necessary to manually set up all shaders and do proper state management in order to get correct drawing and to avoid corrupting the draw of other objects. A new utility class called MDrawContext has been added to assist with state management. An instance of this object is always passed into the draw call of MPxDrawOverride.
For a higher level interface to geometry, see the new MPxGeometryOverride class.
This class represents one of the larger changes from the old API. Where MPxSurfaceShapeUI gave you C++ draw control, MPxGeometryOverride is purely an interface for defining geometry and render items. All control of the actual rendering is left to the shader. By doing this, this class can work with external shaders and it can leverage performance optimization such as geometry consolidation.
MPxGeometryOverride is a high-level interface that allows the user to provide geometry buffers, index buffers and custom render items that will be used by the Viewport 2.0 system to draw a specific DAG object. Data is primarily transferred through the MGeometry class described above. Implementations of MPxGeometryOverride must be registered against the DAG object type just like MPxDrawOverride.
An implementation of MPxGeometryOverride is invoked when an associated DAG object changes. The implementation is expected to provide updated geometry buffers and indexing information which will be packed by Viewport 2.0 and stored on the graphics card (if possible). MPxGeometryOverride is only invoked when something needs updating and not on every frame.
Similar to MPxDrawOverride, MPxGeometryOverride can be used to provide geometry for either plugin shapes or to override the behaviour of standard Maya shapes. The biggest advantage to using this higher level class is that objects which use it will automatically work with any shader supported by Viewport 2.0. This class also requires no direct OpenGL knowledge as it is device independent.
MPxSubSceneOverride is an alternative to MPxDrawOverride and MPxGeometryOverride, and is specifically optimized for representing plug-in DAG objects in Viewport 2.0 that need to produce a large number of independent drawable objects. For example, a plug-in node that can define a whole sub-scene (like the gpuCache plug-in) is a good fit for this interface, as a single node may need to produce tens of thousands of drawable objects.
Implementations of MPxSubSceneOverride operate using the MRenderItem interface and provide a list of the render items needed to draw all instances of the associated DAG object. Implementations must be registered against the DAG object type, just like MPxDrawOverride.
The render items produced by an implementation of MPxSubSceneOverride are stored in a specialized container that is optimized for dealing with large numbers of render items (tens of thousands or more), in a high performance manner. Implementations are responsible for assigning a shader and an optional matrix to each render item, and must also provide the geometry for each render item as required by its shader. Geometry may be shared between render items and management of the geometry is up to the implementation.
MPxSubSceneOverride falls in between MPxDrawOverride and MPxGeometryOverride with respect to the amount of control given to the implementation. MPxDrawOverride allows full control over the entire draw of the object, but as a result the implementation is entirely responsible for the draw. MPxGeometryOverride is relatively simple to work with, but as a result only limited control of the draw is available. MPxSubSceneOverride is allowed to fully define all render items, geometry, and shaders, providing a high degree of control. However, this definition is abstracted from the hardware draw API; therefore, only one implementation is needed to get support for both DirectX and OpenGL. Furthermore, Maya handles the drawing of the render items, and thus the items can participate more fully in the Maya rendering pipeline (including screen-space effects such as screen space ambient occlusion, transparency sorting, shadow casting/receiving, and so forth).
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 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.
Like MPxDrawOverride, this is a low-level class. Any object using an instance of the associated shader to draw will trigger the MPxShaderOverride draw callback at draw time. The implementation is responsible for setting up all shading information. It can then either query the geometry itself through the MDrawContext to do all binding and drawing; or, it can make a call back into Maya to allow Viewport 2.0 to handle the draw using the current state.
Like the other two new interfaces, MPxShaderOverride must be registered with MDrawRegistry using a classification string. This means it can be associated with either a plugin shader type or with an existing Maya shader type. Viewport 2.0 shader classification strings must begin with “drawdb/shader/” (for example, the standard lambert is “drawdb/shader/surface/lambert”).
MPxShadingNodeOverride allows the user to specify how a plug-in software shading node (derived from MPxNode) should interact with other software shading nodes in Viewport 2.0. Specifically, this class lets you inform Maya of the shading fragment (or fragment graph) to use to represent the shading node in the Viewport 2.0 shading graph. Using this system, plug-in software shading nodes may function seamlessly with both internal shading nodes as well as plug-in shading nodes from unrelated plug-ins. All other features of Viewport 2.0 (lights, shadows, effects, transparency, and so forth) also work seamlessly with implementations of MPxShadingNodeOverride.
MPxShadingNodeOverride differs from MPxShaderOverride in that implementations of MPxShaderOverride must produce the entire shading effect for a shading network (including lighting), while MPxShadingNodeOverride is only required to produce a small fragment for an individual node.
Shading fragments and graphs are managed by MFragmentManager. New fragments and/or graphs may be defined using XML and registered with Maya through MFragmentManager. These fragments and graphs may then be referenced by implementations of MPxShadingNodeOverride.
Like MPxShaderOverride, implementations of MPxShadingNodeOverride must be registered with MDrawRegistry using a classification string. This means that implementations can be associated with plug-in nodes, or can be used to override the behaviour of existing Maya shaders. Viewport 2.0 shader classification strings must begin with "drawdb/shader/" (for example, the Maya procedural checker texture is classified with "drawdb/shader/texture/2d/checker").
MPxSurfaceShadingNodeOverride is an extension of MPxShadingNodeOverride, which is specialized for software surface shader nodes. When providing support for Viewport 2.0, plug-in software surface shader nodes that may be connected directly to a Maya shading engine must define an override that derives from this class instead of MPxShadingNodeOverride, in order to be treated like a surface shader by the Viewport 2.0 translation system.
Like MPxShadingNodeOverride, implementations of MPxSurfaceShadingNodeOverride must be registered with MDrawRegistry using a classification string. Viewport 2.0 surface shader classification strings must begin with "drawdb/shader/surface/" (for example, the Maya blinn shader is classified with "drawdb/shader/surface/blinn").