![]()
Drawing and refresh
Drawing is a two step process. In the first, the geometry and materials are evaluated and all of the information necessary for drawing is placed onto a queue. In the second, the actual OpenGL drawing occurs. This two step process allows your shapes to take advantage of the multi-threaded drawing capabilities of Maya.
Drawing occurs whenever the camera changes or the view has to be refreshed. When this happens, the
MPxSurfaceShapeUI::getDrawRequestfunction is called. This is Maya’s way of asking the shape what it needs to draw. Inside this function you should query the drawing state, usingMDrawInfo, and then construct a draw request (MDrawRequest) to place on the queue. You will often want to place multiple requests on the queue (MDrawRequestQueue) in this function. For instance, in shaded mode if your shape is selected you may want to add a request to draw the shaded object and another request to draw wireframe on top of the shaded object.The draw data (
MDrawData) holds information specific to your shape which Maya does not intrinsically know about. The draw data acts as a container to pass your geometry through the draw request queue. For each draw request you must create and add a draw data object which contains geometry-specific information that you will need in the subsequent call toMPxSurfaceShapeUI::draw.To create draw data, use the function
MPxSurfaceShapeUI::getDrawDataand to add the data to a request useMDrawRequest::setDrawData. The following example shows how to create a draw request and draw data for your geometry.void yourShapeUI::getDrawRequests( const MDrawInfo & info, bool objectAndActiveOnly, MDrawRequestQueue & queue ) { MDrawData data; MDrawRequest request = info.getPrototype( *this ); yourShape* shapeNode = (yourShape*)surfaceShape(); yourGeom* geom = shapeNode->geometry(); getDrawData( geom, data ); request.setDrawData( data ); ... }The draw request (
MDrawRequest) should be created in the overriddenMPxSurfaceShapeUI::getDrawRequestsmethod. Once the request is created the appropriate “set” methods of this class should be used to define what is being requested. Then the request should be placed on the draw request queue usingMDrawRequestQueue::add.The draw token is an integer value which you can use to specify what is to be drawn. This is object specific and so you should define an enum with the information you require to decide what is being drawn in your
MPxSurfaceShapeUI::drawmethod. Here is an example of a draw token for a mesh object:enum {kDrawVertices, // component tokenkDrawWireframe,kDrawWireframeOnShaded,kDrawSmoothShaded,kDrawFlatShaded,kLastToken};Maya processes the draw request queue and for each draw request, calls the corresponding objects draw function. In the case of user defined shapes, your
MPxSurfaceShapeUI::drawmethod is called.Drawing in shaded mode
Supporting shaded mode display is a two step process. The first step occurs in your
getDrawRequestsfunction. Here you must “evaluate” or setup the material so that it can be displayed when your object is drawn. The second step occurs in your draw function where you must setup the view to display the material.The following code demonstrates how to setup the material in your
getDrawRequestsfunction if the request is for shaded mode display.MDagPath path = info.multiPath(); M3dView view = info.view(); MMaterial material = MPxSurfaceShapeUI::material( path ); material.evaluateMaterial( view, path ); if ( material.materialIsTextured() ) { material.evaluateTexture( data ); } request.setMaterial( material );In your draw function you will need to setup the scene view so that it can display the material. This is done using
MMaterial::setMaterial. To set up the scene view to display textures, useMMaterial::applyTexture. The following code demonstrates this.void yourShapeUI::draw( const MDrawRequest& request, M3dView & view ) const { ... MMaterial material = request.material(); material.setMaterial( request.isTransparent() ); drawTexture = material.materialIsTextured(); if ( drawTexture ) glEnable(GL_TEXTURE_2D); if ( drawTexture ) { material.applyTexture( view, data ); } ... }